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 { 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 452 static 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 525 static 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 556 static 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 561 static 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 566 static 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 571 static 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 583 static 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 595 static const struct regmap_range da9062_aa_readable_ranges[] = { 596 { 597 .range_min = DA9062AA_PAGE_CON, 598 .range_max = DA9062AA_STATUS_B, 599 }, { 600 .range_min = DA9062AA_STATUS_D, 601 .range_max = DA9062AA_EVENT_C, 602 }, { 603 .range_min = DA9062AA_IRQ_MASK_A, 604 .range_max = DA9062AA_IRQ_MASK_C, 605 }, { 606 .range_min = DA9062AA_CONTROL_A, 607 .range_max = DA9062AA_GPIO_4, 608 }, { 609 .range_min = DA9062AA_GPIO_WKUP_MODE, 610 .range_max = DA9062AA_BUCK4_CONT, 611 }, { 612 .range_min = DA9062AA_BUCK3_CONT, 613 .range_max = DA9062AA_BUCK3_CONT, 614 }, { 615 .range_min = DA9062AA_LDO1_CONT, 616 .range_max = DA9062AA_LDO4_CONT, 617 }, { 618 .range_min = DA9062AA_DVC_1, 619 .range_max = DA9062AA_DVC_1, 620 }, { 621 .range_min = DA9062AA_COUNT_S, 622 .range_max = DA9062AA_SECOND_D, 623 }, { 624 .range_min = DA9062AA_SEQ, 625 .range_max = DA9062AA_ID_4_3, 626 }, { 627 .range_min = DA9062AA_ID_12_11, 628 .range_max = DA9062AA_ID_16_15, 629 }, { 630 .range_min = DA9062AA_ID_22_21, 631 .range_max = DA9062AA_ID_32_31, 632 }, { 633 .range_min = DA9062AA_SEQ_A, 634 .range_max = DA9062AA_BUCK3_CFG, 635 }, { 636 .range_min = DA9062AA_VBUCK2_A, 637 .range_max = DA9062AA_VBUCK4_A, 638 }, { 639 .range_min = DA9062AA_VBUCK3_A, 640 .range_max = DA9062AA_VBUCK3_A, 641 }, { 642 .range_min = DA9062AA_VLDO1_A, 643 .range_max = DA9062AA_VLDO4_A, 644 }, { 645 .range_min = DA9062AA_VBUCK2_B, 646 .range_max = DA9062AA_VBUCK4_B, 647 }, { 648 .range_min = DA9062AA_VBUCK3_B, 649 .range_max = DA9062AA_VBUCK3_B, 650 }, { 651 .range_min = DA9062AA_VLDO1_B, 652 .range_max = DA9062AA_VLDO4_B, 653 }, { 654 .range_min = DA9062AA_BBAT_CONT, 655 .range_max = DA9062AA_BBAT_CONT, 656 }, { 657 .range_min = DA9062AA_INTERFACE, 658 .range_max = DA9062AA_CONFIG_E, 659 }, { 660 .range_min = DA9062AA_CONFIG_G, 661 .range_max = DA9062AA_CONFIG_K, 662 }, { 663 .range_min = DA9062AA_CONFIG_M, 664 .range_max = DA9062AA_CONFIG_M, 665 }, { 666 .range_min = DA9062AA_TRIM_CLDR, 667 .range_max = DA9062AA_GP_ID_19, 668 }, { 669 .range_min = DA9062AA_DEVICE_ID, 670 .range_max = DA9062AA_CONFIG_ID, 671 }, 672 }; 673 674 static const struct regmap_range da9062_aa_writeable_ranges[] = { 675 { 676 .range_min = DA9062AA_PAGE_CON, 677 .range_max = DA9062AA_PAGE_CON, 678 }, { 679 .range_min = DA9062AA_FAULT_LOG, 680 .range_max = DA9062AA_EVENT_C, 681 }, { 682 .range_min = DA9062AA_IRQ_MASK_A, 683 .range_max = DA9062AA_IRQ_MASK_C, 684 }, { 685 .range_min = DA9062AA_CONTROL_A, 686 .range_max = DA9062AA_GPIO_4, 687 }, { 688 .range_min = DA9062AA_GPIO_WKUP_MODE, 689 .range_max = DA9062AA_BUCK4_CONT, 690 }, { 691 .range_min = DA9062AA_BUCK3_CONT, 692 .range_max = DA9062AA_BUCK3_CONT, 693 }, { 694 .range_min = DA9062AA_LDO1_CONT, 695 .range_max = DA9062AA_LDO4_CONT, 696 }, { 697 .range_min = DA9062AA_DVC_1, 698 .range_max = DA9062AA_DVC_1, 699 }, { 700 .range_min = DA9062AA_COUNT_S, 701 .range_max = DA9062AA_ALARM_Y, 702 }, { 703 .range_min = DA9062AA_SEQ, 704 .range_max = DA9062AA_ID_4_3, 705 }, { 706 .range_min = DA9062AA_ID_12_11, 707 .range_max = DA9062AA_ID_16_15, 708 }, { 709 .range_min = DA9062AA_ID_22_21, 710 .range_max = DA9062AA_ID_32_31, 711 }, { 712 .range_min = DA9062AA_SEQ_A, 713 .range_max = DA9062AA_BUCK3_CFG, 714 }, { 715 .range_min = DA9062AA_VBUCK2_A, 716 .range_max = DA9062AA_VBUCK4_A, 717 }, { 718 .range_min = DA9062AA_VBUCK3_A, 719 .range_max = DA9062AA_VBUCK3_A, 720 }, { 721 .range_min = DA9062AA_VLDO1_A, 722 .range_max = DA9062AA_VLDO4_A, 723 }, { 724 .range_min = DA9062AA_VBUCK2_B, 725 .range_max = DA9062AA_VBUCK4_B, 726 }, { 727 .range_min = DA9062AA_VBUCK3_B, 728 .range_max = DA9062AA_VBUCK3_B, 729 }, { 730 .range_min = DA9062AA_VLDO1_B, 731 .range_max = DA9062AA_VLDO4_B, 732 }, { 733 .range_min = DA9062AA_BBAT_CONT, 734 .range_max = DA9062AA_BBAT_CONT, 735 }, { 736 .range_min = DA9062AA_GP_ID_0, 737 .range_max = DA9062AA_GP_ID_19, 738 }, 739 }; 740 741 static const struct regmap_range da9062_aa_volatile_ranges[] = { 742 { 743 .range_min = DA9062AA_PAGE_CON, 744 .range_max = DA9062AA_STATUS_B, 745 }, { 746 .range_min = DA9062AA_STATUS_D, 747 .range_max = DA9062AA_EVENT_C, 748 }, { 749 .range_min = DA9062AA_CONTROL_A, 750 .range_max = DA9062AA_CONTROL_B, 751 }, { 752 .range_min = DA9062AA_CONTROL_E, 753 .range_max = DA9062AA_CONTROL_F, 754 }, { 755 .range_min = DA9062AA_BUCK2_CONT, 756 .range_max = DA9062AA_BUCK4_CONT, 757 }, { 758 .range_min = DA9062AA_BUCK3_CONT, 759 .range_max = DA9062AA_BUCK3_CONT, 760 }, { 761 .range_min = DA9062AA_LDO1_CONT, 762 .range_max = DA9062AA_LDO4_CONT, 763 }, { 764 .range_min = DA9062AA_DVC_1, 765 .range_max = DA9062AA_DVC_1, 766 }, { 767 .range_min = DA9062AA_COUNT_S, 768 .range_max = DA9062AA_SECOND_D, 769 }, { 770 .range_min = DA9062AA_SEQ, 771 .range_max = DA9062AA_SEQ, 772 }, { 773 .range_min = DA9062AA_EN_32K, 774 .range_max = DA9062AA_EN_32K, 775 }, 776 }; 777 778 static const struct regmap_access_table da9062_aa_readable_table = { 779 .yes_ranges = da9062_aa_readable_ranges, 780 .n_yes_ranges = ARRAY_SIZE(da9062_aa_readable_ranges), 781 }; 782 783 static const struct regmap_access_table da9062_aa_writeable_table = { 784 .yes_ranges = da9062_aa_writeable_ranges, 785 .n_yes_ranges = ARRAY_SIZE(da9062_aa_writeable_ranges), 786 }; 787 788 static const struct regmap_access_table da9062_aa_volatile_table = { 789 .yes_ranges = da9062_aa_volatile_ranges, 790 .n_yes_ranges = ARRAY_SIZE(da9062_aa_volatile_ranges), 791 }; 792 793 static const struct regmap_range_cfg da9062_range_cfg[] = { 794 { 795 .range_min = DA9062AA_PAGE_CON, 796 .range_max = DA9062AA_CONFIG_ID, 797 .selector_reg = DA9062AA_PAGE_CON, 798 .selector_mask = 1 << DA9062_I2C_PAGE_SEL_SHIFT, 799 .selector_shift = DA9062_I2C_PAGE_SEL_SHIFT, 800 .window_start = 0, 801 .window_len = 256, 802 } 803 }; 804 805 static struct regmap_config da9062_regmap_config = { 806 .reg_bits = 8, 807 .val_bits = 8, 808 .ranges = da9062_range_cfg, 809 .num_ranges = ARRAY_SIZE(da9062_range_cfg), 810 .max_register = DA9062AA_CONFIG_ID, 811 .cache_type = REGCACHE_RBTREE, 812 .rd_table = &da9062_aa_readable_table, 813 .wr_table = &da9062_aa_writeable_table, 814 .volatile_table = &da9062_aa_volatile_table, 815 }; 816 817 static 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 }; 822 MODULE_DEVICE_TABLE(of, da9062_dt_ids); 823 824 static int da9062_i2c_probe(struct i2c_client *i2c, 825 const struct i2c_device_id *id) 826 { 827 struct da9062 *chip; 828 const struct of_device_id *match; 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; 834 int ret; 835 836 chip = devm_kzalloc(&i2c->dev, sizeof(*chip), GFP_KERNEL); 837 if (!chip) 838 return -ENOMEM; 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 850 i2c_set_clientdata(i2c, chip); 851 chip->dev = &i2c->dev; 852 853 if (!i2c->irq) { 854 dev_err(chip->dev, "No IRQ configured\n"); 855 return -EINVAL; 856 } 857 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); 877 if (IS_ERR(chip->regmap)) { 878 ret = PTR_ERR(chip->regmap); 879 dev_err(chip->dev, "Failed to allocate register map: %d\n", 880 ret); 881 return ret; 882 } 883 884 ret = da9062_clear_fault_log(chip); 885 if (ret < 0) 886 dev_warn(chip->dev, "Cannot clear fault log\n"); 887 888 ret = da9062_get_device_type(chip); 889 if (ret) 890 return ret; 891 892 ret = regmap_add_irq_chip(chip->regmap, i2c->irq, 893 IRQF_TRIGGER_LOW | IRQF_ONESHOT | IRQF_SHARED, 894 -1, irq_chip, 895 &chip->regmap_irq); 896 if (ret) { 897 dev_err(chip->dev, "Failed to request IRQ %d: %d\n", 898 i2c->irq, ret); 899 return ret; 900 } 901 902 irq_base = regmap_irq_chip_get_base(chip->regmap_irq); 903 904 ret = mfd_add_devices(chip->dev, PLATFORM_DEVID_NONE, cell, 905 cell_num, NULL, irq_base, 906 NULL); 907 if (ret) { 908 dev_err(chip->dev, "Cannot register child devices\n"); 909 regmap_del_irq_chip(i2c->irq, chip->regmap_irq); 910 return ret; 911 } 912 913 return ret; 914 } 915 916 static int da9062_i2c_remove(struct i2c_client *i2c) 917 { 918 struct da9062 *chip = i2c_get_clientdata(i2c); 919 920 mfd_remove_devices(chip->dev); 921 regmap_del_irq_chip(i2c->irq, chip->regmap_irq); 922 923 return 0; 924 } 925 926 static const struct i2c_device_id da9062_i2c_id[] = { 927 { "da9061", COMPAT_TYPE_DA9061 }, 928 { "da9062", COMPAT_TYPE_DA9062 }, 929 { }, 930 }; 931 MODULE_DEVICE_TABLE(i2c, da9062_i2c_id); 932 933 static struct i2c_driver da9062_i2c_driver = { 934 .driver = { 935 .name = "da9062", 936 .of_match_table = of_match_ptr(da9062_dt_ids), 937 }, 938 .probe = da9062_i2c_probe, 939 .remove = da9062_i2c_remove, 940 .id_table = da9062_i2c_id, 941 }; 942 943 module_i2c_driver(da9062_i2c_driver); 944 945 MODULE_DESCRIPTION("Core device driver for Dialog DA9061 and DA9062"); 946 MODULE_AUTHOR("Steve Twiss <stwiss.opensource@diasemi.com>"); 947 MODULE_LICENSE("GPL"); 948