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