1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Core, IRQ and I2C device driver for DA9061 and DA9062 PMICs 4 * Copyright (C) 2015-2017 Dialog Semiconductor 5 */ 6 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> 19 20 #define DA9062_REG_EVENT_A_OFFSET 0 21 #define DA9062_REG_EVENT_B_OFFSET 1 22 #define DA9062_REG_EVENT_C_OFFSET 2 23 24 static struct regmap_irq da9061_irqs[] = { 25 /* EVENT A */ 26 [DA9061_IRQ_ONKEY] = { 27 .reg_offset = DA9062_REG_EVENT_A_OFFSET, 28 .mask = DA9062AA_M_NONKEY_MASK, 29 }, 30 [DA9061_IRQ_WDG_WARN] = { 31 .reg_offset = DA9062_REG_EVENT_A_OFFSET, 32 .mask = DA9062AA_M_WDG_WARN_MASK, 33 }, 34 [DA9061_IRQ_SEQ_RDY] = { 35 .reg_offset = DA9062_REG_EVENT_A_OFFSET, 36 .mask = DA9062AA_M_SEQ_RDY_MASK, 37 }, 38 /* EVENT B */ 39 [DA9061_IRQ_TEMP] = { 40 .reg_offset = DA9062_REG_EVENT_B_OFFSET, 41 .mask = DA9062AA_M_TEMP_MASK, 42 }, 43 [DA9061_IRQ_LDO_LIM] = { 44 .reg_offset = DA9062_REG_EVENT_B_OFFSET, 45 .mask = DA9062AA_M_LDO_LIM_MASK, 46 }, 47 [DA9061_IRQ_DVC_RDY] = { 48 .reg_offset = DA9062_REG_EVENT_B_OFFSET, 49 .mask = DA9062AA_M_DVC_RDY_MASK, 50 }, 51 [DA9061_IRQ_VDD_WARN] = { 52 .reg_offset = DA9062_REG_EVENT_B_OFFSET, 53 .mask = DA9062AA_M_VDD_WARN_MASK, 54 }, 55 /* EVENT C */ 56 [DA9061_IRQ_GPI0] = { 57 .reg_offset = DA9062_REG_EVENT_C_OFFSET, 58 .mask = DA9062AA_M_GPI0_MASK, 59 }, 60 [DA9061_IRQ_GPI1] = { 61 .reg_offset = DA9062_REG_EVENT_C_OFFSET, 62 .mask = DA9062AA_M_GPI1_MASK, 63 }, 64 [DA9061_IRQ_GPI2] = { 65 .reg_offset = DA9062_REG_EVENT_C_OFFSET, 66 .mask = DA9062AA_M_GPI2_MASK, 67 }, 68 [DA9061_IRQ_GPI3] = { 69 .reg_offset = DA9062_REG_EVENT_C_OFFSET, 70 .mask = DA9062AA_M_GPI3_MASK, 71 }, 72 [DA9061_IRQ_GPI4] = { 73 .reg_offset = DA9062_REG_EVENT_C_OFFSET, 74 .mask = DA9062AA_M_GPI4_MASK, 75 }, 76 }; 77 78 static struct regmap_irq_chip da9061_irq_chip = { 79 .name = "da9061-irq", 80 .irqs = da9061_irqs, 81 .num_irqs = DA9061_NUM_IRQ, 82 .num_regs = 3, 83 .status_base = DA9062AA_EVENT_A, 84 .mask_base = DA9062AA_IRQ_MASK_A, 85 .ack_base = DA9062AA_EVENT_A, 86 }; 87 88 static struct regmap_irq da9062_irqs[] = { 89 /* EVENT A */ 90 [DA9062_IRQ_ONKEY] = { 91 .reg_offset = DA9062_REG_EVENT_A_OFFSET, 92 .mask = DA9062AA_M_NONKEY_MASK, 93 }, 94 [DA9062_IRQ_ALARM] = { 95 .reg_offset = DA9062_REG_EVENT_A_OFFSET, 96 .mask = DA9062AA_M_ALARM_MASK, 97 }, 98 [DA9062_IRQ_TICK] = { 99 .reg_offset = DA9062_REG_EVENT_A_OFFSET, 100 .mask = DA9062AA_M_TICK_MASK, 101 }, 102 [DA9062_IRQ_WDG_WARN] = { 103 .reg_offset = DA9062_REG_EVENT_A_OFFSET, 104 .mask = DA9062AA_M_WDG_WARN_MASK, 105 }, 106 [DA9062_IRQ_SEQ_RDY] = { 107 .reg_offset = DA9062_REG_EVENT_A_OFFSET, 108 .mask = DA9062AA_M_SEQ_RDY_MASK, 109 }, 110 /* EVENT B */ 111 [DA9062_IRQ_TEMP] = { 112 .reg_offset = DA9062_REG_EVENT_B_OFFSET, 113 .mask = DA9062AA_M_TEMP_MASK, 114 }, 115 [DA9062_IRQ_LDO_LIM] = { 116 .reg_offset = DA9062_REG_EVENT_B_OFFSET, 117 .mask = DA9062AA_M_LDO_LIM_MASK, 118 }, 119 [DA9062_IRQ_DVC_RDY] = { 120 .reg_offset = DA9062_REG_EVENT_B_OFFSET, 121 .mask = DA9062AA_M_DVC_RDY_MASK, 122 }, 123 [DA9062_IRQ_VDD_WARN] = { 124 .reg_offset = DA9062_REG_EVENT_B_OFFSET, 125 .mask = DA9062AA_M_VDD_WARN_MASK, 126 }, 127 /* EVENT C */ 128 [DA9062_IRQ_GPI0] = { 129 .reg_offset = DA9062_REG_EVENT_C_OFFSET, 130 .mask = DA9062AA_M_GPI0_MASK, 131 }, 132 [DA9062_IRQ_GPI1] = { 133 .reg_offset = DA9062_REG_EVENT_C_OFFSET, 134 .mask = DA9062AA_M_GPI1_MASK, 135 }, 136 [DA9062_IRQ_GPI2] = { 137 .reg_offset = DA9062_REG_EVENT_C_OFFSET, 138 .mask = DA9062AA_M_GPI2_MASK, 139 }, 140 [DA9062_IRQ_GPI3] = { 141 .reg_offset = DA9062_REG_EVENT_C_OFFSET, 142 .mask = DA9062AA_M_GPI3_MASK, 143 }, 144 [DA9062_IRQ_GPI4] = { 145 .reg_offset = DA9062_REG_EVENT_C_OFFSET, 146 .mask = DA9062AA_M_GPI4_MASK, 147 }, 148 }; 149 150 static struct regmap_irq_chip da9062_irq_chip = { 151 .name = "da9062-irq", 152 .irqs = da9062_irqs, 153 .num_irqs = DA9062_NUM_IRQ, 154 .num_regs = 3, 155 .status_base = DA9062AA_EVENT_A, 156 .mask_base = DA9062AA_IRQ_MASK_A, 157 .ack_base = DA9062AA_EVENT_A, 158 }; 159 160 static struct resource da9061_core_resources[] = { 161 DEFINE_RES_IRQ_NAMED(DA9061_IRQ_VDD_WARN, "VDD_WARN"), 162 }; 163 164 static struct resource da9061_regulators_resources[] = { 165 DEFINE_RES_IRQ_NAMED(DA9061_IRQ_LDO_LIM, "LDO_LIM"), 166 }; 167 168 static struct resource da9061_thermal_resources[] = { 169 DEFINE_RES_IRQ_NAMED(DA9061_IRQ_TEMP, "THERMAL"), 170 }; 171 172 static struct resource da9061_wdt_resources[] = { 173 DEFINE_RES_IRQ_NAMED(DA9061_IRQ_WDG_WARN, "WD_WARN"), 174 }; 175 176 static struct resource da9061_onkey_resources[] = { 177 DEFINE_RES_IRQ_NAMED(DA9061_IRQ_ONKEY, "ONKEY"), 178 }; 179 180 static const struct mfd_cell da9061_devs[] = { 181 { 182 .name = "da9061-core", 183 .num_resources = ARRAY_SIZE(da9061_core_resources), 184 .resources = da9061_core_resources, 185 }, 186 { 187 .name = "da9062-regulators", 188 .num_resources = ARRAY_SIZE(da9061_regulators_resources), 189 .resources = da9061_regulators_resources, 190 }, 191 { 192 .name = "da9061-watchdog", 193 .num_resources = ARRAY_SIZE(da9061_wdt_resources), 194 .resources = da9061_wdt_resources, 195 .of_compatible = "dlg,da9061-watchdog", 196 }, 197 { 198 .name = "da9061-thermal", 199 .num_resources = ARRAY_SIZE(da9061_thermal_resources), 200 .resources = da9061_thermal_resources, 201 .of_compatible = "dlg,da9061-thermal", 202 }, 203 { 204 .name = "da9061-onkey", 205 .num_resources = ARRAY_SIZE(da9061_onkey_resources), 206 .resources = da9061_onkey_resources, 207 .of_compatible = "dlg,da9061-onkey", 208 }, 209 }; 210 211 static struct resource da9062_core_resources[] = { 212 DEFINE_RES_NAMED(DA9062_IRQ_VDD_WARN, 1, "VDD_WARN", IORESOURCE_IRQ), 213 }; 214 215 static struct resource da9062_regulators_resources[] = { 216 DEFINE_RES_NAMED(DA9062_IRQ_LDO_LIM, 1, "LDO_LIM", IORESOURCE_IRQ), 217 }; 218 219 static struct resource da9062_thermal_resources[] = { 220 DEFINE_RES_NAMED(DA9062_IRQ_TEMP, 1, "THERMAL", IORESOURCE_IRQ), 221 }; 222 223 static struct resource da9062_wdt_resources[] = { 224 DEFINE_RES_NAMED(DA9062_IRQ_WDG_WARN, 1, "WD_WARN", IORESOURCE_IRQ), 225 }; 226 227 static struct resource da9062_rtc_resources[] = { 228 DEFINE_RES_NAMED(DA9062_IRQ_ALARM, 1, "ALARM", IORESOURCE_IRQ), 229 DEFINE_RES_NAMED(DA9062_IRQ_TICK, 1, "TICK", IORESOURCE_IRQ), 230 }; 231 232 static struct resource da9062_onkey_resources[] = { 233 DEFINE_RES_NAMED(DA9062_IRQ_ONKEY, 1, "ONKEY", IORESOURCE_IRQ), 234 }; 235 236 static struct resource da9062_gpio_resources[] = { 237 DEFINE_RES_NAMED(DA9062_IRQ_GPI0, 1, "GPI0", IORESOURCE_IRQ), 238 DEFINE_RES_NAMED(DA9062_IRQ_GPI1, 1, "GPI1", IORESOURCE_IRQ), 239 DEFINE_RES_NAMED(DA9062_IRQ_GPI2, 1, "GPI2", IORESOURCE_IRQ), 240 DEFINE_RES_NAMED(DA9062_IRQ_GPI3, 1, "GPI3", IORESOURCE_IRQ), 241 DEFINE_RES_NAMED(DA9062_IRQ_GPI4, 1, "GPI4", IORESOURCE_IRQ), 242 }; 243 244 static const struct mfd_cell da9062_devs[] = { 245 { 246 .name = "da9062-core", 247 .num_resources = ARRAY_SIZE(da9062_core_resources), 248 .resources = da9062_core_resources, 249 }, 250 { 251 .name = "da9062-regulators", 252 .num_resources = ARRAY_SIZE(da9062_regulators_resources), 253 .resources = da9062_regulators_resources, 254 }, 255 { 256 .name = "da9062-watchdog", 257 .num_resources = ARRAY_SIZE(da9062_wdt_resources), 258 .resources = da9062_wdt_resources, 259 .of_compatible = "dlg,da9062-watchdog", 260 }, 261 { 262 .name = "da9062-thermal", 263 .num_resources = ARRAY_SIZE(da9062_thermal_resources), 264 .resources = da9062_thermal_resources, 265 .of_compatible = "dlg,da9062-thermal", 266 }, 267 { 268 .name = "da9062-rtc", 269 .num_resources = ARRAY_SIZE(da9062_rtc_resources), 270 .resources = da9062_rtc_resources, 271 .of_compatible = "dlg,da9062-rtc", 272 }, 273 { 274 .name = "da9062-onkey", 275 .num_resources = ARRAY_SIZE(da9062_onkey_resources), 276 .resources = da9062_onkey_resources, 277 .of_compatible = "dlg,da9062-onkey", 278 }, 279 { 280 .name = "da9062-gpio", 281 .num_resources = ARRAY_SIZE(da9062_gpio_resources), 282 .resources = da9062_gpio_resources, 283 .of_compatible = "dlg,da9062-gpio", 284 }, 285 }; 286 287 static int da9062_clear_fault_log(struct da9062 *chip) 288 { 289 int ret; 290 int fault_log; 291 292 ret = regmap_read(chip->regmap, DA9062AA_FAULT_LOG, &fault_log); 293 if (ret < 0) 294 return ret; 295 296 if (fault_log) { 297 if (fault_log & DA9062AA_TWD_ERROR_MASK) 298 dev_dbg(chip->dev, "Fault log entry detected: TWD_ERROR\n"); 299 if (fault_log & DA9062AA_POR_MASK) 300 dev_dbg(chip->dev, "Fault log entry detected: POR\n"); 301 if (fault_log & DA9062AA_VDD_FAULT_MASK) 302 dev_dbg(chip->dev, "Fault log entry detected: VDD_FAULT\n"); 303 if (fault_log & DA9062AA_VDD_START_MASK) 304 dev_dbg(chip->dev, "Fault log entry detected: VDD_START\n"); 305 if (fault_log & DA9062AA_TEMP_CRIT_MASK) 306 dev_dbg(chip->dev, "Fault log entry detected: TEMP_CRIT\n"); 307 if (fault_log & DA9062AA_KEY_RESET_MASK) 308 dev_dbg(chip->dev, "Fault log entry detected: KEY_RESET\n"); 309 if (fault_log & DA9062AA_NSHUTDOWN_MASK) 310 dev_dbg(chip->dev, "Fault log entry detected: NSHUTDOWN\n"); 311 if (fault_log & DA9062AA_WAIT_SHUT_MASK) 312 dev_dbg(chip->dev, "Fault log entry detected: WAIT_SHUT\n"); 313 314 ret = regmap_write(chip->regmap, DA9062AA_FAULT_LOG, 315 fault_log); 316 } 317 318 return ret; 319 } 320 321 static int da9062_get_device_type(struct da9062 *chip) 322 { 323 int device_id, variant_id, variant_mrc, variant_vrc; 324 char *type; 325 int ret; 326 327 ret = regmap_read(chip->regmap, DA9062AA_DEVICE_ID, &device_id); 328 if (ret < 0) { 329 dev_err(chip->dev, "Cannot read chip ID.\n"); 330 return -EIO; 331 } 332 if (device_id != DA9062_PMIC_DEVICE_ID) { 333 dev_err(chip->dev, "Invalid device ID: 0x%02x\n", device_id); 334 return -ENODEV; 335 } 336 337 ret = regmap_read(chip->regmap, DA9062AA_VARIANT_ID, &variant_id); 338 if (ret < 0) { 339 dev_err(chip->dev, "Cannot read chip variant id.\n"); 340 return -EIO; 341 } 342 343 variant_vrc = (variant_id & DA9062AA_VRC_MASK) >> DA9062AA_VRC_SHIFT; 344 345 switch (variant_vrc) { 346 case DA9062_PMIC_VARIANT_VRC_DA9061: 347 type = "DA9061"; 348 break; 349 case DA9062_PMIC_VARIANT_VRC_DA9062: 350 type = "DA9062"; 351 break; 352 default: 353 type = "Unknown"; 354 break; 355 } 356 357 dev_info(chip->dev, 358 "Device detected (device-ID: 0x%02X, var-ID: 0x%02X, %s)\n", 359 device_id, variant_id, type); 360 361 variant_mrc = (variant_id & DA9062AA_MRC_MASK) >> DA9062AA_MRC_SHIFT; 362 363 if (variant_mrc < DA9062_PMIC_VARIANT_MRC_AA) { 364 dev_err(chip->dev, 365 "Cannot support variant MRC: 0x%02X\n", variant_mrc); 366 return -ENODEV; 367 } 368 369 return ret; 370 } 371 372 static const struct regmap_range da9061_aa_readable_ranges[] = { 373 regmap_reg_range(DA9062AA_PAGE_CON, DA9062AA_STATUS_B), 374 regmap_reg_range(DA9062AA_STATUS_D, DA9062AA_EVENT_C), 375 regmap_reg_range(DA9062AA_IRQ_MASK_A, DA9062AA_IRQ_MASK_C), 376 regmap_reg_range(DA9062AA_CONTROL_A, DA9062AA_GPIO_4), 377 regmap_reg_range(DA9062AA_GPIO_WKUP_MODE, DA9062AA_GPIO_OUT3_4), 378 regmap_reg_range(DA9062AA_BUCK1_CONT, DA9062AA_BUCK4_CONT), 379 regmap_reg_range(DA9062AA_BUCK3_CONT, DA9062AA_BUCK3_CONT), 380 regmap_reg_range(DA9062AA_LDO1_CONT, DA9062AA_LDO4_CONT), 381 regmap_reg_range(DA9062AA_DVC_1, DA9062AA_DVC_1), 382 regmap_reg_range(DA9062AA_SEQ, DA9062AA_ID_4_3), 383 regmap_reg_range(DA9062AA_ID_12_11, DA9062AA_ID_16_15), 384 regmap_reg_range(DA9062AA_ID_22_21, DA9062AA_ID_32_31), 385 regmap_reg_range(DA9062AA_SEQ_A, DA9062AA_WAIT), 386 regmap_reg_range(DA9062AA_RESET, DA9062AA_BUCK_ILIM_C), 387 regmap_reg_range(DA9062AA_BUCK1_CFG, DA9062AA_BUCK3_CFG), 388 regmap_reg_range(DA9062AA_VBUCK1_A, DA9062AA_VBUCK4_A), 389 regmap_reg_range(DA9062AA_VBUCK3_A, DA9062AA_VBUCK3_A), 390 regmap_reg_range(DA9062AA_VLDO1_A, DA9062AA_VLDO4_A), 391 regmap_reg_range(DA9062AA_VBUCK1_B, DA9062AA_VBUCK4_B), 392 regmap_reg_range(DA9062AA_VBUCK3_B, DA9062AA_VBUCK3_B), 393 regmap_reg_range(DA9062AA_VLDO1_B, DA9062AA_VLDO4_B), 394 regmap_reg_range(DA9062AA_INTERFACE, DA9062AA_CONFIG_E), 395 regmap_reg_range(DA9062AA_CONFIG_G, DA9062AA_CONFIG_K), 396 regmap_reg_range(DA9062AA_CONFIG_M, DA9062AA_CONFIG_M), 397 regmap_reg_range(DA9062AA_GP_ID_0, DA9062AA_GP_ID_19), 398 regmap_reg_range(DA9062AA_DEVICE_ID, DA9062AA_CONFIG_ID), 399 }; 400 401 static const struct regmap_range da9061_aa_writeable_ranges[] = { 402 regmap_reg_range(DA9062AA_PAGE_CON, DA9062AA_PAGE_CON), 403 regmap_reg_range(DA9062AA_FAULT_LOG, DA9062AA_EVENT_C), 404 regmap_reg_range(DA9062AA_IRQ_MASK_A, DA9062AA_IRQ_MASK_C), 405 regmap_reg_range(DA9062AA_CONTROL_A, DA9062AA_GPIO_4), 406 regmap_reg_range(DA9062AA_GPIO_WKUP_MODE, DA9062AA_GPIO_OUT3_4), 407 regmap_reg_range(DA9062AA_BUCK1_CONT, DA9062AA_BUCK4_CONT), 408 regmap_reg_range(DA9062AA_BUCK3_CONT, DA9062AA_BUCK3_CONT), 409 regmap_reg_range(DA9062AA_LDO1_CONT, DA9062AA_LDO4_CONT), 410 regmap_reg_range(DA9062AA_DVC_1, DA9062AA_DVC_1), 411 regmap_reg_range(DA9062AA_SEQ, DA9062AA_ID_4_3), 412 regmap_reg_range(DA9062AA_ID_12_11, DA9062AA_ID_16_15), 413 regmap_reg_range(DA9062AA_ID_22_21, DA9062AA_ID_32_31), 414 regmap_reg_range(DA9062AA_SEQ_A, DA9062AA_WAIT), 415 regmap_reg_range(DA9062AA_RESET, DA9062AA_BUCK_ILIM_C), 416 regmap_reg_range(DA9062AA_BUCK1_CFG, DA9062AA_BUCK3_CFG), 417 regmap_reg_range(DA9062AA_VBUCK1_A, DA9062AA_VBUCK4_A), 418 regmap_reg_range(DA9062AA_VBUCK3_A, DA9062AA_VBUCK3_A), 419 regmap_reg_range(DA9062AA_VLDO1_A, DA9062AA_VLDO4_A), 420 regmap_reg_range(DA9062AA_VBUCK1_B, DA9062AA_VBUCK4_B), 421 regmap_reg_range(DA9062AA_VBUCK3_B, DA9062AA_VBUCK3_B), 422 regmap_reg_range(DA9062AA_VLDO1_B, DA9062AA_VLDO4_B), 423 regmap_reg_range(DA9062AA_GP_ID_0, DA9062AA_GP_ID_19), 424 }; 425 426 static const struct regmap_range da9061_aa_volatile_ranges[] = { 427 regmap_reg_range(DA9062AA_PAGE_CON, DA9062AA_STATUS_B), 428 regmap_reg_range(DA9062AA_STATUS_D, DA9062AA_EVENT_C), 429 regmap_reg_range(DA9062AA_CONTROL_A, DA9062AA_CONTROL_B), 430 regmap_reg_range(DA9062AA_CONTROL_E, DA9062AA_CONTROL_F), 431 regmap_reg_range(DA9062AA_BUCK1_CONT, DA9062AA_BUCK4_CONT), 432 regmap_reg_range(DA9062AA_BUCK3_CONT, DA9062AA_BUCK3_CONT), 433 regmap_reg_range(DA9062AA_LDO1_CONT, DA9062AA_LDO4_CONT), 434 regmap_reg_range(DA9062AA_DVC_1, DA9062AA_DVC_1), 435 regmap_reg_range(DA9062AA_SEQ, DA9062AA_SEQ), 436 }; 437 438 static const struct regmap_access_table da9061_aa_readable_table = { 439 .yes_ranges = da9061_aa_readable_ranges, 440 .n_yes_ranges = ARRAY_SIZE(da9061_aa_readable_ranges), 441 }; 442 443 static const struct regmap_access_table da9061_aa_writeable_table = { 444 .yes_ranges = da9061_aa_writeable_ranges, 445 .n_yes_ranges = ARRAY_SIZE(da9061_aa_writeable_ranges), 446 }; 447 448 static const struct regmap_access_table da9061_aa_volatile_table = { 449 .yes_ranges = da9061_aa_volatile_ranges, 450 .n_yes_ranges = ARRAY_SIZE(da9061_aa_volatile_ranges), 451 }; 452 453 static const struct regmap_range_cfg da9061_range_cfg[] = { 454 { 455 .range_min = DA9062AA_PAGE_CON, 456 .range_max = DA9062AA_CONFIG_ID, 457 .selector_reg = DA9062AA_PAGE_CON, 458 .selector_mask = 1 << DA9062_I2C_PAGE_SEL_SHIFT, 459 .selector_shift = DA9062_I2C_PAGE_SEL_SHIFT, 460 .window_start = 0, 461 .window_len = 256, 462 } 463 }; 464 465 static struct regmap_config da9061_regmap_config = { 466 .reg_bits = 8, 467 .val_bits = 8, 468 .ranges = da9061_range_cfg, 469 .num_ranges = ARRAY_SIZE(da9061_range_cfg), 470 .max_register = DA9062AA_CONFIG_ID, 471 .cache_type = REGCACHE_RBTREE, 472 .rd_table = &da9061_aa_readable_table, 473 .wr_table = &da9061_aa_writeable_table, 474 .volatile_table = &da9061_aa_volatile_table, 475 }; 476 477 static const struct regmap_range da9062_aa_readable_ranges[] = { 478 regmap_reg_range(DA9062AA_PAGE_CON, DA9062AA_STATUS_B), 479 regmap_reg_range(DA9062AA_STATUS_D, DA9062AA_EVENT_C), 480 regmap_reg_range(DA9062AA_IRQ_MASK_A, DA9062AA_IRQ_MASK_C), 481 regmap_reg_range(DA9062AA_CONTROL_A, DA9062AA_GPIO_4), 482 regmap_reg_range(DA9062AA_GPIO_WKUP_MODE, DA9062AA_BUCK4_CONT), 483 regmap_reg_range(DA9062AA_BUCK3_CONT, DA9062AA_BUCK3_CONT), 484 regmap_reg_range(DA9062AA_LDO1_CONT, DA9062AA_LDO4_CONT), 485 regmap_reg_range(DA9062AA_DVC_1, DA9062AA_DVC_1), 486 regmap_reg_range(DA9062AA_COUNT_S, DA9062AA_SECOND_D), 487 regmap_reg_range(DA9062AA_SEQ, DA9062AA_ID_4_3), 488 regmap_reg_range(DA9062AA_ID_12_11, DA9062AA_ID_16_15), 489 regmap_reg_range(DA9062AA_ID_22_21, DA9062AA_ID_32_31), 490 regmap_reg_range(DA9062AA_SEQ_A, DA9062AA_BUCK3_CFG), 491 regmap_reg_range(DA9062AA_VBUCK2_A, DA9062AA_VBUCK4_A), 492 regmap_reg_range(DA9062AA_VBUCK3_A, DA9062AA_VBUCK3_A), 493 regmap_reg_range(DA9062AA_VLDO1_A, DA9062AA_VLDO4_A), 494 regmap_reg_range(DA9062AA_VBUCK2_B, DA9062AA_VBUCK4_B), 495 regmap_reg_range(DA9062AA_VBUCK3_B, DA9062AA_VBUCK3_B), 496 regmap_reg_range(DA9062AA_VLDO1_B, DA9062AA_VLDO4_B), 497 regmap_reg_range(DA9062AA_BBAT_CONT, DA9062AA_BBAT_CONT), 498 regmap_reg_range(DA9062AA_INTERFACE, DA9062AA_CONFIG_E), 499 regmap_reg_range(DA9062AA_CONFIG_G, DA9062AA_CONFIG_K), 500 regmap_reg_range(DA9062AA_CONFIG_M, DA9062AA_CONFIG_M), 501 regmap_reg_range(DA9062AA_TRIM_CLDR, DA9062AA_GP_ID_19), 502 regmap_reg_range(DA9062AA_DEVICE_ID, DA9062AA_CONFIG_ID), 503 }; 504 505 static const struct regmap_range da9062_aa_writeable_ranges[] = { 506 regmap_reg_range(DA9062AA_PAGE_CON, DA9062AA_PAGE_CON), 507 regmap_reg_range(DA9062AA_FAULT_LOG, DA9062AA_EVENT_C), 508 regmap_reg_range(DA9062AA_IRQ_MASK_A, DA9062AA_IRQ_MASK_C), 509 regmap_reg_range(DA9062AA_CONTROL_A, DA9062AA_GPIO_4), 510 regmap_reg_range(DA9062AA_GPIO_WKUP_MODE, DA9062AA_BUCK4_CONT), 511 regmap_reg_range(DA9062AA_BUCK3_CONT, DA9062AA_BUCK3_CONT), 512 regmap_reg_range(DA9062AA_LDO1_CONT, DA9062AA_LDO4_CONT), 513 regmap_reg_range(DA9062AA_DVC_1, DA9062AA_DVC_1), 514 regmap_reg_range(DA9062AA_COUNT_S, DA9062AA_ALARM_Y), 515 regmap_reg_range(DA9062AA_SEQ, DA9062AA_ID_4_3), 516 regmap_reg_range(DA9062AA_ID_12_11, DA9062AA_ID_16_15), 517 regmap_reg_range(DA9062AA_ID_22_21, DA9062AA_ID_32_31), 518 regmap_reg_range(DA9062AA_SEQ_A, DA9062AA_BUCK3_CFG), 519 regmap_reg_range(DA9062AA_VBUCK2_A, DA9062AA_VBUCK4_A), 520 regmap_reg_range(DA9062AA_VBUCK3_A, DA9062AA_VBUCK3_A), 521 regmap_reg_range(DA9062AA_VLDO1_A, DA9062AA_VLDO4_A), 522 regmap_reg_range(DA9062AA_VBUCK2_B, DA9062AA_VBUCK4_B), 523 regmap_reg_range(DA9062AA_VBUCK3_B, DA9062AA_VBUCK3_B), 524 regmap_reg_range(DA9062AA_VLDO1_B, DA9062AA_VLDO4_B), 525 regmap_reg_range(DA9062AA_BBAT_CONT, DA9062AA_BBAT_CONT), 526 regmap_reg_range(DA9062AA_GP_ID_0, DA9062AA_GP_ID_19), 527 }; 528 529 static const struct regmap_range da9062_aa_volatile_ranges[] = { 530 regmap_reg_range(DA9062AA_PAGE_CON, DA9062AA_STATUS_B), 531 regmap_reg_range(DA9062AA_STATUS_D, DA9062AA_EVENT_C), 532 regmap_reg_range(DA9062AA_CONTROL_A, DA9062AA_CONTROL_B), 533 regmap_reg_range(DA9062AA_CONTROL_E, DA9062AA_CONTROL_F), 534 regmap_reg_range(DA9062AA_BUCK2_CONT, DA9062AA_BUCK4_CONT), 535 regmap_reg_range(DA9062AA_BUCK3_CONT, DA9062AA_BUCK3_CONT), 536 regmap_reg_range(DA9062AA_LDO1_CONT, DA9062AA_LDO4_CONT), 537 regmap_reg_range(DA9062AA_DVC_1, DA9062AA_DVC_1), 538 regmap_reg_range(DA9062AA_COUNT_S, DA9062AA_SECOND_D), 539 regmap_reg_range(DA9062AA_SEQ, DA9062AA_SEQ), 540 regmap_reg_range(DA9062AA_EN_32K, DA9062AA_EN_32K), 541 }; 542 543 static const struct regmap_access_table da9062_aa_readable_table = { 544 .yes_ranges = da9062_aa_readable_ranges, 545 .n_yes_ranges = ARRAY_SIZE(da9062_aa_readable_ranges), 546 }; 547 548 static const struct regmap_access_table da9062_aa_writeable_table = { 549 .yes_ranges = da9062_aa_writeable_ranges, 550 .n_yes_ranges = ARRAY_SIZE(da9062_aa_writeable_ranges), 551 }; 552 553 static const struct regmap_access_table da9062_aa_volatile_table = { 554 .yes_ranges = da9062_aa_volatile_ranges, 555 .n_yes_ranges = ARRAY_SIZE(da9062_aa_volatile_ranges), 556 }; 557 558 static const struct regmap_range_cfg da9062_range_cfg[] = { 559 { 560 .range_min = DA9062AA_PAGE_CON, 561 .range_max = DA9062AA_CONFIG_ID, 562 .selector_reg = DA9062AA_PAGE_CON, 563 .selector_mask = 1 << DA9062_I2C_PAGE_SEL_SHIFT, 564 .selector_shift = DA9062_I2C_PAGE_SEL_SHIFT, 565 .window_start = 0, 566 .window_len = 256, 567 } 568 }; 569 570 static struct regmap_config da9062_regmap_config = { 571 .reg_bits = 8, 572 .val_bits = 8, 573 .ranges = da9062_range_cfg, 574 .num_ranges = ARRAY_SIZE(da9062_range_cfg), 575 .max_register = DA9062AA_CONFIG_ID, 576 .cache_type = REGCACHE_RBTREE, 577 .rd_table = &da9062_aa_readable_table, 578 .wr_table = &da9062_aa_writeable_table, 579 .volatile_table = &da9062_aa_volatile_table, 580 }; 581 582 static const struct of_device_id da9062_dt_ids[] = { 583 { .compatible = "dlg,da9061", .data = (void *)COMPAT_TYPE_DA9061, }, 584 { .compatible = "dlg,da9062", .data = (void *)COMPAT_TYPE_DA9062, }, 585 { } 586 }; 587 MODULE_DEVICE_TABLE(of, da9062_dt_ids); 588 589 static int da9062_i2c_probe(struct i2c_client *i2c, 590 const struct i2c_device_id *id) 591 { 592 struct da9062 *chip; 593 const struct of_device_id *match; 594 unsigned int irq_base; 595 const struct mfd_cell *cell; 596 const struct regmap_irq_chip *irq_chip; 597 const struct regmap_config *config; 598 int cell_num; 599 int ret; 600 601 chip = devm_kzalloc(&i2c->dev, sizeof(*chip), GFP_KERNEL); 602 if (!chip) 603 return -ENOMEM; 604 605 if (i2c->dev.of_node) { 606 match = of_match_node(da9062_dt_ids, i2c->dev.of_node); 607 if (!match) 608 return -EINVAL; 609 610 chip->chip_type = (uintptr_t)match->data; 611 } else { 612 chip->chip_type = id->driver_data; 613 } 614 615 i2c_set_clientdata(i2c, chip); 616 chip->dev = &i2c->dev; 617 618 if (!i2c->irq) { 619 dev_err(chip->dev, "No IRQ configured\n"); 620 return -EINVAL; 621 } 622 623 switch (chip->chip_type) { 624 case COMPAT_TYPE_DA9061: 625 cell = da9061_devs; 626 cell_num = ARRAY_SIZE(da9061_devs); 627 irq_chip = &da9061_irq_chip; 628 config = &da9061_regmap_config; 629 break; 630 case COMPAT_TYPE_DA9062: 631 cell = da9062_devs; 632 cell_num = ARRAY_SIZE(da9062_devs); 633 irq_chip = &da9062_irq_chip; 634 config = &da9062_regmap_config; 635 break; 636 default: 637 dev_err(chip->dev, "Unrecognised chip type\n"); 638 return -ENODEV; 639 } 640 641 chip->regmap = devm_regmap_init_i2c(i2c, config); 642 if (IS_ERR(chip->regmap)) { 643 ret = PTR_ERR(chip->regmap); 644 dev_err(chip->dev, "Failed to allocate register map: %d\n", 645 ret); 646 return ret; 647 } 648 649 ret = da9062_clear_fault_log(chip); 650 if (ret < 0) 651 dev_warn(chip->dev, "Cannot clear fault log\n"); 652 653 ret = da9062_get_device_type(chip); 654 if (ret) 655 return ret; 656 657 ret = regmap_add_irq_chip(chip->regmap, i2c->irq, 658 IRQF_TRIGGER_LOW | IRQF_ONESHOT | IRQF_SHARED, 659 -1, irq_chip, 660 &chip->regmap_irq); 661 if (ret) { 662 dev_err(chip->dev, "Failed to request IRQ %d: %d\n", 663 i2c->irq, ret); 664 return ret; 665 } 666 667 irq_base = regmap_irq_chip_get_base(chip->regmap_irq); 668 669 ret = mfd_add_devices(chip->dev, PLATFORM_DEVID_NONE, cell, 670 cell_num, NULL, irq_base, 671 NULL); 672 if (ret) { 673 dev_err(chip->dev, "Cannot register child devices\n"); 674 regmap_del_irq_chip(i2c->irq, chip->regmap_irq); 675 return ret; 676 } 677 678 return ret; 679 } 680 681 static int da9062_i2c_remove(struct i2c_client *i2c) 682 { 683 struct da9062 *chip = i2c_get_clientdata(i2c); 684 685 mfd_remove_devices(chip->dev); 686 regmap_del_irq_chip(i2c->irq, chip->regmap_irq); 687 688 return 0; 689 } 690 691 static const struct i2c_device_id da9062_i2c_id[] = { 692 { "da9061", COMPAT_TYPE_DA9061 }, 693 { "da9062", COMPAT_TYPE_DA9062 }, 694 { }, 695 }; 696 MODULE_DEVICE_TABLE(i2c, da9062_i2c_id); 697 698 static struct i2c_driver da9062_i2c_driver = { 699 .driver = { 700 .name = "da9062", 701 .of_match_table = of_match_ptr(da9062_dt_ids), 702 }, 703 .probe = da9062_i2c_probe, 704 .remove = da9062_i2c_remove, 705 .id_table = da9062_i2c_id, 706 }; 707 708 module_i2c_driver(da9062_i2c_driver); 709 710 MODULE_DESCRIPTION("Core device driver for Dialog DA9061 and DA9062"); 711 MODULE_AUTHOR("Steve Twiss <stwiss.opensource@diasemi.com>"); 712 MODULE_LICENSE("GPL"); 713