1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Core, IRQ and I2C device driver for DA9061 and DA9062 PMICs
4 * Copyright (C) 2015-2017 Dialog Semiconductor
7 #include <linux/kernel.h>
8 #include <linux/module.h>
9 #include <linux/init.h>
10 #include <linux/device.h>
11 #include <linux/interrupt.h>
12 #include <linux/regmap.h>
13 #include <linux/irq.h>
14 #include <linux/mfd/core.h>
15 #include <linux/i2c.h>
16 #include <linux/mfd/da9062/core.h>
17 #include <linux/mfd/da9062/registers.h>
18 #include <linux/regulator/of_regulator.h>
20 #define DA9062_REG_EVENT_A_OFFSET 0
21 #define DA9062_REG_EVENT_B_OFFSET 1
22 #define DA9062_REG_EVENT_C_OFFSET 2
24 static struct regmap_irq da9061_irqs
[] = {
26 [DA9061_IRQ_ONKEY
] = {
27 .reg_offset
= DA9062_REG_EVENT_A_OFFSET
,
28 .mask
= DA9062AA_M_NONKEY_MASK
,
30 [DA9061_IRQ_WDG_WARN
] = {
31 .reg_offset
= DA9062_REG_EVENT_A_OFFSET
,
32 .mask
= DA9062AA_M_WDG_WARN_MASK
,
34 [DA9061_IRQ_SEQ_RDY
] = {
35 .reg_offset
= DA9062_REG_EVENT_A_OFFSET
,
36 .mask
= DA9062AA_M_SEQ_RDY_MASK
,
40 .reg_offset
= DA9062_REG_EVENT_B_OFFSET
,
41 .mask
= DA9062AA_M_TEMP_MASK
,
43 [DA9061_IRQ_LDO_LIM
] = {
44 .reg_offset
= DA9062_REG_EVENT_B_OFFSET
,
45 .mask
= DA9062AA_M_LDO_LIM_MASK
,
47 [DA9061_IRQ_DVC_RDY
] = {
48 .reg_offset
= DA9062_REG_EVENT_B_OFFSET
,
49 .mask
= DA9062AA_M_DVC_RDY_MASK
,
51 [DA9061_IRQ_VDD_WARN
] = {
52 .reg_offset
= DA9062_REG_EVENT_B_OFFSET
,
53 .mask
= DA9062AA_M_VDD_WARN_MASK
,
57 .reg_offset
= DA9062_REG_EVENT_C_OFFSET
,
58 .mask
= DA9062AA_M_GPI0_MASK
,
61 .reg_offset
= DA9062_REG_EVENT_C_OFFSET
,
62 .mask
= DA9062AA_M_GPI1_MASK
,
65 .reg_offset
= DA9062_REG_EVENT_C_OFFSET
,
66 .mask
= DA9062AA_M_GPI2_MASK
,
69 .reg_offset
= DA9062_REG_EVENT_C_OFFSET
,
70 .mask
= DA9062AA_M_GPI3_MASK
,
73 .reg_offset
= DA9062_REG_EVENT_C_OFFSET
,
74 .mask
= DA9062AA_M_GPI4_MASK
,
78 static struct regmap_irq_chip da9061_irq_chip
= {
81 .num_irqs
= DA9061_NUM_IRQ
,
83 .status_base
= DA9062AA_EVENT_A
,
84 .mask_base
= DA9062AA_IRQ_MASK_A
,
85 .ack_base
= DA9062AA_EVENT_A
,
88 static struct regmap_irq da9062_irqs
[] = {
90 [DA9062_IRQ_ONKEY
] = {
91 .reg_offset
= DA9062_REG_EVENT_A_OFFSET
,
92 .mask
= DA9062AA_M_NONKEY_MASK
,
94 [DA9062_IRQ_ALARM
] = {
95 .reg_offset
= DA9062_REG_EVENT_A_OFFSET
,
96 .mask
= DA9062AA_M_ALARM_MASK
,
99 .reg_offset
= DA9062_REG_EVENT_A_OFFSET
,
100 .mask
= DA9062AA_M_TICK_MASK
,
102 [DA9062_IRQ_WDG_WARN
] = {
103 .reg_offset
= DA9062_REG_EVENT_A_OFFSET
,
104 .mask
= DA9062AA_M_WDG_WARN_MASK
,
106 [DA9062_IRQ_SEQ_RDY
] = {
107 .reg_offset
= DA9062_REG_EVENT_A_OFFSET
,
108 .mask
= DA9062AA_M_SEQ_RDY_MASK
,
111 [DA9062_IRQ_TEMP
] = {
112 .reg_offset
= DA9062_REG_EVENT_B_OFFSET
,
113 .mask
= DA9062AA_M_TEMP_MASK
,
115 [DA9062_IRQ_LDO_LIM
] = {
116 .reg_offset
= DA9062_REG_EVENT_B_OFFSET
,
117 .mask
= DA9062AA_M_LDO_LIM_MASK
,
119 [DA9062_IRQ_DVC_RDY
] = {
120 .reg_offset
= DA9062_REG_EVENT_B_OFFSET
,
121 .mask
= DA9062AA_M_DVC_RDY_MASK
,
123 [DA9062_IRQ_VDD_WARN
] = {
124 .reg_offset
= DA9062_REG_EVENT_B_OFFSET
,
125 .mask
= DA9062AA_M_VDD_WARN_MASK
,
128 [DA9062_IRQ_GPI0
] = {
129 .reg_offset
= DA9062_REG_EVENT_C_OFFSET
,
130 .mask
= DA9062AA_M_GPI0_MASK
,
132 [DA9062_IRQ_GPI1
] = {
133 .reg_offset
= DA9062_REG_EVENT_C_OFFSET
,
134 .mask
= DA9062AA_M_GPI1_MASK
,
136 [DA9062_IRQ_GPI2
] = {
137 .reg_offset
= DA9062_REG_EVENT_C_OFFSET
,
138 .mask
= DA9062AA_M_GPI2_MASK
,
140 [DA9062_IRQ_GPI3
] = {
141 .reg_offset
= DA9062_REG_EVENT_C_OFFSET
,
142 .mask
= DA9062AA_M_GPI3_MASK
,
144 [DA9062_IRQ_GPI4
] = {
145 .reg_offset
= DA9062_REG_EVENT_C_OFFSET
,
146 .mask
= DA9062AA_M_GPI4_MASK
,
150 static struct regmap_irq_chip da9062_irq_chip
= {
151 .name
= "da9062-irq",
153 .num_irqs
= DA9062_NUM_IRQ
,
155 .status_base
= DA9062AA_EVENT_A
,
156 .mask_base
= DA9062AA_IRQ_MASK_A
,
157 .ack_base
= DA9062AA_EVENT_A
,
160 static struct resource da9061_core_resources
[] = {
161 DEFINE_RES_IRQ_NAMED(DA9061_IRQ_VDD_WARN
, "VDD_WARN"),
164 static struct resource da9061_regulators_resources
[] = {
165 DEFINE_RES_IRQ_NAMED(DA9061_IRQ_LDO_LIM
, "LDO_LIM"),
168 static struct resource da9061_thermal_resources
[] = {
169 DEFINE_RES_IRQ_NAMED(DA9061_IRQ_TEMP
, "THERMAL"),
172 static struct resource da9061_wdt_resources
[] = {
173 DEFINE_RES_IRQ_NAMED(DA9061_IRQ_WDG_WARN
, "WD_WARN"),
176 static struct resource da9061_onkey_resources
[] = {
177 DEFINE_RES_IRQ_NAMED(DA9061_IRQ_ONKEY
, "ONKEY"),
180 static const struct mfd_cell da9061_devs
[] = {
182 .name
= "da9061-core",
183 .num_resources
= ARRAY_SIZE(da9061_core_resources
),
184 .resources
= da9061_core_resources
,
187 .name
= "da9062-regulators",
188 .num_resources
= ARRAY_SIZE(da9061_regulators_resources
),
189 .resources
= da9061_regulators_resources
,
192 .name
= "da9061-watchdog",
193 .num_resources
= ARRAY_SIZE(da9061_wdt_resources
),
194 .resources
= da9061_wdt_resources
,
195 .of_compatible
= "dlg,da9061-watchdog",
198 .name
= "da9061-thermal",
199 .num_resources
= ARRAY_SIZE(da9061_thermal_resources
),
200 .resources
= da9061_thermal_resources
,
201 .of_compatible
= "dlg,da9061-thermal",
204 .name
= "da9061-onkey",
205 .num_resources
= ARRAY_SIZE(da9061_onkey_resources
),
206 .resources
= da9061_onkey_resources
,
207 .of_compatible
= "dlg,da9061-onkey",
211 static struct resource da9062_core_resources
[] = {
212 DEFINE_RES_NAMED(DA9062_IRQ_VDD_WARN
, 1, "VDD_WARN", IORESOURCE_IRQ
),
215 static struct resource da9062_regulators_resources
[] = {
216 DEFINE_RES_NAMED(DA9062_IRQ_LDO_LIM
, 1, "LDO_LIM", IORESOURCE_IRQ
),
219 static struct resource da9062_thermal_resources
[] = {
220 DEFINE_RES_NAMED(DA9062_IRQ_TEMP
, 1, "THERMAL", IORESOURCE_IRQ
),
223 static struct resource da9062_wdt_resources
[] = {
224 DEFINE_RES_NAMED(DA9062_IRQ_WDG_WARN
, 1, "WD_WARN", IORESOURCE_IRQ
),
227 static struct resource da9062_rtc_resources
[] = {
228 DEFINE_RES_NAMED(DA9062_IRQ_ALARM
, 1, "ALARM", IORESOURCE_IRQ
),
229 DEFINE_RES_NAMED(DA9062_IRQ_TICK
, 1, "TICK", IORESOURCE_IRQ
),
232 static struct resource da9062_onkey_resources
[] = {
233 DEFINE_RES_NAMED(DA9062_IRQ_ONKEY
, 1, "ONKEY", IORESOURCE_IRQ
),
236 static struct resource da9062_gpio_resources
[] = {
237 DEFINE_RES_NAMED(DA9062_IRQ_GPI0
, 1, "GPI0", IORESOURCE_IRQ
),
238 DEFINE_RES_NAMED(DA9062_IRQ_GPI1
, 1, "GPI1", IORESOURCE_IRQ
),
239 DEFINE_RES_NAMED(DA9062_IRQ_GPI2
, 1, "GPI2", IORESOURCE_IRQ
),
240 DEFINE_RES_NAMED(DA9062_IRQ_GPI3
, 1, "GPI3", IORESOURCE_IRQ
),
241 DEFINE_RES_NAMED(DA9062_IRQ_GPI4
, 1, "GPI4", IORESOURCE_IRQ
),
244 static const struct mfd_cell da9062_devs
[] = {
246 .name
= "da9062-core",
247 .num_resources
= ARRAY_SIZE(da9062_core_resources
),
248 .resources
= da9062_core_resources
,
251 .name
= "da9062-regulators",
252 .num_resources
= ARRAY_SIZE(da9062_regulators_resources
),
253 .resources
= da9062_regulators_resources
,
256 .name
= "da9062-watchdog",
257 .num_resources
= ARRAY_SIZE(da9062_wdt_resources
),
258 .resources
= da9062_wdt_resources
,
259 .of_compatible
= "dlg,da9062-watchdog",
262 .name
= "da9062-thermal",
263 .num_resources
= ARRAY_SIZE(da9062_thermal_resources
),
264 .resources
= da9062_thermal_resources
,
265 .of_compatible
= "dlg,da9062-thermal",
268 .name
= "da9062-rtc",
269 .num_resources
= ARRAY_SIZE(da9062_rtc_resources
),
270 .resources
= da9062_rtc_resources
,
271 .of_compatible
= "dlg,da9062-rtc",
274 .name
= "da9062-onkey",
275 .num_resources
= ARRAY_SIZE(da9062_onkey_resources
),
276 .resources
= da9062_onkey_resources
,
277 .of_compatible
= "dlg,da9062-onkey",
280 .name
= "da9062-gpio",
281 .num_resources
= ARRAY_SIZE(da9062_gpio_resources
),
282 .resources
= da9062_gpio_resources
,
283 .of_compatible
= "dlg,da9062-gpio",
287 static int da9062_clear_fault_log(struct da9062
*chip
)
292 ret
= regmap_read(chip
->regmap
, DA9062AA_FAULT_LOG
, &fault_log
);
297 if (fault_log
& DA9062AA_TWD_ERROR_MASK
)
298 dev_dbg(chip
->dev
, "Fault log entry detected: TWD_ERROR\n");
299 if (fault_log
& DA9062AA_POR_MASK
)
300 dev_dbg(chip
->dev
, "Fault log entry detected: POR\n");
301 if (fault_log
& DA9062AA_VDD_FAULT_MASK
)
302 dev_dbg(chip
->dev
, "Fault log entry detected: VDD_FAULT\n");
303 if (fault_log
& DA9062AA_VDD_START_MASK
)
304 dev_dbg(chip
->dev
, "Fault log entry detected: VDD_START\n");
305 if (fault_log
& DA9062AA_TEMP_CRIT_MASK
)
306 dev_dbg(chip
->dev
, "Fault log entry detected: TEMP_CRIT\n");
307 if (fault_log
& DA9062AA_KEY_RESET_MASK
)
308 dev_dbg(chip
->dev
, "Fault log entry detected: KEY_RESET\n");
309 if (fault_log
& DA9062AA_NSHUTDOWN_MASK
)
310 dev_dbg(chip
->dev
, "Fault log entry detected: NSHUTDOWN\n");
311 if (fault_log
& DA9062AA_WAIT_SHUT_MASK
)
312 dev_dbg(chip
->dev
, "Fault log entry detected: WAIT_SHUT\n");
314 ret
= regmap_write(chip
->regmap
, DA9062AA_FAULT_LOG
,
321 static int da9062_get_device_type(struct da9062
*chip
)
323 int device_id
, variant_id
, variant_mrc
, variant_vrc
;
327 ret
= regmap_read(chip
->regmap
, DA9062AA_DEVICE_ID
, &device_id
);
329 dev_err(chip
->dev
, "Cannot read chip ID.\n");
332 if (device_id
!= DA9062_PMIC_DEVICE_ID
) {
333 dev_err(chip
->dev
, "Invalid device ID: 0x%02x\n", device_id
);
337 ret
= regmap_read(chip
->regmap
, DA9062AA_VARIANT_ID
, &variant_id
);
339 dev_err(chip
->dev
, "Cannot read chip variant id.\n");
343 variant_vrc
= (variant_id
& DA9062AA_VRC_MASK
) >> DA9062AA_VRC_SHIFT
;
345 switch (variant_vrc
) {
346 case DA9062_PMIC_VARIANT_VRC_DA9061
:
349 case DA9062_PMIC_VARIANT_VRC_DA9062
:
358 "Device detected (device-ID: 0x%02X, var-ID: 0x%02X, %s)\n",
359 device_id
, variant_id
, type
);
361 variant_mrc
= (variant_id
& DA9062AA_MRC_MASK
) >> DA9062AA_MRC_SHIFT
;
363 if (variant_mrc
< DA9062_PMIC_VARIANT_MRC_AA
) {
365 "Cannot support variant MRC: 0x%02X\n", variant_mrc
);
372 static const struct regmap_range da9061_aa_readable_ranges
[] = {
373 regmap_reg_range(DA9062AA_PAGE_CON
, DA9062AA_STATUS_B
),
374 regmap_reg_range(DA9062AA_STATUS_D
, DA9062AA_EVENT_C
),
375 regmap_reg_range(DA9062AA_IRQ_MASK_A
, DA9062AA_IRQ_MASK_C
),
376 regmap_reg_range(DA9062AA_CONTROL_A
, DA9062AA_GPIO_4
),
377 regmap_reg_range(DA9062AA_GPIO_WKUP_MODE
, DA9062AA_GPIO_OUT3_4
),
378 regmap_reg_range(DA9062AA_BUCK1_CONT
, DA9062AA_BUCK4_CONT
),
379 regmap_reg_range(DA9062AA_BUCK3_CONT
, DA9062AA_BUCK3_CONT
),
380 regmap_reg_range(DA9062AA_LDO1_CONT
, DA9062AA_LDO4_CONT
),
381 regmap_reg_range(DA9062AA_DVC_1
, DA9062AA_DVC_1
),
382 regmap_reg_range(DA9062AA_SEQ
, DA9062AA_ID_4_3
),
383 regmap_reg_range(DA9062AA_ID_12_11
, DA9062AA_ID_16_15
),
384 regmap_reg_range(DA9062AA_ID_22_21
, DA9062AA_ID_32_31
),
385 regmap_reg_range(DA9062AA_SEQ_A
, DA9062AA_WAIT
),
386 regmap_reg_range(DA9062AA_RESET
, DA9062AA_BUCK_ILIM_C
),
387 regmap_reg_range(DA9062AA_BUCK1_CFG
, DA9062AA_BUCK3_CFG
),
388 regmap_reg_range(DA9062AA_VBUCK1_A
, DA9062AA_VBUCK4_A
),
389 regmap_reg_range(DA9062AA_VBUCK3_A
, DA9062AA_VBUCK3_A
),
390 regmap_reg_range(DA9062AA_VLDO1_A
, DA9062AA_VLDO4_A
),
391 regmap_reg_range(DA9062AA_VBUCK1_B
, DA9062AA_VBUCK4_B
),
392 regmap_reg_range(DA9062AA_VBUCK3_B
, DA9062AA_VBUCK3_B
),
393 regmap_reg_range(DA9062AA_VLDO1_B
, DA9062AA_VLDO4_B
),
394 regmap_reg_range(DA9062AA_INTERFACE
, DA9062AA_CONFIG_E
),
395 regmap_reg_range(DA9062AA_CONFIG_G
, DA9062AA_CONFIG_K
),
396 regmap_reg_range(DA9062AA_CONFIG_M
, DA9062AA_CONFIG_M
),
397 regmap_reg_range(DA9062AA_GP_ID_0
, DA9062AA_GP_ID_19
),
398 regmap_reg_range(DA9062AA_DEVICE_ID
, DA9062AA_CONFIG_ID
),
401 static const struct regmap_range da9061_aa_writeable_ranges
[] = {
402 regmap_reg_range(DA9062AA_PAGE_CON
, DA9062AA_PAGE_CON
),
403 regmap_reg_range(DA9062AA_FAULT_LOG
, DA9062AA_EVENT_C
),
404 regmap_reg_range(DA9062AA_IRQ_MASK_A
, DA9062AA_IRQ_MASK_C
),
405 regmap_reg_range(DA9062AA_CONTROL_A
, DA9062AA_GPIO_4
),
406 regmap_reg_range(DA9062AA_GPIO_WKUP_MODE
, DA9062AA_GPIO_OUT3_4
),
407 regmap_reg_range(DA9062AA_BUCK1_CONT
, DA9062AA_BUCK4_CONT
),
408 regmap_reg_range(DA9062AA_BUCK3_CONT
, DA9062AA_BUCK3_CONT
),
409 regmap_reg_range(DA9062AA_LDO1_CONT
, DA9062AA_LDO4_CONT
),
410 regmap_reg_range(DA9062AA_DVC_1
, DA9062AA_DVC_1
),
411 regmap_reg_range(DA9062AA_SEQ
, DA9062AA_ID_4_3
),
412 regmap_reg_range(DA9062AA_ID_12_11
, DA9062AA_ID_16_15
),
413 regmap_reg_range(DA9062AA_ID_22_21
, DA9062AA_ID_32_31
),
414 regmap_reg_range(DA9062AA_SEQ_A
, DA9062AA_WAIT
),
415 regmap_reg_range(DA9062AA_RESET
, DA9062AA_BUCK_ILIM_C
),
416 regmap_reg_range(DA9062AA_BUCK1_CFG
, DA9062AA_BUCK3_CFG
),
417 regmap_reg_range(DA9062AA_VBUCK1_A
, DA9062AA_VBUCK4_A
),
418 regmap_reg_range(DA9062AA_VBUCK3_A
, DA9062AA_VBUCK3_A
),
419 regmap_reg_range(DA9062AA_VLDO1_A
, DA9062AA_VLDO4_A
),
420 regmap_reg_range(DA9062AA_VBUCK1_B
, DA9062AA_VBUCK4_B
),
421 regmap_reg_range(DA9062AA_VBUCK3_B
, DA9062AA_VBUCK3_B
),
422 regmap_reg_range(DA9062AA_VLDO1_B
, DA9062AA_VLDO4_B
),
423 regmap_reg_range(DA9062AA_GP_ID_0
, DA9062AA_GP_ID_19
),
426 static const struct regmap_range da9061_aa_volatile_ranges
[] = {
427 regmap_reg_range(DA9062AA_PAGE_CON
, DA9062AA_STATUS_B
),
428 regmap_reg_range(DA9062AA_STATUS_D
, DA9062AA_EVENT_C
),
429 regmap_reg_range(DA9062AA_CONTROL_A
, DA9062AA_CONTROL_B
),
430 regmap_reg_range(DA9062AA_CONTROL_E
, DA9062AA_CONTROL_F
),
431 regmap_reg_range(DA9062AA_BUCK1_CONT
, DA9062AA_BUCK4_CONT
),
432 regmap_reg_range(DA9062AA_BUCK3_CONT
, DA9062AA_BUCK3_CONT
),
433 regmap_reg_range(DA9062AA_LDO1_CONT
, DA9062AA_LDO4_CONT
),
434 regmap_reg_range(DA9062AA_DVC_1
, DA9062AA_DVC_1
),
435 regmap_reg_range(DA9062AA_SEQ
, DA9062AA_SEQ
),
438 static const struct regmap_access_table da9061_aa_readable_table
= {
439 .yes_ranges
= da9061_aa_readable_ranges
,
440 .n_yes_ranges
= ARRAY_SIZE(da9061_aa_readable_ranges
),
443 static const struct regmap_access_table da9061_aa_writeable_table
= {
444 .yes_ranges
= da9061_aa_writeable_ranges
,
445 .n_yes_ranges
= ARRAY_SIZE(da9061_aa_writeable_ranges
),
448 static const struct regmap_access_table da9061_aa_volatile_table
= {
449 .yes_ranges
= da9061_aa_volatile_ranges
,
450 .n_yes_ranges
= ARRAY_SIZE(da9061_aa_volatile_ranges
),
453 static const struct regmap_range_cfg da9061_range_cfg
[] = {
455 .range_min
= DA9062AA_PAGE_CON
,
456 .range_max
= DA9062AA_CONFIG_ID
,
457 .selector_reg
= DA9062AA_PAGE_CON
,
458 .selector_mask
= 1 << DA9062_I2C_PAGE_SEL_SHIFT
,
459 .selector_shift
= DA9062_I2C_PAGE_SEL_SHIFT
,
465 static struct regmap_config da9061_regmap_config
= {
468 .ranges
= da9061_range_cfg
,
469 .num_ranges
= ARRAY_SIZE(da9061_range_cfg
),
470 .max_register
= DA9062AA_CONFIG_ID
,
471 .cache_type
= REGCACHE_RBTREE
,
472 .rd_table
= &da9061_aa_readable_table
,
473 .wr_table
= &da9061_aa_writeable_table
,
474 .volatile_table
= &da9061_aa_volatile_table
,
477 static const struct regmap_range da9062_aa_readable_ranges
[] = {
478 regmap_reg_range(DA9062AA_PAGE_CON
, DA9062AA_STATUS_B
),
479 regmap_reg_range(DA9062AA_STATUS_D
, DA9062AA_EVENT_C
),
480 regmap_reg_range(DA9062AA_IRQ_MASK_A
, DA9062AA_IRQ_MASK_C
),
481 regmap_reg_range(DA9062AA_CONTROL_A
, DA9062AA_GPIO_4
),
482 regmap_reg_range(DA9062AA_GPIO_WKUP_MODE
, DA9062AA_BUCK4_CONT
),
483 regmap_reg_range(DA9062AA_BUCK3_CONT
, DA9062AA_BUCK3_CONT
),
484 regmap_reg_range(DA9062AA_LDO1_CONT
, DA9062AA_LDO4_CONT
),
485 regmap_reg_range(DA9062AA_DVC_1
, DA9062AA_DVC_1
),
486 regmap_reg_range(DA9062AA_COUNT_S
, DA9062AA_SECOND_D
),
487 regmap_reg_range(DA9062AA_SEQ
, DA9062AA_ID_4_3
),
488 regmap_reg_range(DA9062AA_ID_12_11
, DA9062AA_ID_16_15
),
489 regmap_reg_range(DA9062AA_ID_22_21
, DA9062AA_ID_32_31
),
490 regmap_reg_range(DA9062AA_SEQ_A
, DA9062AA_BUCK3_CFG
),
491 regmap_reg_range(DA9062AA_VBUCK2_A
, DA9062AA_VBUCK4_A
),
492 regmap_reg_range(DA9062AA_VBUCK3_A
, DA9062AA_VBUCK3_A
),
493 regmap_reg_range(DA9062AA_VLDO1_A
, DA9062AA_VLDO4_A
),
494 regmap_reg_range(DA9062AA_VBUCK2_B
, DA9062AA_VBUCK4_B
),
495 regmap_reg_range(DA9062AA_VBUCK3_B
, DA9062AA_VBUCK3_B
),
496 regmap_reg_range(DA9062AA_VLDO1_B
, DA9062AA_VLDO4_B
),
497 regmap_reg_range(DA9062AA_BBAT_CONT
, DA9062AA_BBAT_CONT
),
498 regmap_reg_range(DA9062AA_INTERFACE
, DA9062AA_CONFIG_E
),
499 regmap_reg_range(DA9062AA_CONFIG_G
, DA9062AA_CONFIG_K
),
500 regmap_reg_range(DA9062AA_CONFIG_M
, DA9062AA_CONFIG_M
),
501 regmap_reg_range(DA9062AA_TRIM_CLDR
, DA9062AA_GP_ID_19
),
502 regmap_reg_range(DA9062AA_DEVICE_ID
, DA9062AA_CONFIG_ID
),
505 static const struct regmap_range da9062_aa_writeable_ranges
[] = {
506 regmap_reg_range(DA9062AA_PAGE_CON
, DA9062AA_PAGE_CON
),
507 regmap_reg_range(DA9062AA_FAULT_LOG
, DA9062AA_EVENT_C
),
508 regmap_reg_range(DA9062AA_IRQ_MASK_A
, DA9062AA_IRQ_MASK_C
),
509 regmap_reg_range(DA9062AA_CONTROL_A
, DA9062AA_GPIO_4
),
510 regmap_reg_range(DA9062AA_GPIO_WKUP_MODE
, DA9062AA_BUCK4_CONT
),
511 regmap_reg_range(DA9062AA_BUCK3_CONT
, DA9062AA_BUCK3_CONT
),
512 regmap_reg_range(DA9062AA_LDO1_CONT
, DA9062AA_LDO4_CONT
),
513 regmap_reg_range(DA9062AA_DVC_1
, DA9062AA_DVC_1
),
514 regmap_reg_range(DA9062AA_COUNT_S
, DA9062AA_ALARM_Y
),
515 regmap_reg_range(DA9062AA_SEQ
, DA9062AA_ID_4_3
),
516 regmap_reg_range(DA9062AA_ID_12_11
, DA9062AA_ID_16_15
),
517 regmap_reg_range(DA9062AA_ID_22_21
, DA9062AA_ID_32_31
),
518 regmap_reg_range(DA9062AA_SEQ_A
, DA9062AA_BUCK3_CFG
),
519 regmap_reg_range(DA9062AA_VBUCK2_A
, DA9062AA_VBUCK4_A
),
520 regmap_reg_range(DA9062AA_VBUCK3_A
, DA9062AA_VBUCK3_A
),
521 regmap_reg_range(DA9062AA_VLDO1_A
, DA9062AA_VLDO4_A
),
522 regmap_reg_range(DA9062AA_VBUCK2_B
, DA9062AA_VBUCK4_B
),
523 regmap_reg_range(DA9062AA_VBUCK3_B
, DA9062AA_VBUCK3_B
),
524 regmap_reg_range(DA9062AA_VLDO1_B
, DA9062AA_VLDO4_B
),
525 regmap_reg_range(DA9062AA_BBAT_CONT
, DA9062AA_BBAT_CONT
),
526 regmap_reg_range(DA9062AA_GP_ID_0
, DA9062AA_GP_ID_19
),
529 static const struct regmap_range da9062_aa_volatile_ranges
[] = {
530 regmap_reg_range(DA9062AA_PAGE_CON
, DA9062AA_STATUS_B
),
531 regmap_reg_range(DA9062AA_STATUS_D
, DA9062AA_EVENT_C
),
532 regmap_reg_range(DA9062AA_CONTROL_A
, DA9062AA_CONTROL_B
),
533 regmap_reg_range(DA9062AA_CONTROL_E
, DA9062AA_CONTROL_F
),
534 regmap_reg_range(DA9062AA_BUCK2_CONT
, DA9062AA_BUCK4_CONT
),
535 regmap_reg_range(DA9062AA_BUCK3_CONT
, DA9062AA_BUCK3_CONT
),
536 regmap_reg_range(DA9062AA_LDO1_CONT
, DA9062AA_LDO4_CONT
),
537 regmap_reg_range(DA9062AA_DVC_1
, DA9062AA_DVC_1
),
538 regmap_reg_range(DA9062AA_COUNT_S
, DA9062AA_SECOND_D
),
539 regmap_reg_range(DA9062AA_SEQ
, DA9062AA_SEQ
),
540 regmap_reg_range(DA9062AA_EN_32K
, DA9062AA_EN_32K
),
543 static const struct regmap_access_table da9062_aa_readable_table
= {
544 .yes_ranges
= da9062_aa_readable_ranges
,
545 .n_yes_ranges
= ARRAY_SIZE(da9062_aa_readable_ranges
),
548 static const struct regmap_access_table da9062_aa_writeable_table
= {
549 .yes_ranges
= da9062_aa_writeable_ranges
,
550 .n_yes_ranges
= ARRAY_SIZE(da9062_aa_writeable_ranges
),
553 static const struct regmap_access_table da9062_aa_volatile_table
= {
554 .yes_ranges
= da9062_aa_volatile_ranges
,
555 .n_yes_ranges
= ARRAY_SIZE(da9062_aa_volatile_ranges
),
558 static const struct regmap_range_cfg da9062_range_cfg
[] = {
560 .range_min
= DA9062AA_PAGE_CON
,
561 .range_max
= DA9062AA_CONFIG_ID
,
562 .selector_reg
= DA9062AA_PAGE_CON
,
563 .selector_mask
= 1 << DA9062_I2C_PAGE_SEL_SHIFT
,
564 .selector_shift
= DA9062_I2C_PAGE_SEL_SHIFT
,
570 static struct regmap_config da9062_regmap_config
= {
573 .ranges
= da9062_range_cfg
,
574 .num_ranges
= ARRAY_SIZE(da9062_range_cfg
),
575 .max_register
= DA9062AA_CONFIG_ID
,
576 .cache_type
= REGCACHE_RBTREE
,
577 .rd_table
= &da9062_aa_readable_table
,
578 .wr_table
= &da9062_aa_writeable_table
,
579 .volatile_table
= &da9062_aa_volatile_table
,
582 static const struct of_device_id da9062_dt_ids
[] = {
583 { .compatible
= "dlg,da9061", .data
= (void *)COMPAT_TYPE_DA9061
, },
584 { .compatible
= "dlg,da9062", .data
= (void *)COMPAT_TYPE_DA9062
, },
587 MODULE_DEVICE_TABLE(of
, da9062_dt_ids
);
589 static int da9062_i2c_probe(struct i2c_client
*i2c
,
590 const struct i2c_device_id
*id
)
593 const struct of_device_id
*match
;
594 unsigned int irq_base
;
595 const struct mfd_cell
*cell
;
596 const struct regmap_irq_chip
*irq_chip
;
597 const struct regmap_config
*config
;
601 chip
= devm_kzalloc(&i2c
->dev
, sizeof(*chip
), GFP_KERNEL
);
605 if (i2c
->dev
.of_node
) {
606 match
= of_match_node(da9062_dt_ids
, i2c
->dev
.of_node
);
610 chip
->chip_type
= (uintptr_t)match
->data
;
612 chip
->chip_type
= id
->driver_data
;
615 i2c_set_clientdata(i2c
, chip
);
616 chip
->dev
= &i2c
->dev
;
619 dev_err(chip
->dev
, "No IRQ configured\n");
623 switch (chip
->chip_type
) {
624 case COMPAT_TYPE_DA9061
:
626 cell_num
= ARRAY_SIZE(da9061_devs
);
627 irq_chip
= &da9061_irq_chip
;
628 config
= &da9061_regmap_config
;
630 case COMPAT_TYPE_DA9062
:
632 cell_num
= ARRAY_SIZE(da9062_devs
);
633 irq_chip
= &da9062_irq_chip
;
634 config
= &da9062_regmap_config
;
637 dev_err(chip
->dev
, "Unrecognised chip type\n");
641 chip
->regmap
= devm_regmap_init_i2c(i2c
, config
);
642 if (IS_ERR(chip
->regmap
)) {
643 ret
= PTR_ERR(chip
->regmap
);
644 dev_err(chip
->dev
, "Failed to allocate register map: %d\n",
649 ret
= da9062_clear_fault_log(chip
);
651 dev_warn(chip
->dev
, "Cannot clear fault log\n");
653 ret
= da9062_get_device_type(chip
);
657 ret
= regmap_add_irq_chip(chip
->regmap
, i2c
->irq
,
658 IRQF_TRIGGER_LOW
| IRQF_ONESHOT
| IRQF_SHARED
,
662 dev_err(chip
->dev
, "Failed to request IRQ %d: %d\n",
667 irq_base
= regmap_irq_chip_get_base(chip
->regmap_irq
);
669 ret
= mfd_add_devices(chip
->dev
, PLATFORM_DEVID_NONE
, cell
,
670 cell_num
, NULL
, irq_base
,
673 dev_err(chip
->dev
, "Cannot register child devices\n");
674 regmap_del_irq_chip(i2c
->irq
, chip
->regmap_irq
);
681 static int da9062_i2c_remove(struct i2c_client
*i2c
)
683 struct da9062
*chip
= i2c_get_clientdata(i2c
);
685 mfd_remove_devices(chip
->dev
);
686 regmap_del_irq_chip(i2c
->irq
, chip
->regmap_irq
);
691 static const struct i2c_device_id da9062_i2c_id
[] = {
692 { "da9061", COMPAT_TYPE_DA9061
},
693 { "da9062", COMPAT_TYPE_DA9062
},
696 MODULE_DEVICE_TABLE(i2c
, da9062_i2c_id
);
698 static struct i2c_driver da9062_i2c_driver
= {
701 .of_match_table
= of_match_ptr(da9062_dt_ids
),
703 .probe
= da9062_i2c_probe
,
704 .remove
= da9062_i2c_remove
,
705 .id_table
= da9062_i2c_id
,
708 module_i2c_driver(da9062_i2c_driver
);
710 MODULE_DESCRIPTION("Core device driver for Dialog DA9061 and DA9062");
711 MODULE_AUTHOR("Steve Twiss <stwiss.opensource@diasemi.com>");
712 MODULE_LICENSE("GPL");