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>
13 #include <linux/regmap.h>
14 #include <linux/irq.h>
15 #include <linux/mfd/core.h>
16 #include <linux/i2c.h>
17 #include <linux/mfd/da9062/core.h>
18 #include <linux/mfd/da9062/registers.h>
19 #include <linux/regulator/of_regulator.h>
21 #define DA9062_REG_EVENT_A_OFFSET 0
22 #define DA9062_REG_EVENT_B_OFFSET 1
23 #define DA9062_REG_EVENT_C_OFFSET 2
25 #define DA9062_IRQ_LOW 0
26 #define DA9062_IRQ_HIGH 1
28 static const struct regmap_irq da9061_irqs
[] = {
30 [DA9061_IRQ_ONKEY
] = {
31 .reg_offset
= DA9062_REG_EVENT_A_OFFSET
,
32 .mask
= DA9062AA_M_NONKEY_MASK
,
34 [DA9061_IRQ_WDG_WARN
] = {
35 .reg_offset
= DA9062_REG_EVENT_A_OFFSET
,
36 .mask
= DA9062AA_M_WDG_WARN_MASK
,
38 [DA9061_IRQ_SEQ_RDY
] = {
39 .reg_offset
= DA9062_REG_EVENT_A_OFFSET
,
40 .mask
= DA9062AA_M_SEQ_RDY_MASK
,
44 .reg_offset
= DA9062_REG_EVENT_B_OFFSET
,
45 .mask
= DA9062AA_M_TEMP_MASK
,
47 [DA9061_IRQ_LDO_LIM
] = {
48 .reg_offset
= DA9062_REG_EVENT_B_OFFSET
,
49 .mask
= DA9062AA_M_LDO_LIM_MASK
,
51 [DA9061_IRQ_DVC_RDY
] = {
52 .reg_offset
= DA9062_REG_EVENT_B_OFFSET
,
53 .mask
= DA9062AA_M_DVC_RDY_MASK
,
55 [DA9061_IRQ_VDD_WARN
] = {
56 .reg_offset
= DA9062_REG_EVENT_B_OFFSET
,
57 .mask
= DA9062AA_M_VDD_WARN_MASK
,
61 .reg_offset
= DA9062_REG_EVENT_C_OFFSET
,
62 .mask
= DA9062AA_M_GPI0_MASK
,
65 .reg_offset
= DA9062_REG_EVENT_C_OFFSET
,
66 .mask
= DA9062AA_M_GPI1_MASK
,
69 .reg_offset
= DA9062_REG_EVENT_C_OFFSET
,
70 .mask
= DA9062AA_M_GPI2_MASK
,
73 .reg_offset
= DA9062_REG_EVENT_C_OFFSET
,
74 .mask
= DA9062AA_M_GPI3_MASK
,
77 .reg_offset
= DA9062_REG_EVENT_C_OFFSET
,
78 .mask
= DA9062AA_M_GPI4_MASK
,
82 static const struct regmap_irq_chip da9061_irq_chip
= {
85 .num_irqs
= DA9061_NUM_IRQ
,
87 .status_base
= DA9062AA_EVENT_A
,
88 .mask_base
= DA9062AA_IRQ_MASK_A
,
89 .ack_base
= DA9062AA_EVENT_A
,
92 static const struct regmap_irq da9062_irqs
[] = {
94 [DA9062_IRQ_ONKEY
] = {
95 .reg_offset
= DA9062_REG_EVENT_A_OFFSET
,
96 .mask
= DA9062AA_M_NONKEY_MASK
,
98 [DA9062_IRQ_ALARM
] = {
99 .reg_offset
= DA9062_REG_EVENT_A_OFFSET
,
100 .mask
= DA9062AA_M_ALARM_MASK
,
102 [DA9062_IRQ_TICK
] = {
103 .reg_offset
= DA9062_REG_EVENT_A_OFFSET
,
104 .mask
= DA9062AA_M_TICK_MASK
,
106 [DA9062_IRQ_WDG_WARN
] = {
107 .reg_offset
= DA9062_REG_EVENT_A_OFFSET
,
108 .mask
= DA9062AA_M_WDG_WARN_MASK
,
110 [DA9062_IRQ_SEQ_RDY
] = {
111 .reg_offset
= DA9062_REG_EVENT_A_OFFSET
,
112 .mask
= DA9062AA_M_SEQ_RDY_MASK
,
115 [DA9062_IRQ_TEMP
] = {
116 .reg_offset
= DA9062_REG_EVENT_B_OFFSET
,
117 .mask
= DA9062AA_M_TEMP_MASK
,
119 [DA9062_IRQ_LDO_LIM
] = {
120 .reg_offset
= DA9062_REG_EVENT_B_OFFSET
,
121 .mask
= DA9062AA_M_LDO_LIM_MASK
,
123 [DA9062_IRQ_DVC_RDY
] = {
124 .reg_offset
= DA9062_REG_EVENT_B_OFFSET
,
125 .mask
= DA9062AA_M_DVC_RDY_MASK
,
127 [DA9062_IRQ_VDD_WARN
] = {
128 .reg_offset
= DA9062_REG_EVENT_B_OFFSET
,
129 .mask
= DA9062AA_M_VDD_WARN_MASK
,
132 [DA9062_IRQ_GPI0
] = {
133 .reg_offset
= DA9062_REG_EVENT_C_OFFSET
,
134 .mask
= DA9062AA_M_GPI0_MASK
,
136 [DA9062_IRQ_GPI1
] = {
137 .reg_offset
= DA9062_REG_EVENT_C_OFFSET
,
138 .mask
= DA9062AA_M_GPI1_MASK
,
140 [DA9062_IRQ_GPI2
] = {
141 .reg_offset
= DA9062_REG_EVENT_C_OFFSET
,
142 .mask
= DA9062AA_M_GPI2_MASK
,
144 [DA9062_IRQ_GPI3
] = {
145 .reg_offset
= DA9062_REG_EVENT_C_OFFSET
,
146 .mask
= DA9062AA_M_GPI3_MASK
,
148 [DA9062_IRQ_GPI4
] = {
149 .reg_offset
= DA9062_REG_EVENT_C_OFFSET
,
150 .mask
= DA9062AA_M_GPI4_MASK
,
154 static const struct regmap_irq_chip da9062_irq_chip
= {
155 .name
= "da9062-irq",
157 .num_irqs
= DA9062_NUM_IRQ
,
159 .status_base
= DA9062AA_EVENT_A
,
160 .mask_base
= DA9062AA_IRQ_MASK_A
,
161 .ack_base
= DA9062AA_EVENT_A
,
164 static const struct resource da9061_core_resources
[] = {
165 DEFINE_RES_IRQ_NAMED(DA9061_IRQ_VDD_WARN
, "VDD_WARN"),
168 static const struct resource da9061_regulators_resources
[] = {
169 DEFINE_RES_IRQ_NAMED(DA9061_IRQ_LDO_LIM
, "LDO_LIM"),
172 static const struct resource da9061_thermal_resources
[] = {
173 DEFINE_RES_IRQ_NAMED(DA9061_IRQ_TEMP
, "THERMAL"),
176 static const struct resource da9061_wdt_resources
[] = {
177 DEFINE_RES_IRQ_NAMED(DA9061_IRQ_WDG_WARN
, "WD_WARN"),
180 static const struct resource da9061_onkey_resources
[] = {
181 DEFINE_RES_IRQ_NAMED(DA9061_IRQ_ONKEY
, "ONKEY"),
184 static const struct mfd_cell da9061_devs_irq
[] = {
185 MFD_CELL_OF("da9061-core", da9061_core_resources
, NULL
, 0, 0,
187 MFD_CELL_OF("da9062-regulators", da9061_regulators_resources
, NULL
, 0, 0,
189 MFD_CELL_OF("da9061-watchdog", da9061_wdt_resources
, NULL
, 0, 0,
190 "dlg,da9061-watchdog"),
191 MFD_CELL_OF("da9061-thermal", da9061_thermal_resources
, NULL
, 0, 0,
192 "dlg,da9061-thermal"),
193 MFD_CELL_OF("da9061-onkey", da9061_onkey_resources
, NULL
, 0, 0,
197 static const struct mfd_cell da9061_devs_noirq
[] = {
198 MFD_CELL_OF("da9061-core", NULL
, NULL
, 0, 0, NULL
),
199 MFD_CELL_OF("da9062-regulators", NULL
, NULL
, 0, 0, NULL
),
200 MFD_CELL_OF("da9061-watchdog", NULL
, NULL
, 0, 0, "dlg,da9061-watchdog"),
201 MFD_CELL_OF("da9061-thermal", NULL
, NULL
, 0, 0, "dlg,da9061-thermal"),
202 MFD_CELL_OF("da9061-onkey", NULL
, NULL
, 0, 0, "dlg,da9061-onkey"),
205 static const struct resource da9062_core_resources
[] = {
206 DEFINE_RES_NAMED(DA9062_IRQ_VDD_WARN
, 1, "VDD_WARN", IORESOURCE_IRQ
),
209 static const struct resource da9062_regulators_resources
[] = {
210 DEFINE_RES_NAMED(DA9062_IRQ_LDO_LIM
, 1, "LDO_LIM", IORESOURCE_IRQ
),
213 static const struct resource da9062_thermal_resources
[] = {
214 DEFINE_RES_NAMED(DA9062_IRQ_TEMP
, 1, "THERMAL", IORESOURCE_IRQ
),
217 static const struct resource da9062_wdt_resources
[] = {
218 DEFINE_RES_NAMED(DA9062_IRQ_WDG_WARN
, 1, "WD_WARN", IORESOURCE_IRQ
),
221 static const struct resource da9062_rtc_resources
[] = {
222 DEFINE_RES_NAMED(DA9062_IRQ_ALARM
, 1, "ALARM", IORESOURCE_IRQ
),
223 DEFINE_RES_NAMED(DA9062_IRQ_TICK
, 1, "TICK", IORESOURCE_IRQ
),
226 static const struct resource da9062_onkey_resources
[] = {
227 DEFINE_RES_NAMED(DA9062_IRQ_ONKEY
, 1, "ONKEY", IORESOURCE_IRQ
),
230 static const struct resource da9062_gpio_resources
[] = {
231 DEFINE_RES_NAMED(DA9062_IRQ_GPI0
, 1, "GPI0", IORESOURCE_IRQ
),
232 DEFINE_RES_NAMED(DA9062_IRQ_GPI1
, 1, "GPI1", IORESOURCE_IRQ
),
233 DEFINE_RES_NAMED(DA9062_IRQ_GPI2
, 1, "GPI2", IORESOURCE_IRQ
),
234 DEFINE_RES_NAMED(DA9062_IRQ_GPI3
, 1, "GPI3", IORESOURCE_IRQ
),
235 DEFINE_RES_NAMED(DA9062_IRQ_GPI4
, 1, "GPI4", IORESOURCE_IRQ
),
238 static const struct mfd_cell da9062_devs_irq
[] = {
239 MFD_CELL_OF("da9062-core", da9062_core_resources
, NULL
, 0, 0,
241 MFD_CELL_OF("da9062-regulators", da9062_regulators_resources
, NULL
, 0, 0,
243 MFD_CELL_OF("da9062-watchdog", da9062_wdt_resources
, NULL
, 0, 0,
244 "dlg,da9062-watchdog"),
245 MFD_CELL_OF("da9062-thermal", da9062_thermal_resources
, NULL
, 0, 0,
246 "dlg,da9062-thermal"),
247 MFD_CELL_OF("da9062-rtc", da9062_rtc_resources
, NULL
, 0, 0,
249 MFD_CELL_OF("da9062-onkey", da9062_onkey_resources
, NULL
, 0, 0,
251 MFD_CELL_OF("da9062-gpio", da9062_gpio_resources
, NULL
, 0, 0,
255 static const struct mfd_cell da9062_devs_noirq
[] = {
256 MFD_CELL_OF("da9062-core", NULL
, NULL
, 0, 0, NULL
),
257 MFD_CELL_OF("da9062-regulators", NULL
, NULL
, 0, 0, NULL
),
258 MFD_CELL_OF("da9062-watchdog", NULL
, NULL
, 0, 0, "dlg,da9062-watchdog"),
259 MFD_CELL_OF("da9062-thermal", NULL
, NULL
, 0, 0, "dlg,da9062-thermal"),
260 MFD_CELL_OF("da9062-rtc", NULL
, NULL
, 0, 0, "dlg,da9062-rtc"),
261 MFD_CELL_OF("da9062-onkey", NULL
, NULL
, 0, 0, "dlg,da9062-onkey"),
262 MFD_CELL_OF("da9062-gpio", NULL
, NULL
, 0, 0, "dlg,da9062-gpio"),
265 static int da9062_clear_fault_log(struct da9062
*chip
)
270 ret
= regmap_read(chip
->regmap
, DA9062AA_FAULT_LOG
, &fault_log
);
275 if (fault_log
& DA9062AA_TWD_ERROR_MASK
)
276 dev_dbg(chip
->dev
, "Fault log entry detected: TWD_ERROR\n");
277 if (fault_log
& DA9062AA_POR_MASK
)
278 dev_dbg(chip
->dev
, "Fault log entry detected: POR\n");
279 if (fault_log
& DA9062AA_VDD_FAULT_MASK
)
280 dev_dbg(chip
->dev
, "Fault log entry detected: VDD_FAULT\n");
281 if (fault_log
& DA9062AA_VDD_START_MASK
)
282 dev_dbg(chip
->dev
, "Fault log entry detected: VDD_START\n");
283 if (fault_log
& DA9062AA_TEMP_CRIT_MASK
)
284 dev_dbg(chip
->dev
, "Fault log entry detected: TEMP_CRIT\n");
285 if (fault_log
& DA9062AA_KEY_RESET_MASK
)
286 dev_dbg(chip
->dev
, "Fault log entry detected: KEY_RESET\n");
287 if (fault_log
& DA9062AA_NSHUTDOWN_MASK
)
288 dev_dbg(chip
->dev
, "Fault log entry detected: NSHUTDOWN\n");
289 if (fault_log
& DA9062AA_WAIT_SHUT_MASK
)
290 dev_dbg(chip
->dev
, "Fault log entry detected: WAIT_SHUT\n");
292 ret
= regmap_write(chip
->regmap
, DA9062AA_FAULT_LOG
,
299 static int da9062_get_device_type(struct da9062
*chip
)
301 int device_id
, variant_id
, variant_mrc
, variant_vrc
;
305 ret
= regmap_read(chip
->regmap
, DA9062AA_DEVICE_ID
, &device_id
);
307 dev_err(chip
->dev
, "Cannot read chip ID.\n");
310 if (device_id
!= DA9062_PMIC_DEVICE_ID
) {
311 dev_err(chip
->dev
, "Invalid device ID: 0x%02x\n", device_id
);
315 ret
= regmap_read(chip
->regmap
, DA9062AA_VARIANT_ID
, &variant_id
);
317 dev_err(chip
->dev
, "Cannot read chip variant id.\n");
321 variant_vrc
= (variant_id
& DA9062AA_VRC_MASK
) >> DA9062AA_VRC_SHIFT
;
323 switch (variant_vrc
) {
324 case DA9062_PMIC_VARIANT_VRC_DA9061
:
327 case DA9062_PMIC_VARIANT_VRC_DA9062
:
336 "Device detected (device-ID: 0x%02X, var-ID: 0x%02X, %s)\n",
337 device_id
, variant_id
, type
);
339 variant_mrc
= (variant_id
& DA9062AA_MRC_MASK
) >> DA9062AA_MRC_SHIFT
;
341 if (variant_mrc
< DA9062_PMIC_VARIANT_MRC_AA
) {
343 "Cannot support variant MRC: 0x%02X\n", variant_mrc
);
350 static u32
da9062_configure_irq_type(struct da9062
*chip
, int irq
, u32
*trigger
)
353 struct irq_data
*irq_data
= irq_get_irq_data(irq
);
356 dev_err(chip
->dev
, "Invalid IRQ: %d\n", irq
);
359 *trigger
= irqd_get_trigger_type(irq_data
);
362 case IRQ_TYPE_LEVEL_HIGH
:
363 irq_type
= DA9062_IRQ_HIGH
;
365 case IRQ_TYPE_LEVEL_LOW
:
366 irq_type
= DA9062_IRQ_LOW
;
369 dev_warn(chip
->dev
, "Unsupported IRQ type: %d\n", *trigger
);
372 return regmap_update_bits(chip
->regmap
, DA9062AA_CONFIG_A
,
373 DA9062AA_IRQ_TYPE_MASK
,
374 irq_type
<< DA9062AA_IRQ_TYPE_SHIFT
);
377 static const struct regmap_range da9061_aa_readable_ranges
[] = {
378 regmap_reg_range(DA9062AA_PAGE_CON
, DA9062AA_STATUS_B
),
379 regmap_reg_range(DA9062AA_STATUS_D
, DA9062AA_EVENT_C
),
380 regmap_reg_range(DA9062AA_IRQ_MASK_A
, DA9062AA_IRQ_MASK_C
),
381 regmap_reg_range(DA9062AA_CONTROL_A
, DA9062AA_GPIO_4
),
382 regmap_reg_range(DA9062AA_GPIO_WKUP_MODE
, DA9062AA_GPIO_OUT3_4
),
383 regmap_reg_range(DA9062AA_BUCK1_CONT
, DA9062AA_BUCK4_CONT
),
384 regmap_reg_range(DA9062AA_BUCK3_CONT
, DA9062AA_BUCK3_CONT
),
385 regmap_reg_range(DA9062AA_LDO1_CONT
, DA9062AA_LDO4_CONT
),
386 regmap_reg_range(DA9062AA_DVC_1
, DA9062AA_DVC_1
),
387 regmap_reg_range(DA9062AA_SEQ
, DA9062AA_ID_4_3
),
388 regmap_reg_range(DA9062AA_ID_12_11
, DA9062AA_ID_16_15
),
389 regmap_reg_range(DA9062AA_ID_22_21
, DA9062AA_ID_32_31
),
390 regmap_reg_range(DA9062AA_SEQ_A
, DA9062AA_WAIT
),
391 regmap_reg_range(DA9062AA_RESET
, DA9062AA_BUCK_ILIM_C
),
392 regmap_reg_range(DA9062AA_BUCK1_CFG
, DA9062AA_BUCK3_CFG
),
393 regmap_reg_range(DA9062AA_VBUCK1_A
, DA9062AA_VBUCK4_A
),
394 regmap_reg_range(DA9062AA_VBUCK3_A
, DA9062AA_VBUCK3_A
),
395 regmap_reg_range(DA9062AA_VLDO1_A
, DA9062AA_VLDO4_A
),
396 regmap_reg_range(DA9062AA_CONFIG_A
, DA9062AA_CONFIG_A
),
397 regmap_reg_range(DA9062AA_VBUCK1_B
, DA9062AA_VBUCK4_B
),
398 regmap_reg_range(DA9062AA_VBUCK3_B
, DA9062AA_VBUCK3_B
),
399 regmap_reg_range(DA9062AA_VLDO1_B
, DA9062AA_VLDO4_B
),
400 regmap_reg_range(DA9062AA_INTERFACE
, DA9062AA_CONFIG_E
),
401 regmap_reg_range(DA9062AA_CONFIG_G
, DA9062AA_CONFIG_K
),
402 regmap_reg_range(DA9062AA_CONFIG_M
, DA9062AA_CONFIG_M
),
403 regmap_reg_range(DA9062AA_GP_ID_0
, DA9062AA_GP_ID_19
),
404 regmap_reg_range(DA9062AA_DEVICE_ID
, DA9062AA_CONFIG_ID
),
407 static const struct regmap_range da9061_aa_writeable_ranges
[] = {
408 regmap_reg_range(DA9062AA_PAGE_CON
, DA9062AA_PAGE_CON
),
409 regmap_reg_range(DA9062AA_FAULT_LOG
, DA9062AA_EVENT_C
),
410 regmap_reg_range(DA9062AA_IRQ_MASK_A
, DA9062AA_IRQ_MASK_C
),
411 regmap_reg_range(DA9062AA_CONTROL_A
, DA9062AA_GPIO_4
),
412 regmap_reg_range(DA9062AA_GPIO_WKUP_MODE
, DA9062AA_GPIO_OUT3_4
),
413 regmap_reg_range(DA9062AA_BUCK1_CONT
, DA9062AA_BUCK4_CONT
),
414 regmap_reg_range(DA9062AA_BUCK3_CONT
, DA9062AA_BUCK3_CONT
),
415 regmap_reg_range(DA9062AA_LDO1_CONT
, DA9062AA_LDO4_CONT
),
416 regmap_reg_range(DA9062AA_DVC_1
, DA9062AA_DVC_1
),
417 regmap_reg_range(DA9062AA_SEQ
, DA9062AA_ID_4_3
),
418 regmap_reg_range(DA9062AA_ID_12_11
, DA9062AA_ID_16_15
),
419 regmap_reg_range(DA9062AA_ID_22_21
, DA9062AA_ID_32_31
),
420 regmap_reg_range(DA9062AA_SEQ_A
, DA9062AA_WAIT
),
421 regmap_reg_range(DA9062AA_RESET
, DA9062AA_BUCK_ILIM_C
),
422 regmap_reg_range(DA9062AA_BUCK1_CFG
, DA9062AA_BUCK3_CFG
),
423 regmap_reg_range(DA9062AA_VBUCK1_A
, DA9062AA_VBUCK4_A
),
424 regmap_reg_range(DA9062AA_VBUCK3_A
, DA9062AA_VBUCK3_A
),
425 regmap_reg_range(DA9062AA_VLDO1_A
, DA9062AA_VLDO4_A
),
426 regmap_reg_range(DA9062AA_CONFIG_A
, DA9062AA_CONFIG_A
),
427 regmap_reg_range(DA9062AA_VBUCK1_B
, DA9062AA_VBUCK4_B
),
428 regmap_reg_range(DA9062AA_VBUCK3_B
, DA9062AA_VBUCK3_B
),
429 regmap_reg_range(DA9062AA_VLDO1_B
, DA9062AA_VLDO4_B
),
430 regmap_reg_range(DA9062AA_CONFIG_J
, DA9062AA_CONFIG_J
),
431 regmap_reg_range(DA9062AA_GP_ID_0
, DA9062AA_GP_ID_19
),
434 static const struct regmap_range da9061_aa_volatile_ranges
[] = {
435 regmap_reg_range(DA9062AA_PAGE_CON
, DA9062AA_STATUS_B
),
436 regmap_reg_range(DA9062AA_STATUS_D
, DA9062AA_EVENT_C
),
437 regmap_reg_range(DA9062AA_CONTROL_A
, DA9062AA_CONTROL_B
),
438 regmap_reg_range(DA9062AA_CONTROL_E
, DA9062AA_CONTROL_F
),
439 regmap_reg_range(DA9062AA_BUCK1_CONT
, DA9062AA_BUCK4_CONT
),
440 regmap_reg_range(DA9062AA_BUCK3_CONT
, DA9062AA_BUCK3_CONT
),
441 regmap_reg_range(DA9062AA_LDO1_CONT
, DA9062AA_LDO4_CONT
),
442 regmap_reg_range(DA9062AA_DVC_1
, DA9062AA_DVC_1
),
443 regmap_reg_range(DA9062AA_SEQ
, DA9062AA_SEQ
),
446 static const struct regmap_access_table da9061_aa_readable_table
= {
447 .yes_ranges
= da9061_aa_readable_ranges
,
448 .n_yes_ranges
= ARRAY_SIZE(da9061_aa_readable_ranges
),
451 static const struct regmap_access_table da9061_aa_writeable_table
= {
452 .yes_ranges
= da9061_aa_writeable_ranges
,
453 .n_yes_ranges
= ARRAY_SIZE(da9061_aa_writeable_ranges
),
456 static const struct regmap_access_table da9061_aa_volatile_table
= {
457 .yes_ranges
= da9061_aa_volatile_ranges
,
458 .n_yes_ranges
= ARRAY_SIZE(da9061_aa_volatile_ranges
),
461 static const struct regmap_range_cfg da9061_range_cfg
[] = {
463 .range_min
= DA9062AA_PAGE_CON
,
464 .range_max
= DA9062AA_CONFIG_ID
,
465 .selector_reg
= DA9062AA_PAGE_CON
,
466 .selector_mask
= 1 << DA9062_I2C_PAGE_SEL_SHIFT
,
467 .selector_shift
= DA9062_I2C_PAGE_SEL_SHIFT
,
473 static const struct regmap_config da9061_regmap_config
= {
476 .ranges
= da9061_range_cfg
,
477 .num_ranges
= ARRAY_SIZE(da9061_range_cfg
),
478 .max_register
= DA9062AA_CONFIG_ID
,
479 .cache_type
= REGCACHE_MAPLE
,
480 .rd_table
= &da9061_aa_readable_table
,
481 .wr_table
= &da9061_aa_writeable_table
,
482 .volatile_table
= &da9061_aa_volatile_table
,
485 static const struct regmap_range da9062_aa_readable_ranges
[] = {
486 regmap_reg_range(DA9062AA_PAGE_CON
, DA9062AA_STATUS_B
),
487 regmap_reg_range(DA9062AA_STATUS_D
, DA9062AA_EVENT_C
),
488 regmap_reg_range(DA9062AA_IRQ_MASK_A
, DA9062AA_IRQ_MASK_C
),
489 regmap_reg_range(DA9062AA_CONTROL_A
, DA9062AA_GPIO_4
),
490 regmap_reg_range(DA9062AA_GPIO_WKUP_MODE
, DA9062AA_BUCK4_CONT
),
491 regmap_reg_range(DA9062AA_BUCK3_CONT
, DA9062AA_BUCK3_CONT
),
492 regmap_reg_range(DA9062AA_LDO1_CONT
, DA9062AA_LDO4_CONT
),
493 regmap_reg_range(DA9062AA_DVC_1
, DA9062AA_DVC_1
),
494 regmap_reg_range(DA9062AA_COUNT_S
, DA9062AA_SECOND_D
),
495 regmap_reg_range(DA9062AA_SEQ
, DA9062AA_ID_4_3
),
496 regmap_reg_range(DA9062AA_ID_12_11
, DA9062AA_ID_16_15
),
497 regmap_reg_range(DA9062AA_ID_22_21
, DA9062AA_ID_32_31
),
498 regmap_reg_range(DA9062AA_SEQ_A
, DA9062AA_BUCK3_CFG
),
499 regmap_reg_range(DA9062AA_VBUCK2_A
, DA9062AA_VBUCK4_A
),
500 regmap_reg_range(DA9062AA_VBUCK3_A
, DA9062AA_VBUCK3_A
),
501 regmap_reg_range(DA9062AA_VLDO1_A
, DA9062AA_VLDO4_A
),
502 regmap_reg_range(DA9062AA_VBUCK2_B
, DA9062AA_VBUCK4_B
),
503 regmap_reg_range(DA9062AA_VBUCK3_B
, DA9062AA_VBUCK3_B
),
504 regmap_reg_range(DA9062AA_VLDO1_B
, DA9062AA_VLDO4_B
),
505 regmap_reg_range(DA9062AA_BBAT_CONT
, DA9062AA_BBAT_CONT
),
506 regmap_reg_range(DA9062AA_INTERFACE
, DA9062AA_CONFIG_E
),
507 regmap_reg_range(DA9062AA_CONFIG_G
, DA9062AA_CONFIG_K
),
508 regmap_reg_range(DA9062AA_CONFIG_M
, DA9062AA_CONFIG_M
),
509 regmap_reg_range(DA9062AA_TRIM_CLDR
, DA9062AA_GP_ID_19
),
510 regmap_reg_range(DA9062AA_DEVICE_ID
, DA9062AA_CONFIG_ID
),
513 static const struct regmap_range da9062_aa_writeable_ranges
[] = {
514 regmap_reg_range(DA9062AA_PAGE_CON
, DA9062AA_PAGE_CON
),
515 regmap_reg_range(DA9062AA_FAULT_LOG
, DA9062AA_EVENT_C
),
516 regmap_reg_range(DA9062AA_IRQ_MASK_A
, DA9062AA_IRQ_MASK_C
),
517 regmap_reg_range(DA9062AA_CONTROL_A
, DA9062AA_GPIO_4
),
518 regmap_reg_range(DA9062AA_GPIO_WKUP_MODE
, DA9062AA_BUCK4_CONT
),
519 regmap_reg_range(DA9062AA_BUCK3_CONT
, DA9062AA_BUCK3_CONT
),
520 regmap_reg_range(DA9062AA_LDO1_CONT
, DA9062AA_LDO4_CONT
),
521 regmap_reg_range(DA9062AA_DVC_1
, DA9062AA_DVC_1
),
522 regmap_reg_range(DA9062AA_COUNT_S
, DA9062AA_ALARM_Y
),
523 regmap_reg_range(DA9062AA_SEQ
, DA9062AA_ID_4_3
),
524 regmap_reg_range(DA9062AA_ID_12_11
, DA9062AA_ID_16_15
),
525 regmap_reg_range(DA9062AA_ID_22_21
, DA9062AA_ID_32_31
),
526 regmap_reg_range(DA9062AA_SEQ_A
, DA9062AA_BUCK3_CFG
),
527 regmap_reg_range(DA9062AA_VBUCK2_A
, DA9062AA_VBUCK4_A
),
528 regmap_reg_range(DA9062AA_VBUCK3_A
, DA9062AA_VBUCK3_A
),
529 regmap_reg_range(DA9062AA_VLDO1_A
, DA9062AA_VLDO4_A
),
530 regmap_reg_range(DA9062AA_VBUCK2_B
, DA9062AA_VBUCK4_B
),
531 regmap_reg_range(DA9062AA_VBUCK3_B
, DA9062AA_VBUCK3_B
),
532 regmap_reg_range(DA9062AA_VLDO1_B
, DA9062AA_VLDO4_B
),
533 regmap_reg_range(DA9062AA_BBAT_CONT
, DA9062AA_BBAT_CONT
),
534 regmap_reg_range(DA9062AA_CONFIG_J
, DA9062AA_CONFIG_J
),
535 regmap_reg_range(DA9062AA_GP_ID_0
, DA9062AA_GP_ID_19
),
538 static const struct regmap_range da9062_aa_volatile_ranges
[] = {
539 regmap_reg_range(DA9062AA_PAGE_CON
, DA9062AA_STATUS_B
),
540 regmap_reg_range(DA9062AA_STATUS_D
, DA9062AA_EVENT_C
),
541 regmap_reg_range(DA9062AA_CONTROL_A
, DA9062AA_CONTROL_B
),
542 regmap_reg_range(DA9062AA_CONTROL_E
, DA9062AA_CONTROL_F
),
543 regmap_reg_range(DA9062AA_BUCK2_CONT
, DA9062AA_BUCK4_CONT
),
544 regmap_reg_range(DA9062AA_BUCK3_CONT
, DA9062AA_BUCK3_CONT
),
545 regmap_reg_range(DA9062AA_LDO1_CONT
, DA9062AA_LDO4_CONT
),
546 regmap_reg_range(DA9062AA_DVC_1
, DA9062AA_DVC_1
),
547 regmap_reg_range(DA9062AA_COUNT_S
, DA9062AA_SECOND_D
),
548 regmap_reg_range(DA9062AA_SEQ
, DA9062AA_SEQ
),
549 regmap_reg_range(DA9062AA_EN_32K
, DA9062AA_EN_32K
),
552 static const struct regmap_access_table da9062_aa_readable_table
= {
553 .yes_ranges
= da9062_aa_readable_ranges
,
554 .n_yes_ranges
= ARRAY_SIZE(da9062_aa_readable_ranges
),
557 static const struct regmap_access_table da9062_aa_writeable_table
= {
558 .yes_ranges
= da9062_aa_writeable_ranges
,
559 .n_yes_ranges
= ARRAY_SIZE(da9062_aa_writeable_ranges
),
562 static const struct regmap_access_table da9062_aa_volatile_table
= {
563 .yes_ranges
= da9062_aa_volatile_ranges
,
564 .n_yes_ranges
= ARRAY_SIZE(da9062_aa_volatile_ranges
),
567 static const struct regmap_range_cfg da9062_range_cfg
[] = {
569 .range_min
= DA9062AA_PAGE_CON
,
570 .range_max
= DA9062AA_CONFIG_ID
,
571 .selector_reg
= DA9062AA_PAGE_CON
,
572 .selector_mask
= 1 << DA9062_I2C_PAGE_SEL_SHIFT
,
573 .selector_shift
= DA9062_I2C_PAGE_SEL_SHIFT
,
579 static const struct regmap_config da9062_regmap_config
= {
582 .ranges
= da9062_range_cfg
,
583 .num_ranges
= ARRAY_SIZE(da9062_range_cfg
),
584 .max_register
= DA9062AA_CONFIG_ID
,
585 .cache_type
= REGCACHE_MAPLE
,
586 .rd_table
= &da9062_aa_readable_table
,
587 .wr_table
= &da9062_aa_writeable_table
,
588 .volatile_table
= &da9062_aa_volatile_table
,
591 static int da9062_i2c_probe(struct i2c_client
*i2c
)
594 unsigned int irq_base
= 0;
595 const struct mfd_cell
*cell
;
596 const struct regmap_irq_chip
*irq_chip
;
597 const struct regmap_config
*config
;
599 u32 trigger_type
= 0;
602 chip
= devm_kzalloc(&i2c
->dev
, sizeof(*chip
), GFP_KERNEL
);
606 chip
->chip_type
= (uintptr_t)i2c_get_match_data(i2c
);
608 i2c_set_clientdata(i2c
, chip
);
609 chip
->dev
= &i2c
->dev
;
611 /* Start with a base configuration without IRQ */
612 switch (chip
->chip_type
) {
613 case COMPAT_TYPE_DA9061
:
614 cell
= da9061_devs_noirq
;
615 cell_num
= ARRAY_SIZE(da9061_devs_noirq
);
616 config
= &da9061_regmap_config
;
618 case COMPAT_TYPE_DA9062
:
619 cell
= da9062_devs_noirq
;
620 cell_num
= ARRAY_SIZE(da9062_devs_noirq
);
621 config
= &da9062_regmap_config
;
624 dev_err(chip
->dev
, "Unrecognised chip type\n");
628 chip
->regmap
= devm_regmap_init_i2c(i2c
, config
);
629 if (IS_ERR(chip
->regmap
)) {
630 ret
= PTR_ERR(chip
->regmap
);
631 dev_err(chip
->dev
, "Failed to allocate register map: %d\n",
636 /* If SMBus is not available and only I2C is possible, enter I2C mode */
637 if (i2c_check_functionality(i2c
->adapter
, I2C_FUNC_I2C
)) {
638 dev_info(chip
->dev
, "Entering I2C mode!\n");
639 ret
= regmap_clear_bits(chip
->regmap
, DA9062AA_CONFIG_J
,
640 DA9062AA_TWOWIRE_TO_MASK
);
642 dev_err(chip
->dev
, "Failed to set Two-Wire Bus Mode.\n");
647 ret
= da9062_clear_fault_log(chip
);
649 dev_warn(chip
->dev
, "Cannot clear fault log\n");
651 ret
= da9062_get_device_type(chip
);
655 /* If IRQ is available, reconfigure it accordingly */
657 if (chip
->chip_type
== COMPAT_TYPE_DA9061
) {
658 cell
= da9061_devs_irq
;
659 cell_num
= ARRAY_SIZE(da9061_devs_irq
);
660 irq_chip
= &da9061_irq_chip
;
662 cell
= da9062_devs_irq
;
663 cell_num
= ARRAY_SIZE(da9062_devs_irq
);
664 irq_chip
= &da9062_irq_chip
;
667 ret
= da9062_configure_irq_type(chip
, i2c
->irq
, &trigger_type
);
669 dev_err(chip
->dev
, "Failed to configure IRQ type\n");
673 ret
= regmap_add_irq_chip(chip
->regmap
, i2c
->irq
,
674 trigger_type
| IRQF_SHARED
| IRQF_ONESHOT
,
675 -1, irq_chip
, &chip
->regmap_irq
);
677 dev_err(chip
->dev
, "Failed to request IRQ %d: %d\n",
682 irq_base
= regmap_irq_chip_get_base(chip
->regmap_irq
);
685 ret
= mfd_add_devices(chip
->dev
, PLATFORM_DEVID_NONE
, cell
,
686 cell_num
, NULL
, irq_base
,
689 dev_err(chip
->dev
, "Cannot register child devices\n");
691 regmap_del_irq_chip(i2c
->irq
, chip
->regmap_irq
);
698 static void da9062_i2c_remove(struct i2c_client
*i2c
)
700 struct da9062
*chip
= i2c_get_clientdata(i2c
);
702 mfd_remove_devices(chip
->dev
);
703 regmap_del_irq_chip(i2c
->irq
, chip
->regmap_irq
);
706 static const struct of_device_id da9062_dt_ids
[] = {
707 { .compatible
= "dlg,da9061", .data
= (void *)COMPAT_TYPE_DA9061
},
708 { .compatible
= "dlg,da9062", .data
= (void *)COMPAT_TYPE_DA9062
},
711 MODULE_DEVICE_TABLE(of
, da9062_dt_ids
);
713 static const struct i2c_device_id da9062_i2c_id
[] = {
714 { "da9061", COMPAT_TYPE_DA9061
},
715 { "da9062", COMPAT_TYPE_DA9062
},
718 MODULE_DEVICE_TABLE(i2c
, da9062_i2c_id
);
720 static struct i2c_driver da9062_i2c_driver
= {
723 .of_match_table
= da9062_dt_ids
,
725 .probe
= da9062_i2c_probe
,
726 .remove
= da9062_i2c_remove
,
727 .id_table
= da9062_i2c_id
,
730 module_i2c_driver(da9062_i2c_driver
);
732 MODULE_DESCRIPTION("Core device driver for Dialog DA9061 and DA9062");
733 MODULE_AUTHOR("Steve Twiss <stwiss.opensource@diasemi.com>");
734 MODULE_LICENSE("GPL");