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 #define DA9062_IRQ_LOW 0
25 #define DA9062_IRQ_HIGH 1
27 static struct regmap_irq da9061_irqs
[] = {
29 [DA9061_IRQ_ONKEY
] = {
30 .reg_offset
= DA9062_REG_EVENT_A_OFFSET
,
31 .mask
= DA9062AA_M_NONKEY_MASK
,
33 [DA9061_IRQ_WDG_WARN
] = {
34 .reg_offset
= DA9062_REG_EVENT_A_OFFSET
,
35 .mask
= DA9062AA_M_WDG_WARN_MASK
,
37 [DA9061_IRQ_SEQ_RDY
] = {
38 .reg_offset
= DA9062_REG_EVENT_A_OFFSET
,
39 .mask
= DA9062AA_M_SEQ_RDY_MASK
,
43 .reg_offset
= DA9062_REG_EVENT_B_OFFSET
,
44 .mask
= DA9062AA_M_TEMP_MASK
,
46 [DA9061_IRQ_LDO_LIM
] = {
47 .reg_offset
= DA9062_REG_EVENT_B_OFFSET
,
48 .mask
= DA9062AA_M_LDO_LIM_MASK
,
50 [DA9061_IRQ_DVC_RDY
] = {
51 .reg_offset
= DA9062_REG_EVENT_B_OFFSET
,
52 .mask
= DA9062AA_M_DVC_RDY_MASK
,
54 [DA9061_IRQ_VDD_WARN
] = {
55 .reg_offset
= DA9062_REG_EVENT_B_OFFSET
,
56 .mask
= DA9062AA_M_VDD_WARN_MASK
,
60 .reg_offset
= DA9062_REG_EVENT_C_OFFSET
,
61 .mask
= DA9062AA_M_GPI0_MASK
,
64 .reg_offset
= DA9062_REG_EVENT_C_OFFSET
,
65 .mask
= DA9062AA_M_GPI1_MASK
,
68 .reg_offset
= DA9062_REG_EVENT_C_OFFSET
,
69 .mask
= DA9062AA_M_GPI2_MASK
,
72 .reg_offset
= DA9062_REG_EVENT_C_OFFSET
,
73 .mask
= DA9062AA_M_GPI3_MASK
,
76 .reg_offset
= DA9062_REG_EVENT_C_OFFSET
,
77 .mask
= DA9062AA_M_GPI4_MASK
,
81 static struct regmap_irq_chip da9061_irq_chip
= {
84 .num_irqs
= DA9061_NUM_IRQ
,
86 .status_base
= DA9062AA_EVENT_A
,
87 .mask_base
= DA9062AA_IRQ_MASK_A
,
88 .ack_base
= DA9062AA_EVENT_A
,
91 static struct regmap_irq da9062_irqs
[] = {
93 [DA9062_IRQ_ONKEY
] = {
94 .reg_offset
= DA9062_REG_EVENT_A_OFFSET
,
95 .mask
= DA9062AA_M_NONKEY_MASK
,
97 [DA9062_IRQ_ALARM
] = {
98 .reg_offset
= DA9062_REG_EVENT_A_OFFSET
,
99 .mask
= DA9062AA_M_ALARM_MASK
,
101 [DA9062_IRQ_TICK
] = {
102 .reg_offset
= DA9062_REG_EVENT_A_OFFSET
,
103 .mask
= DA9062AA_M_TICK_MASK
,
105 [DA9062_IRQ_WDG_WARN
] = {
106 .reg_offset
= DA9062_REG_EVENT_A_OFFSET
,
107 .mask
= DA9062AA_M_WDG_WARN_MASK
,
109 [DA9062_IRQ_SEQ_RDY
] = {
110 .reg_offset
= DA9062_REG_EVENT_A_OFFSET
,
111 .mask
= DA9062AA_M_SEQ_RDY_MASK
,
114 [DA9062_IRQ_TEMP
] = {
115 .reg_offset
= DA9062_REG_EVENT_B_OFFSET
,
116 .mask
= DA9062AA_M_TEMP_MASK
,
118 [DA9062_IRQ_LDO_LIM
] = {
119 .reg_offset
= DA9062_REG_EVENT_B_OFFSET
,
120 .mask
= DA9062AA_M_LDO_LIM_MASK
,
122 [DA9062_IRQ_DVC_RDY
] = {
123 .reg_offset
= DA9062_REG_EVENT_B_OFFSET
,
124 .mask
= DA9062AA_M_DVC_RDY_MASK
,
126 [DA9062_IRQ_VDD_WARN
] = {
127 .reg_offset
= DA9062_REG_EVENT_B_OFFSET
,
128 .mask
= DA9062AA_M_VDD_WARN_MASK
,
131 [DA9062_IRQ_GPI0
] = {
132 .reg_offset
= DA9062_REG_EVENT_C_OFFSET
,
133 .mask
= DA9062AA_M_GPI0_MASK
,
135 [DA9062_IRQ_GPI1
] = {
136 .reg_offset
= DA9062_REG_EVENT_C_OFFSET
,
137 .mask
= DA9062AA_M_GPI1_MASK
,
139 [DA9062_IRQ_GPI2
] = {
140 .reg_offset
= DA9062_REG_EVENT_C_OFFSET
,
141 .mask
= DA9062AA_M_GPI2_MASK
,
143 [DA9062_IRQ_GPI3
] = {
144 .reg_offset
= DA9062_REG_EVENT_C_OFFSET
,
145 .mask
= DA9062AA_M_GPI3_MASK
,
147 [DA9062_IRQ_GPI4
] = {
148 .reg_offset
= DA9062_REG_EVENT_C_OFFSET
,
149 .mask
= DA9062AA_M_GPI4_MASK
,
153 static struct regmap_irq_chip da9062_irq_chip
= {
154 .name
= "da9062-irq",
156 .num_irqs
= DA9062_NUM_IRQ
,
158 .status_base
= DA9062AA_EVENT_A
,
159 .mask_base
= DA9062AA_IRQ_MASK_A
,
160 .ack_base
= DA9062AA_EVENT_A
,
163 static const struct resource da9061_core_resources
[] = {
164 DEFINE_RES_IRQ_NAMED(DA9061_IRQ_VDD_WARN
, "VDD_WARN"),
167 static const struct resource da9061_regulators_resources
[] = {
168 DEFINE_RES_IRQ_NAMED(DA9061_IRQ_LDO_LIM
, "LDO_LIM"),
171 static const struct resource da9061_thermal_resources
[] = {
172 DEFINE_RES_IRQ_NAMED(DA9061_IRQ_TEMP
, "THERMAL"),
175 static const struct resource da9061_wdt_resources
[] = {
176 DEFINE_RES_IRQ_NAMED(DA9061_IRQ_WDG_WARN
, "WD_WARN"),
179 static const struct resource da9061_onkey_resources
[] = {
180 DEFINE_RES_IRQ_NAMED(DA9061_IRQ_ONKEY
, "ONKEY"),
183 static const struct mfd_cell da9061_devs
[] = {
185 .name
= "da9061-core",
186 .num_resources
= ARRAY_SIZE(da9061_core_resources
),
187 .resources
= da9061_core_resources
,
190 .name
= "da9062-regulators",
191 .num_resources
= ARRAY_SIZE(da9061_regulators_resources
),
192 .resources
= da9061_regulators_resources
,
195 .name
= "da9061-watchdog",
196 .num_resources
= ARRAY_SIZE(da9061_wdt_resources
),
197 .resources
= da9061_wdt_resources
,
198 .of_compatible
= "dlg,da9061-watchdog",
201 .name
= "da9061-thermal",
202 .num_resources
= ARRAY_SIZE(da9061_thermal_resources
),
203 .resources
= da9061_thermal_resources
,
204 .of_compatible
= "dlg,da9061-thermal",
207 .name
= "da9061-onkey",
208 .num_resources
= ARRAY_SIZE(da9061_onkey_resources
),
209 .resources
= da9061_onkey_resources
,
210 .of_compatible
= "dlg,da9061-onkey",
214 static const struct resource da9062_core_resources
[] = {
215 DEFINE_RES_NAMED(DA9062_IRQ_VDD_WARN
, 1, "VDD_WARN", IORESOURCE_IRQ
),
218 static const struct resource da9062_regulators_resources
[] = {
219 DEFINE_RES_NAMED(DA9062_IRQ_LDO_LIM
, 1, "LDO_LIM", IORESOURCE_IRQ
),
222 static const struct resource da9062_thermal_resources
[] = {
223 DEFINE_RES_NAMED(DA9062_IRQ_TEMP
, 1, "THERMAL", IORESOURCE_IRQ
),
226 static const struct resource da9062_wdt_resources
[] = {
227 DEFINE_RES_NAMED(DA9062_IRQ_WDG_WARN
, 1, "WD_WARN", IORESOURCE_IRQ
),
230 static const struct resource da9062_rtc_resources
[] = {
231 DEFINE_RES_NAMED(DA9062_IRQ_ALARM
, 1, "ALARM", IORESOURCE_IRQ
),
232 DEFINE_RES_NAMED(DA9062_IRQ_TICK
, 1, "TICK", IORESOURCE_IRQ
),
235 static const struct resource da9062_onkey_resources
[] = {
236 DEFINE_RES_NAMED(DA9062_IRQ_ONKEY
, 1, "ONKEY", IORESOURCE_IRQ
),
239 static const struct resource da9062_gpio_resources
[] = {
240 DEFINE_RES_NAMED(DA9062_IRQ_GPI0
, 1, "GPI0", IORESOURCE_IRQ
),
241 DEFINE_RES_NAMED(DA9062_IRQ_GPI1
, 1, "GPI1", IORESOURCE_IRQ
),
242 DEFINE_RES_NAMED(DA9062_IRQ_GPI2
, 1, "GPI2", IORESOURCE_IRQ
),
243 DEFINE_RES_NAMED(DA9062_IRQ_GPI3
, 1, "GPI3", IORESOURCE_IRQ
),
244 DEFINE_RES_NAMED(DA9062_IRQ_GPI4
, 1, "GPI4", IORESOURCE_IRQ
),
247 static const struct mfd_cell da9062_devs
[] = {
249 .name
= "da9062-core",
250 .num_resources
= ARRAY_SIZE(da9062_core_resources
),
251 .resources
= da9062_core_resources
,
254 .name
= "da9062-regulators",
255 .num_resources
= ARRAY_SIZE(da9062_regulators_resources
),
256 .resources
= da9062_regulators_resources
,
259 .name
= "da9062-watchdog",
260 .num_resources
= ARRAY_SIZE(da9062_wdt_resources
),
261 .resources
= da9062_wdt_resources
,
262 .of_compatible
= "dlg,da9062-watchdog",
265 .name
= "da9062-thermal",
266 .num_resources
= ARRAY_SIZE(da9062_thermal_resources
),
267 .resources
= da9062_thermal_resources
,
268 .of_compatible
= "dlg,da9062-thermal",
271 .name
= "da9062-rtc",
272 .num_resources
= ARRAY_SIZE(da9062_rtc_resources
),
273 .resources
= da9062_rtc_resources
,
274 .of_compatible
= "dlg,da9062-rtc",
277 .name
= "da9062-onkey",
278 .num_resources
= ARRAY_SIZE(da9062_onkey_resources
),
279 .resources
= da9062_onkey_resources
,
280 .of_compatible
= "dlg,da9062-onkey",
283 .name
= "da9062-gpio",
284 .num_resources
= ARRAY_SIZE(da9062_gpio_resources
),
285 .resources
= da9062_gpio_resources
,
286 .of_compatible
= "dlg,da9062-gpio",
290 static int da9062_clear_fault_log(struct da9062
*chip
)
295 ret
= regmap_read(chip
->regmap
, DA9062AA_FAULT_LOG
, &fault_log
);
300 if (fault_log
& DA9062AA_TWD_ERROR_MASK
)
301 dev_dbg(chip
->dev
, "Fault log entry detected: TWD_ERROR\n");
302 if (fault_log
& DA9062AA_POR_MASK
)
303 dev_dbg(chip
->dev
, "Fault log entry detected: POR\n");
304 if (fault_log
& DA9062AA_VDD_FAULT_MASK
)
305 dev_dbg(chip
->dev
, "Fault log entry detected: VDD_FAULT\n");
306 if (fault_log
& DA9062AA_VDD_START_MASK
)
307 dev_dbg(chip
->dev
, "Fault log entry detected: VDD_START\n");
308 if (fault_log
& DA9062AA_TEMP_CRIT_MASK
)
309 dev_dbg(chip
->dev
, "Fault log entry detected: TEMP_CRIT\n");
310 if (fault_log
& DA9062AA_KEY_RESET_MASK
)
311 dev_dbg(chip
->dev
, "Fault log entry detected: KEY_RESET\n");
312 if (fault_log
& DA9062AA_NSHUTDOWN_MASK
)
313 dev_dbg(chip
->dev
, "Fault log entry detected: NSHUTDOWN\n");
314 if (fault_log
& DA9062AA_WAIT_SHUT_MASK
)
315 dev_dbg(chip
->dev
, "Fault log entry detected: WAIT_SHUT\n");
317 ret
= regmap_write(chip
->regmap
, DA9062AA_FAULT_LOG
,
324 static int da9062_get_device_type(struct da9062
*chip
)
326 int device_id
, variant_id
, variant_mrc
, variant_vrc
;
330 ret
= regmap_read(chip
->regmap
, DA9062AA_DEVICE_ID
, &device_id
);
332 dev_err(chip
->dev
, "Cannot read chip ID.\n");
335 if (device_id
!= DA9062_PMIC_DEVICE_ID
) {
336 dev_err(chip
->dev
, "Invalid device ID: 0x%02x\n", device_id
);
340 ret
= regmap_read(chip
->regmap
, DA9062AA_VARIANT_ID
, &variant_id
);
342 dev_err(chip
->dev
, "Cannot read chip variant id.\n");
346 variant_vrc
= (variant_id
& DA9062AA_VRC_MASK
) >> DA9062AA_VRC_SHIFT
;
348 switch (variant_vrc
) {
349 case DA9062_PMIC_VARIANT_VRC_DA9061
:
352 case DA9062_PMIC_VARIANT_VRC_DA9062
:
361 "Device detected (device-ID: 0x%02X, var-ID: 0x%02X, %s)\n",
362 device_id
, variant_id
, type
);
364 variant_mrc
= (variant_id
& DA9062AA_MRC_MASK
) >> DA9062AA_MRC_SHIFT
;
366 if (variant_mrc
< DA9062_PMIC_VARIANT_MRC_AA
) {
368 "Cannot support variant MRC: 0x%02X\n", variant_mrc
);
375 static u32
da9062_configure_irq_type(struct da9062
*chip
, int irq
, u32
*trigger
)
378 struct irq_data
*irq_data
= irq_get_irq_data(irq
);
381 dev_err(chip
->dev
, "Invalid IRQ: %d\n", irq
);
384 *trigger
= irqd_get_trigger_type(irq_data
);
387 case IRQ_TYPE_LEVEL_HIGH
:
388 irq_type
= DA9062_IRQ_HIGH
;
390 case IRQ_TYPE_LEVEL_LOW
:
391 irq_type
= DA9062_IRQ_LOW
;
394 dev_warn(chip
->dev
, "Unsupported IRQ type: %d\n", *trigger
);
397 return regmap_update_bits(chip
->regmap
, DA9062AA_CONFIG_A
,
398 DA9062AA_IRQ_TYPE_MASK
,
399 irq_type
<< DA9062AA_IRQ_TYPE_SHIFT
);
402 static const struct regmap_range da9061_aa_readable_ranges
[] = {
403 regmap_reg_range(DA9062AA_PAGE_CON
, DA9062AA_STATUS_B
),
404 regmap_reg_range(DA9062AA_STATUS_D
, DA9062AA_EVENT_C
),
405 regmap_reg_range(DA9062AA_IRQ_MASK_A
, DA9062AA_IRQ_MASK_C
),
406 regmap_reg_range(DA9062AA_CONTROL_A
, DA9062AA_GPIO_4
),
407 regmap_reg_range(DA9062AA_GPIO_WKUP_MODE
, DA9062AA_GPIO_OUT3_4
),
408 regmap_reg_range(DA9062AA_BUCK1_CONT
, DA9062AA_BUCK4_CONT
),
409 regmap_reg_range(DA9062AA_BUCK3_CONT
, DA9062AA_BUCK3_CONT
),
410 regmap_reg_range(DA9062AA_LDO1_CONT
, DA9062AA_LDO4_CONT
),
411 regmap_reg_range(DA9062AA_DVC_1
, DA9062AA_DVC_1
),
412 regmap_reg_range(DA9062AA_SEQ
, DA9062AA_ID_4_3
),
413 regmap_reg_range(DA9062AA_ID_12_11
, DA9062AA_ID_16_15
),
414 regmap_reg_range(DA9062AA_ID_22_21
, DA9062AA_ID_32_31
),
415 regmap_reg_range(DA9062AA_SEQ_A
, DA9062AA_WAIT
),
416 regmap_reg_range(DA9062AA_RESET
, DA9062AA_BUCK_ILIM_C
),
417 regmap_reg_range(DA9062AA_BUCK1_CFG
, DA9062AA_BUCK3_CFG
),
418 regmap_reg_range(DA9062AA_VBUCK1_A
, DA9062AA_VBUCK4_A
),
419 regmap_reg_range(DA9062AA_VBUCK3_A
, DA9062AA_VBUCK3_A
),
420 regmap_reg_range(DA9062AA_VLDO1_A
, DA9062AA_VLDO4_A
),
421 regmap_reg_range(DA9062AA_CONFIG_A
, DA9062AA_CONFIG_A
),
422 regmap_reg_range(DA9062AA_VBUCK1_B
, DA9062AA_VBUCK4_B
),
423 regmap_reg_range(DA9062AA_VBUCK3_B
, DA9062AA_VBUCK3_B
),
424 regmap_reg_range(DA9062AA_VLDO1_B
, DA9062AA_VLDO4_B
),
425 regmap_reg_range(DA9062AA_INTERFACE
, DA9062AA_CONFIG_E
),
426 regmap_reg_range(DA9062AA_CONFIG_G
, DA9062AA_CONFIG_K
),
427 regmap_reg_range(DA9062AA_CONFIG_M
, DA9062AA_CONFIG_M
),
428 regmap_reg_range(DA9062AA_GP_ID_0
, DA9062AA_GP_ID_19
),
429 regmap_reg_range(DA9062AA_DEVICE_ID
, DA9062AA_CONFIG_ID
),
432 static const struct regmap_range da9061_aa_writeable_ranges
[] = {
433 regmap_reg_range(DA9062AA_PAGE_CON
, DA9062AA_PAGE_CON
),
434 regmap_reg_range(DA9062AA_FAULT_LOG
, DA9062AA_EVENT_C
),
435 regmap_reg_range(DA9062AA_IRQ_MASK_A
, DA9062AA_IRQ_MASK_C
),
436 regmap_reg_range(DA9062AA_CONTROL_A
, DA9062AA_GPIO_4
),
437 regmap_reg_range(DA9062AA_GPIO_WKUP_MODE
, DA9062AA_GPIO_OUT3_4
),
438 regmap_reg_range(DA9062AA_BUCK1_CONT
, DA9062AA_BUCK4_CONT
),
439 regmap_reg_range(DA9062AA_BUCK3_CONT
, DA9062AA_BUCK3_CONT
),
440 regmap_reg_range(DA9062AA_LDO1_CONT
, DA9062AA_LDO4_CONT
),
441 regmap_reg_range(DA9062AA_DVC_1
, DA9062AA_DVC_1
),
442 regmap_reg_range(DA9062AA_SEQ
, DA9062AA_ID_4_3
),
443 regmap_reg_range(DA9062AA_ID_12_11
, DA9062AA_ID_16_15
),
444 regmap_reg_range(DA9062AA_ID_22_21
, DA9062AA_ID_32_31
),
445 regmap_reg_range(DA9062AA_SEQ_A
, DA9062AA_WAIT
),
446 regmap_reg_range(DA9062AA_RESET
, DA9062AA_BUCK_ILIM_C
),
447 regmap_reg_range(DA9062AA_BUCK1_CFG
, DA9062AA_BUCK3_CFG
),
448 regmap_reg_range(DA9062AA_VBUCK1_A
, DA9062AA_VBUCK4_A
),
449 regmap_reg_range(DA9062AA_VBUCK3_A
, DA9062AA_VBUCK3_A
),
450 regmap_reg_range(DA9062AA_VLDO1_A
, DA9062AA_VLDO4_A
),
451 regmap_reg_range(DA9062AA_CONFIG_A
, DA9062AA_CONFIG_A
),
452 regmap_reg_range(DA9062AA_VBUCK1_B
, DA9062AA_VBUCK4_B
),
453 regmap_reg_range(DA9062AA_VBUCK3_B
, DA9062AA_VBUCK3_B
),
454 regmap_reg_range(DA9062AA_VLDO1_B
, DA9062AA_VLDO4_B
),
455 regmap_reg_range(DA9062AA_GP_ID_0
, DA9062AA_GP_ID_19
),
458 static const struct regmap_range da9061_aa_volatile_ranges
[] = {
459 regmap_reg_range(DA9062AA_PAGE_CON
, DA9062AA_STATUS_B
),
460 regmap_reg_range(DA9062AA_STATUS_D
, DA9062AA_EVENT_C
),
461 regmap_reg_range(DA9062AA_CONTROL_A
, DA9062AA_CONTROL_B
),
462 regmap_reg_range(DA9062AA_CONTROL_E
, DA9062AA_CONTROL_F
),
463 regmap_reg_range(DA9062AA_BUCK1_CONT
, DA9062AA_BUCK4_CONT
),
464 regmap_reg_range(DA9062AA_BUCK3_CONT
, DA9062AA_BUCK3_CONT
),
465 regmap_reg_range(DA9062AA_LDO1_CONT
, DA9062AA_LDO4_CONT
),
466 regmap_reg_range(DA9062AA_DVC_1
, DA9062AA_DVC_1
),
467 regmap_reg_range(DA9062AA_SEQ
, DA9062AA_SEQ
),
470 static const struct regmap_access_table da9061_aa_readable_table
= {
471 .yes_ranges
= da9061_aa_readable_ranges
,
472 .n_yes_ranges
= ARRAY_SIZE(da9061_aa_readable_ranges
),
475 static const struct regmap_access_table da9061_aa_writeable_table
= {
476 .yes_ranges
= da9061_aa_writeable_ranges
,
477 .n_yes_ranges
= ARRAY_SIZE(da9061_aa_writeable_ranges
),
480 static const struct regmap_access_table da9061_aa_volatile_table
= {
481 .yes_ranges
= da9061_aa_volatile_ranges
,
482 .n_yes_ranges
= ARRAY_SIZE(da9061_aa_volatile_ranges
),
485 static const struct regmap_range_cfg da9061_range_cfg
[] = {
487 .range_min
= DA9062AA_PAGE_CON
,
488 .range_max
= DA9062AA_CONFIG_ID
,
489 .selector_reg
= DA9062AA_PAGE_CON
,
490 .selector_mask
= 1 << DA9062_I2C_PAGE_SEL_SHIFT
,
491 .selector_shift
= DA9062_I2C_PAGE_SEL_SHIFT
,
497 static struct regmap_config da9061_regmap_config
= {
500 .ranges
= da9061_range_cfg
,
501 .num_ranges
= ARRAY_SIZE(da9061_range_cfg
),
502 .max_register
= DA9062AA_CONFIG_ID
,
503 .cache_type
= REGCACHE_RBTREE
,
504 .rd_table
= &da9061_aa_readable_table
,
505 .wr_table
= &da9061_aa_writeable_table
,
506 .volatile_table
= &da9061_aa_volatile_table
,
509 static const struct regmap_range da9062_aa_readable_ranges
[] = {
510 regmap_reg_range(DA9062AA_PAGE_CON
, DA9062AA_STATUS_B
),
511 regmap_reg_range(DA9062AA_STATUS_D
, DA9062AA_EVENT_C
),
512 regmap_reg_range(DA9062AA_IRQ_MASK_A
, DA9062AA_IRQ_MASK_C
),
513 regmap_reg_range(DA9062AA_CONTROL_A
, DA9062AA_GPIO_4
),
514 regmap_reg_range(DA9062AA_GPIO_WKUP_MODE
, DA9062AA_BUCK4_CONT
),
515 regmap_reg_range(DA9062AA_BUCK3_CONT
, DA9062AA_BUCK3_CONT
),
516 regmap_reg_range(DA9062AA_LDO1_CONT
, DA9062AA_LDO4_CONT
),
517 regmap_reg_range(DA9062AA_DVC_1
, DA9062AA_DVC_1
),
518 regmap_reg_range(DA9062AA_COUNT_S
, DA9062AA_SECOND_D
),
519 regmap_reg_range(DA9062AA_SEQ
, DA9062AA_ID_4_3
),
520 regmap_reg_range(DA9062AA_ID_12_11
, DA9062AA_ID_16_15
),
521 regmap_reg_range(DA9062AA_ID_22_21
, DA9062AA_ID_32_31
),
522 regmap_reg_range(DA9062AA_SEQ_A
, DA9062AA_BUCK3_CFG
),
523 regmap_reg_range(DA9062AA_VBUCK2_A
, DA9062AA_VBUCK4_A
),
524 regmap_reg_range(DA9062AA_VBUCK3_A
, DA9062AA_VBUCK3_A
),
525 regmap_reg_range(DA9062AA_VLDO1_A
, DA9062AA_VLDO4_A
),
526 regmap_reg_range(DA9062AA_VBUCK2_B
, DA9062AA_VBUCK4_B
),
527 regmap_reg_range(DA9062AA_VBUCK3_B
, DA9062AA_VBUCK3_B
),
528 regmap_reg_range(DA9062AA_VLDO1_B
, DA9062AA_VLDO4_B
),
529 regmap_reg_range(DA9062AA_BBAT_CONT
, DA9062AA_BBAT_CONT
),
530 regmap_reg_range(DA9062AA_INTERFACE
, DA9062AA_CONFIG_E
),
531 regmap_reg_range(DA9062AA_CONFIG_G
, DA9062AA_CONFIG_K
),
532 regmap_reg_range(DA9062AA_CONFIG_M
, DA9062AA_CONFIG_M
),
533 regmap_reg_range(DA9062AA_TRIM_CLDR
, DA9062AA_GP_ID_19
),
534 regmap_reg_range(DA9062AA_DEVICE_ID
, DA9062AA_CONFIG_ID
),
537 static const struct regmap_range da9062_aa_writeable_ranges
[] = {
538 regmap_reg_range(DA9062AA_PAGE_CON
, DA9062AA_PAGE_CON
),
539 regmap_reg_range(DA9062AA_FAULT_LOG
, DA9062AA_EVENT_C
),
540 regmap_reg_range(DA9062AA_IRQ_MASK_A
, DA9062AA_IRQ_MASK_C
),
541 regmap_reg_range(DA9062AA_CONTROL_A
, DA9062AA_GPIO_4
),
542 regmap_reg_range(DA9062AA_GPIO_WKUP_MODE
, DA9062AA_BUCK4_CONT
),
543 regmap_reg_range(DA9062AA_BUCK3_CONT
, DA9062AA_BUCK3_CONT
),
544 regmap_reg_range(DA9062AA_LDO1_CONT
, DA9062AA_LDO4_CONT
),
545 regmap_reg_range(DA9062AA_DVC_1
, DA9062AA_DVC_1
),
546 regmap_reg_range(DA9062AA_COUNT_S
, DA9062AA_ALARM_Y
),
547 regmap_reg_range(DA9062AA_SEQ
, DA9062AA_ID_4_3
),
548 regmap_reg_range(DA9062AA_ID_12_11
, DA9062AA_ID_16_15
),
549 regmap_reg_range(DA9062AA_ID_22_21
, DA9062AA_ID_32_31
),
550 regmap_reg_range(DA9062AA_SEQ_A
, DA9062AA_BUCK3_CFG
),
551 regmap_reg_range(DA9062AA_VBUCK2_A
, DA9062AA_VBUCK4_A
),
552 regmap_reg_range(DA9062AA_VBUCK3_A
, DA9062AA_VBUCK3_A
),
553 regmap_reg_range(DA9062AA_VLDO1_A
, DA9062AA_VLDO4_A
),
554 regmap_reg_range(DA9062AA_VBUCK2_B
, DA9062AA_VBUCK4_B
),
555 regmap_reg_range(DA9062AA_VBUCK3_B
, DA9062AA_VBUCK3_B
),
556 regmap_reg_range(DA9062AA_VLDO1_B
, DA9062AA_VLDO4_B
),
557 regmap_reg_range(DA9062AA_BBAT_CONT
, DA9062AA_BBAT_CONT
),
558 regmap_reg_range(DA9062AA_GP_ID_0
, DA9062AA_GP_ID_19
),
561 static const struct regmap_range da9062_aa_volatile_ranges
[] = {
562 regmap_reg_range(DA9062AA_PAGE_CON
, DA9062AA_STATUS_B
),
563 regmap_reg_range(DA9062AA_STATUS_D
, DA9062AA_EVENT_C
),
564 regmap_reg_range(DA9062AA_CONTROL_A
, DA9062AA_CONTROL_B
),
565 regmap_reg_range(DA9062AA_CONTROL_E
, DA9062AA_CONTROL_F
),
566 regmap_reg_range(DA9062AA_BUCK2_CONT
, DA9062AA_BUCK4_CONT
),
567 regmap_reg_range(DA9062AA_BUCK3_CONT
, DA9062AA_BUCK3_CONT
),
568 regmap_reg_range(DA9062AA_LDO1_CONT
, DA9062AA_LDO4_CONT
),
569 regmap_reg_range(DA9062AA_DVC_1
, DA9062AA_DVC_1
),
570 regmap_reg_range(DA9062AA_COUNT_S
, DA9062AA_SECOND_D
),
571 regmap_reg_range(DA9062AA_SEQ
, DA9062AA_SEQ
),
572 regmap_reg_range(DA9062AA_EN_32K
, DA9062AA_EN_32K
),
575 static const struct regmap_access_table da9062_aa_readable_table
= {
576 .yes_ranges
= da9062_aa_readable_ranges
,
577 .n_yes_ranges
= ARRAY_SIZE(da9062_aa_readable_ranges
),
580 static const struct regmap_access_table da9062_aa_writeable_table
= {
581 .yes_ranges
= da9062_aa_writeable_ranges
,
582 .n_yes_ranges
= ARRAY_SIZE(da9062_aa_writeable_ranges
),
585 static const struct regmap_access_table da9062_aa_volatile_table
= {
586 .yes_ranges
= da9062_aa_volatile_ranges
,
587 .n_yes_ranges
= ARRAY_SIZE(da9062_aa_volatile_ranges
),
590 static const struct regmap_range_cfg da9062_range_cfg
[] = {
592 .range_min
= DA9062AA_PAGE_CON
,
593 .range_max
= DA9062AA_CONFIG_ID
,
594 .selector_reg
= DA9062AA_PAGE_CON
,
595 .selector_mask
= 1 << DA9062_I2C_PAGE_SEL_SHIFT
,
596 .selector_shift
= DA9062_I2C_PAGE_SEL_SHIFT
,
602 static struct regmap_config da9062_regmap_config
= {
605 .ranges
= da9062_range_cfg
,
606 .num_ranges
= ARRAY_SIZE(da9062_range_cfg
),
607 .max_register
= DA9062AA_CONFIG_ID
,
608 .cache_type
= REGCACHE_RBTREE
,
609 .rd_table
= &da9062_aa_readable_table
,
610 .wr_table
= &da9062_aa_writeable_table
,
611 .volatile_table
= &da9062_aa_volatile_table
,
614 static const struct of_device_id da9062_dt_ids
[] = {
615 { .compatible
= "dlg,da9061", .data
= (void *)COMPAT_TYPE_DA9061
, },
616 { .compatible
= "dlg,da9062", .data
= (void *)COMPAT_TYPE_DA9062
, },
619 MODULE_DEVICE_TABLE(of
, da9062_dt_ids
);
621 static int da9062_i2c_probe(struct i2c_client
*i2c
,
622 const struct i2c_device_id
*id
)
625 const struct of_device_id
*match
;
626 unsigned int irq_base
;
627 const struct mfd_cell
*cell
;
628 const struct regmap_irq_chip
*irq_chip
;
629 const struct regmap_config
*config
;
631 u32 trigger_type
= 0;
634 chip
= devm_kzalloc(&i2c
->dev
, sizeof(*chip
), GFP_KERNEL
);
638 if (i2c
->dev
.of_node
) {
639 match
= of_match_node(da9062_dt_ids
, i2c
->dev
.of_node
);
643 chip
->chip_type
= (uintptr_t)match
->data
;
645 chip
->chip_type
= id
->driver_data
;
648 i2c_set_clientdata(i2c
, chip
);
649 chip
->dev
= &i2c
->dev
;
652 dev_err(chip
->dev
, "No IRQ configured\n");
656 switch (chip
->chip_type
) {
657 case COMPAT_TYPE_DA9061
:
659 cell_num
= ARRAY_SIZE(da9061_devs
);
660 irq_chip
= &da9061_irq_chip
;
661 config
= &da9061_regmap_config
;
663 case COMPAT_TYPE_DA9062
:
665 cell_num
= ARRAY_SIZE(da9062_devs
);
666 irq_chip
= &da9062_irq_chip
;
667 config
= &da9062_regmap_config
;
670 dev_err(chip
->dev
, "Unrecognised chip type\n");
674 chip
->regmap
= devm_regmap_init_i2c(i2c
, config
);
675 if (IS_ERR(chip
->regmap
)) {
676 ret
= PTR_ERR(chip
->regmap
);
677 dev_err(chip
->dev
, "Failed to allocate register map: %d\n",
682 ret
= da9062_clear_fault_log(chip
);
684 dev_warn(chip
->dev
, "Cannot clear fault log\n");
686 ret
= da9062_get_device_type(chip
);
690 ret
= da9062_configure_irq_type(chip
, i2c
->irq
, &trigger_type
);
692 dev_err(chip
->dev
, "Failed to configure IRQ type\n");
696 ret
= regmap_add_irq_chip(chip
->regmap
, i2c
->irq
,
697 trigger_type
| IRQF_SHARED
| IRQF_ONESHOT
,
698 -1, irq_chip
, &chip
->regmap_irq
);
700 dev_err(chip
->dev
, "Failed to request IRQ %d: %d\n",
705 irq_base
= regmap_irq_chip_get_base(chip
->regmap_irq
);
707 ret
= mfd_add_devices(chip
->dev
, PLATFORM_DEVID_NONE
, cell
,
708 cell_num
, NULL
, irq_base
,
711 dev_err(chip
->dev
, "Cannot register child devices\n");
712 regmap_del_irq_chip(i2c
->irq
, chip
->regmap_irq
);
719 static int da9062_i2c_remove(struct i2c_client
*i2c
)
721 struct da9062
*chip
= i2c_get_clientdata(i2c
);
723 mfd_remove_devices(chip
->dev
);
724 regmap_del_irq_chip(i2c
->irq
, chip
->regmap_irq
);
729 static const struct i2c_device_id da9062_i2c_id
[] = {
730 { "da9061", COMPAT_TYPE_DA9061
},
731 { "da9062", COMPAT_TYPE_DA9062
},
734 MODULE_DEVICE_TABLE(i2c
, da9062_i2c_id
);
736 static struct i2c_driver da9062_i2c_driver
= {
739 .of_match_table
= da9062_dt_ids
,
741 .probe
= da9062_i2c_probe
,
742 .remove
= da9062_i2c_remove
,
743 .id_table
= da9062_i2c_id
,
746 module_i2c_driver(da9062_i2c_driver
);
748 MODULE_DESCRIPTION("Core device driver for Dialog DA9061 and DA9062");
749 MODULE_AUTHOR("Steve Twiss <stwiss.opensource@diasemi.com>");
750 MODULE_LICENSE("GPL");