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