1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright (C) 2024 ROHM Semiconductors
4 *
5 * ROHM BD96801 PMIC driver
6 *
7 * This version of the "BD86801 scalable PMIC"'s driver supports only very
8 * basic set of the PMIC features.
9 * Most notably, there is no support for the configurations which should
10 * be done when the PMIC is in STBY mode.
11 *
12 * Being able to reliably do the configurations like changing the
13 * regulator safety limits (like limits for the over/under -voltages, over
14 * current, thermal protection) would require the configuring driver to be
15 * synchronized with entity causing the PMIC state transitions. Eg, one
16 * should be able to ensure the PMIC is in STBY state when the
17 * configurations are applied to the hardware. How and when the PMIC state
18 * transitions are to be done is likely to be very system specific, as will
19 * be the need to configure these safety limits. Hence it's not simple to
20 * come up with a generic solution.
21 *
22 * Users who require the STBY state configurations can have a look at the
23 * original RFC:
24 * https://lore.kernel.org/all/cover.1712920132.git.mazziesaccount@gmail.com/
25 * which implements some of the safety limit configurations - but leaves the
26 * state change handling and synchronization to be implemented.
27 *
28 * It would be great to hear (and receive a patch!) if you implement the
29 * STBY configuration support or a proper fix in your downstream driver ;)
30 */
31
32 #include <linux/i2c.h>
33 #include <linux/interrupt.h>
34 #include <linux/mfd/core.h>
35 #include <linux/module.h>
36 #include <linux/property.h>
37 #include <linux/regmap.h>
38 #include <linux/types.h>
39
40 #include <linux/mfd/rohm-bd96801.h>
41 #include <linux/mfd/rohm-bd96802.h>
42 #include <linux/mfd/rohm-generic.h>
43
44 struct bd968xx {
45 const struct resource *errb_irqs;
46 const struct resource *intb_irqs;
47 int num_errb_irqs;
48 int num_intb_irqs;
49 const struct regmap_irq_chip *errb_irq_chip;
50 const struct regmap_irq_chip *intb_irq_chip;
51 const struct regmap_config *regmap_config;
52 struct mfd_cell *cells;
53 int num_cells;
54 int unlock_reg;
55 int unlock_val;
56 };
57
58 static const struct resource bd96801_reg_errb_irqs[] = {
59 DEFINE_RES_IRQ_NAMED(BD96801_OTP_ERR_STAT, "otp-err"),
60 DEFINE_RES_IRQ_NAMED(BD96801_DBIST_ERR_STAT, "dbist-err"),
61 DEFINE_RES_IRQ_NAMED(BD96801_EEP_ERR_STAT, "eep-err"),
62 DEFINE_RES_IRQ_NAMED(BD96801_ABIST_ERR_STAT, "abist-err"),
63 DEFINE_RES_IRQ_NAMED(BD96801_PRSTB_ERR_STAT, "prstb-err"),
64 DEFINE_RES_IRQ_NAMED(BD96801_DRMOS1_ERR_STAT, "drmoserr1"),
65 DEFINE_RES_IRQ_NAMED(BD96801_DRMOS2_ERR_STAT, "drmoserr2"),
66 DEFINE_RES_IRQ_NAMED(BD96801_SLAVE_ERR_STAT, "slave-err"),
67 DEFINE_RES_IRQ_NAMED(BD96801_VREF_ERR_STAT, "vref-err"),
68 DEFINE_RES_IRQ_NAMED(BD96801_TSD_ERR_STAT, "tsd"),
69 DEFINE_RES_IRQ_NAMED(BD96801_UVLO_ERR_STAT, "uvlo-err"),
70 DEFINE_RES_IRQ_NAMED(BD96801_OVLO_ERR_STAT, "ovlo-err"),
71 DEFINE_RES_IRQ_NAMED(BD96801_OSC_ERR_STAT, "osc-err"),
72 DEFINE_RES_IRQ_NAMED(BD96801_PON_ERR_STAT, "pon-err"),
73 DEFINE_RES_IRQ_NAMED(BD96801_POFF_ERR_STAT, "poff-err"),
74 DEFINE_RES_IRQ_NAMED(BD96801_CMD_SHDN_ERR_STAT, "cmd-shdn-err"),
75
76 DEFINE_RES_IRQ_NAMED(BD96801_INT_PRSTB_WDT_ERR, "bd96801-prstb-wdt-err"),
77 DEFINE_RES_IRQ_NAMED(BD96801_INT_CHIP_IF_ERR, "bd96801-chip-if-err"),
78
79 DEFINE_RES_IRQ_NAMED(BD96801_INT_SHDN_ERR_STAT, "int-shdn-err"),
80
81 DEFINE_RES_IRQ_NAMED(BD96801_BUCK1_PVIN_ERR_STAT, "buck1-pvin-err"),
82 DEFINE_RES_IRQ_NAMED(BD96801_BUCK1_OVP_ERR_STAT, "buck1-ovp-err"),
83 DEFINE_RES_IRQ_NAMED(BD96801_BUCK1_UVP_ERR_STAT, "buck1-uvp-err"),
84 DEFINE_RES_IRQ_NAMED(BD96801_BUCK1_SHDN_ERR_STAT, "buck1-shdn-err"),
85
86 DEFINE_RES_IRQ_NAMED(BD96801_BUCK2_PVIN_ERR_STAT, "buck2-pvin-err"),
87 DEFINE_RES_IRQ_NAMED(BD96801_BUCK2_OVP_ERR_STAT, "buck2-ovp-err"),
88 DEFINE_RES_IRQ_NAMED(BD96801_BUCK2_UVP_ERR_STAT, "buck2-uvp-err"),
89 DEFINE_RES_IRQ_NAMED(BD96801_BUCK2_SHDN_ERR_STAT, "buck2-shdn-err"),
90
91 DEFINE_RES_IRQ_NAMED(BD96801_BUCK3_PVIN_ERR_STAT, "buck3-pvin-err"),
92 DEFINE_RES_IRQ_NAMED(BD96801_BUCK3_OVP_ERR_STAT, "buck3-ovp-err"),
93 DEFINE_RES_IRQ_NAMED(BD96801_BUCK3_UVP_ERR_STAT, "buck3-uvp-err"),
94 DEFINE_RES_IRQ_NAMED(BD96801_BUCK3_SHDN_ERR_STAT, "buck3-shdn-err"),
95
96 DEFINE_RES_IRQ_NAMED(BD96801_BUCK4_PVIN_ERR_STAT, "buck4-pvin-err"),
97 DEFINE_RES_IRQ_NAMED(BD96801_BUCK4_OVP_ERR_STAT, "buck4-ovp-err"),
98 DEFINE_RES_IRQ_NAMED(BD96801_BUCK4_UVP_ERR_STAT, "buck4-uvp-err"),
99 DEFINE_RES_IRQ_NAMED(BD96801_BUCK4_SHDN_ERR_STAT, "buck4-shdn-err"),
100
101 DEFINE_RES_IRQ_NAMED(BD96801_LDO5_PVIN_ERR_STAT, "ldo5-pvin-err"),
102 DEFINE_RES_IRQ_NAMED(BD96801_LDO5_OVP_ERR_STAT, "ldo5-ovp-err"),
103 DEFINE_RES_IRQ_NAMED(BD96801_LDO5_UVP_ERR_STAT, "ldo5-uvp-err"),
104 DEFINE_RES_IRQ_NAMED(BD96801_LDO5_SHDN_ERR_STAT, "ldo5-shdn-err"),
105
106 DEFINE_RES_IRQ_NAMED(BD96801_LDO6_PVIN_ERR_STAT, "ldo6-pvin-err"),
107 DEFINE_RES_IRQ_NAMED(BD96801_LDO6_OVP_ERR_STAT, "ldo6-ovp-err"),
108 DEFINE_RES_IRQ_NAMED(BD96801_LDO6_UVP_ERR_STAT, "ldo6-uvp-err"),
109 DEFINE_RES_IRQ_NAMED(BD96801_LDO6_SHDN_ERR_STAT, "ldo6-shdn-err"),
110
111 DEFINE_RES_IRQ_NAMED(BD96801_LDO7_PVIN_ERR_STAT, "ldo7-pvin-err"),
112 DEFINE_RES_IRQ_NAMED(BD96801_LDO7_OVP_ERR_STAT, "ldo7-ovp-err"),
113 DEFINE_RES_IRQ_NAMED(BD96801_LDO7_UVP_ERR_STAT, "ldo7-uvp-err"),
114 DEFINE_RES_IRQ_NAMED(BD96801_LDO7_SHDN_ERR_STAT, "ldo7-shdn-err"),
115 };
116
117 static const struct resource bd96802_reg_errb_irqs[] = {
118 DEFINE_RES_IRQ_NAMED(BD96802_OTP_ERR_STAT, "otp-err"),
119 DEFINE_RES_IRQ_NAMED(BD96802_DBIST_ERR_STAT, "dbist-err"),
120 DEFINE_RES_IRQ_NAMED(BD96802_EEP_ERR_STAT, "eep-err"),
121 DEFINE_RES_IRQ_NAMED(BD96802_ABIST_ERR_STAT, "abist-err"),
122 DEFINE_RES_IRQ_NAMED(BD96802_PRSTB_ERR_STAT, "prstb-err"),
123 DEFINE_RES_IRQ_NAMED(BD96802_DRMOS1_ERR_STAT, "drmoserr1"),
124 DEFINE_RES_IRQ_NAMED(BD96802_DRMOS1_ERR_STAT, "drmoserr2"),
125 DEFINE_RES_IRQ_NAMED(BD96802_SLAVE_ERR_STAT, "slave-err"),
126 DEFINE_RES_IRQ_NAMED(BD96802_VREF_ERR_STAT, "vref-err"),
127 DEFINE_RES_IRQ_NAMED(BD96802_TSD_ERR_STAT, "tsd"),
128 DEFINE_RES_IRQ_NAMED(BD96802_UVLO_ERR_STAT, "uvlo-err"),
129 DEFINE_RES_IRQ_NAMED(BD96802_OVLO_ERR_STAT, "ovlo-err"),
130 DEFINE_RES_IRQ_NAMED(BD96802_OSC_ERR_STAT, "osc-err"),
131 DEFINE_RES_IRQ_NAMED(BD96802_PON_ERR_STAT, "pon-err"),
132 DEFINE_RES_IRQ_NAMED(BD96802_POFF_ERR_STAT, "poff-err"),
133 DEFINE_RES_IRQ_NAMED(BD96802_CMD_SHDN_ERR_STAT, "cmd-shdn-err"),
134 DEFINE_RES_IRQ_NAMED(BD96802_INT_SHDN_ERR_STAT, "int-shdn-err"),
135
136 DEFINE_RES_IRQ_NAMED(BD96802_BUCK1_PVIN_ERR_STAT, "buck1-pvin-err"),
137 DEFINE_RES_IRQ_NAMED(BD96802_BUCK1_OVP_ERR_STAT, "buck1-ovp-err"),
138 DEFINE_RES_IRQ_NAMED(BD96802_BUCK1_UVP_ERR_STAT, "buck1-uvp-err"),
139 DEFINE_RES_IRQ_NAMED(BD96802_BUCK1_SHDN_ERR_STAT, "buck1-shdn-err"),
140
141 DEFINE_RES_IRQ_NAMED(BD96802_BUCK2_PVIN_ERR_STAT, "buck2-pvin-err"),
142 DEFINE_RES_IRQ_NAMED(BD96802_BUCK2_OVP_ERR_STAT, "buck2-ovp-err"),
143 DEFINE_RES_IRQ_NAMED(BD96802_BUCK2_UVP_ERR_STAT, "buck2-uvp-err"),
144 DEFINE_RES_IRQ_NAMED(BD96802_BUCK2_SHDN_ERR_STAT, "buck2-shdn-err"),
145 };
146
147 static const struct resource bd96801_reg_intb_irqs[] = {
148 DEFINE_RES_IRQ_NAMED(BD96801_TW_STAT, "core-thermal"),
149
150 DEFINE_RES_IRQ_NAMED(BD96801_BUCK1_OCPH_STAT, "buck1-overcurr-h"),
151 DEFINE_RES_IRQ_NAMED(BD96801_BUCK1_OCPL_STAT, "buck1-overcurr-l"),
152 DEFINE_RES_IRQ_NAMED(BD96801_BUCK1_OCPN_STAT, "buck1-overcurr-n"),
153 DEFINE_RES_IRQ_NAMED(BD96801_BUCK1_OVD_STAT, "buck1-overvolt"),
154 DEFINE_RES_IRQ_NAMED(BD96801_BUCK1_UVD_STAT, "buck1-undervolt"),
155 DEFINE_RES_IRQ_NAMED(BD96801_BUCK1_TW_CH_STAT, "buck1-thermal"),
156
157 DEFINE_RES_IRQ_NAMED(BD96801_BUCK2_OCPH_STAT, "buck2-overcurr-h"),
158 DEFINE_RES_IRQ_NAMED(BD96801_BUCK2_OCPL_STAT, "buck2-overcurr-l"),
159 DEFINE_RES_IRQ_NAMED(BD96801_BUCK2_OCPN_STAT, "buck2-overcurr-n"),
160 DEFINE_RES_IRQ_NAMED(BD96801_BUCK2_OVD_STAT, "buck2-overvolt"),
161 DEFINE_RES_IRQ_NAMED(BD96801_BUCK2_UVD_STAT, "buck2-undervolt"),
162 DEFINE_RES_IRQ_NAMED(BD96801_BUCK2_TW_CH_STAT, "buck2-thermal"),
163
164 DEFINE_RES_IRQ_NAMED(BD96801_BUCK3_OCPH_STAT, "buck3-overcurr-h"),
165 DEFINE_RES_IRQ_NAMED(BD96801_BUCK3_OCPL_STAT, "buck3-overcurr-l"),
166 DEFINE_RES_IRQ_NAMED(BD96801_BUCK3_OCPN_STAT, "buck3-overcurr-n"),
167 DEFINE_RES_IRQ_NAMED(BD96801_BUCK3_OVD_STAT, "buck3-overvolt"),
168 DEFINE_RES_IRQ_NAMED(BD96801_BUCK3_UVD_STAT, "buck3-undervolt"),
169 DEFINE_RES_IRQ_NAMED(BD96801_BUCK3_TW_CH_STAT, "buck3-thermal"),
170
171 DEFINE_RES_IRQ_NAMED(BD96801_BUCK4_OCPH_STAT, "buck4-overcurr-h"),
172 DEFINE_RES_IRQ_NAMED(BD96801_BUCK4_OCPL_STAT, "buck4-overcurr-l"),
173 DEFINE_RES_IRQ_NAMED(BD96801_BUCK4_OCPN_STAT, "buck4-overcurr-n"),
174 DEFINE_RES_IRQ_NAMED(BD96801_BUCK4_OVD_STAT, "buck4-overvolt"),
175 DEFINE_RES_IRQ_NAMED(BD96801_BUCK4_UVD_STAT, "buck4-undervolt"),
176 DEFINE_RES_IRQ_NAMED(BD96801_BUCK4_TW_CH_STAT, "buck4-thermal"),
177
178 DEFINE_RES_IRQ_NAMED(BD96801_LDO5_OCPH_STAT, "ldo5-overcurr"),
179 DEFINE_RES_IRQ_NAMED(BD96801_LDO5_OVD_STAT, "ldo5-overvolt"),
180 DEFINE_RES_IRQ_NAMED(BD96801_LDO5_UVD_STAT, "ldo5-undervolt"),
181
182 DEFINE_RES_IRQ_NAMED(BD96801_LDO6_OCPH_STAT, "ldo6-overcurr"),
183 DEFINE_RES_IRQ_NAMED(BD96801_LDO6_OVD_STAT, "ldo6-overvolt"),
184 DEFINE_RES_IRQ_NAMED(BD96801_LDO6_UVD_STAT, "ldo6-undervolt"),
185
186 DEFINE_RES_IRQ_NAMED(BD96801_LDO7_OCPH_STAT, "ldo7-overcurr"),
187 DEFINE_RES_IRQ_NAMED(BD96801_LDO7_OVD_STAT, "ldo7-overvolt"),
188 DEFINE_RES_IRQ_NAMED(BD96801_LDO7_UVD_STAT, "ldo7-undervolt"),
189 };
190
191 static const struct resource bd96802_reg_intb_irqs[] = {
192 DEFINE_RES_IRQ_NAMED(BD96802_TW_STAT, "core-thermal"),
193
194 DEFINE_RES_IRQ_NAMED(BD96802_BUCK1_OCPH_STAT, "buck1-overcurr-h"),
195 DEFINE_RES_IRQ_NAMED(BD96802_BUCK1_OCPL_STAT, "buck1-overcurr-l"),
196 DEFINE_RES_IRQ_NAMED(BD96802_BUCK1_OCPN_STAT, "buck1-overcurr-n"),
197 DEFINE_RES_IRQ_NAMED(BD96802_BUCK1_OVD_STAT, "buck1-overvolt"),
198 DEFINE_RES_IRQ_NAMED(BD96802_BUCK1_UVD_STAT, "buck1-undervolt"),
199 DEFINE_RES_IRQ_NAMED(BD96802_BUCK1_TW_CH_STAT, "buck1-thermal"),
200
201 DEFINE_RES_IRQ_NAMED(BD96802_BUCK2_OCPH_STAT, "buck2-overcurr-h"),
202 DEFINE_RES_IRQ_NAMED(BD96802_BUCK2_OCPL_STAT, "buck2-overcurr-l"),
203 DEFINE_RES_IRQ_NAMED(BD96802_BUCK2_OCPN_STAT, "buck2-overcurr-n"),
204 DEFINE_RES_IRQ_NAMED(BD96802_BUCK2_OVD_STAT, "buck2-overvolt"),
205 DEFINE_RES_IRQ_NAMED(BD96802_BUCK2_UVD_STAT, "buck2-undervolt"),
206 DEFINE_RES_IRQ_NAMED(BD96802_BUCK2_TW_CH_STAT, "buck2-thermal"),
207 };
208
209 enum {
210 WDG_CELL = 0,
211 REGULATOR_CELL,
212 };
213
214 static struct mfd_cell bd96801_cells[] = {
215 [WDG_CELL] = { .name = "bd96801-wdt", },
216 [REGULATOR_CELL] = { .name = "bd96801-regulator", },
217 };
218
219 static struct mfd_cell bd96802_cells[] = {
220 [WDG_CELL] = { .name = "bd96801-wdt", },
221 [REGULATOR_CELL] = { .name = "bd96802-regulator", },
222 };
223 static struct mfd_cell bd96805_cells[] = {
224 [WDG_CELL] = { .name = "bd96801-wdt", },
225 [REGULATOR_CELL] = { .name = "bd96805-regulator", },
226 };
227
228 static struct mfd_cell bd96806_cells[] = {
229 [WDG_CELL] = { .name = "bd96806-wdt", },
230 [REGULATOR_CELL] = { .name = "bd96806-regulator", },
231 };
232
233 static const struct regmap_range bd96801_volatile_ranges[] = {
234 /* Status registers */
235 regmap_reg_range(BD96801_REG_WD_FEED, BD96801_REG_WD_FAILCOUNT),
236 regmap_reg_range(BD96801_REG_WD_ASK, BD96801_REG_WD_ASK),
237 regmap_reg_range(BD96801_REG_WD_STATUS, BD96801_REG_WD_STATUS),
238 regmap_reg_range(BD96801_REG_PMIC_STATE, BD96801_REG_INT_LDO7_INTB),
239 /* Registers which do not update value unless PMIC is in STBY */
240 regmap_reg_range(BD96801_REG_SSCG_CTRL, BD96801_REG_SHD_INTB),
241 regmap_reg_range(BD96801_REG_BUCK_OVP, BD96801_REG_BOOT_OVERTIME),
242 /*
243 * LDO control registers have single bit (LDO MODE) which does not
244 * change when we write it unless PMIC is in STBY. It's safer to not
245 * cache it.
246 */
247 regmap_reg_range(BD96801_LDO5_VOL_LVL_REG, BD96801_LDO7_VOL_LVL_REG),
248 };
249
250 static const struct regmap_range bd96802_volatile_ranges[] = {
251 /* Status regs */
252 regmap_reg_range(BD96801_REG_WD_FEED, BD96801_REG_WD_FAILCOUNT),
253 regmap_reg_range(BD96801_REG_WD_ASK, BD96801_REG_WD_ASK),
254 regmap_reg_range(BD96801_REG_WD_STATUS, BD96801_REG_WD_STATUS),
255 regmap_reg_range(BD96801_REG_PMIC_STATE, BD96801_REG_INT_BUCK2_ERRB),
256 regmap_reg_range(BD96801_REG_INT_SYS_INTB, BD96801_REG_INT_BUCK2_INTB),
257 /* Registers which do not update value unless PMIC is in STBY */
258 regmap_reg_range(BD96801_REG_SSCG_CTRL, BD96801_REG_SHD_INTB),
259 regmap_reg_range(BD96801_REG_BUCK_OVP, BD96801_REG_BOOT_OVERTIME),
260 };
261
262 static const struct regmap_access_table bd96801_volatile_regs = {
263 .yes_ranges = bd96801_volatile_ranges,
264 .n_yes_ranges = ARRAY_SIZE(bd96801_volatile_ranges),
265 };
266
267 static const struct regmap_access_table bd96802_volatile_regs = {
268 .yes_ranges = bd96802_volatile_ranges,
269 .n_yes_ranges = ARRAY_SIZE(bd96802_volatile_ranges),
270 };
271
272 /*
273 * For ERRB we need main register bit mapping as bit(0) indicates active IRQ
274 * in one of the first 3 sub IRQ registers, For INTB we can use default 1 to 1
275 * mapping.
276 */
277 static unsigned int bit0_offsets[] = {0, 1, 2}; /* System stat, 3 registers */
278 static unsigned int bit1_offsets[] = {3}; /* Buck 1 stat */
279 static unsigned int bit2_offsets[] = {4}; /* Buck 2 stat */
280 static unsigned int bit3_offsets[] = {5}; /* Buck 3 stat */
281 static unsigned int bit4_offsets[] = {6}; /* Buck 4 stat */
282 static unsigned int bit5_offsets[] = {7}; /* LDO 5 stat */
283 static unsigned int bit6_offsets[] = {8}; /* LDO 6 stat */
284 static unsigned int bit7_offsets[] = {9}; /* LDO 7 stat */
285
286 static const struct regmap_irq_sub_irq_map bd96801_errb_sub_irq_offsets[] = {
287 REGMAP_IRQ_MAIN_REG_OFFSET(bit0_offsets),
288 REGMAP_IRQ_MAIN_REG_OFFSET(bit1_offsets),
289 REGMAP_IRQ_MAIN_REG_OFFSET(bit2_offsets),
290 REGMAP_IRQ_MAIN_REG_OFFSET(bit3_offsets),
291 REGMAP_IRQ_MAIN_REG_OFFSET(bit4_offsets),
292 REGMAP_IRQ_MAIN_REG_OFFSET(bit5_offsets),
293 REGMAP_IRQ_MAIN_REG_OFFSET(bit6_offsets),
294 REGMAP_IRQ_MAIN_REG_OFFSET(bit7_offsets),
295 };
296
297 static const struct regmap_irq_sub_irq_map bd96802_errb_sub_irq_offsets[] = {
298 REGMAP_IRQ_MAIN_REG_OFFSET(bit0_offsets),
299 REGMAP_IRQ_MAIN_REG_OFFSET(bit1_offsets),
300 REGMAP_IRQ_MAIN_REG_OFFSET(bit2_offsets),
301 };
302
303 static const struct regmap_irq bd96801_errb_irqs[] = {
304 /* Reg 0x52 Fatal ERRB1 */
305 REGMAP_IRQ_REG(BD96801_OTP_ERR_STAT, 0, BD96801_OTP_ERR_MASK),
306 REGMAP_IRQ_REG(BD96801_DBIST_ERR_STAT, 0, BD96801_DBIST_ERR_MASK),
307 REGMAP_IRQ_REG(BD96801_EEP_ERR_STAT, 0, BD96801_EEP_ERR_MASK),
308 REGMAP_IRQ_REG(BD96801_ABIST_ERR_STAT, 0, BD96801_ABIST_ERR_MASK),
309 REGMAP_IRQ_REG(BD96801_PRSTB_ERR_STAT, 0, BD96801_PRSTB_ERR_MASK),
310 REGMAP_IRQ_REG(BD96801_DRMOS1_ERR_STAT, 0, BD96801_DRMOS1_ERR_MASK),
311 REGMAP_IRQ_REG(BD96801_DRMOS2_ERR_STAT, 0, BD96801_DRMOS2_ERR_MASK),
312 REGMAP_IRQ_REG(BD96801_SLAVE_ERR_STAT, 0, BD96801_SLAVE_ERR_MASK),
313 /* 0x53 Fatal ERRB2 */
314 REGMAP_IRQ_REG(BD96801_VREF_ERR_STAT, 1, BD96801_VREF_ERR_MASK),
315 REGMAP_IRQ_REG(BD96801_TSD_ERR_STAT, 1, BD96801_TSD_ERR_MASK),
316 REGMAP_IRQ_REG(BD96801_UVLO_ERR_STAT, 1, BD96801_UVLO_ERR_MASK),
317 REGMAP_IRQ_REG(BD96801_OVLO_ERR_STAT, 1, BD96801_OVLO_ERR_MASK),
318 REGMAP_IRQ_REG(BD96801_OSC_ERR_STAT, 1, BD96801_OSC_ERR_MASK),
319 REGMAP_IRQ_REG(BD96801_PON_ERR_STAT, 1, BD96801_PON_ERR_MASK),
320 REGMAP_IRQ_REG(BD96801_POFF_ERR_STAT, 1, BD96801_POFF_ERR_MASK),
321 REGMAP_IRQ_REG(BD96801_CMD_SHDN_ERR_STAT, 1, BD96801_CMD_SHDN_ERR_MASK),
322 /* 0x54 Fatal INTB shadowed to ERRB */
323 REGMAP_IRQ_REG(BD96801_INT_PRSTB_WDT_ERR, 2, BD96801_INT_PRSTB_WDT_ERR_MASK),
324 REGMAP_IRQ_REG(BD96801_INT_CHIP_IF_ERR, 2, BD96801_INT_CHIP_IF_ERR_MASK),
325 REGMAP_IRQ_REG(BD96801_INT_SHDN_ERR_STAT, 2, BD96801_INT_SHDN_ERR_MASK),
326 /* Reg 0x55 BUCK1 ERR IRQs */
327 REGMAP_IRQ_REG(BD96801_BUCK1_PVIN_ERR_STAT, 3, BD96801_OUT_PVIN_ERR_MASK),
328 REGMAP_IRQ_REG(BD96801_BUCK1_OVP_ERR_STAT, 3, BD96801_OUT_OVP_ERR_MASK),
329 REGMAP_IRQ_REG(BD96801_BUCK1_UVP_ERR_STAT, 3, BD96801_OUT_UVP_ERR_MASK),
330 REGMAP_IRQ_REG(BD96801_BUCK1_SHDN_ERR_STAT, 3, BD96801_OUT_SHDN_ERR_MASK),
331 /* Reg 0x56 BUCK2 ERR IRQs */
332 REGMAP_IRQ_REG(BD96801_BUCK2_PVIN_ERR_STAT, 4, BD96801_OUT_PVIN_ERR_MASK),
333 REGMAP_IRQ_REG(BD96801_BUCK2_OVP_ERR_STAT, 4, BD96801_OUT_OVP_ERR_MASK),
334 REGMAP_IRQ_REG(BD96801_BUCK2_UVP_ERR_STAT, 4, BD96801_OUT_UVP_ERR_MASK),
335 REGMAP_IRQ_REG(BD96801_BUCK2_SHDN_ERR_STAT, 4, BD96801_OUT_SHDN_ERR_MASK),
336 /* Reg 0x57 BUCK3 ERR IRQs */
337 REGMAP_IRQ_REG(BD96801_BUCK3_PVIN_ERR_STAT, 5, BD96801_OUT_PVIN_ERR_MASK),
338 REGMAP_IRQ_REG(BD96801_BUCK3_OVP_ERR_STAT, 5, BD96801_OUT_OVP_ERR_MASK),
339 REGMAP_IRQ_REG(BD96801_BUCK3_UVP_ERR_STAT, 5, BD96801_OUT_UVP_ERR_MASK),
340 REGMAP_IRQ_REG(BD96801_BUCK3_SHDN_ERR_STAT, 5, BD96801_OUT_SHDN_ERR_MASK),
341 /* Reg 0x58 BUCK4 ERR IRQs */
342 REGMAP_IRQ_REG(BD96801_BUCK4_PVIN_ERR_STAT, 6, BD96801_OUT_PVIN_ERR_MASK),
343 REGMAP_IRQ_REG(BD96801_BUCK4_OVP_ERR_STAT, 6, BD96801_OUT_OVP_ERR_MASK),
344 REGMAP_IRQ_REG(BD96801_BUCK4_UVP_ERR_STAT, 6, BD96801_OUT_UVP_ERR_MASK),
345 REGMAP_IRQ_REG(BD96801_BUCK4_SHDN_ERR_STAT, 6, BD96801_OUT_SHDN_ERR_MASK),
346 /* Reg 0x59 LDO5 ERR IRQs */
347 REGMAP_IRQ_REG(BD96801_LDO5_PVIN_ERR_STAT, 7, BD96801_OUT_PVIN_ERR_MASK),
348 REGMAP_IRQ_REG(BD96801_LDO5_OVP_ERR_STAT, 7, BD96801_OUT_OVP_ERR_MASK),
349 REGMAP_IRQ_REG(BD96801_LDO5_UVP_ERR_STAT, 7, BD96801_OUT_UVP_ERR_MASK),
350 REGMAP_IRQ_REG(BD96801_LDO5_SHDN_ERR_STAT, 7, BD96801_OUT_SHDN_ERR_MASK),
351 /* Reg 0x5a LDO6 ERR IRQs */
352 REGMAP_IRQ_REG(BD96801_LDO6_PVIN_ERR_STAT, 8, BD96801_OUT_PVIN_ERR_MASK),
353 REGMAP_IRQ_REG(BD96801_LDO6_OVP_ERR_STAT, 8, BD96801_OUT_OVP_ERR_MASK),
354 REGMAP_IRQ_REG(BD96801_LDO6_UVP_ERR_STAT, 8, BD96801_OUT_UVP_ERR_MASK),
355 REGMAP_IRQ_REG(BD96801_LDO6_SHDN_ERR_STAT, 8, BD96801_OUT_SHDN_ERR_MASK),
356 /* Reg 0x5b LDO7 ERR IRQs */
357 REGMAP_IRQ_REG(BD96801_LDO7_PVIN_ERR_STAT, 9, BD96801_OUT_PVIN_ERR_MASK),
358 REGMAP_IRQ_REG(BD96801_LDO7_OVP_ERR_STAT, 9, BD96801_OUT_OVP_ERR_MASK),
359 REGMAP_IRQ_REG(BD96801_LDO7_UVP_ERR_STAT, 9, BD96801_OUT_UVP_ERR_MASK),
360 REGMAP_IRQ_REG(BD96801_LDO7_SHDN_ERR_STAT, 9, BD96801_OUT_SHDN_ERR_MASK),
361 };
362
363 static const struct regmap_irq bd96802_errb_irqs[] = {
364 /* Reg 0x52 Fatal ERRB1 */
365 REGMAP_IRQ_REG(BD96802_OTP_ERR_STAT, 0, BD96801_OTP_ERR_MASK),
366 REGMAP_IRQ_REG(BD96802_DBIST_ERR_STAT, 0, BD96801_DBIST_ERR_MASK),
367 REGMAP_IRQ_REG(BD96802_EEP_ERR_STAT, 0, BD96801_EEP_ERR_MASK),
368 REGMAP_IRQ_REG(BD96802_ABIST_ERR_STAT, 0, BD96801_ABIST_ERR_MASK),
369 REGMAP_IRQ_REG(BD96802_PRSTB_ERR_STAT, 0, BD96801_PRSTB_ERR_MASK),
370 REGMAP_IRQ_REG(BD96802_DRMOS1_ERR_STAT, 0, BD96801_DRMOS1_ERR_MASK),
371 REGMAP_IRQ_REG(BD96802_DRMOS2_ERR_STAT, 0, BD96801_DRMOS2_ERR_MASK),
372 REGMAP_IRQ_REG(BD96802_SLAVE_ERR_STAT, 0, BD96801_SLAVE_ERR_MASK),
373 /* 0x53 Fatal ERRB2 */
374 REGMAP_IRQ_REG(BD96802_VREF_ERR_STAT, 1, BD96801_VREF_ERR_MASK),
375 REGMAP_IRQ_REG(BD96802_TSD_ERR_STAT, 1, BD96801_TSD_ERR_MASK),
376 REGMAP_IRQ_REG(BD96802_UVLO_ERR_STAT, 1, BD96801_UVLO_ERR_MASK),
377 REGMAP_IRQ_REG(BD96802_OVLO_ERR_STAT, 1, BD96801_OVLO_ERR_MASK),
378 REGMAP_IRQ_REG(BD96802_OSC_ERR_STAT, 1, BD96801_OSC_ERR_MASK),
379 REGMAP_IRQ_REG(BD96802_PON_ERR_STAT, 1, BD96801_PON_ERR_MASK),
380 REGMAP_IRQ_REG(BD96802_POFF_ERR_STAT, 1, BD96801_POFF_ERR_MASK),
381 REGMAP_IRQ_REG(BD96802_CMD_SHDN_ERR_STAT, 1, BD96801_CMD_SHDN_ERR_MASK),
382 /* 0x54 Fatal INTB shadowed to ERRB */
383 REGMAP_IRQ_REG(BD96802_INT_SHDN_ERR_STAT, 2, BD96801_INT_SHDN_ERR_MASK),
384 /* Reg 0x55 BUCK1 ERR IRQs */
385 REGMAP_IRQ_REG(BD96802_BUCK1_PVIN_ERR_STAT, 3, BD96801_OUT_PVIN_ERR_MASK),
386 REGMAP_IRQ_REG(BD96802_BUCK1_OVP_ERR_STAT, 3, BD96801_OUT_OVP_ERR_MASK),
387 REGMAP_IRQ_REG(BD96802_BUCK1_UVP_ERR_STAT, 3, BD96801_OUT_UVP_ERR_MASK),
388 REGMAP_IRQ_REG(BD96802_BUCK1_SHDN_ERR_STAT, 3, BD96801_OUT_SHDN_ERR_MASK),
389 /* Reg 0x56 BUCK2 ERR IRQs */
390 REGMAP_IRQ_REG(BD96802_BUCK2_PVIN_ERR_STAT, 4, BD96801_OUT_PVIN_ERR_MASK),
391 REGMAP_IRQ_REG(BD96802_BUCK2_OVP_ERR_STAT, 4, BD96801_OUT_OVP_ERR_MASK),
392 REGMAP_IRQ_REG(BD96802_BUCK2_UVP_ERR_STAT, 4, BD96801_OUT_UVP_ERR_MASK),
393 REGMAP_IRQ_REG(BD96802_BUCK2_SHDN_ERR_STAT, 4, BD96801_OUT_SHDN_ERR_MASK),
394 };
395
396 static const struct regmap_irq bd96801_intb_irqs[] = {
397 /* STATUS SYSTEM INTB */
398 REGMAP_IRQ_REG(BD96801_TW_STAT, 0, BD96801_TW_STAT_MASK),
399 REGMAP_IRQ_REG(BD96801_WDT_ERR_STAT, 0, BD96801_WDT_ERR_STAT_MASK),
400 REGMAP_IRQ_REG(BD96801_I2C_ERR_STAT, 0, BD96801_I2C_ERR_STAT_MASK),
401 REGMAP_IRQ_REG(BD96801_CHIP_IF_ERR_STAT, 0, BD96801_CHIP_IF_ERR_STAT_MASK),
402 /* STATUS BUCK1 INTB */
403 REGMAP_IRQ_REG(BD96801_BUCK1_OCPH_STAT, 1, BD96801_BUCK_OCPH_STAT_MASK),
404 REGMAP_IRQ_REG(BD96801_BUCK1_OCPL_STAT, 1, BD96801_BUCK_OCPL_STAT_MASK),
405 REGMAP_IRQ_REG(BD96801_BUCK1_OCPN_STAT, 1, BD96801_BUCK_OCPN_STAT_MASK),
406 REGMAP_IRQ_REG(BD96801_BUCK1_OVD_STAT, 1, BD96801_BUCK_OVD_STAT_MASK),
407 REGMAP_IRQ_REG(BD96801_BUCK1_UVD_STAT, 1, BD96801_BUCK_UVD_STAT_MASK),
408 REGMAP_IRQ_REG(BD96801_BUCK1_TW_CH_STAT, 1, BD96801_BUCK_TW_CH_STAT_MASK),
409 /* BUCK 2 INTB */
410 REGMAP_IRQ_REG(BD96801_BUCK2_OCPH_STAT, 2, BD96801_BUCK_OCPH_STAT_MASK),
411 REGMAP_IRQ_REG(BD96801_BUCK2_OCPL_STAT, 2, BD96801_BUCK_OCPL_STAT_MASK),
412 REGMAP_IRQ_REG(BD96801_BUCK2_OCPN_STAT, 2, BD96801_BUCK_OCPN_STAT_MASK),
413 REGMAP_IRQ_REG(BD96801_BUCK2_OVD_STAT, 2, BD96801_BUCK_OVD_STAT_MASK),
414 REGMAP_IRQ_REG(BD96801_BUCK2_UVD_STAT, 2, BD96801_BUCK_UVD_STAT_MASK),
415 REGMAP_IRQ_REG(BD96801_BUCK2_TW_CH_STAT, 2, BD96801_BUCK_TW_CH_STAT_MASK),
416 /* BUCK 3 INTB */
417 REGMAP_IRQ_REG(BD96801_BUCK3_OCPH_STAT, 3, BD96801_BUCK_OCPH_STAT_MASK),
418 REGMAP_IRQ_REG(BD96801_BUCK3_OCPL_STAT, 3, BD96801_BUCK_OCPL_STAT_MASK),
419 REGMAP_IRQ_REG(BD96801_BUCK3_OCPN_STAT, 3, BD96801_BUCK_OCPN_STAT_MASK),
420 REGMAP_IRQ_REG(BD96801_BUCK3_OVD_STAT, 3, BD96801_BUCK_OVD_STAT_MASK),
421 REGMAP_IRQ_REG(BD96801_BUCK3_UVD_STAT, 3, BD96801_BUCK_UVD_STAT_MASK),
422 REGMAP_IRQ_REG(BD96801_BUCK3_TW_CH_STAT, 3, BD96801_BUCK_TW_CH_STAT_MASK),
423 /* BUCK 4 INTB */
424 REGMAP_IRQ_REG(BD96801_BUCK4_OCPH_STAT, 4, BD96801_BUCK_OCPH_STAT_MASK),
425 REGMAP_IRQ_REG(BD96801_BUCK4_OCPL_STAT, 4, BD96801_BUCK_OCPL_STAT_MASK),
426 REGMAP_IRQ_REG(BD96801_BUCK4_OCPN_STAT, 4, BD96801_BUCK_OCPN_STAT_MASK),
427 REGMAP_IRQ_REG(BD96801_BUCK4_OVD_STAT, 4, BD96801_BUCK_OVD_STAT_MASK),
428 REGMAP_IRQ_REG(BD96801_BUCK4_UVD_STAT, 4, BD96801_BUCK_UVD_STAT_MASK),
429 REGMAP_IRQ_REG(BD96801_BUCK4_TW_CH_STAT, 4, BD96801_BUCK_TW_CH_STAT_MASK),
430 /* LDO5 INTB */
431 REGMAP_IRQ_REG(BD96801_LDO5_OCPH_STAT, 5, BD96801_LDO_OCPH_STAT_MASK),
432 REGMAP_IRQ_REG(BD96801_LDO5_OVD_STAT, 5, BD96801_LDO_OVD_STAT_MASK),
433 REGMAP_IRQ_REG(BD96801_LDO5_UVD_STAT, 5, BD96801_LDO_UVD_STAT_MASK),
434 /* LDO6 INTB */
435 REGMAP_IRQ_REG(BD96801_LDO6_OCPH_STAT, 6, BD96801_LDO_OCPH_STAT_MASK),
436 REGMAP_IRQ_REG(BD96801_LDO6_OVD_STAT, 6, BD96801_LDO_OVD_STAT_MASK),
437 REGMAP_IRQ_REG(BD96801_LDO6_UVD_STAT, 6, BD96801_LDO_UVD_STAT_MASK),
438 /* LDO7 INTB */
439 REGMAP_IRQ_REG(BD96801_LDO7_OCPH_STAT, 7, BD96801_LDO_OCPH_STAT_MASK),
440 REGMAP_IRQ_REG(BD96801_LDO7_OVD_STAT, 7, BD96801_LDO_OVD_STAT_MASK),
441 REGMAP_IRQ_REG(BD96801_LDO7_UVD_STAT, 7, BD96801_LDO_UVD_STAT_MASK),
442 };
443
444 static const struct regmap_irq bd96802_intb_irqs[] = {
445 /* STATUS SYSTEM INTB */
446 REGMAP_IRQ_REG(BD96802_TW_STAT, 0, BD96801_TW_STAT_MASK),
447 REGMAP_IRQ_REG(BD96802_WDT_ERR_STAT, 0, BD96801_WDT_ERR_STAT_MASK),
448 REGMAP_IRQ_REG(BD96802_I2C_ERR_STAT, 0, BD96801_I2C_ERR_STAT_MASK),
449 REGMAP_IRQ_REG(BD96802_CHIP_IF_ERR_STAT, 0, BD96801_CHIP_IF_ERR_STAT_MASK),
450 /* STATUS BUCK1 INTB */
451 REGMAP_IRQ_REG(BD96802_BUCK1_OCPH_STAT, 1, BD96801_BUCK_OCPH_STAT_MASK),
452 REGMAP_IRQ_REG(BD96802_BUCK1_OCPL_STAT, 1, BD96801_BUCK_OCPL_STAT_MASK),
453 REGMAP_IRQ_REG(BD96802_BUCK1_OCPN_STAT, 1, BD96801_BUCK_OCPN_STAT_MASK),
454 REGMAP_IRQ_REG(BD96802_BUCK1_OVD_STAT, 1, BD96801_BUCK_OVD_STAT_MASK),
455 REGMAP_IRQ_REG(BD96802_BUCK1_UVD_STAT, 1, BD96801_BUCK_UVD_STAT_MASK),
456 REGMAP_IRQ_REG(BD96802_BUCK1_TW_CH_STAT, 1, BD96801_BUCK_TW_CH_STAT_MASK),
457 /* BUCK 2 INTB */
458 REGMAP_IRQ_REG(BD96802_BUCK2_OCPH_STAT, 2, BD96801_BUCK_OCPH_STAT_MASK),
459 REGMAP_IRQ_REG(BD96802_BUCK2_OCPL_STAT, 2, BD96801_BUCK_OCPL_STAT_MASK),
460 REGMAP_IRQ_REG(BD96802_BUCK2_OCPN_STAT, 2, BD96801_BUCK_OCPN_STAT_MASK),
461 REGMAP_IRQ_REG(BD96802_BUCK2_OVD_STAT, 2, BD96801_BUCK_OVD_STAT_MASK),
462 REGMAP_IRQ_REG(BD96802_BUCK2_UVD_STAT, 2, BD96801_BUCK_UVD_STAT_MASK),
463 REGMAP_IRQ_REG(BD96802_BUCK2_TW_CH_STAT, 2, BD96801_BUCK_TW_CH_STAT_MASK),
464 };
465
466 /*
467 * The IRQ stuff is a bit hairy. The BD96801 / BD96802 provide two physical
468 * IRQ lines called INTB and ERRB. They share the same main status register.
469 *
470 * For ERRB, mapping from main status to sub-status is such that the
471 * 'global' faults are mapped to first 3 sub-status registers - and indicated
472 * by the first bit[0] in main status reg.
473 *
474 * Rest of the status registers are for indicating stuff for individual
475 * regulators, 1 sub register / regulator and 1 main status register bit /
476 * regulator, starting from bit[1].
477 *
478 * Eg, regulator specific stuff has 1 to 1 mapping from main-status to sub
479 * registers but 'global' ERRB IRQs require mapping from main status bit[0] to
480 * 3 status registers.
481 *
482 * Furthermore, the BD96801 has 7 regulators where the BD96802 has only 2.
483 *
484 * INTB has only 1 sub status register for 'global' events and then own sub
485 * status register for each of the regulators. So, for INTB we have direct
486 * 1 to 1 mapping - BD96801 just having 5 register and 5 main status bits
487 * more than the BD96802.
488 *
489 * Sharing the main status bits could be a problem if we had both INTB and
490 * ERRB IRQs asserted but for different sub-status offsets. This might lead
491 * IRQ controller code to go read a sub status register which indicates no
492 * active IRQs. I assume this occurring repeteadly might lead the IRQ to be
493 * disabled by core as a result of repeteadly returned IRQ_NONEs.
494 *
495 * I don't consider this as a fatal problem for now because:
496 * a) Having ERRB asserted leads to PMIC fault state which will kill
497 * the SoC powered by the PMIC. (So, relevant only for potential
498 * case of not powering the processor with this PMIC).
499 * b) Having ERRB set without having respective INTB is unlikely
500 * (haven't actually verified this).
501 *
502 * So, let's proceed with main status enabled for both INTB and ERRB. We can
503 * later disable main-status usage on systems where this ever proves to be
504 * a problem.
505 */
506
507 static const struct regmap_irq_chip bd96801_irq_chip_errb = {
508 .name = "bd96801-irq-errb",
509 .domain_suffix = "errb",
510 .main_status = BD96801_REG_INT_MAIN,
511 .num_main_regs = 1,
512 .irqs = &bd96801_errb_irqs[0],
513 .num_irqs = ARRAY_SIZE(bd96801_errb_irqs),
514 .status_base = BD96801_REG_INT_SYS_ERRB1,
515 .mask_base = BD96801_REG_MASK_SYS_ERRB,
516 .ack_base = BD96801_REG_INT_SYS_ERRB1,
517 .init_ack_masked = true,
518 .num_regs = 10,
519 .irq_reg_stride = 1,
520 .sub_reg_offsets = &bd96801_errb_sub_irq_offsets[0],
521 };
522
523 static const struct regmap_irq_chip bd96802_irq_chip_errb = {
524 .name = "bd96802-irq-errb",
525 .domain_suffix = "errb",
526 .main_status = BD96801_REG_INT_MAIN,
527 .num_main_regs = 1,
528 .irqs = &bd96802_errb_irqs[0],
529 .num_irqs = ARRAY_SIZE(bd96802_errb_irqs),
530 .status_base = BD96801_REG_INT_SYS_ERRB1,
531 .mask_base = BD96801_REG_MASK_SYS_ERRB,
532 .ack_base = BD96801_REG_INT_SYS_ERRB1,
533 .init_ack_masked = true,
534 .num_regs = 5,
535 .irq_reg_stride = 1,
536 .sub_reg_offsets = &bd96802_errb_sub_irq_offsets[0],
537 };
538
539 static const struct regmap_irq_chip bd96801_irq_chip_intb = {
540 .name = "bd96801-irq-intb",
541 .domain_suffix = "intb",
542 .main_status = BD96801_REG_INT_MAIN,
543 .num_main_regs = 1,
544 .irqs = &bd96801_intb_irqs[0],
545 .num_irqs = ARRAY_SIZE(bd96801_intb_irqs),
546 .status_base = BD96801_REG_INT_SYS_INTB,
547 .mask_base = BD96801_REG_MASK_SYS_INTB,
548 .ack_base = BD96801_REG_INT_SYS_INTB,
549 .init_ack_masked = true,
550 .num_regs = 8,
551 .irq_reg_stride = 1,
552 };
553
554 static const struct regmap_irq_chip bd96802_irq_chip_intb = {
555 .name = "bd96802-irq-intb",
556 .domain_suffix = "intb",
557 .main_status = BD96801_REG_INT_MAIN,
558 .num_main_regs = 1,
559 .irqs = &bd96802_intb_irqs[0],
560 .num_irqs = ARRAY_SIZE(bd96802_intb_irqs),
561 .status_base = BD96801_REG_INT_SYS_INTB,
562 .mask_base = BD96801_REG_MASK_SYS_INTB,
563 .ack_base = BD96801_REG_INT_SYS_INTB,
564 .init_ack_masked = true,
565 .num_regs = 3,
566 .irq_reg_stride = 1,
567 };
568
569 static const struct regmap_config bd96801_regmap_config = {
570 .reg_bits = 8,
571 .val_bits = 8,
572 .volatile_table = &bd96801_volatile_regs,
573 .cache_type = REGCACHE_MAPLE,
574 };
575
576 static const struct regmap_config bd96802_regmap_config = {
577 .reg_bits = 8,
578 .val_bits = 8,
579 .volatile_table = &bd96802_volatile_regs,
580 .cache_type = REGCACHE_MAPLE,
581 };
582
583 static const struct bd968xx bd96801_data = {
584 .errb_irqs = bd96801_reg_errb_irqs,
585 .intb_irqs = bd96801_reg_intb_irqs,
586 .num_errb_irqs = ARRAY_SIZE(bd96801_reg_errb_irqs),
587 .num_intb_irqs = ARRAY_SIZE(bd96801_reg_intb_irqs),
588 .errb_irq_chip = &bd96801_irq_chip_errb,
589 .intb_irq_chip = &bd96801_irq_chip_intb,
590 .regmap_config = &bd96801_regmap_config,
591 .cells = bd96801_cells,
592 .num_cells = ARRAY_SIZE(bd96801_cells),
593 .unlock_reg = BD96801_LOCK_REG,
594 .unlock_val = BD96801_UNLOCK,
595 };
596
597 static const struct bd968xx bd96802_data = {
598 .errb_irqs = bd96802_reg_errb_irqs,
599 .intb_irqs = bd96802_reg_intb_irqs,
600 .num_errb_irqs = ARRAY_SIZE(bd96802_reg_errb_irqs),
601 .num_intb_irqs = ARRAY_SIZE(bd96802_reg_intb_irqs),
602 .errb_irq_chip = &bd96802_irq_chip_errb,
603 .intb_irq_chip = &bd96802_irq_chip_intb,
604 .regmap_config = &bd96802_regmap_config,
605 .cells = bd96802_cells,
606 .num_cells = ARRAY_SIZE(bd96802_cells),
607 .unlock_reg = BD96801_LOCK_REG,
608 .unlock_val = BD96801_UNLOCK,
609 };
610
611 static const struct bd968xx bd96805_data = {
612 .errb_irqs = bd96801_reg_errb_irqs,
613 .intb_irqs = bd96801_reg_intb_irqs,
614 .num_errb_irqs = ARRAY_SIZE(bd96801_reg_errb_irqs),
615 .num_intb_irqs = ARRAY_SIZE(bd96801_reg_intb_irqs),
616 .errb_irq_chip = &bd96801_irq_chip_errb,
617 .intb_irq_chip = &bd96801_irq_chip_intb,
618 .regmap_config = &bd96801_regmap_config,
619 .cells = bd96805_cells,
620 .num_cells = ARRAY_SIZE(bd96805_cells),
621 .unlock_reg = BD96801_LOCK_REG,
622 .unlock_val = BD96801_UNLOCK,
623 };
624
625 static struct bd968xx bd96806_data = {
626 .errb_irqs = bd96802_reg_errb_irqs,
627 .intb_irqs = bd96802_reg_intb_irqs,
628 .num_errb_irqs = ARRAY_SIZE(bd96802_reg_errb_irqs),
629 .num_intb_irqs = ARRAY_SIZE(bd96802_reg_intb_irqs),
630 .errb_irq_chip = &bd96802_irq_chip_errb,
631 .intb_irq_chip = &bd96802_irq_chip_intb,
632 .regmap_config = &bd96802_regmap_config,
633 .cells = bd96806_cells,
634 .num_cells = ARRAY_SIZE(bd96806_cells),
635 .unlock_reg = BD96801_LOCK_REG,
636 .unlock_val = BD96801_UNLOCK,
637 };
638
bd96801_i2c_probe(struct i2c_client * i2c)639 static int bd96801_i2c_probe(struct i2c_client *i2c)
640 {
641 struct regmap_irq_chip_data *intb_irq_data, *errb_irq_data;
642 struct irq_domain *intb_domain, *errb_domain;
643 const struct bd968xx *ddata;
644 const struct fwnode_handle *fwnode;
645 struct resource *regulator_res;
646 struct resource wdg_irq;
647 struct regmap *regmap;
648 int intb_irq, errb_irq, num_errb = 0;
649 int num_regu_irqs, wdg_irq_no;
650 unsigned int chip_type;
651 int i, ret;
652
653 chip_type = (unsigned int)(uintptr_t)device_get_match_data(&i2c->dev);
654 switch (chip_type) {
655 case ROHM_CHIP_TYPE_BD96801:
656 ddata = &bd96801_data;
657 break;
658 case ROHM_CHIP_TYPE_BD96802:
659 ddata = &bd96802_data;
660 break;
661 case ROHM_CHIP_TYPE_BD96805:
662 ddata = &bd96805_data;
663 break;
664 case ROHM_CHIP_TYPE_BD96806:
665 ddata = &bd96806_data;
666 break;
667 default:
668 dev_err(&i2c->dev, "Unknown IC\n");
669 return -EINVAL;
670 }
671
672 fwnode = dev_fwnode(&i2c->dev);
673 if (!fwnode)
674 return dev_err_probe(&i2c->dev, -EINVAL, "Failed to find fwnode\n");
675
676 intb_irq = fwnode_irq_get_byname(fwnode, "intb");
677 if (intb_irq < 0)
678 return dev_err_probe(&i2c->dev, intb_irq, "INTB IRQ not configured\n");
679
680 /* ERRB may be omitted if processor is powered by the PMIC */
681 errb_irq = fwnode_irq_get_byname(fwnode, "errb");
682 if (errb_irq == -EPROBE_DEFER)
683 return errb_irq;
684
685 if (errb_irq > 0)
686 num_errb = ddata->num_errb_irqs;
687
688 num_regu_irqs = ddata->num_intb_irqs + num_errb;
689
690 regulator_res = devm_kcalloc(&i2c->dev, num_regu_irqs,
691 sizeof(*regulator_res), GFP_KERNEL);
692 if (!regulator_res)
693 return -ENOMEM;
694
695 regmap = devm_regmap_init_i2c(i2c, ddata->regmap_config);
696 if (IS_ERR(regmap))
697 return dev_err_probe(&i2c->dev, PTR_ERR(regmap),
698 "Regmap initialization failed\n");
699
700 ret = regmap_write(regmap, ddata->unlock_reg, ddata->unlock_val);
701 if (ret)
702 return dev_err_probe(&i2c->dev, ret, "Failed to unlock PMIC\n");
703
704 ret = devm_regmap_add_irq_chip(&i2c->dev, regmap, intb_irq,
705 IRQF_ONESHOT, 0, ddata->intb_irq_chip,
706 &intb_irq_data);
707 if (ret)
708 return dev_err_probe(&i2c->dev, ret, "Failed to add INTB IRQ chip\n");
709
710 intb_domain = regmap_irq_get_domain(intb_irq_data);
711
712 /*
713 * MFD core code is built to handle only one IRQ domain. BD96801
714 * has two domains so we do IRQ mapping here and provide the
715 * already mapped IRQ numbers to sub-devices.
716 */
717 for (i = 0; i < ddata->num_intb_irqs; i++) {
718 struct resource *res = ®ulator_res[i];
719
720 *res = ddata->intb_irqs[i];
721 res->start = res->end = irq_create_mapping(intb_domain,
722 res->start);
723 }
724
725 wdg_irq_no = irq_create_mapping(intb_domain, BD96801_WDT_ERR_STAT);
726 wdg_irq = DEFINE_RES_IRQ_NAMED(wdg_irq_no, "bd96801-wdg");
727
728 ddata->cells[WDG_CELL].resources = &wdg_irq;
729 ddata->cells[WDG_CELL].num_resources = 1;
730
731 if (!num_errb)
732 goto skip_errb;
733
734 ret = devm_regmap_add_irq_chip(&i2c->dev, regmap, errb_irq, IRQF_ONESHOT,
735 0, ddata->errb_irq_chip, &errb_irq_data);
736 if (ret)
737 return dev_err_probe(&i2c->dev, ret,
738 "Failed to add ERRB IRQ chip\n");
739
740 errb_domain = regmap_irq_get_domain(errb_irq_data);
741
742 for (i = 0; i < num_errb; i++) {
743 struct resource *res = ®ulator_res[ddata->num_intb_irqs + i];
744
745 *res = ddata->errb_irqs[i];
746 res->start = res->end = irq_create_mapping(errb_domain, res->start);
747 }
748
749 skip_errb:
750 ddata->cells[REGULATOR_CELL].resources = regulator_res;
751 ddata->cells[REGULATOR_CELL].num_resources = num_regu_irqs;
752 ret = devm_mfd_add_devices(&i2c->dev, PLATFORM_DEVID_AUTO, ddata->cells,
753 ddata->num_cells, NULL, 0, NULL);
754 if (ret)
755 dev_err_probe(&i2c->dev, ret, "Failed to create subdevices\n");
756
757 return ret;
758 }
759
760 static const struct of_device_id bd96801_of_match[] = {
761 { .compatible = "rohm,bd96801", .data = (void *)ROHM_CHIP_TYPE_BD96801 },
762 { .compatible = "rohm,bd96802", .data = (void *)ROHM_CHIP_TYPE_BD96802 },
763 { .compatible = "rohm,bd96805", .data = (void *)ROHM_CHIP_TYPE_BD96805 },
764 { .compatible = "rohm,bd96806", .data = (void *)ROHM_CHIP_TYPE_BD96806 },
765 { }
766 };
767 MODULE_DEVICE_TABLE(of, bd96801_of_match);
768
769 static struct i2c_driver bd96801_i2c_driver = {
770 .driver = {
771 .name = "rohm-bd96801",
772 .of_match_table = bd96801_of_match,
773 },
774 .probe = bd96801_i2c_probe,
775 };
776
bd96801_i2c_init(void)777 static int __init bd96801_i2c_init(void)
778 {
779 return i2c_add_driver(&bd96801_i2c_driver);
780 }
781
782 /* Initialise early so consumer devices can complete system boot */
783 subsys_initcall(bd96801_i2c_init);
784
bd96801_i2c_exit(void)785 static void __exit bd96801_i2c_exit(void)
786 {
787 i2c_del_driver(&bd96801_i2c_driver);
788 }
789 module_exit(bd96801_i2c_exit);
790
791 MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>");
792 MODULE_DESCRIPTION("ROHM BD9680X Power Management IC driver");
793 MODULE_LICENSE("GPL");
794