GNU Linux-libre 5.10.219-gnu1
[releases.git] / drivers / mfd / da9063-irq.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /* Interrupt support for Dialog DA9063
3  *
4  * Copyright 2012 Dialog Semiconductor Ltd.
5  * Copyright 2013 Philipp Zabel, Pengutronix
6  *
7  * Author: Michal Hajduk, Dialog Semiconductor
8  */
9
10 #include <linux/kernel.h>
11 #include <linux/module.h>
12 #include <linux/irq.h>
13 #include <linux/mfd/core.h>
14 #include <linux/interrupt.h>
15 #include <linux/regmap.h>
16 #include <linux/mfd/da9063/core.h>
17
18 #define DA9063_REG_EVENT_A_OFFSET       0
19 #define DA9063_REG_EVENT_B_OFFSET       1
20 #define DA9063_REG_EVENT_C_OFFSET       2
21 #define DA9063_REG_EVENT_D_OFFSET       3
22
23 static const struct regmap_irq da9063_irqs[] = {
24         /* DA9063 event A register */
25         REGMAP_IRQ_REG(DA9063_IRQ_ONKEY,
26                        DA9063_REG_EVENT_A_OFFSET, DA9063_M_ONKEY),
27         REGMAP_IRQ_REG(DA9063_IRQ_ALARM,
28                        DA9063_REG_EVENT_A_OFFSET, DA9063_M_ALARM),
29         REGMAP_IRQ_REG(DA9063_IRQ_TICK,
30                        DA9063_REG_EVENT_A_OFFSET, DA9063_M_TICK),
31         REGMAP_IRQ_REG(DA9063_IRQ_ADC_RDY,
32                        DA9063_REG_EVENT_A_OFFSET, DA9063_M_ADC_RDY),
33         REGMAP_IRQ_REG(DA9063_IRQ_SEQ_RDY,
34                        DA9063_REG_EVENT_A_OFFSET, DA9063_M_SEQ_RDY),
35         /* DA9063 event B register */
36         REGMAP_IRQ_REG(DA9063_IRQ_WAKE,
37                        DA9063_REG_EVENT_B_OFFSET, DA9063_M_WAKE),
38         REGMAP_IRQ_REG(DA9063_IRQ_TEMP,
39                        DA9063_REG_EVENT_B_OFFSET, DA9063_M_TEMP),
40         REGMAP_IRQ_REG(DA9063_IRQ_COMP_1V2,
41                        DA9063_REG_EVENT_B_OFFSET, DA9063_M_COMP_1V2),
42         REGMAP_IRQ_REG(DA9063_IRQ_LDO_LIM,
43                        DA9063_REG_EVENT_B_OFFSET, DA9063_M_LDO_LIM),
44         REGMAP_IRQ_REG(DA9063_IRQ_REG_UVOV,
45                        DA9063_REG_EVENT_B_OFFSET, DA9063_M_UVOV),
46         REGMAP_IRQ_REG(DA9063_IRQ_DVC_RDY,
47                        DA9063_REG_EVENT_B_OFFSET, DA9063_M_DVC_RDY),
48         REGMAP_IRQ_REG(DA9063_IRQ_VDD_MON,
49                        DA9063_REG_EVENT_B_OFFSET, DA9063_M_VDD_MON),
50         REGMAP_IRQ_REG(DA9063_IRQ_WARN,
51                        DA9063_REG_EVENT_B_OFFSET, DA9063_M_VDD_WARN),
52         /* DA9063 event C register */
53         REGMAP_IRQ_REG(DA9063_IRQ_GPI0,
54                        DA9063_REG_EVENT_C_OFFSET, DA9063_M_GPI0),
55         REGMAP_IRQ_REG(DA9063_IRQ_GPI1,
56                        DA9063_REG_EVENT_C_OFFSET, DA9063_M_GPI1),
57         REGMAP_IRQ_REG(DA9063_IRQ_GPI2,
58                        DA9063_REG_EVENT_C_OFFSET, DA9063_M_GPI2),
59         REGMAP_IRQ_REG(DA9063_IRQ_GPI3,
60                        DA9063_REG_EVENT_C_OFFSET, DA9063_M_GPI3),
61         REGMAP_IRQ_REG(DA9063_IRQ_GPI4,
62                        DA9063_REG_EVENT_C_OFFSET, DA9063_M_GPI4),
63         REGMAP_IRQ_REG(DA9063_IRQ_GPI5,
64                        DA9063_REG_EVENT_C_OFFSET, DA9063_M_GPI5),
65         REGMAP_IRQ_REG(DA9063_IRQ_GPI6,
66                        DA9063_REG_EVENT_C_OFFSET, DA9063_M_GPI6),
67         REGMAP_IRQ_REG(DA9063_IRQ_GPI7,
68                        DA9063_REG_EVENT_C_OFFSET, DA9063_M_GPI7),
69         /* DA9063 event D register */
70         REGMAP_IRQ_REG(DA9063_IRQ_GPI8,
71                        DA9063_REG_EVENT_D_OFFSET, DA9063_M_GPI8),
72         REGMAP_IRQ_REG(DA9063_IRQ_GPI9,
73                        DA9063_REG_EVENT_D_OFFSET, DA9063_M_GPI9),
74         REGMAP_IRQ_REG(DA9063_IRQ_GPI10,
75                        DA9063_REG_EVENT_D_OFFSET, DA9063_M_GPI10),
76         REGMAP_IRQ_REG(DA9063_IRQ_GPI11,
77                        DA9063_REG_EVENT_D_OFFSET, DA9063_M_GPI11),
78         REGMAP_IRQ_REG(DA9063_IRQ_GPI12,
79                        DA9063_REG_EVENT_D_OFFSET, DA9063_M_GPI12),
80         REGMAP_IRQ_REG(DA9063_IRQ_GPI13,
81                        DA9063_REG_EVENT_D_OFFSET, DA9063_M_GPI13),
82         REGMAP_IRQ_REG(DA9063_IRQ_GPI14,
83                        DA9063_REG_EVENT_D_OFFSET, DA9063_M_GPI14),
84         REGMAP_IRQ_REG(DA9063_IRQ_GPI15,
85                        DA9063_REG_EVENT_D_OFFSET, DA9063_M_GPI15),
86 };
87
88 static const struct regmap_irq_chip da9063_irq_chip = {
89         .name = "da9063-irq",
90         .irqs = da9063_irqs,
91         .num_irqs = ARRAY_SIZE(da9063_irqs),
92         .num_regs = 4,
93         .status_base = DA9063_REG_EVENT_A,
94         .mask_base = DA9063_REG_IRQ_MASK_A,
95         .ack_base = DA9063_REG_EVENT_A,
96         .init_ack_masked = true,
97 };
98
99 static const struct regmap_irq da9063l_irqs[] = {
100         /* DA9063 event A register */
101         REGMAP_IRQ_REG(DA9063_IRQ_ONKEY,
102                        DA9063_REG_EVENT_A_OFFSET, DA9063_M_ONKEY),
103         REGMAP_IRQ_REG(DA9063_IRQ_ADC_RDY,
104                        DA9063_REG_EVENT_A_OFFSET, DA9063_M_ADC_RDY),
105         REGMAP_IRQ_REG(DA9063_IRQ_SEQ_RDY,
106                        DA9063_REG_EVENT_A_OFFSET, DA9063_M_SEQ_RDY),
107         /* DA9063 event B register */
108         REGMAP_IRQ_REG(DA9063_IRQ_WAKE,
109                        DA9063_REG_EVENT_B_OFFSET, DA9063_M_WAKE),
110         REGMAP_IRQ_REG(DA9063_IRQ_TEMP,
111                        DA9063_REG_EVENT_B_OFFSET, DA9063_M_TEMP),
112         REGMAP_IRQ_REG(DA9063_IRQ_COMP_1V2,
113                        DA9063_REG_EVENT_B_OFFSET, DA9063_M_COMP_1V2),
114         REGMAP_IRQ_REG(DA9063_IRQ_LDO_LIM,
115                        DA9063_REG_EVENT_B_OFFSET, DA9063_M_LDO_LIM),
116         REGMAP_IRQ_REG(DA9063_IRQ_REG_UVOV,
117                        DA9063_REG_EVENT_B_OFFSET, DA9063_M_UVOV),
118         REGMAP_IRQ_REG(DA9063_IRQ_DVC_RDY,
119                        DA9063_REG_EVENT_B_OFFSET, DA9063_M_DVC_RDY),
120         REGMAP_IRQ_REG(DA9063_IRQ_VDD_MON,
121                        DA9063_REG_EVENT_B_OFFSET, DA9063_M_VDD_MON),
122         REGMAP_IRQ_REG(DA9063_IRQ_WARN,
123                        DA9063_REG_EVENT_B_OFFSET, DA9063_M_VDD_WARN),
124         /* DA9063 event C register */
125         REGMAP_IRQ_REG(DA9063_IRQ_GPI0,
126                        DA9063_REG_EVENT_C_OFFSET, DA9063_M_GPI0),
127         REGMAP_IRQ_REG(DA9063_IRQ_GPI1,
128                        DA9063_REG_EVENT_C_OFFSET, DA9063_M_GPI1),
129         REGMAP_IRQ_REG(DA9063_IRQ_GPI2,
130                        DA9063_REG_EVENT_C_OFFSET, DA9063_M_GPI2),
131         REGMAP_IRQ_REG(DA9063_IRQ_GPI3,
132                        DA9063_REG_EVENT_C_OFFSET, DA9063_M_GPI3),
133         REGMAP_IRQ_REG(DA9063_IRQ_GPI4,
134                        DA9063_REG_EVENT_C_OFFSET, DA9063_M_GPI4),
135         REGMAP_IRQ_REG(DA9063_IRQ_GPI5,
136                        DA9063_REG_EVENT_C_OFFSET, DA9063_M_GPI5),
137         REGMAP_IRQ_REG(DA9063_IRQ_GPI6,
138                        DA9063_REG_EVENT_C_OFFSET, DA9063_M_GPI6),
139         REGMAP_IRQ_REG(DA9063_IRQ_GPI7,
140                        DA9063_REG_EVENT_C_OFFSET, DA9063_M_GPI7),
141         /* DA9063 event D register */
142         REGMAP_IRQ_REG(DA9063_IRQ_GPI8,
143                        DA9063_REG_EVENT_D_OFFSET, DA9063_M_GPI8),
144         REGMAP_IRQ_REG(DA9063_IRQ_GPI9,
145                        DA9063_REG_EVENT_D_OFFSET, DA9063_M_GPI9),
146         REGMAP_IRQ_REG(DA9063_IRQ_GPI10,
147                        DA9063_REG_EVENT_D_OFFSET, DA9063_M_GPI10),
148         REGMAP_IRQ_REG(DA9063_IRQ_GPI11,
149                        DA9063_REG_EVENT_D_OFFSET, DA9063_M_GPI11),
150         REGMAP_IRQ_REG(DA9063_IRQ_GPI12,
151                        DA9063_REG_EVENT_D_OFFSET, DA9063_M_GPI12),
152         REGMAP_IRQ_REG(DA9063_IRQ_GPI13,
153                        DA9063_REG_EVENT_D_OFFSET, DA9063_M_GPI13),
154         REGMAP_IRQ_REG(DA9063_IRQ_GPI14,
155                        DA9063_REG_EVENT_D_OFFSET, DA9063_M_GPI14),
156         REGMAP_IRQ_REG(DA9063_IRQ_GPI15,
157                        DA9063_REG_EVENT_D_OFFSET, DA9063_M_GPI15),
158 };
159
160 static const struct regmap_irq_chip da9063l_irq_chip = {
161         .name = "da9063l-irq",
162         .irqs = da9063l_irqs,
163         .num_irqs = ARRAY_SIZE(da9063l_irqs),
164         .num_regs = 4,
165         .status_base = DA9063_REG_EVENT_A,
166         .mask_base = DA9063_REG_IRQ_MASK_A,
167         .ack_base = DA9063_REG_EVENT_A,
168         .init_ack_masked = true,
169 };
170
171 int da9063_irq_init(struct da9063 *da9063)
172 {
173         const struct regmap_irq_chip *irq_chip;
174         int ret;
175
176         if (!da9063->chip_irq) {
177                 dev_err(da9063->dev, "No IRQ configured\n");
178                 return -EINVAL;
179         }
180
181         if (da9063->type == PMIC_TYPE_DA9063)
182                 irq_chip = &da9063_irq_chip;
183         else
184                 irq_chip = &da9063l_irq_chip;
185
186         ret = devm_regmap_add_irq_chip(da9063->dev, da9063->regmap,
187                         da9063->chip_irq,
188                         IRQF_TRIGGER_LOW | IRQF_ONESHOT | IRQF_SHARED,
189                         da9063->irq_base, irq_chip, &da9063->regmap_irq);
190         if (ret) {
191                 dev_err(da9063->dev, "Failed to reguest IRQ %d: %d\n",
192                                 da9063->chip_irq, ret);
193                 return ret;
194         }
195
196         return 0;
197 }