Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Core, IRQ and I2C device driver for DA9061 and DA9062 PMICs
0004  * Copyright (C) 2015-2017  Dialog Semiconductor
0005  */
0006 
0007 #include <linux/kernel.h>
0008 #include <linux/module.h>
0009 #include <linux/init.h>
0010 #include <linux/device.h>
0011 #include <linux/interrupt.h>
0012 #include <linux/of_device.h>
0013 #include <linux/regmap.h>
0014 #include <linux/irq.h>
0015 #include <linux/mfd/core.h>
0016 #include <linux/i2c.h>
0017 #include <linux/mfd/da9062/core.h>
0018 #include <linux/mfd/da9062/registers.h>
0019 #include <linux/regulator/of_regulator.h>
0020 
0021 #define DA9062_REG_EVENT_A_OFFSET   0
0022 #define DA9062_REG_EVENT_B_OFFSET   1
0023 #define DA9062_REG_EVENT_C_OFFSET   2
0024 
0025 #define DA9062_IRQ_LOW  0
0026 #define DA9062_IRQ_HIGH 1
0027 
0028 static struct regmap_irq da9061_irqs[] = {
0029     /* EVENT A */
0030     [DA9061_IRQ_ONKEY] = {
0031         .reg_offset = DA9062_REG_EVENT_A_OFFSET,
0032         .mask = DA9062AA_M_NONKEY_MASK,
0033     },
0034     [DA9061_IRQ_WDG_WARN] = {
0035         .reg_offset = DA9062_REG_EVENT_A_OFFSET,
0036         .mask = DA9062AA_M_WDG_WARN_MASK,
0037     },
0038     [DA9061_IRQ_SEQ_RDY] = {
0039         .reg_offset = DA9062_REG_EVENT_A_OFFSET,
0040         .mask = DA9062AA_M_SEQ_RDY_MASK,
0041     },
0042     /* EVENT B */
0043     [DA9061_IRQ_TEMP] = {
0044         .reg_offset = DA9062_REG_EVENT_B_OFFSET,
0045         .mask = DA9062AA_M_TEMP_MASK,
0046     },
0047     [DA9061_IRQ_LDO_LIM] = {
0048         .reg_offset = DA9062_REG_EVENT_B_OFFSET,
0049         .mask = DA9062AA_M_LDO_LIM_MASK,
0050     },
0051     [DA9061_IRQ_DVC_RDY] = {
0052         .reg_offset = DA9062_REG_EVENT_B_OFFSET,
0053         .mask = DA9062AA_M_DVC_RDY_MASK,
0054     },
0055     [DA9061_IRQ_VDD_WARN] = {
0056         .reg_offset = DA9062_REG_EVENT_B_OFFSET,
0057         .mask = DA9062AA_M_VDD_WARN_MASK,
0058     },
0059     /* EVENT C */
0060     [DA9061_IRQ_GPI0] = {
0061         .reg_offset = DA9062_REG_EVENT_C_OFFSET,
0062         .mask = DA9062AA_M_GPI0_MASK,
0063     },
0064     [DA9061_IRQ_GPI1] = {
0065         .reg_offset = DA9062_REG_EVENT_C_OFFSET,
0066         .mask = DA9062AA_M_GPI1_MASK,
0067     },
0068     [DA9061_IRQ_GPI2] = {
0069         .reg_offset = DA9062_REG_EVENT_C_OFFSET,
0070         .mask = DA9062AA_M_GPI2_MASK,
0071     },
0072     [DA9061_IRQ_GPI3] = {
0073         .reg_offset = DA9062_REG_EVENT_C_OFFSET,
0074         .mask = DA9062AA_M_GPI3_MASK,
0075     },
0076     [DA9061_IRQ_GPI4] = {
0077         .reg_offset = DA9062_REG_EVENT_C_OFFSET,
0078         .mask = DA9062AA_M_GPI4_MASK,
0079     },
0080 };
0081 
0082 static struct regmap_irq_chip da9061_irq_chip = {
0083     .name = "da9061-irq",
0084     .irqs = da9061_irqs,
0085     .num_irqs = DA9061_NUM_IRQ,
0086     .num_regs = 3,
0087     .status_base = DA9062AA_EVENT_A,
0088     .mask_base = DA9062AA_IRQ_MASK_A,
0089     .ack_base = DA9062AA_EVENT_A,
0090 };
0091 
0092 static struct regmap_irq da9062_irqs[] = {
0093     /* EVENT A */
0094     [DA9062_IRQ_ONKEY] = {
0095         .reg_offset = DA9062_REG_EVENT_A_OFFSET,
0096         .mask = DA9062AA_M_NONKEY_MASK,
0097     },
0098     [DA9062_IRQ_ALARM] = {
0099         .reg_offset = DA9062_REG_EVENT_A_OFFSET,
0100         .mask = DA9062AA_M_ALARM_MASK,
0101     },
0102     [DA9062_IRQ_TICK] = {
0103         .reg_offset = DA9062_REG_EVENT_A_OFFSET,
0104         .mask = DA9062AA_M_TICK_MASK,
0105     },
0106     [DA9062_IRQ_WDG_WARN] = {
0107         .reg_offset = DA9062_REG_EVENT_A_OFFSET,
0108         .mask = DA9062AA_M_WDG_WARN_MASK,
0109     },
0110     [DA9062_IRQ_SEQ_RDY] = {
0111         .reg_offset = DA9062_REG_EVENT_A_OFFSET,
0112         .mask = DA9062AA_M_SEQ_RDY_MASK,
0113     },
0114     /* EVENT B */
0115     [DA9062_IRQ_TEMP] = {
0116         .reg_offset = DA9062_REG_EVENT_B_OFFSET,
0117         .mask = DA9062AA_M_TEMP_MASK,
0118     },
0119     [DA9062_IRQ_LDO_LIM] = {
0120         .reg_offset = DA9062_REG_EVENT_B_OFFSET,
0121         .mask = DA9062AA_M_LDO_LIM_MASK,
0122     },
0123     [DA9062_IRQ_DVC_RDY] = {
0124         .reg_offset = DA9062_REG_EVENT_B_OFFSET,
0125         .mask = DA9062AA_M_DVC_RDY_MASK,
0126     },
0127     [DA9062_IRQ_VDD_WARN] = {
0128         .reg_offset = DA9062_REG_EVENT_B_OFFSET,
0129         .mask = DA9062AA_M_VDD_WARN_MASK,
0130     },
0131     /* EVENT C */
0132     [DA9062_IRQ_GPI0] = {
0133         .reg_offset = DA9062_REG_EVENT_C_OFFSET,
0134         .mask = DA9062AA_M_GPI0_MASK,
0135     },
0136     [DA9062_IRQ_GPI1] = {
0137         .reg_offset = DA9062_REG_EVENT_C_OFFSET,
0138         .mask = DA9062AA_M_GPI1_MASK,
0139     },
0140     [DA9062_IRQ_GPI2] = {
0141         .reg_offset = DA9062_REG_EVENT_C_OFFSET,
0142         .mask = DA9062AA_M_GPI2_MASK,
0143     },
0144     [DA9062_IRQ_GPI3] = {
0145         .reg_offset = DA9062_REG_EVENT_C_OFFSET,
0146         .mask = DA9062AA_M_GPI3_MASK,
0147     },
0148     [DA9062_IRQ_GPI4] = {
0149         .reg_offset = DA9062_REG_EVENT_C_OFFSET,
0150         .mask = DA9062AA_M_GPI4_MASK,
0151     },
0152 };
0153 
0154 static struct regmap_irq_chip da9062_irq_chip = {
0155     .name = "da9062-irq",
0156     .irqs = da9062_irqs,
0157     .num_irqs = DA9062_NUM_IRQ,
0158     .num_regs = 3,
0159     .status_base = DA9062AA_EVENT_A,
0160     .mask_base = DA9062AA_IRQ_MASK_A,
0161     .ack_base = DA9062AA_EVENT_A,
0162 };
0163 
0164 static const struct resource da9061_core_resources[] = {
0165     DEFINE_RES_IRQ_NAMED(DA9061_IRQ_VDD_WARN, "VDD_WARN"),
0166 };
0167 
0168 static const struct resource da9061_regulators_resources[] = {
0169     DEFINE_RES_IRQ_NAMED(DA9061_IRQ_LDO_LIM, "LDO_LIM"),
0170 };
0171 
0172 static const struct resource da9061_thermal_resources[] = {
0173     DEFINE_RES_IRQ_NAMED(DA9061_IRQ_TEMP, "THERMAL"),
0174 };
0175 
0176 static const struct resource da9061_wdt_resources[] = {
0177     DEFINE_RES_IRQ_NAMED(DA9061_IRQ_WDG_WARN, "WD_WARN"),
0178 };
0179 
0180 static const struct resource da9061_onkey_resources[] = {
0181     DEFINE_RES_IRQ_NAMED(DA9061_IRQ_ONKEY, "ONKEY"),
0182 };
0183 
0184 static const struct mfd_cell da9061_devs[] = {
0185     {
0186         .name       = "da9061-core",
0187         .num_resources  = ARRAY_SIZE(da9061_core_resources),
0188         .resources  = da9061_core_resources,
0189     },
0190     {
0191         .name       = "da9062-regulators",
0192         .num_resources  = ARRAY_SIZE(da9061_regulators_resources),
0193         .resources  = da9061_regulators_resources,
0194     },
0195     {
0196         .name       = "da9061-watchdog",
0197         .num_resources  = ARRAY_SIZE(da9061_wdt_resources),
0198         .resources  = da9061_wdt_resources,
0199         .of_compatible  = "dlg,da9061-watchdog",
0200     },
0201     {
0202         .name       = "da9061-thermal",
0203         .num_resources  = ARRAY_SIZE(da9061_thermal_resources),
0204         .resources  = da9061_thermal_resources,
0205         .of_compatible  = "dlg,da9061-thermal",
0206     },
0207     {
0208         .name       = "da9061-onkey",
0209         .num_resources  = ARRAY_SIZE(da9061_onkey_resources),
0210         .resources  = da9061_onkey_resources,
0211         .of_compatible = "dlg,da9061-onkey",
0212     },
0213 };
0214 
0215 static const struct resource da9062_core_resources[] = {
0216     DEFINE_RES_NAMED(DA9062_IRQ_VDD_WARN, 1, "VDD_WARN", IORESOURCE_IRQ),
0217 };
0218 
0219 static const struct resource da9062_regulators_resources[] = {
0220     DEFINE_RES_NAMED(DA9062_IRQ_LDO_LIM, 1, "LDO_LIM", IORESOURCE_IRQ),
0221 };
0222 
0223 static const struct resource da9062_thermal_resources[] = {
0224     DEFINE_RES_NAMED(DA9062_IRQ_TEMP, 1, "THERMAL", IORESOURCE_IRQ),
0225 };
0226 
0227 static const struct resource da9062_wdt_resources[] = {
0228     DEFINE_RES_NAMED(DA9062_IRQ_WDG_WARN, 1, "WD_WARN", IORESOURCE_IRQ),
0229 };
0230 
0231 static const struct resource da9062_rtc_resources[] = {
0232     DEFINE_RES_NAMED(DA9062_IRQ_ALARM, 1, "ALARM", IORESOURCE_IRQ),
0233     DEFINE_RES_NAMED(DA9062_IRQ_TICK, 1, "TICK", IORESOURCE_IRQ),
0234 };
0235 
0236 static const struct resource da9062_onkey_resources[] = {
0237     DEFINE_RES_NAMED(DA9062_IRQ_ONKEY, 1, "ONKEY", IORESOURCE_IRQ),
0238 };
0239 
0240 static const struct resource da9062_gpio_resources[] = {
0241     DEFINE_RES_NAMED(DA9062_IRQ_GPI0, 1, "GPI0", IORESOURCE_IRQ),
0242     DEFINE_RES_NAMED(DA9062_IRQ_GPI1, 1, "GPI1", IORESOURCE_IRQ),
0243     DEFINE_RES_NAMED(DA9062_IRQ_GPI2, 1, "GPI2", IORESOURCE_IRQ),
0244     DEFINE_RES_NAMED(DA9062_IRQ_GPI3, 1, "GPI3", IORESOURCE_IRQ),
0245     DEFINE_RES_NAMED(DA9062_IRQ_GPI4, 1, "GPI4", IORESOURCE_IRQ),
0246 };
0247 
0248 static const struct mfd_cell da9062_devs[] = {
0249     {
0250         .name       = "da9062-core",
0251         .num_resources  = ARRAY_SIZE(da9062_core_resources),
0252         .resources  = da9062_core_resources,
0253     },
0254     {
0255         .name       = "da9062-regulators",
0256         .num_resources  = ARRAY_SIZE(da9062_regulators_resources),
0257         .resources  = da9062_regulators_resources,
0258     },
0259     {
0260         .name       = "da9062-watchdog",
0261         .num_resources  = ARRAY_SIZE(da9062_wdt_resources),
0262         .resources  = da9062_wdt_resources,
0263         .of_compatible  = "dlg,da9062-watchdog",
0264     },
0265     {
0266         .name       = "da9062-thermal",
0267         .num_resources  = ARRAY_SIZE(da9062_thermal_resources),
0268         .resources  = da9062_thermal_resources,
0269         .of_compatible  = "dlg,da9062-thermal",
0270     },
0271     {
0272         .name       = "da9062-rtc",
0273         .num_resources  = ARRAY_SIZE(da9062_rtc_resources),
0274         .resources  = da9062_rtc_resources,
0275         .of_compatible  = "dlg,da9062-rtc",
0276     },
0277     {
0278         .name       = "da9062-onkey",
0279         .num_resources  = ARRAY_SIZE(da9062_onkey_resources),
0280         .resources  = da9062_onkey_resources,
0281         .of_compatible  = "dlg,da9062-onkey",
0282     },
0283     {
0284         .name       = "da9062-gpio",
0285         .num_resources  = ARRAY_SIZE(da9062_gpio_resources),
0286         .resources  = da9062_gpio_resources,
0287         .of_compatible  = "dlg,da9062-gpio",
0288     },
0289 };
0290 
0291 static int da9062_clear_fault_log(struct da9062 *chip)
0292 {
0293     int ret;
0294     int fault_log;
0295 
0296     ret = regmap_read(chip->regmap, DA9062AA_FAULT_LOG, &fault_log);
0297     if (ret < 0)
0298         return ret;
0299 
0300     if (fault_log) {
0301         if (fault_log & DA9062AA_TWD_ERROR_MASK)
0302             dev_dbg(chip->dev, "Fault log entry detected: TWD_ERROR\n");
0303         if (fault_log & DA9062AA_POR_MASK)
0304             dev_dbg(chip->dev, "Fault log entry detected: POR\n");
0305         if (fault_log & DA9062AA_VDD_FAULT_MASK)
0306             dev_dbg(chip->dev, "Fault log entry detected: VDD_FAULT\n");
0307         if (fault_log & DA9062AA_VDD_START_MASK)
0308             dev_dbg(chip->dev, "Fault log entry detected: VDD_START\n");
0309         if (fault_log & DA9062AA_TEMP_CRIT_MASK)
0310             dev_dbg(chip->dev, "Fault log entry detected: TEMP_CRIT\n");
0311         if (fault_log & DA9062AA_KEY_RESET_MASK)
0312             dev_dbg(chip->dev, "Fault log entry detected: KEY_RESET\n");
0313         if (fault_log & DA9062AA_NSHUTDOWN_MASK)
0314             dev_dbg(chip->dev, "Fault log entry detected: NSHUTDOWN\n");
0315         if (fault_log & DA9062AA_WAIT_SHUT_MASK)
0316             dev_dbg(chip->dev, "Fault log entry detected: WAIT_SHUT\n");
0317 
0318         ret = regmap_write(chip->regmap, DA9062AA_FAULT_LOG,
0319                    fault_log);
0320     }
0321 
0322     return ret;
0323 }
0324 
0325 static int da9062_get_device_type(struct da9062 *chip)
0326 {
0327     int device_id, variant_id, variant_mrc, variant_vrc;
0328     char *type;
0329     int ret;
0330 
0331     ret = regmap_read(chip->regmap, DA9062AA_DEVICE_ID, &device_id);
0332     if (ret < 0) {
0333         dev_err(chip->dev, "Cannot read chip ID.\n");
0334         return -EIO;
0335     }
0336     if (device_id != DA9062_PMIC_DEVICE_ID) {
0337         dev_err(chip->dev, "Invalid device ID: 0x%02x\n", device_id);
0338         return -ENODEV;
0339     }
0340 
0341     ret = regmap_read(chip->regmap, DA9062AA_VARIANT_ID, &variant_id);
0342     if (ret < 0) {
0343         dev_err(chip->dev, "Cannot read chip variant id.\n");
0344         return -EIO;
0345     }
0346 
0347     variant_vrc = (variant_id & DA9062AA_VRC_MASK) >> DA9062AA_VRC_SHIFT;
0348 
0349     switch (variant_vrc) {
0350     case DA9062_PMIC_VARIANT_VRC_DA9061:
0351         type = "DA9061";
0352         break;
0353     case DA9062_PMIC_VARIANT_VRC_DA9062:
0354         type = "DA9062";
0355         break;
0356     default:
0357         type = "Unknown";
0358         break;
0359     }
0360 
0361     dev_info(chip->dev,
0362          "Device detected (device-ID: 0x%02X, var-ID: 0x%02X, %s)\n",
0363          device_id, variant_id, type);
0364 
0365     variant_mrc = (variant_id & DA9062AA_MRC_MASK) >> DA9062AA_MRC_SHIFT;
0366 
0367     if (variant_mrc < DA9062_PMIC_VARIANT_MRC_AA) {
0368         dev_err(chip->dev,
0369             "Cannot support variant MRC: 0x%02X\n", variant_mrc);
0370         return -ENODEV;
0371     }
0372 
0373     return ret;
0374 }
0375 
0376 static u32 da9062_configure_irq_type(struct da9062 *chip, int irq, u32 *trigger)
0377 {
0378     u32 irq_type = 0;
0379     struct irq_data *irq_data = irq_get_irq_data(irq);
0380 
0381     if (!irq_data) {
0382         dev_err(chip->dev, "Invalid IRQ: %d\n", irq);
0383         return -EINVAL;
0384     }
0385     *trigger = irqd_get_trigger_type(irq_data);
0386 
0387     switch (*trigger) {
0388     case IRQ_TYPE_LEVEL_HIGH:
0389         irq_type = DA9062_IRQ_HIGH;
0390         break;
0391     case IRQ_TYPE_LEVEL_LOW:
0392         irq_type = DA9062_IRQ_LOW;
0393         break;
0394     default:
0395         dev_warn(chip->dev, "Unsupported IRQ type: %d\n", *trigger);
0396         return -EINVAL;
0397     }
0398     return regmap_update_bits(chip->regmap, DA9062AA_CONFIG_A,
0399             DA9062AA_IRQ_TYPE_MASK,
0400             irq_type << DA9062AA_IRQ_TYPE_SHIFT);
0401 }
0402 
0403 static const struct regmap_range da9061_aa_readable_ranges[] = {
0404     regmap_reg_range(DA9062AA_PAGE_CON, DA9062AA_STATUS_B),
0405     regmap_reg_range(DA9062AA_STATUS_D, DA9062AA_EVENT_C),
0406     regmap_reg_range(DA9062AA_IRQ_MASK_A, DA9062AA_IRQ_MASK_C),
0407     regmap_reg_range(DA9062AA_CONTROL_A, DA9062AA_GPIO_4),
0408     regmap_reg_range(DA9062AA_GPIO_WKUP_MODE, DA9062AA_GPIO_OUT3_4),
0409     regmap_reg_range(DA9062AA_BUCK1_CONT, DA9062AA_BUCK4_CONT),
0410     regmap_reg_range(DA9062AA_BUCK3_CONT, DA9062AA_BUCK3_CONT),
0411     regmap_reg_range(DA9062AA_LDO1_CONT, DA9062AA_LDO4_CONT),
0412     regmap_reg_range(DA9062AA_DVC_1, DA9062AA_DVC_1),
0413     regmap_reg_range(DA9062AA_SEQ, DA9062AA_ID_4_3),
0414     regmap_reg_range(DA9062AA_ID_12_11, DA9062AA_ID_16_15),
0415     regmap_reg_range(DA9062AA_ID_22_21, DA9062AA_ID_32_31),
0416     regmap_reg_range(DA9062AA_SEQ_A, DA9062AA_WAIT),
0417     regmap_reg_range(DA9062AA_RESET, DA9062AA_BUCK_ILIM_C),
0418     regmap_reg_range(DA9062AA_BUCK1_CFG, DA9062AA_BUCK3_CFG),
0419     regmap_reg_range(DA9062AA_VBUCK1_A, DA9062AA_VBUCK4_A),
0420     regmap_reg_range(DA9062AA_VBUCK3_A, DA9062AA_VBUCK3_A),
0421     regmap_reg_range(DA9062AA_VLDO1_A, DA9062AA_VLDO4_A),
0422     regmap_reg_range(DA9062AA_CONFIG_A, DA9062AA_CONFIG_A),
0423     regmap_reg_range(DA9062AA_VBUCK1_B, DA9062AA_VBUCK4_B),
0424     regmap_reg_range(DA9062AA_VBUCK3_B, DA9062AA_VBUCK3_B),
0425     regmap_reg_range(DA9062AA_VLDO1_B, DA9062AA_VLDO4_B),
0426     regmap_reg_range(DA9062AA_INTERFACE, DA9062AA_CONFIG_E),
0427     regmap_reg_range(DA9062AA_CONFIG_G, DA9062AA_CONFIG_K),
0428     regmap_reg_range(DA9062AA_CONFIG_M, DA9062AA_CONFIG_M),
0429     regmap_reg_range(DA9062AA_GP_ID_0, DA9062AA_GP_ID_19),
0430     regmap_reg_range(DA9062AA_DEVICE_ID, DA9062AA_CONFIG_ID),
0431 };
0432 
0433 static const struct regmap_range da9061_aa_writeable_ranges[] = {
0434     regmap_reg_range(DA9062AA_PAGE_CON, DA9062AA_PAGE_CON),
0435     regmap_reg_range(DA9062AA_FAULT_LOG, DA9062AA_EVENT_C),
0436     regmap_reg_range(DA9062AA_IRQ_MASK_A, DA9062AA_IRQ_MASK_C),
0437     regmap_reg_range(DA9062AA_CONTROL_A, DA9062AA_GPIO_4),
0438     regmap_reg_range(DA9062AA_GPIO_WKUP_MODE, DA9062AA_GPIO_OUT3_4),
0439     regmap_reg_range(DA9062AA_BUCK1_CONT, DA9062AA_BUCK4_CONT),
0440     regmap_reg_range(DA9062AA_BUCK3_CONT, DA9062AA_BUCK3_CONT),
0441     regmap_reg_range(DA9062AA_LDO1_CONT, DA9062AA_LDO4_CONT),
0442     regmap_reg_range(DA9062AA_DVC_1, DA9062AA_DVC_1),
0443     regmap_reg_range(DA9062AA_SEQ, DA9062AA_ID_4_3),
0444     regmap_reg_range(DA9062AA_ID_12_11, DA9062AA_ID_16_15),
0445     regmap_reg_range(DA9062AA_ID_22_21, DA9062AA_ID_32_31),
0446     regmap_reg_range(DA9062AA_SEQ_A, DA9062AA_WAIT),
0447     regmap_reg_range(DA9062AA_RESET, DA9062AA_BUCK_ILIM_C),
0448     regmap_reg_range(DA9062AA_BUCK1_CFG, DA9062AA_BUCK3_CFG),
0449     regmap_reg_range(DA9062AA_VBUCK1_A, DA9062AA_VBUCK4_A),
0450     regmap_reg_range(DA9062AA_VBUCK3_A, DA9062AA_VBUCK3_A),
0451     regmap_reg_range(DA9062AA_VLDO1_A, DA9062AA_VLDO4_A),
0452     regmap_reg_range(DA9062AA_CONFIG_A, DA9062AA_CONFIG_A),
0453     regmap_reg_range(DA9062AA_VBUCK1_B, DA9062AA_VBUCK4_B),
0454     regmap_reg_range(DA9062AA_VBUCK3_B, DA9062AA_VBUCK3_B),
0455     regmap_reg_range(DA9062AA_VLDO1_B, DA9062AA_VLDO4_B),
0456     regmap_reg_range(DA9062AA_GP_ID_0, DA9062AA_GP_ID_19),
0457 };
0458 
0459 static const struct regmap_range da9061_aa_volatile_ranges[] = {
0460     regmap_reg_range(DA9062AA_PAGE_CON, DA9062AA_STATUS_B),
0461     regmap_reg_range(DA9062AA_STATUS_D, DA9062AA_EVENT_C),
0462     regmap_reg_range(DA9062AA_CONTROL_A, DA9062AA_CONTROL_B),
0463     regmap_reg_range(DA9062AA_CONTROL_E, DA9062AA_CONTROL_F),
0464     regmap_reg_range(DA9062AA_BUCK1_CONT, DA9062AA_BUCK4_CONT),
0465     regmap_reg_range(DA9062AA_BUCK3_CONT, DA9062AA_BUCK3_CONT),
0466     regmap_reg_range(DA9062AA_LDO1_CONT, DA9062AA_LDO4_CONT),
0467     regmap_reg_range(DA9062AA_DVC_1, DA9062AA_DVC_1),
0468     regmap_reg_range(DA9062AA_SEQ, DA9062AA_SEQ),
0469 };
0470 
0471 static const struct regmap_access_table da9061_aa_readable_table = {
0472     .yes_ranges = da9061_aa_readable_ranges,
0473     .n_yes_ranges = ARRAY_SIZE(da9061_aa_readable_ranges),
0474 };
0475 
0476 static const struct regmap_access_table da9061_aa_writeable_table = {
0477     .yes_ranges = da9061_aa_writeable_ranges,
0478     .n_yes_ranges = ARRAY_SIZE(da9061_aa_writeable_ranges),
0479 };
0480 
0481 static const struct regmap_access_table da9061_aa_volatile_table = {
0482     .yes_ranges = da9061_aa_volatile_ranges,
0483     .n_yes_ranges = ARRAY_SIZE(da9061_aa_volatile_ranges),
0484 };
0485 
0486 static const struct regmap_range_cfg da9061_range_cfg[] = {
0487     {
0488         .range_min = DA9062AA_PAGE_CON,
0489         .range_max = DA9062AA_CONFIG_ID,
0490         .selector_reg = DA9062AA_PAGE_CON,
0491         .selector_mask = 1 << DA9062_I2C_PAGE_SEL_SHIFT,
0492         .selector_shift = DA9062_I2C_PAGE_SEL_SHIFT,
0493         .window_start = 0,
0494         .window_len = 256,
0495     }
0496 };
0497 
0498 static struct regmap_config da9061_regmap_config = {
0499     .reg_bits = 8,
0500     .val_bits = 8,
0501     .ranges = da9061_range_cfg,
0502     .num_ranges = ARRAY_SIZE(da9061_range_cfg),
0503     .max_register = DA9062AA_CONFIG_ID,
0504     .cache_type = REGCACHE_RBTREE,
0505     .rd_table = &da9061_aa_readable_table,
0506     .wr_table = &da9061_aa_writeable_table,
0507     .volatile_table = &da9061_aa_volatile_table,
0508 };
0509 
0510 static const struct regmap_range da9062_aa_readable_ranges[] = {
0511     regmap_reg_range(DA9062AA_PAGE_CON, DA9062AA_STATUS_B),
0512     regmap_reg_range(DA9062AA_STATUS_D, DA9062AA_EVENT_C),
0513     regmap_reg_range(DA9062AA_IRQ_MASK_A, DA9062AA_IRQ_MASK_C),
0514     regmap_reg_range(DA9062AA_CONTROL_A, DA9062AA_GPIO_4),
0515     regmap_reg_range(DA9062AA_GPIO_WKUP_MODE, DA9062AA_BUCK4_CONT),
0516     regmap_reg_range(DA9062AA_BUCK3_CONT, DA9062AA_BUCK3_CONT),
0517     regmap_reg_range(DA9062AA_LDO1_CONT, DA9062AA_LDO4_CONT),
0518     regmap_reg_range(DA9062AA_DVC_1, DA9062AA_DVC_1),
0519     regmap_reg_range(DA9062AA_COUNT_S, DA9062AA_SECOND_D),
0520     regmap_reg_range(DA9062AA_SEQ, DA9062AA_ID_4_3),
0521     regmap_reg_range(DA9062AA_ID_12_11, DA9062AA_ID_16_15),
0522     regmap_reg_range(DA9062AA_ID_22_21, DA9062AA_ID_32_31),
0523     regmap_reg_range(DA9062AA_SEQ_A, DA9062AA_BUCK3_CFG),
0524     regmap_reg_range(DA9062AA_VBUCK2_A, DA9062AA_VBUCK4_A),
0525     regmap_reg_range(DA9062AA_VBUCK3_A, DA9062AA_VBUCK3_A),
0526     regmap_reg_range(DA9062AA_VLDO1_A, DA9062AA_VLDO4_A),
0527     regmap_reg_range(DA9062AA_VBUCK2_B, DA9062AA_VBUCK4_B),
0528     regmap_reg_range(DA9062AA_VBUCK3_B, DA9062AA_VBUCK3_B),
0529     regmap_reg_range(DA9062AA_VLDO1_B, DA9062AA_VLDO4_B),
0530     regmap_reg_range(DA9062AA_BBAT_CONT, DA9062AA_BBAT_CONT),
0531     regmap_reg_range(DA9062AA_INTERFACE, DA9062AA_CONFIG_E),
0532     regmap_reg_range(DA9062AA_CONFIG_G, DA9062AA_CONFIG_K),
0533     regmap_reg_range(DA9062AA_CONFIG_M, DA9062AA_CONFIG_M),
0534     regmap_reg_range(DA9062AA_TRIM_CLDR, DA9062AA_GP_ID_19),
0535     regmap_reg_range(DA9062AA_DEVICE_ID, DA9062AA_CONFIG_ID),
0536 };
0537 
0538 static const struct regmap_range da9062_aa_writeable_ranges[] = {
0539     regmap_reg_range(DA9062AA_PAGE_CON, DA9062AA_PAGE_CON),
0540     regmap_reg_range(DA9062AA_FAULT_LOG, DA9062AA_EVENT_C),
0541     regmap_reg_range(DA9062AA_IRQ_MASK_A, DA9062AA_IRQ_MASK_C),
0542     regmap_reg_range(DA9062AA_CONTROL_A, DA9062AA_GPIO_4),
0543     regmap_reg_range(DA9062AA_GPIO_WKUP_MODE, DA9062AA_BUCK4_CONT),
0544     regmap_reg_range(DA9062AA_BUCK3_CONT, DA9062AA_BUCK3_CONT),
0545     regmap_reg_range(DA9062AA_LDO1_CONT, DA9062AA_LDO4_CONT),
0546     regmap_reg_range(DA9062AA_DVC_1, DA9062AA_DVC_1),
0547     regmap_reg_range(DA9062AA_COUNT_S, DA9062AA_ALARM_Y),
0548     regmap_reg_range(DA9062AA_SEQ, DA9062AA_ID_4_3),
0549     regmap_reg_range(DA9062AA_ID_12_11, DA9062AA_ID_16_15),
0550     regmap_reg_range(DA9062AA_ID_22_21, DA9062AA_ID_32_31),
0551     regmap_reg_range(DA9062AA_SEQ_A, DA9062AA_BUCK3_CFG),
0552     regmap_reg_range(DA9062AA_VBUCK2_A, DA9062AA_VBUCK4_A),
0553     regmap_reg_range(DA9062AA_VBUCK3_A, DA9062AA_VBUCK3_A),
0554     regmap_reg_range(DA9062AA_VLDO1_A, DA9062AA_VLDO4_A),
0555     regmap_reg_range(DA9062AA_VBUCK2_B, DA9062AA_VBUCK4_B),
0556     regmap_reg_range(DA9062AA_VBUCK3_B, DA9062AA_VBUCK3_B),
0557     regmap_reg_range(DA9062AA_VLDO1_B, DA9062AA_VLDO4_B),
0558     regmap_reg_range(DA9062AA_BBAT_CONT, DA9062AA_BBAT_CONT),
0559     regmap_reg_range(DA9062AA_CONFIG_J, DA9062AA_CONFIG_J),
0560     regmap_reg_range(DA9062AA_GP_ID_0, DA9062AA_GP_ID_19),
0561 };
0562 
0563 static const struct regmap_range da9062_aa_volatile_ranges[] = {
0564     regmap_reg_range(DA9062AA_PAGE_CON, DA9062AA_STATUS_B),
0565     regmap_reg_range(DA9062AA_STATUS_D, DA9062AA_EVENT_C),
0566     regmap_reg_range(DA9062AA_CONTROL_A, DA9062AA_CONTROL_B),
0567     regmap_reg_range(DA9062AA_CONTROL_E, DA9062AA_CONTROL_F),
0568     regmap_reg_range(DA9062AA_BUCK2_CONT, DA9062AA_BUCK4_CONT),
0569     regmap_reg_range(DA9062AA_BUCK3_CONT, DA9062AA_BUCK3_CONT),
0570     regmap_reg_range(DA9062AA_LDO1_CONT, DA9062AA_LDO4_CONT),
0571     regmap_reg_range(DA9062AA_DVC_1, DA9062AA_DVC_1),
0572     regmap_reg_range(DA9062AA_COUNT_S, DA9062AA_SECOND_D),
0573     regmap_reg_range(DA9062AA_SEQ, DA9062AA_SEQ),
0574     regmap_reg_range(DA9062AA_EN_32K, DA9062AA_EN_32K),
0575 };
0576 
0577 static const struct regmap_access_table da9062_aa_readable_table = {
0578     .yes_ranges = da9062_aa_readable_ranges,
0579     .n_yes_ranges = ARRAY_SIZE(da9062_aa_readable_ranges),
0580 };
0581 
0582 static const struct regmap_access_table da9062_aa_writeable_table = {
0583     .yes_ranges = da9062_aa_writeable_ranges,
0584     .n_yes_ranges = ARRAY_SIZE(da9062_aa_writeable_ranges),
0585 };
0586 
0587 static const struct regmap_access_table da9062_aa_volatile_table = {
0588     .yes_ranges = da9062_aa_volatile_ranges,
0589     .n_yes_ranges = ARRAY_SIZE(da9062_aa_volatile_ranges),
0590 };
0591 
0592 static const struct regmap_range_cfg da9062_range_cfg[] = {
0593     {
0594         .range_min = DA9062AA_PAGE_CON,
0595         .range_max = DA9062AA_CONFIG_ID,
0596         .selector_reg = DA9062AA_PAGE_CON,
0597         .selector_mask = 1 << DA9062_I2C_PAGE_SEL_SHIFT,
0598         .selector_shift = DA9062_I2C_PAGE_SEL_SHIFT,
0599         .window_start = 0,
0600         .window_len = 256,
0601     }
0602 };
0603 
0604 static struct regmap_config da9062_regmap_config = {
0605     .reg_bits = 8,
0606     .val_bits = 8,
0607     .ranges = da9062_range_cfg,
0608     .num_ranges = ARRAY_SIZE(da9062_range_cfg),
0609     .max_register = DA9062AA_CONFIG_ID,
0610     .cache_type = REGCACHE_RBTREE,
0611     .rd_table = &da9062_aa_readable_table,
0612     .wr_table = &da9062_aa_writeable_table,
0613     .volatile_table = &da9062_aa_volatile_table,
0614 };
0615 
0616 static const struct of_device_id da9062_dt_ids[] = {
0617     { .compatible = "dlg,da9061", .data = (void *)COMPAT_TYPE_DA9061, },
0618     { .compatible = "dlg,da9062", .data = (void *)COMPAT_TYPE_DA9062, },
0619     { }
0620 };
0621 MODULE_DEVICE_TABLE(of, da9062_dt_ids);
0622 
0623 static int da9062_i2c_probe(struct i2c_client *i2c,
0624     const struct i2c_device_id *id)
0625 {
0626     struct da9062 *chip;
0627     unsigned int irq_base;
0628     const struct mfd_cell *cell;
0629     const struct regmap_irq_chip *irq_chip;
0630     const struct regmap_config *config;
0631     int cell_num;
0632     u32 trigger_type = 0;
0633     int ret;
0634 
0635     chip = devm_kzalloc(&i2c->dev, sizeof(*chip), GFP_KERNEL);
0636     if (!chip)
0637         return -ENOMEM;
0638 
0639     if (i2c->dev.of_node)
0640         chip->chip_type = (uintptr_t)of_device_get_match_data(&i2c->dev);
0641     else
0642         chip->chip_type = id->driver_data;
0643 
0644     i2c_set_clientdata(i2c, chip);
0645     chip->dev = &i2c->dev;
0646 
0647     if (!i2c->irq) {
0648         dev_err(chip->dev, "No IRQ configured\n");
0649         return -EINVAL;
0650     }
0651 
0652     switch (chip->chip_type) {
0653     case COMPAT_TYPE_DA9061:
0654         cell = da9061_devs;
0655         cell_num = ARRAY_SIZE(da9061_devs);
0656         irq_chip = &da9061_irq_chip;
0657         config = &da9061_regmap_config;
0658         break;
0659     case COMPAT_TYPE_DA9062:
0660         cell = da9062_devs;
0661         cell_num = ARRAY_SIZE(da9062_devs);
0662         irq_chip = &da9062_irq_chip;
0663         config = &da9062_regmap_config;
0664         break;
0665     default:
0666         dev_err(chip->dev, "Unrecognised chip type\n");
0667         return -ENODEV;
0668     }
0669 
0670     chip->regmap = devm_regmap_init_i2c(i2c, config);
0671     if (IS_ERR(chip->regmap)) {
0672         ret = PTR_ERR(chip->regmap);
0673         dev_err(chip->dev, "Failed to allocate register map: %d\n",
0674             ret);
0675         return ret;
0676     }
0677 
0678     /* If SMBus is not available and only I2C is possible, enter I2C mode */
0679     if (i2c_check_functionality(i2c->adapter, I2C_FUNC_I2C)) {
0680         dev_info(chip->dev, "Entering I2C mode!\n");
0681         ret = regmap_clear_bits(chip->regmap, DA9062AA_CONFIG_J,
0682                     DA9062AA_TWOWIRE_TO_MASK);
0683         if (ret < 0) {
0684             dev_err(chip->dev, "Failed to set Two-Wire Bus Mode.\n");
0685             return ret;
0686         }
0687     }
0688 
0689     ret = da9062_clear_fault_log(chip);
0690     if (ret < 0)
0691         dev_warn(chip->dev, "Cannot clear fault log\n");
0692 
0693     ret = da9062_get_device_type(chip);
0694     if (ret)
0695         return ret;
0696 
0697     ret = da9062_configure_irq_type(chip, i2c->irq, &trigger_type);
0698     if (ret < 0) {
0699         dev_err(chip->dev, "Failed to configure IRQ type\n");
0700         return ret;
0701     }
0702 
0703     ret = regmap_add_irq_chip(chip->regmap, i2c->irq,
0704             trigger_type | IRQF_SHARED | IRQF_ONESHOT,
0705             -1, irq_chip, &chip->regmap_irq);
0706     if (ret) {
0707         dev_err(chip->dev, "Failed to request IRQ %d: %d\n",
0708             i2c->irq, ret);
0709         return ret;
0710     }
0711 
0712     irq_base = regmap_irq_chip_get_base(chip->regmap_irq);
0713 
0714     ret = mfd_add_devices(chip->dev, PLATFORM_DEVID_NONE, cell,
0715                   cell_num, NULL, irq_base,
0716                   NULL);
0717     if (ret) {
0718         dev_err(chip->dev, "Cannot register child devices\n");
0719         regmap_del_irq_chip(i2c->irq, chip->regmap_irq);
0720         return ret;
0721     }
0722 
0723     return ret;
0724 }
0725 
0726 static int da9062_i2c_remove(struct i2c_client *i2c)
0727 {
0728     struct da9062 *chip = i2c_get_clientdata(i2c);
0729 
0730     mfd_remove_devices(chip->dev);
0731     regmap_del_irq_chip(i2c->irq, chip->regmap_irq);
0732 
0733     return 0;
0734 }
0735 
0736 static const struct i2c_device_id da9062_i2c_id[] = {
0737     { "da9061", COMPAT_TYPE_DA9061 },
0738     { "da9062", COMPAT_TYPE_DA9062 },
0739     { },
0740 };
0741 MODULE_DEVICE_TABLE(i2c, da9062_i2c_id);
0742 
0743 static struct i2c_driver da9062_i2c_driver = {
0744     .driver = {
0745         .name = "da9062",
0746         .of_match_table = da9062_dt_ids,
0747     },
0748     .probe    = da9062_i2c_probe,
0749     .remove   = da9062_i2c_remove,
0750     .id_table = da9062_i2c_id,
0751 };
0752 
0753 module_i2c_driver(da9062_i2c_driver);
0754 
0755 MODULE_DESCRIPTION("Core device driver for Dialog DA9061 and DA9062");
0756 MODULE_AUTHOR("Steve Twiss <stwiss.opensource@diasemi.com>");
0757 MODULE_LICENSE("GPL");