1 // SPDX-License-Identifier: GPL-2.0+
3 // Copyright (c) 2011-2014 Samsung Electronics Co., Ltd
4 // http://www.samsung.com
6 #include <linux/device.h>
7 #include <linux/interrupt.h>
9 #include <linux/module.h>
10 #include <linux/regmap.h>
12 #include <linux/mfd/samsung/core.h>
13 #include <linux/mfd/samsung/irq.h>
14 #include <linux/mfd/samsung/s2mps11.h>
15 #include <linux/mfd/samsung/s2mps14.h>
16 #include <linux/mfd/samsung/s2mpu02.h>
17 #include <linux/mfd/samsung/s5m8763.h>
18 #include <linux/mfd/samsung/s5m8767.h>
20 static const struct regmap_irq s2mps11_irqs
[] = {
21 [S2MPS11_IRQ_PWRONF
] = {
23 .mask
= S2MPS11_IRQ_PWRONF_MASK
,
25 [S2MPS11_IRQ_PWRONR
] = {
27 .mask
= S2MPS11_IRQ_PWRONR_MASK
,
29 [S2MPS11_IRQ_JIGONBF
] = {
31 .mask
= S2MPS11_IRQ_JIGONBF_MASK
,
33 [S2MPS11_IRQ_JIGONBR
] = {
35 .mask
= S2MPS11_IRQ_JIGONBR_MASK
,
37 [S2MPS11_IRQ_ACOKBF
] = {
39 .mask
= S2MPS11_IRQ_ACOKBF_MASK
,
41 [S2MPS11_IRQ_ACOKBR
] = {
43 .mask
= S2MPS11_IRQ_ACOKBR_MASK
,
45 [S2MPS11_IRQ_PWRON1S
] = {
47 .mask
= S2MPS11_IRQ_PWRON1S_MASK
,
51 .mask
= S2MPS11_IRQ_MRB_MASK
,
53 [S2MPS11_IRQ_RTC60S
] = {
55 .mask
= S2MPS11_IRQ_RTC60S_MASK
,
57 [S2MPS11_IRQ_RTCA1
] = {
59 .mask
= S2MPS11_IRQ_RTCA1_MASK
,
61 [S2MPS11_IRQ_RTCA0
] = {
63 .mask
= S2MPS11_IRQ_RTCA0_MASK
,
65 [S2MPS11_IRQ_SMPL
] = {
67 .mask
= S2MPS11_IRQ_SMPL_MASK
,
69 [S2MPS11_IRQ_RTC1S
] = {
71 .mask
= S2MPS11_IRQ_RTC1S_MASK
,
73 [S2MPS11_IRQ_WTSR
] = {
75 .mask
= S2MPS11_IRQ_WTSR_MASK
,
77 [S2MPS11_IRQ_INT120C
] = {
79 .mask
= S2MPS11_IRQ_INT120C_MASK
,
81 [S2MPS11_IRQ_INT140C
] = {
83 .mask
= S2MPS11_IRQ_INT140C_MASK
,
87 static const struct regmap_irq s2mps14_irqs
[] = {
88 [S2MPS14_IRQ_PWRONF
] = {
90 .mask
= S2MPS11_IRQ_PWRONF_MASK
,
92 [S2MPS14_IRQ_PWRONR
] = {
94 .mask
= S2MPS11_IRQ_PWRONR_MASK
,
96 [S2MPS14_IRQ_JIGONBF
] = {
98 .mask
= S2MPS11_IRQ_JIGONBF_MASK
,
100 [S2MPS14_IRQ_JIGONBR
] = {
102 .mask
= S2MPS11_IRQ_JIGONBR_MASK
,
104 [S2MPS14_IRQ_ACOKBF
] = {
106 .mask
= S2MPS11_IRQ_ACOKBF_MASK
,
108 [S2MPS14_IRQ_ACOKBR
] = {
110 .mask
= S2MPS11_IRQ_ACOKBR_MASK
,
112 [S2MPS14_IRQ_PWRON1S
] = {
114 .mask
= S2MPS11_IRQ_PWRON1S_MASK
,
116 [S2MPS14_IRQ_MRB
] = {
118 .mask
= S2MPS11_IRQ_MRB_MASK
,
120 [S2MPS14_IRQ_RTC60S
] = {
122 .mask
= S2MPS11_IRQ_RTC60S_MASK
,
124 [S2MPS14_IRQ_RTCA1
] = {
126 .mask
= S2MPS11_IRQ_RTCA1_MASK
,
128 [S2MPS14_IRQ_RTCA0
] = {
130 .mask
= S2MPS11_IRQ_RTCA0_MASK
,
132 [S2MPS14_IRQ_SMPL
] = {
134 .mask
= S2MPS11_IRQ_SMPL_MASK
,
136 [S2MPS14_IRQ_RTC1S
] = {
138 .mask
= S2MPS11_IRQ_RTC1S_MASK
,
140 [S2MPS14_IRQ_WTSR
] = {
142 .mask
= S2MPS11_IRQ_WTSR_MASK
,
144 [S2MPS14_IRQ_INT120C
] = {
146 .mask
= S2MPS11_IRQ_INT120C_MASK
,
148 [S2MPS14_IRQ_INT140C
] = {
150 .mask
= S2MPS11_IRQ_INT140C_MASK
,
152 [S2MPS14_IRQ_TSD
] = {
154 .mask
= S2MPS14_IRQ_TSD_MASK
,
158 static const struct regmap_irq s2mpu02_irqs
[] = {
159 [S2MPU02_IRQ_PWRONF
] = {
161 .mask
= S2MPS11_IRQ_PWRONF_MASK
,
163 [S2MPU02_IRQ_PWRONR
] = {
165 .mask
= S2MPS11_IRQ_PWRONR_MASK
,
167 [S2MPU02_IRQ_JIGONBF
] = {
169 .mask
= S2MPS11_IRQ_JIGONBF_MASK
,
171 [S2MPU02_IRQ_JIGONBR
] = {
173 .mask
= S2MPS11_IRQ_JIGONBR_MASK
,
175 [S2MPU02_IRQ_ACOKBF
] = {
177 .mask
= S2MPS11_IRQ_ACOKBF_MASK
,
179 [S2MPU02_IRQ_ACOKBR
] = {
181 .mask
= S2MPS11_IRQ_ACOKBR_MASK
,
183 [S2MPU02_IRQ_PWRON1S
] = {
185 .mask
= S2MPS11_IRQ_PWRON1S_MASK
,
187 [S2MPU02_IRQ_MRB
] = {
189 .mask
= S2MPS11_IRQ_MRB_MASK
,
191 [S2MPU02_IRQ_RTC60S
] = {
193 .mask
= S2MPS11_IRQ_RTC60S_MASK
,
195 [S2MPU02_IRQ_RTCA1
] = {
197 .mask
= S2MPS11_IRQ_RTCA1_MASK
,
199 [S2MPU02_IRQ_RTCA0
] = {
201 .mask
= S2MPS11_IRQ_RTCA0_MASK
,
203 [S2MPU02_IRQ_SMPL
] = {
205 .mask
= S2MPS11_IRQ_SMPL_MASK
,
207 [S2MPU02_IRQ_RTC1S
] = {
209 .mask
= S2MPS11_IRQ_RTC1S_MASK
,
211 [S2MPU02_IRQ_WTSR
] = {
213 .mask
= S2MPS11_IRQ_WTSR_MASK
,
215 [S2MPU02_IRQ_INT120C
] = {
217 .mask
= S2MPS11_IRQ_INT120C_MASK
,
219 [S2MPU02_IRQ_INT140C
] = {
221 .mask
= S2MPS11_IRQ_INT140C_MASK
,
223 [S2MPU02_IRQ_TSD
] = {
225 .mask
= S2MPS14_IRQ_TSD_MASK
,
229 static const struct regmap_irq s5m8767_irqs
[] = {
230 [S5M8767_IRQ_PWRR
] = {
232 .mask
= S5M8767_IRQ_PWRR_MASK
,
234 [S5M8767_IRQ_PWRF
] = {
236 .mask
= S5M8767_IRQ_PWRF_MASK
,
238 [S5M8767_IRQ_PWR1S
] = {
240 .mask
= S5M8767_IRQ_PWR1S_MASK
,
242 [S5M8767_IRQ_JIGR
] = {
244 .mask
= S5M8767_IRQ_JIGR_MASK
,
246 [S5M8767_IRQ_JIGF
] = {
248 .mask
= S5M8767_IRQ_JIGF_MASK
,
250 [S5M8767_IRQ_LOWBAT2
] = {
252 .mask
= S5M8767_IRQ_LOWBAT2_MASK
,
254 [S5M8767_IRQ_LOWBAT1
] = {
256 .mask
= S5M8767_IRQ_LOWBAT1_MASK
,
258 [S5M8767_IRQ_MRB
] = {
260 .mask
= S5M8767_IRQ_MRB_MASK
,
262 [S5M8767_IRQ_DVSOK2
] = {
264 .mask
= S5M8767_IRQ_DVSOK2_MASK
,
266 [S5M8767_IRQ_DVSOK3
] = {
268 .mask
= S5M8767_IRQ_DVSOK3_MASK
,
270 [S5M8767_IRQ_DVSOK4
] = {
272 .mask
= S5M8767_IRQ_DVSOK4_MASK
,
274 [S5M8767_IRQ_RTC60S
] = {
276 .mask
= S5M8767_IRQ_RTC60S_MASK
,
278 [S5M8767_IRQ_RTCA1
] = {
280 .mask
= S5M8767_IRQ_RTCA1_MASK
,
282 [S5M8767_IRQ_RTCA2
] = {
284 .mask
= S5M8767_IRQ_RTCA2_MASK
,
286 [S5M8767_IRQ_SMPL
] = {
288 .mask
= S5M8767_IRQ_SMPL_MASK
,
290 [S5M8767_IRQ_RTC1S
] = {
292 .mask
= S5M8767_IRQ_RTC1S_MASK
,
294 [S5M8767_IRQ_WTSR
] = {
296 .mask
= S5M8767_IRQ_WTSR_MASK
,
300 static const struct regmap_irq s5m8763_irqs
[] = {
301 [S5M8763_IRQ_DCINF
] = {
303 .mask
= S5M8763_IRQ_DCINF_MASK
,
305 [S5M8763_IRQ_DCINR
] = {
307 .mask
= S5M8763_IRQ_DCINR_MASK
,
309 [S5M8763_IRQ_JIGF
] = {
311 .mask
= S5M8763_IRQ_JIGF_MASK
,
313 [S5M8763_IRQ_JIGR
] = {
315 .mask
= S5M8763_IRQ_JIGR_MASK
,
317 [S5M8763_IRQ_PWRONF
] = {
319 .mask
= S5M8763_IRQ_PWRONF_MASK
,
321 [S5M8763_IRQ_PWRONR
] = {
323 .mask
= S5M8763_IRQ_PWRONR_MASK
,
325 [S5M8763_IRQ_WTSREVNT
] = {
327 .mask
= S5M8763_IRQ_WTSREVNT_MASK
,
329 [S5M8763_IRQ_SMPLEVNT
] = {
331 .mask
= S5M8763_IRQ_SMPLEVNT_MASK
,
333 [S5M8763_IRQ_ALARM1
] = {
335 .mask
= S5M8763_IRQ_ALARM1_MASK
,
337 [S5M8763_IRQ_ALARM0
] = {
339 .mask
= S5M8763_IRQ_ALARM0_MASK
,
341 [S5M8763_IRQ_ONKEY1S
] = {
343 .mask
= S5M8763_IRQ_ONKEY1S_MASK
,
345 [S5M8763_IRQ_TOPOFFR
] = {
347 .mask
= S5M8763_IRQ_TOPOFFR_MASK
,
349 [S5M8763_IRQ_DCINOVPR
] = {
351 .mask
= S5M8763_IRQ_DCINOVPR_MASK
,
353 [S5M8763_IRQ_CHGRSTF
] = {
355 .mask
= S5M8763_IRQ_CHGRSTF_MASK
,
357 [S5M8763_IRQ_DONER
] = {
359 .mask
= S5M8763_IRQ_DONER_MASK
,
361 [S5M8763_IRQ_CHGFAULT
] = {
363 .mask
= S5M8763_IRQ_CHGFAULT_MASK
,
365 [S5M8763_IRQ_LOBAT1
] = {
367 .mask
= S5M8763_IRQ_LOBAT1_MASK
,
369 [S5M8763_IRQ_LOBAT2
] = {
371 .mask
= S5M8763_IRQ_LOBAT2_MASK
,
375 static const struct regmap_irq_chip s2mps11_irq_chip
= {
377 .irqs
= s2mps11_irqs
,
378 .num_irqs
= ARRAY_SIZE(s2mps11_irqs
),
380 .status_base
= S2MPS11_REG_INT1
,
381 .mask_base
= S2MPS11_REG_INT1M
,
382 .ack_base
= S2MPS11_REG_INT1
,
385 #define S2MPS1X_IRQ_CHIP_COMMON_DATA \
386 .irqs = s2mps14_irqs, \
387 .num_irqs = ARRAY_SIZE(s2mps14_irqs), \
389 .status_base = S2MPS14_REG_INT1, \
390 .mask_base = S2MPS14_REG_INT1M, \
391 .ack_base = S2MPS14_REG_INT1 \
393 static const struct regmap_irq_chip s2mps13_irq_chip = {
395 S2MPS1X_IRQ_CHIP_COMMON_DATA
,
398 static const struct regmap_irq_chip s2mps14_irq_chip
= {
400 S2MPS1X_IRQ_CHIP_COMMON_DATA
,
403 static const struct regmap_irq_chip s2mps15_irq_chip
= {
405 S2MPS1X_IRQ_CHIP_COMMON_DATA
,
408 static const struct regmap_irq_chip s2mpu02_irq_chip
= {
410 .irqs
= s2mpu02_irqs
,
411 .num_irqs
= ARRAY_SIZE(s2mpu02_irqs
),
413 .status_base
= S2MPU02_REG_INT1
,
414 .mask_base
= S2MPU02_REG_INT1M
,
415 .ack_base
= S2MPU02_REG_INT1
,
418 static const struct regmap_irq_chip s5m8767_irq_chip
= {
420 .irqs
= s5m8767_irqs
,
421 .num_irqs
= ARRAY_SIZE(s5m8767_irqs
),
423 .status_base
= S5M8767_REG_INT1
,
424 .mask_base
= S5M8767_REG_INT1M
,
425 .ack_base
= S5M8767_REG_INT1
,
428 static const struct regmap_irq_chip s5m8763_irq_chip
= {
430 .irqs
= s5m8763_irqs
,
431 .num_irqs
= ARRAY_SIZE(s5m8763_irqs
),
433 .status_base
= S5M8763_REG_IRQ1
,
434 .mask_base
= S5M8763_REG_IRQM1
,
435 .ack_base
= S5M8763_REG_IRQ1
,
438 int sec_irq_init(struct sec_pmic_dev
*sec_pmic
)
441 int type
= sec_pmic
->device_type
;
442 const struct regmap_irq_chip
*sec_irq_chip
;
444 if (!sec_pmic
->irq
) {
445 dev_warn(sec_pmic
->dev
,
446 "No interrupt specified, no interrupts\n");
447 sec_pmic
->irq_base
= 0;
453 sec_irq_chip
= &s5m8763_irq_chip
;
456 sec_irq_chip
= &s5m8767_irq_chip
;
459 sec_irq_chip
= &s2mps14_irq_chip
;
462 sec_irq_chip
= &s2mps11_irq_chip
;
465 sec_irq_chip
= &s2mps13_irq_chip
;
468 sec_irq_chip
= &s2mps14_irq_chip
;
471 sec_irq_chip
= &s2mps15_irq_chip
;
474 sec_irq_chip
= &s2mpu02_irq_chip
;
477 dev_err(sec_pmic
->dev
, "Unknown device type %lu\n",
478 sec_pmic
->device_type
);
482 ret
= devm_regmap_add_irq_chip(sec_pmic
->dev
, sec_pmic
->regmap_pmic
,
484 IRQF_TRIGGER_FALLING
| IRQF_ONESHOT
,
485 sec_pmic
->irq_base
, sec_irq_chip
,
486 &sec_pmic
->irq_data
);
488 dev_err(sec_pmic
->dev
, "Failed to register IRQ chip: %d\n", ret
);
493 * The rtc-s5m driver requests S2MPS14_IRQ_RTCA0 also for S2MPS11
494 * so the interrupt number must be consistent.
496 BUILD_BUG_ON(((enum s2mps14_irq
)S2MPS11_IRQ_RTCA0
) != S2MPS14_IRQ_RTCA0
);
500 EXPORT_SYMBOL_GPL(sec_irq_init
);
502 MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>");
503 MODULE_AUTHOR("Chanwoo Choi <cw00.choi@samsung.com>");
504 MODULE_AUTHOR("Krzysztof Kozlowski <krzk@kernel.org>");
505 MODULE_DESCRIPTION("Interrupt support for the S5M MFD");
506 MODULE_LICENSE("GPL");