aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteve Twiss <stwiss.opensource@diasemi.com>2017-04-03 10:46:40 -0400
committerLee Jones <lee.jones@linaro.org>2017-04-27 04:25:07 -0400
commit656211b1dfb9e0b68d4e634931432e29a6facf46 (patch)
tree04a6dae41ed8b4c8c69b793431b696034e1040a2
parente1569fb64e5efb31b835ac8e76bf1c18313da8e5 (diff)
mfd: Add support for DA9061
MFD support for DA9061 is provided as part of the DA9062 device driver. The registers header file adds two new chip variant IDs defined in DA9061 and DA9062 hardware. The core header file adds new software enumerations for listing the valid DA9061 IRQs and a da9062_compatible_types enumeration for distinguishing between DA9061/62 devices in software. The core source code adds a new .compatible of_device_id entry. This is extended from DA9062 to support both "dlg,da9061" and "dlg,da9062". The .data entry now holds a reference to the enumerated device type. A new regmap_irq_chip model is added for DA9061 and this supports the new list of regmap_irq entries. A new mfd_cell da9061_devs[] array lists the new sub system components for DA9061. Support is added for a new DA9061 regmap_config which lists the correct readable, writable and volatile ranges for this chip. The probe function uses the device tree compatible string to switch on the da9062_compatible_types and configure the correct mfd cells, irq chip and regmap config. Kconfig is updated to reflect support for DA9061 and DA9062 PMICs. Signed-off-by: Steve Twiss <stwiss.opensource@diasemi.com> Signed-off-by: Lee Jones <lee.jones@linaro.org>
-rw-r--r--drivers/mfd/Kconfig5
-rw-r--r--drivers/mfd/da9062-core.c427
-rw-r--r--include/linux/mfd/da9062/core.h29
-rw-r--r--include/linux/mfd/da9062/registers.h5
4 files changed, 443 insertions, 23 deletions
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index ce3a9180a765..de68b5ba8741 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -267,13 +267,14 @@ config MFD_DA9055
267 called "da9055" 267 called "da9055"
268 268
269config MFD_DA9062 269config MFD_DA9062
270 tristate "Dialog Semiconductor DA9062 PMIC Support" 270 tristate "Dialog Semiconductor DA9062/61 PMIC Support"
271 select MFD_CORE 271 select MFD_CORE
272 select REGMAP_I2C 272 select REGMAP_I2C
273 select REGMAP_IRQ 273 select REGMAP_IRQ
274 depends on I2C 274 depends on I2C
275 help 275 help
276 Say yes here for support for the Dialog Semiconductor DA9062 PMIC. 276 Say yes here for support for the Dialog Semiconductor DA9061 and
277 DA9062 PMICs.
277 This includes the I2C driver and core APIs. 278 This includes the I2C driver and core APIs.
278 Additional drivers must be enabled in order to use the functionality 279 Additional drivers must be enabled in order to use the functionality
279 of the device. 280 of the device.
diff --git a/drivers/mfd/da9062-core.c b/drivers/mfd/da9062-core.c
index 8f873866ea60..7f5e8be0a9ea 100644
--- a/drivers/mfd/da9062-core.c
+++ b/drivers/mfd/da9062-core.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * Core, IRQ and I2C device driver for DA9062 PMIC 2 * Core, IRQ and I2C device driver for DA9061 and DA9062 PMICs
3 * Copyright (C) 2015 Dialog Semiconductor Ltd. 3 * Copyright (C) 2015-2017 Dialog Semiconductor
4 * 4 *
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License 6 * modify it under the terms of the GNU General Public License
@@ -30,6 +30,70 @@
30#define DA9062_REG_EVENT_B_OFFSET 1 30#define DA9062_REG_EVENT_B_OFFSET 1
31#define DA9062_REG_EVENT_C_OFFSET 2 31#define DA9062_REG_EVENT_C_OFFSET 2
32 32
33static struct regmap_irq da9061_irqs[] = {
34 /* EVENT A */
35 [DA9061_IRQ_ONKEY] = {
36 .reg_offset = DA9062_REG_EVENT_A_OFFSET,
37 .mask = DA9062AA_M_NONKEY_MASK,
38 },
39 [DA9061_IRQ_WDG_WARN] = {
40 .reg_offset = DA9062_REG_EVENT_A_OFFSET,
41 .mask = DA9062AA_M_WDG_WARN_MASK,
42 },
43 [DA9061_IRQ_SEQ_RDY] = {
44 .reg_offset = DA9062_REG_EVENT_A_OFFSET,
45 .mask = DA9062AA_M_SEQ_RDY_MASK,
46 },
47 /* EVENT B */
48 [DA9061_IRQ_TEMP] = {
49 .reg_offset = DA9062_REG_EVENT_B_OFFSET,
50 .mask = DA9062AA_M_TEMP_MASK,
51 },
52 [DA9061_IRQ_LDO_LIM] = {
53 .reg_offset = DA9062_REG_EVENT_B_OFFSET,
54 .mask = DA9062AA_M_LDO_LIM_MASK,
55 },
56 [DA9061_IRQ_DVC_RDY] = {
57 .reg_offset = DA9062_REG_EVENT_B_OFFSET,
58 .mask = DA9062AA_M_DVC_RDY_MASK,
59 },
60 [DA9061_IRQ_VDD_WARN] = {
61 .reg_offset = DA9062_REG_EVENT_B_OFFSET,
62 .mask = DA9062AA_M_VDD_WARN_MASK,
63 },
64 /* EVENT C */
65 [DA9061_IRQ_GPI0] = {
66 .reg_offset = DA9062_REG_EVENT_C_OFFSET,
67 .mask = DA9062AA_M_GPI0_MASK,
68 },
69 [DA9061_IRQ_GPI1] = {
70 .reg_offset = DA9062_REG_EVENT_C_OFFSET,
71 .mask = DA9062AA_M_GPI1_MASK,
72 },
73 [DA9061_IRQ_GPI2] = {
74 .reg_offset = DA9062_REG_EVENT_C_OFFSET,
75 .mask = DA9062AA_M_GPI2_MASK,
76 },
77 [DA9061_IRQ_GPI3] = {
78 .reg_offset = DA9062_REG_EVENT_C_OFFSET,
79 .mask = DA9062AA_M_GPI3_MASK,
80 },
81 [DA9061_IRQ_GPI4] = {
82 .reg_offset = DA9062_REG_EVENT_C_OFFSET,
83 .mask = DA9062AA_M_GPI4_MASK,
84 },
85};
86
87static struct regmap_irq_chip da9061_irq_chip = {
88 .name = "da9061-irq",
89 .irqs = da9061_irqs,
90 .num_irqs = DA9061_NUM_IRQ,
91 .num_regs = 3,
92 .status_base = DA9062AA_EVENT_A,
93 .mask_base = DA9062AA_IRQ_MASK_A,
94 .ack_base = DA9062AA_EVENT_A,
95};
96
33static struct regmap_irq da9062_irqs[] = { 97static struct regmap_irq da9062_irqs[] = {
34 /* EVENT A */ 98 /* EVENT A */
35 [DA9062_IRQ_ONKEY] = { 99 [DA9062_IRQ_ONKEY] = {
@@ -102,6 +166,57 @@ static struct regmap_irq_chip da9062_irq_chip = {
102 .ack_base = DA9062AA_EVENT_A, 166 .ack_base = DA9062AA_EVENT_A,
103}; 167};
104 168
169static struct resource da9061_core_resources[] = {
170 DEFINE_RES_IRQ_NAMED(DA9061_IRQ_VDD_WARN, "VDD_WARN"),
171};
172
173static struct resource da9061_regulators_resources[] = {
174 DEFINE_RES_IRQ_NAMED(DA9061_IRQ_LDO_LIM, "LDO_LIM"),
175};
176
177static struct resource da9061_thermal_resources[] = {
178 DEFINE_RES_IRQ_NAMED(DA9061_IRQ_TEMP, "THERMAL"),
179};
180
181static struct resource da9061_wdt_resources[] = {
182 DEFINE_RES_IRQ_NAMED(DA9061_IRQ_WDG_WARN, "WD_WARN"),
183};
184
185static struct resource da9061_onkey_resources[] = {
186 DEFINE_RES_IRQ_NAMED(DA9061_IRQ_ONKEY, "ONKEY"),
187};
188
189static const struct mfd_cell da9061_devs[] = {
190 {
191 .name = "da9061-core",
192 .num_resources = ARRAY_SIZE(da9061_core_resources),
193 .resources = da9061_core_resources,
194 },
195 {
196 .name = "da9062-regulators",
197 .num_resources = ARRAY_SIZE(da9061_regulators_resources),
198 .resources = da9061_regulators_resources,
199 },
200 {
201 .name = "da9061-watchdog",
202 .num_resources = ARRAY_SIZE(da9061_wdt_resources),
203 .resources = da9061_wdt_resources,
204 .of_compatible = "dlg,da9061-watchdog",
205 },
206 {
207 .name = "da9061-thermal",
208 .num_resources = ARRAY_SIZE(da9061_thermal_resources),
209 .resources = da9061_thermal_resources,
210 .of_compatible = "dlg,da9061-thermal",
211 },
212 {
213 .name = "da9061-onkey",
214 .num_resources = ARRAY_SIZE(da9061_onkey_resources),
215 .resources = da9061_onkey_resources,
216 .of_compatible = "dlg,da9061-onkey",
217 },
218};
219
105static struct resource da9062_core_resources[] = { 220static struct resource da9062_core_resources[] = {
106 DEFINE_RES_NAMED(DA9062_IRQ_VDD_WARN, 1, "VDD_WARN", IORESOURCE_IRQ), 221 DEFINE_RES_NAMED(DA9062_IRQ_VDD_WARN, 1, "VDD_WARN", IORESOURCE_IRQ),
107}; 222};
@@ -200,7 +315,8 @@ static int da9062_clear_fault_log(struct da9062 *chip)
200 315
201static int da9062_get_device_type(struct da9062 *chip) 316static int da9062_get_device_type(struct da9062 *chip)
202{ 317{
203 int device_id, variant_id, variant_mrc; 318 int device_id, variant_id, variant_mrc, variant_vrc;
319 char *type;
204 int ret; 320 int ret;
205 321
206 ret = regmap_read(chip->regmap, DA9062AA_DEVICE_ID, &device_id); 322 ret = regmap_read(chip->regmap, DA9062AA_DEVICE_ID, &device_id);
@@ -219,9 +335,23 @@ static int da9062_get_device_type(struct da9062 *chip)
219 return -EIO; 335 return -EIO;
220 } 336 }
221 337
338 variant_vrc = (variant_id & DA9062AA_VRC_MASK) >> DA9062AA_VRC_SHIFT;
339
340 switch (variant_vrc) {
341 case DA9062_PMIC_VARIANT_VRC_DA9061:
342 type = "DA9061";
343 break;
344 case DA9062_PMIC_VARIANT_VRC_DA9062:
345 type = "DA9062";
346 break;
347 default:
348 type = "Unknown";
349 break;
350 }
351
222 dev_info(chip->dev, 352 dev_info(chip->dev,
223 "Device detected (device-ID: 0x%02X, var-ID: 0x%02X)\n", 353 "Device detected (device-ID: 0x%02X, var-ID: 0x%02X, %s)\n",
224 device_id, variant_id); 354 device_id, variant_id, type);
225 355
226 variant_mrc = (variant_id & DA9062AA_MRC_MASK) >> DA9062AA_MRC_SHIFT; 356 variant_mrc = (variant_id & DA9062AA_MRC_MASK) >> DA9062AA_MRC_SHIFT;
227 357
@@ -234,6 +364,234 @@ static int da9062_get_device_type(struct da9062 *chip)
234 return ret; 364 return ret;
235} 365}
236 366
367static const struct regmap_range da9061_aa_readable_ranges[] = {
368 {
369 .range_min = DA9062AA_PAGE_CON,
370 .range_max = DA9062AA_STATUS_B,
371 }, {
372 .range_min = DA9062AA_STATUS_D,
373 .range_max = DA9062AA_EVENT_C,
374 }, {
375 .range_min = DA9062AA_IRQ_MASK_A,
376 .range_max = DA9062AA_IRQ_MASK_C,
377 }, {
378 .range_min = DA9062AA_CONTROL_A,
379 .range_max = DA9062AA_GPIO_4,
380 }, {
381 .range_min = DA9062AA_GPIO_WKUP_MODE,
382 .range_max = DA9062AA_GPIO_OUT3_4,
383 }, {
384 .range_min = DA9062AA_BUCK1_CONT,
385 .range_max = DA9062AA_BUCK4_CONT,
386 }, {
387 .range_min = DA9062AA_BUCK3_CONT,
388 .range_max = DA9062AA_BUCK3_CONT,
389 }, {
390 .range_min = DA9062AA_LDO1_CONT,
391 .range_max = DA9062AA_LDO4_CONT,
392 }, {
393 .range_min = DA9062AA_DVC_1,
394 .range_max = DA9062AA_DVC_1,
395 }, {
396 .range_min = DA9062AA_SEQ,
397 .range_max = DA9062AA_ID_4_3,
398 }, {
399 .range_min = DA9062AA_ID_12_11,
400 .range_max = DA9062AA_ID_16_15,
401 }, {
402 .range_min = DA9062AA_ID_22_21,
403 .range_max = DA9062AA_ID_32_31,
404 }, {
405 .range_min = DA9062AA_SEQ_A,
406 .range_max = DA9062AA_WAIT,
407 }, {
408 .range_min = DA9062AA_RESET,
409 .range_max = DA9062AA_BUCK_ILIM_C,
410 }, {
411 .range_min = DA9062AA_BUCK1_CFG,
412 .range_max = DA9062AA_BUCK3_CFG,
413 }, {
414 .range_min = DA9062AA_VBUCK1_A,
415 .range_max = DA9062AA_VBUCK4_A,
416 }, {
417 .range_min = DA9062AA_VBUCK3_A,
418 .range_max = DA9062AA_VBUCK3_A,
419 }, {
420 .range_min = DA9062AA_VLDO1_A,
421 .range_max = DA9062AA_VLDO4_A,
422 }, {
423 .range_min = DA9062AA_VBUCK1_B,
424 .range_max = DA9062AA_VBUCK4_B,
425 }, {
426 .range_min = DA9062AA_VBUCK3_B,
427 .range_max = DA9062AA_VBUCK3_B,
428 }, {
429 .range_min = DA9062AA_VLDO1_B,
430 .range_max = DA9062AA_VLDO4_B,
431 }, {
432 .range_min = DA9062AA_BBAT_CONT,
433 .range_max = DA9062AA_BBAT_CONT,
434 }, {
435 .range_min = DA9062AA_INTERFACE,
436 .range_max = DA9062AA_CONFIG_E,
437 }, {
438 .range_min = DA9062AA_CONFIG_G,
439 .range_max = DA9062AA_CONFIG_K,
440 }, {
441 .range_min = DA9062AA_CONFIG_M,
442 .range_max = DA9062AA_CONFIG_M,
443 }, {
444 .range_min = DA9062AA_GP_ID_0,
445 .range_max = DA9062AA_GP_ID_19,
446 }, {
447 .range_min = DA9062AA_DEVICE_ID,
448 .range_max = DA9062AA_CONFIG_ID,
449 },
450};
451
452static const struct regmap_range da9061_aa_writeable_ranges[] = {
453 {
454 .range_min = DA9062AA_PAGE_CON,
455 .range_max = DA9062AA_PAGE_CON,
456 }, {
457 .range_min = DA9062AA_FAULT_LOG,
458 .range_max = DA9062AA_EVENT_C,
459 }, {
460 .range_min = DA9062AA_IRQ_MASK_A,
461 .range_max = DA9062AA_IRQ_MASK_C,
462 }, {
463 .range_min = DA9062AA_CONTROL_A,
464 .range_max = DA9062AA_GPIO_4,
465 }, {
466 .range_min = DA9062AA_GPIO_WKUP_MODE,
467 .range_max = DA9062AA_GPIO_OUT3_4,
468 }, {
469 .range_min = DA9062AA_BUCK1_CONT,
470 .range_max = DA9062AA_BUCK4_CONT,
471 }, {
472 .range_min = DA9062AA_BUCK3_CONT,
473 .range_max = DA9062AA_BUCK3_CONT,
474 }, {
475 .range_min = DA9062AA_LDO1_CONT,
476 .range_max = DA9062AA_LDO4_CONT,
477 }, {
478 .range_min = DA9062AA_DVC_1,
479 .range_max = DA9062AA_DVC_1,
480 }, {
481 .range_min = DA9062AA_SEQ,
482 .range_max = DA9062AA_ID_4_3,
483 }, {
484 .range_min = DA9062AA_ID_12_11,
485 .range_max = DA9062AA_ID_16_15,
486 }, {
487 .range_min = DA9062AA_ID_22_21,
488 .range_max = DA9062AA_ID_32_31,
489 }, {
490 .range_min = DA9062AA_SEQ_A,
491 .range_max = DA9062AA_WAIT,
492 }, {
493 .range_min = DA9062AA_RESET,
494 .range_max = DA9062AA_BUCK_ILIM_C,
495 }, {
496 .range_min = DA9062AA_BUCK1_CFG,
497 .range_max = DA9062AA_BUCK3_CFG,
498 }, {
499 .range_min = DA9062AA_VBUCK1_A,
500 .range_max = DA9062AA_VBUCK4_A,
501 }, {
502 .range_min = DA9062AA_VBUCK3_A,
503 .range_max = DA9062AA_VBUCK3_A,
504 }, {
505 .range_min = DA9062AA_VLDO1_A,
506 .range_max = DA9062AA_VLDO4_A,
507 }, {
508 .range_min = DA9062AA_VBUCK1_B,
509 .range_max = DA9062AA_VBUCK4_B,
510 }, {
511 .range_min = DA9062AA_VBUCK3_B,
512 .range_max = DA9062AA_VBUCK3_B,
513 }, {
514 .range_min = DA9062AA_VLDO1_B,
515 .range_max = DA9062AA_VLDO4_B,
516 }, {
517 .range_min = DA9062AA_BBAT_CONT,
518 .range_max = DA9062AA_BBAT_CONT,
519 }, {
520 .range_min = DA9062AA_GP_ID_0,
521 .range_max = DA9062AA_GP_ID_19,
522 },
523};
524
525static const struct regmap_range da9061_aa_volatile_ranges[] = {
526 {
527 .range_min = DA9062AA_PAGE_CON,
528 .range_max = DA9062AA_STATUS_B,
529 }, {
530 .range_min = DA9062AA_STATUS_D,
531 .range_max = DA9062AA_EVENT_C,
532 }, {
533 .range_min = DA9062AA_CONTROL_A,
534 .range_max = DA9062AA_CONTROL_B,
535 }, {
536 .range_min = DA9062AA_CONTROL_E,
537 .range_max = DA9062AA_CONTROL_F,
538 }, {
539 .range_min = DA9062AA_BUCK1_CONT,
540 .range_max = DA9062AA_BUCK4_CONT,
541 }, {
542 .range_min = DA9062AA_BUCK3_CONT,
543 .range_max = DA9062AA_BUCK3_CONT,
544 }, {
545 .range_min = DA9062AA_LDO1_CONT,
546 .range_max = DA9062AA_LDO4_CONT,
547 }, {
548 .range_min = DA9062AA_DVC_1,
549 .range_max = DA9062AA_DVC_1,
550 }, {
551 .range_min = DA9062AA_SEQ,
552 .range_max = DA9062AA_SEQ,
553 },
554};
555
556static const struct regmap_access_table da9061_aa_readable_table = {
557 .yes_ranges = da9061_aa_readable_ranges,
558 .n_yes_ranges = ARRAY_SIZE(da9061_aa_readable_ranges),
559};
560
561static const struct regmap_access_table da9061_aa_writeable_table = {
562 .yes_ranges = da9061_aa_writeable_ranges,
563 .n_yes_ranges = ARRAY_SIZE(da9061_aa_writeable_ranges),
564};
565
566static const struct regmap_access_table da9061_aa_volatile_table = {
567 .yes_ranges = da9061_aa_volatile_ranges,
568 .n_yes_ranges = ARRAY_SIZE(da9061_aa_volatile_ranges),
569};
570
571static const struct regmap_range_cfg da9061_range_cfg[] = {
572 {
573 .range_min = DA9062AA_PAGE_CON,
574 .range_max = DA9062AA_CONFIG_ID,
575 .selector_reg = DA9062AA_PAGE_CON,
576 .selector_mask = 1 << DA9062_I2C_PAGE_SEL_SHIFT,
577 .selector_shift = DA9062_I2C_PAGE_SEL_SHIFT,
578 .window_start = 0,
579 .window_len = 256,
580 }
581};
582
583static struct regmap_config da9061_regmap_config = {
584 .reg_bits = 8,
585 .val_bits = 8,
586 .ranges = da9061_range_cfg,
587 .num_ranges = ARRAY_SIZE(da9061_range_cfg),
588 .max_register = DA9062AA_CONFIG_ID,
589 .cache_type = REGCACHE_RBTREE,
590 .rd_table = &da9061_aa_readable_table,
591 .wr_table = &da9061_aa_writeable_table,
592 .volatile_table = &da9061_aa_volatile_table,
593};
594
237static const struct regmap_range da9062_aa_readable_ranges[] = { 595static const struct regmap_range da9062_aa_readable_ranges[] = {
238 { 596 {
239 .range_min = DA9062AA_PAGE_CON, 597 .range_min = DA9062AA_PAGE_CON,
@@ -456,17 +814,39 @@ static struct regmap_config da9062_regmap_config = {
456 .volatile_table = &da9062_aa_volatile_table, 814 .volatile_table = &da9062_aa_volatile_table,
457}; 815};
458 816
817static const struct of_device_id da9062_dt_ids[] = {
818 { .compatible = "dlg,da9061", .data = (void *)COMPAT_TYPE_DA9061, },
819 { .compatible = "dlg,da9062", .data = (void *)COMPAT_TYPE_DA9062, },
820 { }
821};
822MODULE_DEVICE_TABLE(of, da9062_dt_ids);
823
459static int da9062_i2c_probe(struct i2c_client *i2c, 824static int da9062_i2c_probe(struct i2c_client *i2c,
460 const struct i2c_device_id *id) 825 const struct i2c_device_id *id)
461{ 826{
462 struct da9062 *chip; 827 struct da9062 *chip;
828 const struct of_device_id *match;
463 unsigned int irq_base; 829 unsigned int irq_base;
830 const struct mfd_cell *cell;
831 const struct regmap_irq_chip *irq_chip;
832 const struct regmap_config *config;
833 int cell_num;
464 int ret; 834 int ret;
465 835
466 chip = devm_kzalloc(&i2c->dev, sizeof(*chip), GFP_KERNEL); 836 chip = devm_kzalloc(&i2c->dev, sizeof(*chip), GFP_KERNEL);
467 if (!chip) 837 if (!chip)
468 return -ENOMEM; 838 return -ENOMEM;
469 839
840 if (i2c->dev.of_node) {
841 match = of_match_node(da9062_dt_ids, i2c->dev.of_node);
842 if (!match)
843 return -EINVAL;
844
845 chip->chip_type = (uintptr_t)match->data;
846 } else {
847 chip->chip_type = id->driver_data;
848 }
849
470 i2c_set_clientdata(i2c, chip); 850 i2c_set_clientdata(i2c, chip);
471 chip->dev = &i2c->dev; 851 chip->dev = &i2c->dev;
472 852
@@ -475,7 +855,25 @@ static int da9062_i2c_probe(struct i2c_client *i2c,
475 return -EINVAL; 855 return -EINVAL;
476 } 856 }
477 857
478 chip->regmap = devm_regmap_init_i2c(i2c, &da9062_regmap_config); 858 switch (chip->chip_type) {
859 case COMPAT_TYPE_DA9061:
860 cell = da9061_devs;
861 cell_num = ARRAY_SIZE(da9061_devs);
862 irq_chip = &da9061_irq_chip;
863 config = &da9061_regmap_config;
864 break;
865 case COMPAT_TYPE_DA9062:
866 cell = da9062_devs;
867 cell_num = ARRAY_SIZE(da9062_devs);
868 irq_chip = &da9062_irq_chip;
869 config = &da9062_regmap_config;
870 break;
871 default:
872 dev_err(chip->dev, "Unrecognised chip type\n");
873 return -ENODEV;
874 }
875
876 chip->regmap = devm_regmap_init_i2c(i2c, config);
479 if (IS_ERR(chip->regmap)) { 877 if (IS_ERR(chip->regmap)) {
480 ret = PTR_ERR(chip->regmap); 878 ret = PTR_ERR(chip->regmap);
481 dev_err(chip->dev, "Failed to allocate register map: %d\n", 879 dev_err(chip->dev, "Failed to allocate register map: %d\n",
@@ -493,7 +891,7 @@ static int da9062_i2c_probe(struct i2c_client *i2c,
493 891
494 ret = regmap_add_irq_chip(chip->regmap, i2c->irq, 892 ret = regmap_add_irq_chip(chip->regmap, i2c->irq,
495 IRQF_TRIGGER_LOW | IRQF_ONESHOT | IRQF_SHARED, 893 IRQF_TRIGGER_LOW | IRQF_ONESHOT | IRQF_SHARED,
496 -1, &da9062_irq_chip, 894 -1, irq_chip,
497 &chip->regmap_irq); 895 &chip->regmap_irq);
498 if (ret) { 896 if (ret) {
499 dev_err(chip->dev, "Failed to request IRQ %d: %d\n", 897 dev_err(chip->dev, "Failed to request IRQ %d: %d\n",
@@ -503,8 +901,8 @@ static int da9062_i2c_probe(struct i2c_client *i2c,
503 901
504 irq_base = regmap_irq_chip_get_base(chip->regmap_irq); 902 irq_base = regmap_irq_chip_get_base(chip->regmap_irq);
505 903
506 ret = mfd_add_devices(chip->dev, PLATFORM_DEVID_NONE, da9062_devs, 904 ret = mfd_add_devices(chip->dev, PLATFORM_DEVID_NONE, cell,
507 ARRAY_SIZE(da9062_devs), NULL, irq_base, 905 cell_num, NULL, irq_base,
508 NULL); 906 NULL);
509 if (ret) { 907 if (ret) {
510 dev_err(chip->dev, "Cannot register child devices\n"); 908 dev_err(chip->dev, "Cannot register child devices\n");
@@ -526,17 +924,12 @@ static int da9062_i2c_remove(struct i2c_client *i2c)
526} 924}
527 925
528static const struct i2c_device_id da9062_i2c_id[] = { 926static const struct i2c_device_id da9062_i2c_id[] = {
529 { "da9062", 0 }, 927 { "da9061", COMPAT_TYPE_DA9061 },
928 { "da9062", COMPAT_TYPE_DA9062 },
530 { }, 929 { },
531}; 930};
532MODULE_DEVICE_TABLE(i2c, da9062_i2c_id); 931MODULE_DEVICE_TABLE(i2c, da9062_i2c_id);
533 932
534static const struct of_device_id da9062_dt_ids[] = {
535 { .compatible = "dlg,da9062", },
536 { }
537};
538MODULE_DEVICE_TABLE(of, da9062_dt_ids);
539
540static struct i2c_driver da9062_i2c_driver = { 933static struct i2c_driver da9062_i2c_driver = {
541 .driver = { 934 .driver = {
542 .name = "da9062", 935 .name = "da9062",
@@ -549,6 +942,6 @@ static struct i2c_driver da9062_i2c_driver = {
549 942
550module_i2c_driver(da9062_i2c_driver); 943module_i2c_driver(da9062_i2c_driver);
551 944
552MODULE_DESCRIPTION("Core device driver for Dialog DA9062"); 945MODULE_DESCRIPTION("Core device driver for Dialog DA9061 and DA9062");
553MODULE_AUTHOR("Steve Twiss <stwiss.opensource@diasemi.com>"); 946MODULE_AUTHOR("Steve Twiss <stwiss.opensource@diasemi.com>");
554MODULE_LICENSE("GPL"); 947MODULE_LICENSE("GPL");
diff --git a/include/linux/mfd/da9062/core.h b/include/linux/mfd/da9062/core.h
index 376ba84366a0..74d33a01ddae 100644
--- a/include/linux/mfd/da9062/core.h
+++ b/include/linux/mfd/da9062/core.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (C) 2015 Dialog Semiconductor Ltd. 2 * Copyright (C) 2015-2017 Dialog Semiconductor
3 * 3 *
4 * This program is free software; you can redistribute it and/or 4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License 5 * modify it under the terms of the GNU General Public License
@@ -18,7 +18,31 @@
18#include <linux/interrupt.h> 18#include <linux/interrupt.h>
19#include <linux/mfd/da9062/registers.h> 19#include <linux/mfd/da9062/registers.h>
20 20
21/* Interrupts */ 21enum da9062_compatible_types {
22 COMPAT_TYPE_DA9061 = 1,
23 COMPAT_TYPE_DA9062,
24};
25
26enum da9061_irqs {
27 /* IRQ A */
28 DA9061_IRQ_ONKEY,
29 DA9061_IRQ_WDG_WARN,
30 DA9061_IRQ_SEQ_RDY,
31 /* IRQ B*/
32 DA9061_IRQ_TEMP,
33 DA9061_IRQ_LDO_LIM,
34 DA9061_IRQ_DVC_RDY,
35 DA9061_IRQ_VDD_WARN,
36 /* IRQ C */
37 DA9061_IRQ_GPI0,
38 DA9061_IRQ_GPI1,
39 DA9061_IRQ_GPI2,
40 DA9061_IRQ_GPI3,
41 DA9061_IRQ_GPI4,
42
43 DA9061_NUM_IRQ,
44};
45
22enum da9062_irqs { 46enum da9062_irqs {
23 /* IRQ A */ 47 /* IRQ A */
24 DA9062_IRQ_ONKEY, 48 DA9062_IRQ_ONKEY,
@@ -45,6 +69,7 @@ struct da9062 {
45 struct device *dev; 69 struct device *dev;
46 struct regmap *regmap; 70 struct regmap *regmap;
47 struct regmap_irq_chip_data *regmap_irq; 71 struct regmap_irq_chip_data *regmap_irq;
72 enum da9062_compatible_types chip_type;
48}; 73};
49 74
50#endif /* __MFD_DA9062_CORE_H__ */ 75#endif /* __MFD_DA9062_CORE_H__ */
diff --git a/include/linux/mfd/da9062/registers.h b/include/linux/mfd/da9062/registers.h
index 97790d1b02c5..18d576aed902 100644
--- a/include/linux/mfd/da9062/registers.h
+++ b/include/linux/mfd/da9062/registers.h
@@ -1,6 +1,5 @@
1/* 1/*
2 * registers.h - REGISTERS H for DA9062 2 * Copyright (C) 2015-2017 Dialog Semiconductor
3 * Copyright (C) 2015 Dialog Semiconductor Ltd.
4 * 3 *
5 * This program is free software; you can redistribute it and/or 4 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License 5 * modify it under the terms of the GNU General Public License
@@ -18,6 +17,8 @@
18 17
19#define DA9062_PMIC_DEVICE_ID 0x62 18#define DA9062_PMIC_DEVICE_ID 0x62
20#define DA9062_PMIC_VARIANT_MRC_AA 0x01 19#define DA9062_PMIC_VARIANT_MRC_AA 0x01
20#define DA9062_PMIC_VARIANT_VRC_DA9061 0x01
21#define DA9062_PMIC_VARIANT_VRC_DA9062 0x02
21 22
22#define DA9062_I2C_PAGE_SEL_SHIFT 1 23#define DA9062_I2C_PAGE_SEL_SHIFT 1
23 24