4 * Copyright (c) 2011-2014 Samsung Electronics Co., Ltd
5 * http://www.samsung.com
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.
14 #include <linux/device.h>
15 #include <linux/interrupt.h>
16 #include <linux/irq.h>
17 #include <linux/regmap.h>
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/s2mpu02.h>
24 #include <linux/mfd/samsung/s5m8763.h>
25 #include <linux/mfd/samsung/s5m8767.h>
27 static const struct regmap_irq s2mps11_irqs
[] = {
28 [S2MPS11_IRQ_PWRONF
] = {
30 .mask
= S2MPS11_IRQ_PWRONF_MASK
,
32 [S2MPS11_IRQ_PWRONR
] = {
34 .mask
= S2MPS11_IRQ_PWRONR_MASK
,
36 [S2MPS11_IRQ_JIGONBF
] = {
38 .mask
= S2MPS11_IRQ_JIGONBF_MASK
,
40 [S2MPS11_IRQ_JIGONBR
] = {
42 .mask
= S2MPS11_IRQ_JIGONBR_MASK
,
44 [S2MPS11_IRQ_ACOKBF
] = {
46 .mask
= S2MPS11_IRQ_ACOKBF_MASK
,
48 [S2MPS11_IRQ_ACOKBR
] = {
50 .mask
= S2MPS11_IRQ_ACOKBR_MASK
,
52 [S2MPS11_IRQ_PWRON1S
] = {
54 .mask
= S2MPS11_IRQ_PWRON1S_MASK
,
58 .mask
= S2MPS11_IRQ_MRB_MASK
,
60 [S2MPS11_IRQ_RTC60S
] = {
62 .mask
= S2MPS11_IRQ_RTC60S_MASK
,
64 [S2MPS11_IRQ_RTCA1
] = {
66 .mask
= S2MPS11_IRQ_RTCA1_MASK
,
68 [S2MPS11_IRQ_RTCA0
] = {
70 .mask
= S2MPS11_IRQ_RTCA0_MASK
,
72 [S2MPS11_IRQ_SMPL
] = {
74 .mask
= S2MPS11_IRQ_SMPL_MASK
,
76 [S2MPS11_IRQ_RTC1S
] = {
78 .mask
= S2MPS11_IRQ_RTC1S_MASK
,
80 [S2MPS11_IRQ_WTSR
] = {
82 .mask
= S2MPS11_IRQ_WTSR_MASK
,
84 [S2MPS11_IRQ_INT120C
] = {
86 .mask
= S2MPS11_IRQ_INT120C_MASK
,
88 [S2MPS11_IRQ_INT140C
] = {
90 .mask
= S2MPS11_IRQ_INT140C_MASK
,
94 static const struct regmap_irq s2mps14_irqs
[] = {
95 [S2MPS14_IRQ_PWRONF
] = {
97 .mask
= S2MPS11_IRQ_PWRONF_MASK
,
99 [S2MPS14_IRQ_PWRONR
] = {
101 .mask
= S2MPS11_IRQ_PWRONR_MASK
,
103 [S2MPS14_IRQ_JIGONBF
] = {
105 .mask
= S2MPS11_IRQ_JIGONBF_MASK
,
107 [S2MPS14_IRQ_JIGONBR
] = {
109 .mask
= S2MPS11_IRQ_JIGONBR_MASK
,
111 [S2MPS14_IRQ_ACOKBF
] = {
113 .mask
= S2MPS11_IRQ_ACOKBF_MASK
,
115 [S2MPS14_IRQ_ACOKBR
] = {
117 .mask
= S2MPS11_IRQ_ACOKBR_MASK
,
119 [S2MPS14_IRQ_PWRON1S
] = {
121 .mask
= S2MPS11_IRQ_PWRON1S_MASK
,
123 [S2MPS14_IRQ_MRB
] = {
125 .mask
= S2MPS11_IRQ_MRB_MASK
,
127 [S2MPS14_IRQ_RTC60S
] = {
129 .mask
= S2MPS11_IRQ_RTC60S_MASK
,
131 [S2MPS14_IRQ_RTCA1
] = {
133 .mask
= S2MPS11_IRQ_RTCA1_MASK
,
135 [S2MPS14_IRQ_RTCA0
] = {
137 .mask
= S2MPS11_IRQ_RTCA0_MASK
,
139 [S2MPS14_IRQ_SMPL
] = {
141 .mask
= S2MPS11_IRQ_SMPL_MASK
,
143 [S2MPS14_IRQ_RTC1S
] = {
145 .mask
= S2MPS11_IRQ_RTC1S_MASK
,
147 [S2MPS14_IRQ_WTSR
] = {
149 .mask
= S2MPS11_IRQ_WTSR_MASK
,
151 [S2MPS14_IRQ_INT120C
] = {
153 .mask
= S2MPS11_IRQ_INT120C_MASK
,
155 [S2MPS14_IRQ_INT140C
] = {
157 .mask
= S2MPS11_IRQ_INT140C_MASK
,
159 [S2MPS14_IRQ_TSD
] = {
161 .mask
= S2MPS14_IRQ_TSD_MASK
,
165 static const struct regmap_irq s2mpu02_irqs
[] = {
166 [S2MPU02_IRQ_PWRONF
] = {
168 .mask
= S2MPS11_IRQ_PWRONF_MASK
,
170 [S2MPU02_IRQ_PWRONR
] = {
172 .mask
= S2MPS11_IRQ_PWRONR_MASK
,
174 [S2MPU02_IRQ_JIGONBF
] = {
176 .mask
= S2MPS11_IRQ_JIGONBF_MASK
,
178 [S2MPU02_IRQ_JIGONBR
] = {
180 .mask
= S2MPS11_IRQ_JIGONBR_MASK
,
182 [S2MPU02_IRQ_ACOKBF
] = {
184 .mask
= S2MPS11_IRQ_ACOKBF_MASK
,
186 [S2MPU02_IRQ_ACOKBR
] = {
188 .mask
= S2MPS11_IRQ_ACOKBR_MASK
,
190 [S2MPU02_IRQ_PWRON1S
] = {
192 .mask
= S2MPS11_IRQ_PWRON1S_MASK
,
194 [S2MPU02_IRQ_MRB
] = {
196 .mask
= S2MPS11_IRQ_MRB_MASK
,
198 [S2MPU02_IRQ_RTC60S
] = {
200 .mask
= S2MPS11_IRQ_RTC60S_MASK
,
202 [S2MPU02_IRQ_RTCA1
] = {
204 .mask
= S2MPS11_IRQ_RTCA1_MASK
,
206 [S2MPU02_IRQ_RTCA0
] = {
208 .mask
= S2MPS11_IRQ_RTCA0_MASK
,
210 [S2MPU02_IRQ_SMPL
] = {
212 .mask
= S2MPS11_IRQ_SMPL_MASK
,
214 [S2MPU02_IRQ_RTC1S
] = {
216 .mask
= S2MPS11_IRQ_RTC1S_MASK
,
218 [S2MPU02_IRQ_WTSR
] = {
220 .mask
= S2MPS11_IRQ_WTSR_MASK
,
222 [S2MPU02_IRQ_INT120C
] = {
224 .mask
= S2MPS11_IRQ_INT120C_MASK
,
226 [S2MPU02_IRQ_INT140C
] = {
228 .mask
= S2MPS11_IRQ_INT140C_MASK
,
230 [S2MPU02_IRQ_TSD
] = {
232 .mask
= S2MPS14_IRQ_TSD_MASK
,
236 static const struct regmap_irq s5m8767_irqs
[] = {
237 [S5M8767_IRQ_PWRR
] = {
239 .mask
= S5M8767_IRQ_PWRR_MASK
,
241 [S5M8767_IRQ_PWRF
] = {
243 .mask
= S5M8767_IRQ_PWRF_MASK
,
245 [S5M8767_IRQ_PWR1S
] = {
247 .mask
= S5M8767_IRQ_PWR1S_MASK
,
249 [S5M8767_IRQ_JIGR
] = {
251 .mask
= S5M8767_IRQ_JIGR_MASK
,
253 [S5M8767_IRQ_JIGF
] = {
255 .mask
= S5M8767_IRQ_JIGF_MASK
,
257 [S5M8767_IRQ_LOWBAT2
] = {
259 .mask
= S5M8767_IRQ_LOWBAT2_MASK
,
261 [S5M8767_IRQ_LOWBAT1
] = {
263 .mask
= S5M8767_IRQ_LOWBAT1_MASK
,
265 [S5M8767_IRQ_MRB
] = {
267 .mask
= S5M8767_IRQ_MRB_MASK
,
269 [S5M8767_IRQ_DVSOK2
] = {
271 .mask
= S5M8767_IRQ_DVSOK2_MASK
,
273 [S5M8767_IRQ_DVSOK3
] = {
275 .mask
= S5M8767_IRQ_DVSOK3_MASK
,
277 [S5M8767_IRQ_DVSOK4
] = {
279 .mask
= S5M8767_IRQ_DVSOK4_MASK
,
281 [S5M8767_IRQ_RTC60S
] = {
283 .mask
= S5M8767_IRQ_RTC60S_MASK
,
285 [S5M8767_IRQ_RTCA1
] = {
287 .mask
= S5M8767_IRQ_RTCA1_MASK
,
289 [S5M8767_IRQ_RTCA2
] = {
291 .mask
= S5M8767_IRQ_RTCA2_MASK
,
293 [S5M8767_IRQ_SMPL
] = {
295 .mask
= S5M8767_IRQ_SMPL_MASK
,
297 [S5M8767_IRQ_RTC1S
] = {
299 .mask
= S5M8767_IRQ_RTC1S_MASK
,
301 [S5M8767_IRQ_WTSR
] = {
303 .mask
= S5M8767_IRQ_WTSR_MASK
,
307 static const struct regmap_irq s5m8763_irqs
[] = {
308 [S5M8763_IRQ_DCINF
] = {
310 .mask
= S5M8763_IRQ_DCINF_MASK
,
312 [S5M8763_IRQ_DCINR
] = {
314 .mask
= S5M8763_IRQ_DCINR_MASK
,
316 [S5M8763_IRQ_JIGF
] = {
318 .mask
= S5M8763_IRQ_JIGF_MASK
,
320 [S5M8763_IRQ_JIGR
] = {
322 .mask
= S5M8763_IRQ_JIGR_MASK
,
324 [S5M8763_IRQ_PWRONF
] = {
326 .mask
= S5M8763_IRQ_PWRONF_MASK
,
328 [S5M8763_IRQ_PWRONR
] = {
330 .mask
= S5M8763_IRQ_PWRONR_MASK
,
332 [S5M8763_IRQ_WTSREVNT
] = {
334 .mask
= S5M8763_IRQ_WTSREVNT_MASK
,
336 [S5M8763_IRQ_SMPLEVNT
] = {
338 .mask
= S5M8763_IRQ_SMPLEVNT_MASK
,
340 [S5M8763_IRQ_ALARM1
] = {
342 .mask
= S5M8763_IRQ_ALARM1_MASK
,
344 [S5M8763_IRQ_ALARM0
] = {
346 .mask
= S5M8763_IRQ_ALARM0_MASK
,
348 [S5M8763_IRQ_ONKEY1S
] = {
350 .mask
= S5M8763_IRQ_ONKEY1S_MASK
,
352 [S5M8763_IRQ_TOPOFFR
] = {
354 .mask
= S5M8763_IRQ_TOPOFFR_MASK
,
356 [S5M8763_IRQ_DCINOVPR
] = {
358 .mask
= S5M8763_IRQ_DCINOVPR_MASK
,
360 [S5M8763_IRQ_CHGRSTF
] = {
362 .mask
= S5M8763_IRQ_CHGRSTF_MASK
,
364 [S5M8763_IRQ_DONER
] = {
366 .mask
= S5M8763_IRQ_DONER_MASK
,
368 [S5M8763_IRQ_CHGFAULT
] = {
370 .mask
= S5M8763_IRQ_CHGFAULT_MASK
,
372 [S5M8763_IRQ_LOBAT1
] = {
374 .mask
= S5M8763_IRQ_LOBAT1_MASK
,
376 [S5M8763_IRQ_LOBAT2
] = {
378 .mask
= S5M8763_IRQ_LOBAT2_MASK
,
382 static const struct regmap_irq_chip s2mps11_irq_chip
= {
384 .irqs
= s2mps11_irqs
,
385 .num_irqs
= ARRAY_SIZE(s2mps11_irqs
),
387 .status_base
= S2MPS11_REG_INT1
,
388 .mask_base
= S2MPS11_REG_INT1M
,
389 .ack_base
= S2MPS11_REG_INT1
,
392 #define S2MPS1X_IRQ_CHIP_COMMON_DATA \
393 .irqs = s2mps14_irqs, \
394 .num_irqs = ARRAY_SIZE(s2mps14_irqs), \
396 .status_base = S2MPS14_REG_INT1, \
397 .mask_base = S2MPS14_REG_INT1M, \
398 .ack_base = S2MPS14_REG_INT1 \
400 static const struct regmap_irq_chip s2mps13_irq_chip = {
402 S2MPS1X_IRQ_CHIP_COMMON_DATA
,
405 static const struct regmap_irq_chip s2mps14_irq_chip
= {
407 S2MPS1X_IRQ_CHIP_COMMON_DATA
,
410 static const struct regmap_irq_chip s2mpu02_irq_chip
= {
412 .irqs
= s2mpu02_irqs
,
413 .num_irqs
= ARRAY_SIZE(s2mpu02_irqs
),
415 .status_base
= S2MPU02_REG_INT1
,
416 .mask_base
= S2MPU02_REG_INT1M
,
417 .ack_base
= S2MPU02_REG_INT1
,
420 static const struct regmap_irq_chip s5m8767_irq_chip
= {
422 .irqs
= s5m8767_irqs
,
423 .num_irqs
= ARRAY_SIZE(s5m8767_irqs
),
425 .status_base
= S5M8767_REG_INT1
,
426 .mask_base
= S5M8767_REG_INT1M
,
427 .ack_base
= S5M8767_REG_INT1
,
430 static const struct regmap_irq_chip s5m8763_irq_chip
= {
432 .irqs
= s5m8763_irqs
,
433 .num_irqs
= ARRAY_SIZE(s5m8763_irqs
),
435 .status_base
= S5M8763_REG_IRQ1
,
436 .mask_base
= S5M8763_REG_IRQM1
,
437 .ack_base
= S5M8763_REG_IRQ1
,
440 int sec_irq_init(struct sec_pmic_dev
*sec_pmic
)
443 int type
= sec_pmic
->device_type
;
444 const struct regmap_irq_chip
*sec_irq_chip
;
446 if (!sec_pmic
->irq
) {
447 dev_warn(sec_pmic
->dev
,
448 "No interrupt specified, no interrupts\n");
449 sec_pmic
->irq_base
= 0;
455 sec_irq_chip
= &s5m8763_irq_chip
;
458 sec_irq_chip
= &s5m8767_irq_chip
;
461 sec_irq_chip
= &s2mps11_irq_chip
;
464 sec_irq_chip
= &s2mps13_irq_chip
;
467 sec_irq_chip
= &s2mps14_irq_chip
;
470 sec_irq_chip
= &s2mpu02_irq_chip
;
473 dev_err(sec_pmic
->dev
, "Unknown device type %lu\n",
474 sec_pmic
->device_type
);
478 ret
= regmap_add_irq_chip(sec_pmic
->regmap_pmic
, sec_pmic
->irq
,
479 IRQF_TRIGGER_FALLING
| IRQF_ONESHOT
,
480 sec_pmic
->irq_base
, sec_irq_chip
,
481 &sec_pmic
->irq_data
);
483 dev_err(sec_pmic
->dev
, "Failed to register IRQ chip: %d\n", ret
);
488 * The rtc-s5m driver requests S2MPS14_IRQ_RTCA0 also for S2MPS11
489 * so the interrupt number must be consistent.
491 BUILD_BUG_ON(((enum s2mps14_irq
)S2MPS11_IRQ_RTCA0
) != S2MPS14_IRQ_RTCA0
);
496 void sec_irq_exit(struct sec_pmic_dev
*sec_pmic
)
498 regmap_del_irq_chip(sec_pmic
->irq
, sec_pmic
->irq_data
);