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