]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/mfd/sec-irq.c
arm: imx6qdl: tx6: defconfig: mfg tool
[karo-tx-linux.git] / drivers / mfd / sec-irq.c
1 /*
2  * sec-irq.c
3  *
4  * Copyright (c) 2011-2014 Samsung Electronics Co., Ltd
5  *              http://www.samsung.com
6  *
7  *  This program is free software; you can redistribute  it and/or modify it
8  *  under  the terms of  the GNU General  Public License as published by the
9  *  Free Software Foundation;  either version 2 of the  License, or (at your
10  *  option) any later version.
11  *
12  */
13
14 #include <linux/device.h>
15 #include <linux/interrupt.h>
16 #include <linux/irq.h>
17 #include <linux/regmap.h>
18
19 #include <linux/mfd/samsung/core.h>
20 #include <linux/mfd/samsung/irq.h>
21 #include <linux/mfd/samsung/s2mps11.h>
22 #include <linux/mfd/samsung/s2mps14.h>
23 #include <linux/mfd/samsung/s5m8763.h>
24 #include <linux/mfd/samsung/s5m8767.h>
25
26 static const struct regmap_irq s2mps11_irqs[] = {
27         [S2MPS11_IRQ_PWRONF] = {
28                 .reg_offset = 0,
29                 .mask = S2MPS11_IRQ_PWRONF_MASK,
30         },
31         [S2MPS11_IRQ_PWRONR] = {
32                 .reg_offset = 0,
33                 .mask = S2MPS11_IRQ_PWRONR_MASK,
34         },
35         [S2MPS11_IRQ_JIGONBF] = {
36                 .reg_offset = 0,
37                 .mask = S2MPS11_IRQ_JIGONBF_MASK,
38         },
39         [S2MPS11_IRQ_JIGONBR] = {
40                 .reg_offset = 0,
41                 .mask = S2MPS11_IRQ_JIGONBR_MASK,
42         },
43         [S2MPS11_IRQ_ACOKBF] = {
44                 .reg_offset = 0,
45                 .mask = S2MPS11_IRQ_ACOKBF_MASK,
46         },
47         [S2MPS11_IRQ_ACOKBR] = {
48                 .reg_offset = 0,
49                 .mask = S2MPS11_IRQ_ACOKBR_MASK,
50         },
51         [S2MPS11_IRQ_PWRON1S] = {
52                 .reg_offset = 0,
53                 .mask = S2MPS11_IRQ_PWRON1S_MASK,
54         },
55         [S2MPS11_IRQ_MRB] = {
56                 .reg_offset = 0,
57                 .mask = S2MPS11_IRQ_MRB_MASK,
58         },
59         [S2MPS11_IRQ_RTC60S] = {
60                 .reg_offset = 1,
61                 .mask = S2MPS11_IRQ_RTC60S_MASK,
62         },
63         [S2MPS11_IRQ_RTCA0] = {
64                 .reg_offset = 1,
65                 .mask = S2MPS11_IRQ_RTCA0_MASK,
66         },
67         [S2MPS11_IRQ_RTCA1] = {
68                 .reg_offset = 1,
69                 .mask = S2MPS11_IRQ_RTCA1_MASK,
70         },
71         [S2MPS11_IRQ_SMPL] = {
72                 .reg_offset = 1,
73                 .mask = S2MPS11_IRQ_SMPL_MASK,
74         },
75         [S2MPS11_IRQ_RTC1S] = {
76                 .reg_offset = 1,
77                 .mask = S2MPS11_IRQ_RTC1S_MASK,
78         },
79         [S2MPS11_IRQ_WTSR] = {
80                 .reg_offset = 1,
81                 .mask = S2MPS11_IRQ_WTSR_MASK,
82         },
83         [S2MPS11_IRQ_INT120C] = {
84                 .reg_offset = 2,
85                 .mask = S2MPS11_IRQ_INT120C_MASK,
86         },
87         [S2MPS11_IRQ_INT140C] = {
88                 .reg_offset = 2,
89                 .mask = S2MPS11_IRQ_INT140C_MASK,
90         },
91 };
92
93 static const struct regmap_irq s2mps14_irqs[] = {
94         [S2MPS14_IRQ_PWRONF] = {
95                 .reg_offset = 0,
96                 .mask = S2MPS11_IRQ_PWRONF_MASK,
97         },
98         [S2MPS14_IRQ_PWRONR] = {
99                 .reg_offset = 0,
100                 .mask = S2MPS11_IRQ_PWRONR_MASK,
101         },
102         [S2MPS14_IRQ_JIGONBF] = {
103                 .reg_offset = 0,
104                 .mask = S2MPS11_IRQ_JIGONBF_MASK,
105         },
106         [S2MPS14_IRQ_JIGONBR] = {
107                 .reg_offset = 0,
108                 .mask = S2MPS11_IRQ_JIGONBR_MASK,
109         },
110         [S2MPS14_IRQ_ACOKBF] = {
111                 .reg_offset = 0,
112                 .mask = S2MPS11_IRQ_ACOKBF_MASK,
113         },
114         [S2MPS14_IRQ_ACOKBR] = {
115                 .reg_offset = 0,
116                 .mask = S2MPS11_IRQ_ACOKBR_MASK,
117         },
118         [S2MPS14_IRQ_PWRON1S] = {
119                 .reg_offset = 0,
120                 .mask = S2MPS11_IRQ_PWRON1S_MASK,
121         },
122         [S2MPS14_IRQ_MRB] = {
123                 .reg_offset = 0,
124                 .mask = S2MPS11_IRQ_MRB_MASK,
125         },
126         [S2MPS14_IRQ_RTC60S] = {
127                 .reg_offset = 1,
128                 .mask = S2MPS11_IRQ_RTC60S_MASK,
129         },
130         [S2MPS14_IRQ_RTCA1] = {
131                 .reg_offset = 1,
132                 .mask = S2MPS11_IRQ_RTCA1_MASK,
133         },
134         [S2MPS14_IRQ_RTCA0] = {
135                 .reg_offset = 1,
136                 .mask = S2MPS11_IRQ_RTCA0_MASK,
137         },
138         [S2MPS14_IRQ_SMPL] = {
139                 .reg_offset = 1,
140                 .mask = S2MPS11_IRQ_SMPL_MASK,
141         },
142         [S2MPS14_IRQ_RTC1S] = {
143                 .reg_offset = 1,
144                 .mask = S2MPS11_IRQ_RTC1S_MASK,
145         },
146         [S2MPS14_IRQ_WTSR] = {
147                 .reg_offset = 1,
148                 .mask = S2MPS11_IRQ_WTSR_MASK,
149         },
150         [S2MPS14_IRQ_INT120C] = {
151                 .reg_offset = 2,
152                 .mask = S2MPS11_IRQ_INT120C_MASK,
153         },
154         [S2MPS14_IRQ_INT140C] = {
155                 .reg_offset = 2,
156                 .mask = S2MPS11_IRQ_INT140C_MASK,
157         },
158         [S2MPS14_IRQ_TSD] = {
159                 .reg_offset = 2,
160                 .mask = S2MPS14_IRQ_TSD_MASK,
161         },
162 };
163
164 static const struct regmap_irq s5m8767_irqs[] = {
165         [S5M8767_IRQ_PWRR] = {
166                 .reg_offset = 0,
167                 .mask = S5M8767_IRQ_PWRR_MASK,
168         },
169         [S5M8767_IRQ_PWRF] = {
170                 .reg_offset = 0,
171                 .mask = S5M8767_IRQ_PWRF_MASK,
172         },
173         [S5M8767_IRQ_PWR1S] = {
174                 .reg_offset = 0,
175                 .mask = S5M8767_IRQ_PWR1S_MASK,
176         },
177         [S5M8767_IRQ_JIGR] = {
178                 .reg_offset = 0,
179                 .mask = S5M8767_IRQ_JIGR_MASK,
180         },
181         [S5M8767_IRQ_JIGF] = {
182                 .reg_offset = 0,
183                 .mask = S5M8767_IRQ_JIGF_MASK,
184         },
185         [S5M8767_IRQ_LOWBAT2] = {
186                 .reg_offset = 0,
187                 .mask = S5M8767_IRQ_LOWBAT2_MASK,
188         },
189         [S5M8767_IRQ_LOWBAT1] = {
190                 .reg_offset = 0,
191                 .mask = S5M8767_IRQ_LOWBAT1_MASK,
192         },
193         [S5M8767_IRQ_MRB] = {
194                 .reg_offset = 1,
195                 .mask = S5M8767_IRQ_MRB_MASK,
196         },
197         [S5M8767_IRQ_DVSOK2] = {
198                 .reg_offset = 1,
199                 .mask = S5M8767_IRQ_DVSOK2_MASK,
200         },
201         [S5M8767_IRQ_DVSOK3] = {
202                 .reg_offset = 1,
203                 .mask = S5M8767_IRQ_DVSOK3_MASK,
204         },
205         [S5M8767_IRQ_DVSOK4] = {
206                 .reg_offset = 1,
207                 .mask = S5M8767_IRQ_DVSOK4_MASK,
208         },
209         [S5M8767_IRQ_RTC60S] = {
210                 .reg_offset = 2,
211                 .mask = S5M8767_IRQ_RTC60S_MASK,
212         },
213         [S5M8767_IRQ_RTCA1] = {
214                 .reg_offset = 2,
215                 .mask = S5M8767_IRQ_RTCA1_MASK,
216         },
217         [S5M8767_IRQ_RTCA2] = {
218                 .reg_offset = 2,
219                 .mask = S5M8767_IRQ_RTCA2_MASK,
220         },
221         [S5M8767_IRQ_SMPL] = {
222                 .reg_offset = 2,
223                 .mask = S5M8767_IRQ_SMPL_MASK,
224         },
225         [S5M8767_IRQ_RTC1S] = {
226                 .reg_offset = 2,
227                 .mask = S5M8767_IRQ_RTC1S_MASK,
228         },
229         [S5M8767_IRQ_WTSR] = {
230                 .reg_offset = 2,
231                 .mask = S5M8767_IRQ_WTSR_MASK,
232         },
233 };
234
235 static const struct regmap_irq s5m8763_irqs[] = {
236         [S5M8763_IRQ_DCINF] = {
237                 .reg_offset = 0,
238                 .mask = S5M8763_IRQ_DCINF_MASK,
239         },
240         [S5M8763_IRQ_DCINR] = {
241                 .reg_offset = 0,
242                 .mask = S5M8763_IRQ_DCINR_MASK,
243         },
244         [S5M8763_IRQ_JIGF] = {
245                 .reg_offset = 0,
246                 .mask = S5M8763_IRQ_JIGF_MASK,
247         },
248         [S5M8763_IRQ_JIGR] = {
249                 .reg_offset = 0,
250                 .mask = S5M8763_IRQ_JIGR_MASK,
251         },
252         [S5M8763_IRQ_PWRONF] = {
253                 .reg_offset = 0,
254                 .mask = S5M8763_IRQ_PWRONF_MASK,
255         },
256         [S5M8763_IRQ_PWRONR] = {
257                 .reg_offset = 0,
258                 .mask = S5M8763_IRQ_PWRONR_MASK,
259         },
260         [S5M8763_IRQ_WTSREVNT] = {
261                 .reg_offset = 1,
262                 .mask = S5M8763_IRQ_WTSREVNT_MASK,
263         },
264         [S5M8763_IRQ_SMPLEVNT] = {
265                 .reg_offset = 1,
266                 .mask = S5M8763_IRQ_SMPLEVNT_MASK,
267         },
268         [S5M8763_IRQ_ALARM1] = {
269                 .reg_offset = 1,
270                 .mask = S5M8763_IRQ_ALARM1_MASK,
271         },
272         [S5M8763_IRQ_ALARM0] = {
273                 .reg_offset = 1,
274                 .mask = S5M8763_IRQ_ALARM0_MASK,
275         },
276         [S5M8763_IRQ_ONKEY1S] = {
277                 .reg_offset = 2,
278                 .mask = S5M8763_IRQ_ONKEY1S_MASK,
279         },
280         [S5M8763_IRQ_TOPOFFR] = {
281                 .reg_offset = 2,
282                 .mask = S5M8763_IRQ_TOPOFFR_MASK,
283         },
284         [S5M8763_IRQ_DCINOVPR] = {
285                 .reg_offset = 2,
286                 .mask = S5M8763_IRQ_DCINOVPR_MASK,
287         },
288         [S5M8763_IRQ_CHGRSTF] = {
289                 .reg_offset = 2,
290                 .mask = S5M8763_IRQ_CHGRSTF_MASK,
291         },
292         [S5M8763_IRQ_DONER] = {
293                 .reg_offset = 2,
294                 .mask = S5M8763_IRQ_DONER_MASK,
295         },
296         [S5M8763_IRQ_CHGFAULT] = {
297                 .reg_offset = 2,
298                 .mask = S5M8763_IRQ_CHGFAULT_MASK,
299         },
300         [S5M8763_IRQ_LOBAT1] = {
301                 .reg_offset = 3,
302                 .mask = S5M8763_IRQ_LOBAT1_MASK,
303         },
304         [S5M8763_IRQ_LOBAT2] = {
305                 .reg_offset = 3,
306                 .mask = S5M8763_IRQ_LOBAT2_MASK,
307         },
308 };
309
310 static const struct regmap_irq_chip s2mps11_irq_chip = {
311         .name = "s2mps11",
312         .irqs = s2mps11_irqs,
313         .num_irqs = ARRAY_SIZE(s2mps11_irqs),
314         .num_regs = 3,
315         .status_base = S2MPS11_REG_INT1,
316         .mask_base = S2MPS11_REG_INT1M,
317         .ack_base = S2MPS11_REG_INT1,
318 };
319
320 static const struct regmap_irq_chip s2mps14_irq_chip = {
321         .name = "s2mps14",
322         .irqs = s2mps14_irqs,
323         .num_irqs = ARRAY_SIZE(s2mps14_irqs),
324         .num_regs = 3,
325         .status_base = S2MPS14_REG_INT1,
326         .mask_base = S2MPS14_REG_INT1M,
327         .ack_base = S2MPS14_REG_INT1,
328 };
329
330 static const struct regmap_irq_chip s5m8767_irq_chip = {
331         .name = "s5m8767",
332         .irqs = s5m8767_irqs,
333         .num_irqs = ARRAY_SIZE(s5m8767_irqs),
334         .num_regs = 3,
335         .status_base = S5M8767_REG_INT1,
336         .mask_base = S5M8767_REG_INT1M,
337         .ack_base = S5M8767_REG_INT1,
338 };
339
340 static const struct regmap_irq_chip s5m8763_irq_chip = {
341         .name = "s5m8763",
342         .irqs = s5m8763_irqs,
343         .num_irqs = ARRAY_SIZE(s5m8763_irqs),
344         .num_regs = 4,
345         .status_base = S5M8763_REG_IRQ1,
346         .mask_base = S5M8763_REG_IRQM1,
347         .ack_base = S5M8763_REG_IRQ1,
348 };
349
350 int sec_irq_init(struct sec_pmic_dev *sec_pmic)
351 {
352         int ret = 0;
353         int type = sec_pmic->device_type;
354
355         if (!sec_pmic->irq) {
356                 dev_warn(sec_pmic->dev,
357                          "No interrupt specified, no interrupts\n");
358                 sec_pmic->irq_base = 0;
359                 return 0;
360         }
361
362         switch (type) {
363         case S5M8763X:
364                 ret = regmap_add_irq_chip(sec_pmic->regmap_pmic, sec_pmic->irq,
365                                   IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
366                                   sec_pmic->irq_base, &s5m8763_irq_chip,
367                                   &sec_pmic->irq_data);
368                 break;
369         case S5M8767X:
370                 ret = regmap_add_irq_chip(sec_pmic->regmap_pmic, sec_pmic->irq,
371                                   IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
372                                   sec_pmic->irq_base, &s5m8767_irq_chip,
373                                   &sec_pmic->irq_data);
374                 break;
375         case S2MPS11X:
376                 ret = regmap_add_irq_chip(sec_pmic->regmap_pmic, sec_pmic->irq,
377                                   IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
378                                   sec_pmic->irq_base, &s2mps11_irq_chip,
379                                   &sec_pmic->irq_data);
380                 break;
381         case S2MPS14X:
382                 ret = regmap_add_irq_chip(sec_pmic->regmap_pmic, sec_pmic->irq,
383                                   IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
384                                   sec_pmic->irq_base, &s2mps14_irq_chip,
385                                   &sec_pmic->irq_data);
386                 break;
387         default:
388                 dev_err(sec_pmic->dev, "Unknown device type %lu\n",
389                         sec_pmic->device_type);
390                 return -EINVAL;
391         }
392
393         if (ret != 0) {
394                 dev_err(sec_pmic->dev, "Failed to register IRQ chip: %d\n", ret);
395                 return ret;
396         }
397
398         return 0;
399 }
400
401 void sec_irq_exit(struct sec_pmic_dev *sec_pmic)
402 {
403         regmap_del_irq_chip(sec_pmic->irq, sec_pmic->irq_data);
404 }