2 * Core, IRQ and I2C device driver for DA9061 and DA9062 PMICs
3 * Copyright (C) 2015-2017 Dialog Semiconductor
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
16 #include <linux/kernel.h>
17 #include <linux/module.h>
18 #include <linux/init.h>
19 #include <linux/device.h>
20 #include <linux/interrupt.h>
21 #include <linux/regmap.h>
22 #include <linux/irq.h>
23 #include <linux/mfd/core.h>
24 #include <linux/i2c.h>
25 #include <linux/mfd/da9062/core.h>
26 #include <linux/mfd/da9062/registers.h>
27 #include <linux/regulator/of_regulator.h>
29 #define DA9062_REG_EVENT_A_OFFSET 0
30 #define DA9062_REG_EVENT_B_OFFSET 1
31 #define DA9062_REG_EVENT_C_OFFSET 2
33 static struct regmap_irq da9061_irqs
[] = {
35 [DA9061_IRQ_ONKEY
] = {
36 .reg_offset
= DA9062_REG_EVENT_A_OFFSET
,
37 .mask
= DA9062AA_M_NONKEY_MASK
,
39 [DA9061_IRQ_WDG_WARN
] = {
40 .reg_offset
= DA9062_REG_EVENT_A_OFFSET
,
41 .mask
= DA9062AA_M_WDG_WARN_MASK
,
43 [DA9061_IRQ_SEQ_RDY
] = {
44 .reg_offset
= DA9062_REG_EVENT_A_OFFSET
,
45 .mask
= DA9062AA_M_SEQ_RDY_MASK
,
49 .reg_offset
= DA9062_REG_EVENT_B_OFFSET
,
50 .mask
= DA9062AA_M_TEMP_MASK
,
52 [DA9061_IRQ_LDO_LIM
] = {
53 .reg_offset
= DA9062_REG_EVENT_B_OFFSET
,
54 .mask
= DA9062AA_M_LDO_LIM_MASK
,
56 [DA9061_IRQ_DVC_RDY
] = {
57 .reg_offset
= DA9062_REG_EVENT_B_OFFSET
,
58 .mask
= DA9062AA_M_DVC_RDY_MASK
,
60 [DA9061_IRQ_VDD_WARN
] = {
61 .reg_offset
= DA9062_REG_EVENT_B_OFFSET
,
62 .mask
= DA9062AA_M_VDD_WARN_MASK
,
66 .reg_offset
= DA9062_REG_EVENT_C_OFFSET
,
67 .mask
= DA9062AA_M_GPI0_MASK
,
70 .reg_offset
= DA9062_REG_EVENT_C_OFFSET
,
71 .mask
= DA9062AA_M_GPI1_MASK
,
74 .reg_offset
= DA9062_REG_EVENT_C_OFFSET
,
75 .mask
= DA9062AA_M_GPI2_MASK
,
78 .reg_offset
= DA9062_REG_EVENT_C_OFFSET
,
79 .mask
= DA9062AA_M_GPI3_MASK
,
82 .reg_offset
= DA9062_REG_EVENT_C_OFFSET
,
83 .mask
= DA9062AA_M_GPI4_MASK
,
87 static struct regmap_irq_chip da9061_irq_chip
= {
90 .num_irqs
= DA9061_NUM_IRQ
,
92 .status_base
= DA9062AA_EVENT_A
,
93 .mask_base
= DA9062AA_IRQ_MASK_A
,
94 .ack_base
= DA9062AA_EVENT_A
,
97 static struct regmap_irq da9062_irqs
[] = {
99 [DA9062_IRQ_ONKEY
] = {
100 .reg_offset
= DA9062_REG_EVENT_A_OFFSET
,
101 .mask
= DA9062AA_M_NONKEY_MASK
,
103 [DA9062_IRQ_ALARM
] = {
104 .reg_offset
= DA9062_REG_EVENT_A_OFFSET
,
105 .mask
= DA9062AA_M_ALARM_MASK
,
107 [DA9062_IRQ_TICK
] = {
108 .reg_offset
= DA9062_REG_EVENT_A_OFFSET
,
109 .mask
= DA9062AA_M_TICK_MASK
,
111 [DA9062_IRQ_WDG_WARN
] = {
112 .reg_offset
= DA9062_REG_EVENT_A_OFFSET
,
113 .mask
= DA9062AA_M_WDG_WARN_MASK
,
115 [DA9062_IRQ_SEQ_RDY
] = {
116 .reg_offset
= DA9062_REG_EVENT_A_OFFSET
,
117 .mask
= DA9062AA_M_SEQ_RDY_MASK
,
120 [DA9062_IRQ_TEMP
] = {
121 .reg_offset
= DA9062_REG_EVENT_B_OFFSET
,
122 .mask
= DA9062AA_M_TEMP_MASK
,
124 [DA9062_IRQ_LDO_LIM
] = {
125 .reg_offset
= DA9062_REG_EVENT_B_OFFSET
,
126 .mask
= DA9062AA_M_LDO_LIM_MASK
,
128 [DA9062_IRQ_DVC_RDY
] = {
129 .reg_offset
= DA9062_REG_EVENT_B_OFFSET
,
130 .mask
= DA9062AA_M_DVC_RDY_MASK
,
132 [DA9062_IRQ_VDD_WARN
] = {
133 .reg_offset
= DA9062_REG_EVENT_B_OFFSET
,
134 .mask
= DA9062AA_M_VDD_WARN_MASK
,
137 [DA9062_IRQ_GPI0
] = {
138 .reg_offset
= DA9062_REG_EVENT_C_OFFSET
,
139 .mask
= DA9062AA_M_GPI0_MASK
,
141 [DA9062_IRQ_GPI1
] = {
142 .reg_offset
= DA9062_REG_EVENT_C_OFFSET
,
143 .mask
= DA9062AA_M_GPI1_MASK
,
145 [DA9062_IRQ_GPI2
] = {
146 .reg_offset
= DA9062_REG_EVENT_C_OFFSET
,
147 .mask
= DA9062AA_M_GPI2_MASK
,
149 [DA9062_IRQ_GPI3
] = {
150 .reg_offset
= DA9062_REG_EVENT_C_OFFSET
,
151 .mask
= DA9062AA_M_GPI3_MASK
,
153 [DA9062_IRQ_GPI4
] = {
154 .reg_offset
= DA9062_REG_EVENT_C_OFFSET
,
155 .mask
= DA9062AA_M_GPI4_MASK
,
159 static struct regmap_irq_chip da9062_irq_chip
= {
160 .name
= "da9062-irq",
162 .num_irqs
= DA9062_NUM_IRQ
,
164 .status_base
= DA9062AA_EVENT_A
,
165 .mask_base
= DA9062AA_IRQ_MASK_A
,
166 .ack_base
= DA9062AA_EVENT_A
,
169 static struct resource da9061_core_resources
[] = {
170 DEFINE_RES_IRQ_NAMED(DA9061_IRQ_VDD_WARN
, "VDD_WARN"),
173 static struct resource da9061_regulators_resources
[] = {
174 DEFINE_RES_IRQ_NAMED(DA9061_IRQ_LDO_LIM
, "LDO_LIM"),
177 static struct resource da9061_thermal_resources
[] = {
178 DEFINE_RES_IRQ_NAMED(DA9061_IRQ_TEMP
, "THERMAL"),
181 static struct resource da9061_wdt_resources
[] = {
182 DEFINE_RES_IRQ_NAMED(DA9061_IRQ_WDG_WARN
, "WD_WARN"),
185 static struct resource da9061_onkey_resources
[] = {
186 DEFINE_RES_IRQ_NAMED(DA9061_IRQ_ONKEY
, "ONKEY"),
189 static const struct mfd_cell da9061_devs
[] = {
191 .name
= "da9061-core",
192 .num_resources
= ARRAY_SIZE(da9061_core_resources
),
193 .resources
= da9061_core_resources
,
196 .name
= "da9062-regulators",
197 .num_resources
= ARRAY_SIZE(da9061_regulators_resources
),
198 .resources
= da9061_regulators_resources
,
201 .name
= "da9061-watchdog",
202 .num_resources
= ARRAY_SIZE(da9061_wdt_resources
),
203 .resources
= da9061_wdt_resources
,
204 .of_compatible
= "dlg,da9061-watchdog",
207 .name
= "da9061-thermal",
208 .num_resources
= ARRAY_SIZE(da9061_thermal_resources
),
209 .resources
= da9061_thermal_resources
,
210 .of_compatible
= "dlg,da9061-thermal",
213 .name
= "da9061-onkey",
214 .num_resources
= ARRAY_SIZE(da9061_onkey_resources
),
215 .resources
= da9061_onkey_resources
,
216 .of_compatible
= "dlg,da9061-onkey",
220 static struct resource da9062_core_resources
[] = {
221 DEFINE_RES_NAMED(DA9062_IRQ_VDD_WARN
, 1, "VDD_WARN", IORESOURCE_IRQ
),
224 static struct resource da9062_regulators_resources
[] = {
225 DEFINE_RES_NAMED(DA9062_IRQ_LDO_LIM
, 1, "LDO_LIM", IORESOURCE_IRQ
),
228 static struct resource da9062_thermal_resources
[] = {
229 DEFINE_RES_NAMED(DA9062_IRQ_TEMP
, 1, "THERMAL", IORESOURCE_IRQ
),
232 static struct resource da9062_wdt_resources
[] = {
233 DEFINE_RES_NAMED(DA9062_IRQ_WDG_WARN
, 1, "WD_WARN", IORESOURCE_IRQ
),
236 static struct resource da9062_rtc_resources
[] = {
237 DEFINE_RES_NAMED(DA9062_IRQ_ALARM
, 1, "ALARM", IORESOURCE_IRQ
),
238 DEFINE_RES_NAMED(DA9062_IRQ_TICK
, 1, "TICK", IORESOURCE_IRQ
),
241 static struct resource da9062_onkey_resources
[] = {
242 DEFINE_RES_NAMED(DA9062_IRQ_ONKEY
, 1, "ONKEY", IORESOURCE_IRQ
),
245 static const struct mfd_cell da9062_devs
[] = {
247 .name
= "da9062-core",
248 .num_resources
= ARRAY_SIZE(da9062_core_resources
),
249 .resources
= da9062_core_resources
,
252 .name
= "da9062-regulators",
253 .num_resources
= ARRAY_SIZE(da9062_regulators_resources
),
254 .resources
= da9062_regulators_resources
,
257 .name
= "da9062-watchdog",
258 .num_resources
= ARRAY_SIZE(da9062_wdt_resources
),
259 .resources
= da9062_wdt_resources
,
260 .of_compatible
= "dlg,da9062-wdt",
263 .name
= "da9062-thermal",
264 .num_resources
= ARRAY_SIZE(da9062_thermal_resources
),
265 .resources
= da9062_thermal_resources
,
266 .of_compatible
= "dlg,da9062-thermal",
269 .name
= "da9062-rtc",
270 .num_resources
= ARRAY_SIZE(da9062_rtc_resources
),
271 .resources
= da9062_rtc_resources
,
272 .of_compatible
= "dlg,da9062-rtc",
275 .name
= "da9062-onkey",
276 .num_resources
= ARRAY_SIZE(da9062_onkey_resources
),
277 .resources
= da9062_onkey_resources
,
278 .of_compatible
= "dlg,da9062-onkey",
282 static int da9062_clear_fault_log(struct da9062
*chip
)
287 ret
= regmap_read(chip
->regmap
, DA9062AA_FAULT_LOG
, &fault_log
);
292 if (fault_log
& DA9062AA_TWD_ERROR_MASK
)
293 dev_dbg(chip
->dev
, "Fault log entry detected: TWD_ERROR\n");
294 if (fault_log
& DA9062AA_POR_MASK
)
295 dev_dbg(chip
->dev
, "Fault log entry detected: POR\n");
296 if (fault_log
& DA9062AA_VDD_FAULT_MASK
)
297 dev_dbg(chip
->dev
, "Fault log entry detected: VDD_FAULT\n");
298 if (fault_log
& DA9062AA_VDD_START_MASK
)
299 dev_dbg(chip
->dev
, "Fault log entry detected: VDD_START\n");
300 if (fault_log
& DA9062AA_TEMP_CRIT_MASK
)
301 dev_dbg(chip
->dev
, "Fault log entry detected: TEMP_CRIT\n");
302 if (fault_log
& DA9062AA_KEY_RESET_MASK
)
303 dev_dbg(chip
->dev
, "Fault log entry detected: KEY_RESET\n");
304 if (fault_log
& DA9062AA_NSHUTDOWN_MASK
)
305 dev_dbg(chip
->dev
, "Fault log entry detected: NSHUTDOWN\n");
306 if (fault_log
& DA9062AA_WAIT_SHUT_MASK
)
307 dev_dbg(chip
->dev
, "Fault log entry detected: WAIT_SHUT\n");
309 ret
= regmap_write(chip
->regmap
, DA9062AA_FAULT_LOG
,
316 static int da9062_get_device_type(struct da9062
*chip
)
318 int device_id
, variant_id
, variant_mrc
, variant_vrc
;
322 ret
= regmap_read(chip
->regmap
, DA9062AA_DEVICE_ID
, &device_id
);
324 dev_err(chip
->dev
, "Cannot read chip ID.\n");
327 if (device_id
!= DA9062_PMIC_DEVICE_ID
) {
328 dev_err(chip
->dev
, "Invalid device ID: 0x%02x\n", device_id
);
332 ret
= regmap_read(chip
->regmap
, DA9062AA_VARIANT_ID
, &variant_id
);
334 dev_err(chip
->dev
, "Cannot read chip variant id.\n");
338 variant_vrc
= (variant_id
& DA9062AA_VRC_MASK
) >> DA9062AA_VRC_SHIFT
;
340 switch (variant_vrc
) {
341 case DA9062_PMIC_VARIANT_VRC_DA9061
:
344 case DA9062_PMIC_VARIANT_VRC_DA9062
:
353 "Device detected (device-ID: 0x%02X, var-ID: 0x%02X, %s)\n",
354 device_id
, variant_id
, type
);
356 variant_mrc
= (variant_id
& DA9062AA_MRC_MASK
) >> DA9062AA_MRC_SHIFT
;
358 if (variant_mrc
< DA9062_PMIC_VARIANT_MRC_AA
) {
360 "Cannot support variant MRC: 0x%02X\n", variant_mrc
);
367 static const struct regmap_range da9061_aa_readable_ranges
[] = {
369 .range_min
= DA9062AA_PAGE_CON
,
370 .range_max
= DA9062AA_STATUS_B
,
372 .range_min
= DA9062AA_STATUS_D
,
373 .range_max
= DA9062AA_EVENT_C
,
375 .range_min
= DA9062AA_IRQ_MASK_A
,
376 .range_max
= DA9062AA_IRQ_MASK_C
,
378 .range_min
= DA9062AA_CONTROL_A
,
379 .range_max
= DA9062AA_GPIO_4
,
381 .range_min
= DA9062AA_GPIO_WKUP_MODE
,
382 .range_max
= DA9062AA_GPIO_OUT3_4
,
384 .range_min
= DA9062AA_BUCK1_CONT
,
385 .range_max
= DA9062AA_BUCK4_CONT
,
387 .range_min
= DA9062AA_BUCK3_CONT
,
388 .range_max
= DA9062AA_BUCK3_CONT
,
390 .range_min
= DA9062AA_LDO1_CONT
,
391 .range_max
= DA9062AA_LDO4_CONT
,
393 .range_min
= DA9062AA_DVC_1
,
394 .range_max
= DA9062AA_DVC_1
,
396 .range_min
= DA9062AA_SEQ
,
397 .range_max
= DA9062AA_ID_4_3
,
399 .range_min
= DA9062AA_ID_12_11
,
400 .range_max
= DA9062AA_ID_16_15
,
402 .range_min
= DA9062AA_ID_22_21
,
403 .range_max
= DA9062AA_ID_32_31
,
405 .range_min
= DA9062AA_SEQ_A
,
406 .range_max
= DA9062AA_WAIT
,
408 .range_min
= DA9062AA_RESET
,
409 .range_max
= DA9062AA_BUCK_ILIM_C
,
411 .range_min
= DA9062AA_BUCK1_CFG
,
412 .range_max
= DA9062AA_BUCK3_CFG
,
414 .range_min
= DA9062AA_VBUCK1_A
,
415 .range_max
= DA9062AA_VBUCK4_A
,
417 .range_min
= DA9062AA_VBUCK3_A
,
418 .range_max
= DA9062AA_VBUCK3_A
,
420 .range_min
= DA9062AA_VLDO1_A
,
421 .range_max
= DA9062AA_VLDO4_A
,
423 .range_min
= DA9062AA_VBUCK1_B
,
424 .range_max
= DA9062AA_VBUCK4_B
,
426 .range_min
= DA9062AA_VBUCK3_B
,
427 .range_max
= DA9062AA_VBUCK3_B
,
429 .range_min
= DA9062AA_VLDO1_B
,
430 .range_max
= DA9062AA_VLDO4_B
,
432 .range_min
= DA9062AA_INTERFACE
,
433 .range_max
= DA9062AA_CONFIG_E
,
435 .range_min
= DA9062AA_CONFIG_G
,
436 .range_max
= DA9062AA_CONFIG_K
,
438 .range_min
= DA9062AA_CONFIG_M
,
439 .range_max
= DA9062AA_CONFIG_M
,
441 .range_min
= DA9062AA_GP_ID_0
,
442 .range_max
= DA9062AA_GP_ID_19
,
444 .range_min
= DA9062AA_DEVICE_ID
,
445 .range_max
= DA9062AA_CONFIG_ID
,
449 static const struct regmap_range da9061_aa_writeable_ranges
[] = {
451 .range_min
= DA9062AA_PAGE_CON
,
452 .range_max
= DA9062AA_PAGE_CON
,
454 .range_min
= DA9062AA_FAULT_LOG
,
455 .range_max
= DA9062AA_EVENT_C
,
457 .range_min
= DA9062AA_IRQ_MASK_A
,
458 .range_max
= DA9062AA_IRQ_MASK_C
,
460 .range_min
= DA9062AA_CONTROL_A
,
461 .range_max
= DA9062AA_GPIO_4
,
463 .range_min
= DA9062AA_GPIO_WKUP_MODE
,
464 .range_max
= DA9062AA_GPIO_OUT3_4
,
466 .range_min
= DA9062AA_BUCK1_CONT
,
467 .range_max
= DA9062AA_BUCK4_CONT
,
469 .range_min
= DA9062AA_BUCK3_CONT
,
470 .range_max
= DA9062AA_BUCK3_CONT
,
472 .range_min
= DA9062AA_LDO1_CONT
,
473 .range_max
= DA9062AA_LDO4_CONT
,
475 .range_min
= DA9062AA_DVC_1
,
476 .range_max
= DA9062AA_DVC_1
,
478 .range_min
= DA9062AA_SEQ
,
479 .range_max
= DA9062AA_ID_4_3
,
481 .range_min
= DA9062AA_ID_12_11
,
482 .range_max
= DA9062AA_ID_16_15
,
484 .range_min
= DA9062AA_ID_22_21
,
485 .range_max
= DA9062AA_ID_32_31
,
487 .range_min
= DA9062AA_SEQ_A
,
488 .range_max
= DA9062AA_WAIT
,
490 .range_min
= DA9062AA_RESET
,
491 .range_max
= DA9062AA_BUCK_ILIM_C
,
493 .range_min
= DA9062AA_BUCK1_CFG
,
494 .range_max
= DA9062AA_BUCK3_CFG
,
496 .range_min
= DA9062AA_VBUCK1_A
,
497 .range_max
= DA9062AA_VBUCK4_A
,
499 .range_min
= DA9062AA_VBUCK3_A
,
500 .range_max
= DA9062AA_VBUCK3_A
,
502 .range_min
= DA9062AA_VLDO1_A
,
503 .range_max
= DA9062AA_VLDO4_A
,
505 .range_min
= DA9062AA_VBUCK1_B
,
506 .range_max
= DA9062AA_VBUCK4_B
,
508 .range_min
= DA9062AA_VBUCK3_B
,
509 .range_max
= DA9062AA_VBUCK3_B
,
511 .range_min
= DA9062AA_VLDO1_B
,
512 .range_max
= DA9062AA_VLDO4_B
,
514 .range_min
= DA9062AA_GP_ID_0
,
515 .range_max
= DA9062AA_GP_ID_19
,
519 static const struct regmap_range da9061_aa_volatile_ranges
[] = {
521 .range_min
= DA9062AA_PAGE_CON
,
522 .range_max
= DA9062AA_STATUS_B
,
524 .range_min
= DA9062AA_STATUS_D
,
525 .range_max
= DA9062AA_EVENT_C
,
527 .range_min
= DA9062AA_CONTROL_A
,
528 .range_max
= DA9062AA_CONTROL_B
,
530 .range_min
= DA9062AA_CONTROL_E
,
531 .range_max
= DA9062AA_CONTROL_F
,
533 .range_min
= DA9062AA_BUCK1_CONT
,
534 .range_max
= DA9062AA_BUCK4_CONT
,
536 .range_min
= DA9062AA_BUCK3_CONT
,
537 .range_max
= DA9062AA_BUCK3_CONT
,
539 .range_min
= DA9062AA_LDO1_CONT
,
540 .range_max
= DA9062AA_LDO4_CONT
,
542 .range_min
= DA9062AA_DVC_1
,
543 .range_max
= DA9062AA_DVC_1
,
545 .range_min
= DA9062AA_SEQ
,
546 .range_max
= DA9062AA_SEQ
,
550 static const struct regmap_access_table da9061_aa_readable_table
= {
551 .yes_ranges
= da9061_aa_readable_ranges
,
552 .n_yes_ranges
= ARRAY_SIZE(da9061_aa_readable_ranges
),
555 static const struct regmap_access_table da9061_aa_writeable_table
= {
556 .yes_ranges
= da9061_aa_writeable_ranges
,
557 .n_yes_ranges
= ARRAY_SIZE(da9061_aa_writeable_ranges
),
560 static const struct regmap_access_table da9061_aa_volatile_table
= {
561 .yes_ranges
= da9061_aa_volatile_ranges
,
562 .n_yes_ranges
= ARRAY_SIZE(da9061_aa_volatile_ranges
),
565 static const struct regmap_range_cfg da9061_range_cfg
[] = {
567 .range_min
= DA9062AA_PAGE_CON
,
568 .range_max
= DA9062AA_CONFIG_ID
,
569 .selector_reg
= DA9062AA_PAGE_CON
,
570 .selector_mask
= 1 << DA9062_I2C_PAGE_SEL_SHIFT
,
571 .selector_shift
= DA9062_I2C_PAGE_SEL_SHIFT
,
577 static struct regmap_config da9061_regmap_config
= {
580 .ranges
= da9061_range_cfg
,
581 .num_ranges
= ARRAY_SIZE(da9061_range_cfg
),
582 .max_register
= DA9062AA_CONFIG_ID
,
583 .cache_type
= REGCACHE_RBTREE
,
584 .rd_table
= &da9061_aa_readable_table
,
585 .wr_table
= &da9061_aa_writeable_table
,
586 .volatile_table
= &da9061_aa_volatile_table
,
589 static const struct regmap_range da9062_aa_readable_ranges
[] = {
591 .range_min
= DA9062AA_PAGE_CON
,
592 .range_max
= DA9062AA_STATUS_B
,
594 .range_min
= DA9062AA_STATUS_D
,
595 .range_max
= DA9062AA_EVENT_C
,
597 .range_min
= DA9062AA_IRQ_MASK_A
,
598 .range_max
= DA9062AA_IRQ_MASK_C
,
600 .range_min
= DA9062AA_CONTROL_A
,
601 .range_max
= DA9062AA_GPIO_4
,
603 .range_min
= DA9062AA_GPIO_WKUP_MODE
,
604 .range_max
= DA9062AA_BUCK4_CONT
,
606 .range_min
= DA9062AA_BUCK3_CONT
,
607 .range_max
= DA9062AA_BUCK3_CONT
,
609 .range_min
= DA9062AA_LDO1_CONT
,
610 .range_max
= DA9062AA_LDO4_CONT
,
612 .range_min
= DA9062AA_DVC_1
,
613 .range_max
= DA9062AA_DVC_1
,
615 .range_min
= DA9062AA_COUNT_S
,
616 .range_max
= DA9062AA_SECOND_D
,
618 .range_min
= DA9062AA_SEQ
,
619 .range_max
= DA9062AA_ID_4_3
,
621 .range_min
= DA9062AA_ID_12_11
,
622 .range_max
= DA9062AA_ID_16_15
,
624 .range_min
= DA9062AA_ID_22_21
,
625 .range_max
= DA9062AA_ID_32_31
,
627 .range_min
= DA9062AA_SEQ_A
,
628 .range_max
= DA9062AA_BUCK3_CFG
,
630 .range_min
= DA9062AA_VBUCK2_A
,
631 .range_max
= DA9062AA_VBUCK4_A
,
633 .range_min
= DA9062AA_VBUCK3_A
,
634 .range_max
= DA9062AA_VBUCK3_A
,
636 .range_min
= DA9062AA_VLDO1_A
,
637 .range_max
= DA9062AA_VLDO4_A
,
639 .range_min
= DA9062AA_VBUCK2_B
,
640 .range_max
= DA9062AA_VBUCK4_B
,
642 .range_min
= DA9062AA_VBUCK3_B
,
643 .range_max
= DA9062AA_VBUCK3_B
,
645 .range_min
= DA9062AA_VLDO1_B
,
646 .range_max
= DA9062AA_VLDO4_B
,
648 .range_min
= DA9062AA_BBAT_CONT
,
649 .range_max
= DA9062AA_BBAT_CONT
,
651 .range_min
= DA9062AA_INTERFACE
,
652 .range_max
= DA9062AA_CONFIG_E
,
654 .range_min
= DA9062AA_CONFIG_G
,
655 .range_max
= DA9062AA_CONFIG_K
,
657 .range_min
= DA9062AA_CONFIG_M
,
658 .range_max
= DA9062AA_CONFIG_M
,
660 .range_min
= DA9062AA_TRIM_CLDR
,
661 .range_max
= DA9062AA_GP_ID_19
,
663 .range_min
= DA9062AA_DEVICE_ID
,
664 .range_max
= DA9062AA_CONFIG_ID
,
668 static const struct regmap_range da9062_aa_writeable_ranges
[] = {
670 .range_min
= DA9062AA_PAGE_CON
,
671 .range_max
= DA9062AA_PAGE_CON
,
673 .range_min
= DA9062AA_FAULT_LOG
,
674 .range_max
= DA9062AA_EVENT_C
,
676 .range_min
= DA9062AA_IRQ_MASK_A
,
677 .range_max
= DA9062AA_IRQ_MASK_C
,
679 .range_min
= DA9062AA_CONTROL_A
,
680 .range_max
= DA9062AA_GPIO_4
,
682 .range_min
= DA9062AA_GPIO_WKUP_MODE
,
683 .range_max
= DA9062AA_BUCK4_CONT
,
685 .range_min
= DA9062AA_BUCK3_CONT
,
686 .range_max
= DA9062AA_BUCK3_CONT
,
688 .range_min
= DA9062AA_LDO1_CONT
,
689 .range_max
= DA9062AA_LDO4_CONT
,
691 .range_min
= DA9062AA_DVC_1
,
692 .range_max
= DA9062AA_DVC_1
,
694 .range_min
= DA9062AA_COUNT_S
,
695 .range_max
= DA9062AA_ALARM_Y
,
697 .range_min
= DA9062AA_SEQ
,
698 .range_max
= DA9062AA_ID_4_3
,
700 .range_min
= DA9062AA_ID_12_11
,
701 .range_max
= DA9062AA_ID_16_15
,
703 .range_min
= DA9062AA_ID_22_21
,
704 .range_max
= DA9062AA_ID_32_31
,
706 .range_min
= DA9062AA_SEQ_A
,
707 .range_max
= DA9062AA_BUCK3_CFG
,
709 .range_min
= DA9062AA_VBUCK2_A
,
710 .range_max
= DA9062AA_VBUCK4_A
,
712 .range_min
= DA9062AA_VBUCK3_A
,
713 .range_max
= DA9062AA_VBUCK3_A
,
715 .range_min
= DA9062AA_VLDO1_A
,
716 .range_max
= DA9062AA_VLDO4_A
,
718 .range_min
= DA9062AA_VBUCK2_B
,
719 .range_max
= DA9062AA_VBUCK4_B
,
721 .range_min
= DA9062AA_VBUCK3_B
,
722 .range_max
= DA9062AA_VBUCK3_B
,
724 .range_min
= DA9062AA_VLDO1_B
,
725 .range_max
= DA9062AA_VLDO4_B
,
727 .range_min
= DA9062AA_BBAT_CONT
,
728 .range_max
= DA9062AA_BBAT_CONT
,
730 .range_min
= DA9062AA_GP_ID_0
,
731 .range_max
= DA9062AA_GP_ID_19
,
735 static const struct regmap_range da9062_aa_volatile_ranges
[] = {
737 .range_min
= DA9062AA_PAGE_CON
,
738 .range_max
= DA9062AA_STATUS_B
,
740 .range_min
= DA9062AA_STATUS_D
,
741 .range_max
= DA9062AA_EVENT_C
,
743 .range_min
= DA9062AA_CONTROL_A
,
744 .range_max
= DA9062AA_CONTROL_B
,
746 .range_min
= DA9062AA_CONTROL_E
,
747 .range_max
= DA9062AA_CONTROL_F
,
749 .range_min
= DA9062AA_BUCK2_CONT
,
750 .range_max
= DA9062AA_BUCK4_CONT
,
752 .range_min
= DA9062AA_BUCK3_CONT
,
753 .range_max
= DA9062AA_BUCK3_CONT
,
755 .range_min
= DA9062AA_LDO1_CONT
,
756 .range_max
= DA9062AA_LDO4_CONT
,
758 .range_min
= DA9062AA_DVC_1
,
759 .range_max
= DA9062AA_DVC_1
,
761 .range_min
= DA9062AA_COUNT_S
,
762 .range_max
= DA9062AA_SECOND_D
,
764 .range_min
= DA9062AA_SEQ
,
765 .range_max
= DA9062AA_SEQ
,
767 .range_min
= DA9062AA_EN_32K
,
768 .range_max
= DA9062AA_EN_32K
,
772 static const struct regmap_access_table da9062_aa_readable_table
= {
773 .yes_ranges
= da9062_aa_readable_ranges
,
774 .n_yes_ranges
= ARRAY_SIZE(da9062_aa_readable_ranges
),
777 static const struct regmap_access_table da9062_aa_writeable_table
= {
778 .yes_ranges
= da9062_aa_writeable_ranges
,
779 .n_yes_ranges
= ARRAY_SIZE(da9062_aa_writeable_ranges
),
782 static const struct regmap_access_table da9062_aa_volatile_table
= {
783 .yes_ranges
= da9062_aa_volatile_ranges
,
784 .n_yes_ranges
= ARRAY_SIZE(da9062_aa_volatile_ranges
),
787 static const struct regmap_range_cfg da9062_range_cfg
[] = {
789 .range_min
= DA9062AA_PAGE_CON
,
790 .range_max
= DA9062AA_CONFIG_ID
,
791 .selector_reg
= DA9062AA_PAGE_CON
,
792 .selector_mask
= 1 << DA9062_I2C_PAGE_SEL_SHIFT
,
793 .selector_shift
= DA9062_I2C_PAGE_SEL_SHIFT
,
799 static struct regmap_config da9062_regmap_config
= {
802 .ranges
= da9062_range_cfg
,
803 .num_ranges
= ARRAY_SIZE(da9062_range_cfg
),
804 .max_register
= DA9062AA_CONFIG_ID
,
805 .cache_type
= REGCACHE_RBTREE
,
806 .rd_table
= &da9062_aa_readable_table
,
807 .wr_table
= &da9062_aa_writeable_table
,
808 .volatile_table
= &da9062_aa_volatile_table
,
811 static const struct of_device_id da9062_dt_ids
[] = {
812 { .compatible
= "dlg,da9061", .data
= (void *)COMPAT_TYPE_DA9061
, },
813 { .compatible
= "dlg,da9062", .data
= (void *)COMPAT_TYPE_DA9062
, },
816 MODULE_DEVICE_TABLE(of
, da9062_dt_ids
);
818 static int da9062_i2c_probe(struct i2c_client
*i2c
,
819 const struct i2c_device_id
*id
)
822 const struct of_device_id
*match
;
823 unsigned int irq_base
;
824 const struct mfd_cell
*cell
;
825 const struct regmap_irq_chip
*irq_chip
;
826 const struct regmap_config
*config
;
830 chip
= devm_kzalloc(&i2c
->dev
, sizeof(*chip
), GFP_KERNEL
);
834 if (i2c
->dev
.of_node
) {
835 match
= of_match_node(da9062_dt_ids
, i2c
->dev
.of_node
);
839 chip
->chip_type
= (uintptr_t)match
->data
;
841 chip
->chip_type
= id
->driver_data
;
844 i2c_set_clientdata(i2c
, chip
);
845 chip
->dev
= &i2c
->dev
;
848 dev_err(chip
->dev
, "No IRQ configured\n");
852 switch (chip
->chip_type
) {
853 case COMPAT_TYPE_DA9061
:
855 cell_num
= ARRAY_SIZE(da9061_devs
);
856 irq_chip
= &da9061_irq_chip
;
857 config
= &da9061_regmap_config
;
859 case COMPAT_TYPE_DA9062
:
861 cell_num
= ARRAY_SIZE(da9062_devs
);
862 irq_chip
= &da9062_irq_chip
;
863 config
= &da9062_regmap_config
;
866 dev_err(chip
->dev
, "Unrecognised chip type\n");
870 chip
->regmap
= devm_regmap_init_i2c(i2c
, config
);
871 if (IS_ERR(chip
->regmap
)) {
872 ret
= PTR_ERR(chip
->regmap
);
873 dev_err(chip
->dev
, "Failed to allocate register map: %d\n",
878 ret
= da9062_clear_fault_log(chip
);
880 dev_warn(chip
->dev
, "Cannot clear fault log\n");
882 ret
= da9062_get_device_type(chip
);
886 ret
= regmap_add_irq_chip(chip
->regmap
, i2c
->irq
,
887 IRQF_TRIGGER_LOW
| IRQF_ONESHOT
| IRQF_SHARED
,
891 dev_err(chip
->dev
, "Failed to request IRQ %d: %d\n",
896 irq_base
= regmap_irq_chip_get_base(chip
->regmap_irq
);
898 ret
= mfd_add_devices(chip
->dev
, PLATFORM_DEVID_NONE
, cell
,
899 cell_num
, NULL
, irq_base
,
902 dev_err(chip
->dev
, "Cannot register child devices\n");
903 regmap_del_irq_chip(i2c
->irq
, chip
->regmap_irq
);
910 static int da9062_i2c_remove(struct i2c_client
*i2c
)
912 struct da9062
*chip
= i2c_get_clientdata(i2c
);
914 mfd_remove_devices(chip
->dev
);
915 regmap_del_irq_chip(i2c
->irq
, chip
->regmap_irq
);
920 static const struct i2c_device_id da9062_i2c_id
[] = {
921 { "da9061", COMPAT_TYPE_DA9061
},
922 { "da9062", COMPAT_TYPE_DA9062
},
925 MODULE_DEVICE_TABLE(i2c
, da9062_i2c_id
);
927 static struct i2c_driver da9062_i2c_driver
= {
930 .of_match_table
= of_match_ptr(da9062_dt_ids
),
932 .probe
= da9062_i2c_probe
,
933 .remove
= da9062_i2c_remove
,
934 .id_table
= da9062_i2c_id
,
937 module_i2c_driver(da9062_i2c_driver
);
939 MODULE_DESCRIPTION("Core device driver for Dialog DA9061 and DA9062");
940 MODULE_AUTHOR("Steve Twiss <stwiss.opensource@diasemi.com>");
941 MODULE_LICENSE("GPL");