Linux 6.9-rc1
[linux-2.6-microblaze.git] / drivers / mfd / sec-irq.c
1 // SPDX-License-Identifier: GPL-2.0+
2 //
3 // Copyright (c) 2011-2014 Samsung Electronics Co., Ltd
4 //              http://www.samsung.com
5
6 #include <linux/device.h>
7 #include <linux/interrupt.h>
8 #include <linux/irq.h>
9 #include <linux/module.h>
10 #include <linux/regmap.h>
11
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/s5m8767.h>
18
19 static const struct regmap_irq s2mps11_irqs[] = {
20         [S2MPS11_IRQ_PWRONF] = {
21                 .reg_offset = 0,
22                 .mask = S2MPS11_IRQ_PWRONF_MASK,
23         },
24         [S2MPS11_IRQ_PWRONR] = {
25                 .reg_offset = 0,
26                 .mask = S2MPS11_IRQ_PWRONR_MASK,
27         },
28         [S2MPS11_IRQ_JIGONBF] = {
29                 .reg_offset = 0,
30                 .mask = S2MPS11_IRQ_JIGONBF_MASK,
31         },
32         [S2MPS11_IRQ_JIGONBR] = {
33                 .reg_offset = 0,
34                 .mask = S2MPS11_IRQ_JIGONBR_MASK,
35         },
36         [S2MPS11_IRQ_ACOKBF] = {
37                 .reg_offset = 0,
38                 .mask = S2MPS11_IRQ_ACOKBF_MASK,
39         },
40         [S2MPS11_IRQ_ACOKBR] = {
41                 .reg_offset = 0,
42                 .mask = S2MPS11_IRQ_ACOKBR_MASK,
43         },
44         [S2MPS11_IRQ_PWRON1S] = {
45                 .reg_offset = 0,
46                 .mask = S2MPS11_IRQ_PWRON1S_MASK,
47         },
48         [S2MPS11_IRQ_MRB] = {
49                 .reg_offset = 0,
50                 .mask = S2MPS11_IRQ_MRB_MASK,
51         },
52         [S2MPS11_IRQ_RTC60S] = {
53                 .reg_offset = 1,
54                 .mask = S2MPS11_IRQ_RTC60S_MASK,
55         },
56         [S2MPS11_IRQ_RTCA1] = {
57                 .reg_offset = 1,
58                 .mask = S2MPS11_IRQ_RTCA1_MASK,
59         },
60         [S2MPS11_IRQ_RTCA0] = {
61                 .reg_offset = 1,
62                 .mask = S2MPS11_IRQ_RTCA0_MASK,
63         },
64         [S2MPS11_IRQ_SMPL] = {
65                 .reg_offset = 1,
66                 .mask = S2MPS11_IRQ_SMPL_MASK,
67         },
68         [S2MPS11_IRQ_RTC1S] = {
69                 .reg_offset = 1,
70                 .mask = S2MPS11_IRQ_RTC1S_MASK,
71         },
72         [S2MPS11_IRQ_WTSR] = {
73                 .reg_offset = 1,
74                 .mask = S2MPS11_IRQ_WTSR_MASK,
75         },
76         [S2MPS11_IRQ_INT120C] = {
77                 .reg_offset = 2,
78                 .mask = S2MPS11_IRQ_INT120C_MASK,
79         },
80         [S2MPS11_IRQ_INT140C] = {
81                 .reg_offset = 2,
82                 .mask = S2MPS11_IRQ_INT140C_MASK,
83         },
84 };
85
86 static const struct regmap_irq s2mps14_irqs[] = {
87         [S2MPS14_IRQ_PWRONF] = {
88                 .reg_offset = 0,
89                 .mask = S2MPS11_IRQ_PWRONF_MASK,
90         },
91         [S2MPS14_IRQ_PWRONR] = {
92                 .reg_offset = 0,
93                 .mask = S2MPS11_IRQ_PWRONR_MASK,
94         },
95         [S2MPS14_IRQ_JIGONBF] = {
96                 .reg_offset = 0,
97                 .mask = S2MPS11_IRQ_JIGONBF_MASK,
98         },
99         [S2MPS14_IRQ_JIGONBR] = {
100                 .reg_offset = 0,
101                 .mask = S2MPS11_IRQ_JIGONBR_MASK,
102         },
103         [S2MPS14_IRQ_ACOKBF] = {
104                 .reg_offset = 0,
105                 .mask = S2MPS11_IRQ_ACOKBF_MASK,
106         },
107         [S2MPS14_IRQ_ACOKBR] = {
108                 .reg_offset = 0,
109                 .mask = S2MPS11_IRQ_ACOKBR_MASK,
110         },
111         [S2MPS14_IRQ_PWRON1S] = {
112                 .reg_offset = 0,
113                 .mask = S2MPS11_IRQ_PWRON1S_MASK,
114         },
115         [S2MPS14_IRQ_MRB] = {
116                 .reg_offset = 0,
117                 .mask = S2MPS11_IRQ_MRB_MASK,
118         },
119         [S2MPS14_IRQ_RTC60S] = {
120                 .reg_offset = 1,
121                 .mask = S2MPS11_IRQ_RTC60S_MASK,
122         },
123         [S2MPS14_IRQ_RTCA1] = {
124                 .reg_offset = 1,
125                 .mask = S2MPS11_IRQ_RTCA1_MASK,
126         },
127         [S2MPS14_IRQ_RTCA0] = {
128                 .reg_offset = 1,
129                 .mask = S2MPS11_IRQ_RTCA0_MASK,
130         },
131         [S2MPS14_IRQ_SMPL] = {
132                 .reg_offset = 1,
133                 .mask = S2MPS11_IRQ_SMPL_MASK,
134         },
135         [S2MPS14_IRQ_RTC1S] = {
136                 .reg_offset = 1,
137                 .mask = S2MPS11_IRQ_RTC1S_MASK,
138         },
139         [S2MPS14_IRQ_WTSR] = {
140                 .reg_offset = 1,
141                 .mask = S2MPS11_IRQ_WTSR_MASK,
142         },
143         [S2MPS14_IRQ_INT120C] = {
144                 .reg_offset = 2,
145                 .mask = S2MPS11_IRQ_INT120C_MASK,
146         },
147         [S2MPS14_IRQ_INT140C] = {
148                 .reg_offset = 2,
149                 .mask = S2MPS11_IRQ_INT140C_MASK,
150         },
151         [S2MPS14_IRQ_TSD] = {
152                 .reg_offset = 2,
153                 .mask = S2MPS14_IRQ_TSD_MASK,
154         },
155 };
156
157 static const struct regmap_irq s2mpu02_irqs[] = {
158         [S2MPU02_IRQ_PWRONF] = {
159                 .reg_offset = 0,
160                 .mask = S2MPS11_IRQ_PWRONF_MASK,
161         },
162         [S2MPU02_IRQ_PWRONR] = {
163                 .reg_offset = 0,
164                 .mask = S2MPS11_IRQ_PWRONR_MASK,
165         },
166         [S2MPU02_IRQ_JIGONBF] = {
167                 .reg_offset = 0,
168                 .mask = S2MPS11_IRQ_JIGONBF_MASK,
169         },
170         [S2MPU02_IRQ_JIGONBR] = {
171                 .reg_offset = 0,
172                 .mask = S2MPS11_IRQ_JIGONBR_MASK,
173         },
174         [S2MPU02_IRQ_ACOKBF] = {
175                 .reg_offset = 0,
176                 .mask = S2MPS11_IRQ_ACOKBF_MASK,
177         },
178         [S2MPU02_IRQ_ACOKBR] = {
179                 .reg_offset = 0,
180                 .mask = S2MPS11_IRQ_ACOKBR_MASK,
181         },
182         [S2MPU02_IRQ_PWRON1S] = {
183                 .reg_offset = 0,
184                 .mask = S2MPS11_IRQ_PWRON1S_MASK,
185         },
186         [S2MPU02_IRQ_MRB] = {
187                 .reg_offset = 0,
188                 .mask = S2MPS11_IRQ_MRB_MASK,
189         },
190         [S2MPU02_IRQ_RTC60S] = {
191                 .reg_offset = 1,
192                 .mask = S2MPS11_IRQ_RTC60S_MASK,
193         },
194         [S2MPU02_IRQ_RTCA1] = {
195                 .reg_offset = 1,
196                 .mask = S2MPS11_IRQ_RTCA1_MASK,
197         },
198         [S2MPU02_IRQ_RTCA0] = {
199                 .reg_offset = 1,
200                 .mask = S2MPS11_IRQ_RTCA0_MASK,
201         },
202         [S2MPU02_IRQ_SMPL] = {
203                 .reg_offset = 1,
204                 .mask = S2MPS11_IRQ_SMPL_MASK,
205         },
206         [S2MPU02_IRQ_RTC1S] = {
207                 .reg_offset = 1,
208                 .mask = S2MPS11_IRQ_RTC1S_MASK,
209         },
210         [S2MPU02_IRQ_WTSR] = {
211                 .reg_offset = 1,
212                 .mask = S2MPS11_IRQ_WTSR_MASK,
213         },
214         [S2MPU02_IRQ_INT120C] = {
215                 .reg_offset = 2,
216                 .mask = S2MPS11_IRQ_INT120C_MASK,
217         },
218         [S2MPU02_IRQ_INT140C] = {
219                 .reg_offset = 2,
220                 .mask = S2MPS11_IRQ_INT140C_MASK,
221         },
222         [S2MPU02_IRQ_TSD] = {
223                 .reg_offset = 2,
224                 .mask = S2MPS14_IRQ_TSD_MASK,
225         },
226 };
227
228 static const struct regmap_irq s5m8767_irqs[] = {
229         [S5M8767_IRQ_PWRR] = {
230                 .reg_offset = 0,
231                 .mask = S5M8767_IRQ_PWRR_MASK,
232         },
233         [S5M8767_IRQ_PWRF] = {
234                 .reg_offset = 0,
235                 .mask = S5M8767_IRQ_PWRF_MASK,
236         },
237         [S5M8767_IRQ_PWR1S] = {
238                 .reg_offset = 0,
239                 .mask = S5M8767_IRQ_PWR1S_MASK,
240         },
241         [S5M8767_IRQ_JIGR] = {
242                 .reg_offset = 0,
243                 .mask = S5M8767_IRQ_JIGR_MASK,
244         },
245         [S5M8767_IRQ_JIGF] = {
246                 .reg_offset = 0,
247                 .mask = S5M8767_IRQ_JIGF_MASK,
248         },
249         [S5M8767_IRQ_LOWBAT2] = {
250                 .reg_offset = 0,
251                 .mask = S5M8767_IRQ_LOWBAT2_MASK,
252         },
253         [S5M8767_IRQ_LOWBAT1] = {
254                 .reg_offset = 0,
255                 .mask = S5M8767_IRQ_LOWBAT1_MASK,
256         },
257         [S5M8767_IRQ_MRB] = {
258                 .reg_offset = 1,
259                 .mask = S5M8767_IRQ_MRB_MASK,
260         },
261         [S5M8767_IRQ_DVSOK2] = {
262                 .reg_offset = 1,
263                 .mask = S5M8767_IRQ_DVSOK2_MASK,
264         },
265         [S5M8767_IRQ_DVSOK3] = {
266                 .reg_offset = 1,
267                 .mask = S5M8767_IRQ_DVSOK3_MASK,
268         },
269         [S5M8767_IRQ_DVSOK4] = {
270                 .reg_offset = 1,
271                 .mask = S5M8767_IRQ_DVSOK4_MASK,
272         },
273         [S5M8767_IRQ_RTC60S] = {
274                 .reg_offset = 2,
275                 .mask = S5M8767_IRQ_RTC60S_MASK,
276         },
277         [S5M8767_IRQ_RTCA1] = {
278                 .reg_offset = 2,
279                 .mask = S5M8767_IRQ_RTCA1_MASK,
280         },
281         [S5M8767_IRQ_RTCA2] = {
282                 .reg_offset = 2,
283                 .mask = S5M8767_IRQ_RTCA2_MASK,
284         },
285         [S5M8767_IRQ_SMPL] = {
286                 .reg_offset = 2,
287                 .mask = S5M8767_IRQ_SMPL_MASK,
288         },
289         [S5M8767_IRQ_RTC1S] = {
290                 .reg_offset = 2,
291                 .mask = S5M8767_IRQ_RTC1S_MASK,
292         },
293         [S5M8767_IRQ_WTSR] = {
294                 .reg_offset = 2,
295                 .mask = S5M8767_IRQ_WTSR_MASK,
296         },
297 };
298
299 static const struct regmap_irq_chip s2mps11_irq_chip = {
300         .name = "s2mps11",
301         .irqs = s2mps11_irqs,
302         .num_irqs = ARRAY_SIZE(s2mps11_irqs),
303         .num_regs = 3,
304         .status_base = S2MPS11_REG_INT1,
305         .mask_base = S2MPS11_REG_INT1M,
306         .ack_base = S2MPS11_REG_INT1,
307 };
308
309 #define S2MPS1X_IRQ_CHIP_COMMON_DATA            \
310         .irqs = s2mps14_irqs,                   \
311         .num_irqs = ARRAY_SIZE(s2mps14_irqs),   \
312         .num_regs = 3,                          \
313         .status_base = S2MPS14_REG_INT1,        \
314         .mask_base = S2MPS14_REG_INT1M,         \
315         .ack_base = S2MPS14_REG_INT1            \
316
317 static const struct regmap_irq_chip s2mps13_irq_chip = {
318         .name = "s2mps13",
319         S2MPS1X_IRQ_CHIP_COMMON_DATA,
320 };
321
322 static const struct regmap_irq_chip s2mps14_irq_chip = {
323         .name = "s2mps14",
324         S2MPS1X_IRQ_CHIP_COMMON_DATA,
325 };
326
327 static const struct regmap_irq_chip s2mps15_irq_chip = {
328         .name = "s2mps15",
329         S2MPS1X_IRQ_CHIP_COMMON_DATA,
330 };
331
332 static const struct regmap_irq_chip s2mpu02_irq_chip = {
333         .name = "s2mpu02",
334         .irqs = s2mpu02_irqs,
335         .num_irqs = ARRAY_SIZE(s2mpu02_irqs),
336         .num_regs = 3,
337         .status_base = S2MPU02_REG_INT1,
338         .mask_base = S2MPU02_REG_INT1M,
339         .ack_base = S2MPU02_REG_INT1,
340 };
341
342 static const struct regmap_irq_chip s5m8767_irq_chip = {
343         .name = "s5m8767",
344         .irqs = s5m8767_irqs,
345         .num_irqs = ARRAY_SIZE(s5m8767_irqs),
346         .num_regs = 3,
347         .status_base = S5M8767_REG_INT1,
348         .mask_base = S5M8767_REG_INT1M,
349         .ack_base = S5M8767_REG_INT1,
350 };
351
352 int sec_irq_init(struct sec_pmic_dev *sec_pmic)
353 {
354         int ret = 0;
355         int type = sec_pmic->device_type;
356         const struct regmap_irq_chip *sec_irq_chip;
357
358         if (!sec_pmic->irq) {
359                 dev_warn(sec_pmic->dev,
360                          "No interrupt specified, no interrupts\n");
361                 return 0;
362         }
363
364         switch (type) {
365         case S5M8767X:
366                 sec_irq_chip = &s5m8767_irq_chip;
367                 break;
368         case S2MPA01:
369                 sec_irq_chip = &s2mps14_irq_chip;
370                 break;
371         case S2MPS11X:
372                 sec_irq_chip = &s2mps11_irq_chip;
373                 break;
374         case S2MPS13X:
375                 sec_irq_chip = &s2mps13_irq_chip;
376                 break;
377         case S2MPS14X:
378                 sec_irq_chip = &s2mps14_irq_chip;
379                 break;
380         case S2MPS15X:
381                 sec_irq_chip = &s2mps15_irq_chip;
382                 break;
383         case S2MPU02:
384                 sec_irq_chip = &s2mpu02_irq_chip;
385                 break;
386         default:
387                 dev_err(sec_pmic->dev, "Unknown device type %lu\n",
388                         sec_pmic->device_type);
389                 return -EINVAL;
390         }
391
392         ret = devm_regmap_add_irq_chip(sec_pmic->dev, sec_pmic->regmap_pmic,
393                                        sec_pmic->irq, IRQF_ONESHOT,
394                                        0, sec_irq_chip, &sec_pmic->irq_data);
395         if (ret != 0) {
396                 dev_err(sec_pmic->dev, "Failed to register IRQ chip: %d\n", ret);
397                 return ret;
398         }
399
400         /*
401          * The rtc-s5m driver requests S2MPS14_IRQ_RTCA0 also for S2MPS11
402          * so the interrupt number must be consistent.
403          */
404         BUILD_BUG_ON(((enum s2mps14_irq)S2MPS11_IRQ_RTCA0) != S2MPS14_IRQ_RTCA0);
405
406         return 0;
407 }
408 EXPORT_SYMBOL_GPL(sec_irq_init);
409
410 MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>");
411 MODULE_AUTHOR("Chanwoo Choi <cw00.choi@samsung.com>");
412 MODULE_AUTHOR("Krzysztof Kozlowski <krzk@kernel.org>");
413 MODULE_DESCRIPTION("Interrupt support for the S5M MFD");
414 MODULE_LICENSE("GPL");