1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (C) 2017 NXP 4 * Copyright (C) 2019 Boundary Devices 5 * Copyright (C) 2020 Amarula Solutions(India) 6 */ 7 8 #include <linux/delay.h> 9 #include <linux/err.h> 10 #include <linux/gpio/consumer.h> 11 #include <linux/i2c.h> 12 #include <linux/module.h> 13 #include <linux/regmap.h> 14 #include <linux/regulator/driver.h> 15 #include <linux/regulator/machine.h> 16 17 /* registers */ 18 #define PF8X00_DEVICEID 0x00 19 #define PF8X00_REVID 0x01 20 #define PF8X00_EMREV 0x02 21 #define PF8X00_PROGID 0x03 22 #define PF8X00_IMS_INT 0x04 23 #define PF8X00_IMS_THERM 0x07 24 #define PF8X00_SW_MODE_INT 0x0a 25 #define PF8X00_SW_MODE_MASK 0x0b 26 #define PF8X00_IMS_SW_ILIM 0x12 27 #define PF8X00_IMS_LDO_ILIM 0x15 28 #define PF8X00_IMS_SW_UV 0x18 29 #define PF8X00_IMS_SW_OV 0x1b 30 #define PF8X00_IMS_LDO_UV 0x1e 31 #define PF8X00_IMS_LDO_OV 0x21 32 #define PF8X00_IMS_PWRON 0x24 33 #define PF8X00_SYS_INT 0x27 34 #define PF8X00_HARD_FAULT 0x29 35 #define PF8X00_FSOB_FLAGS 0x2a 36 #define PF8X00_FSOB_SELECT 0x2b 37 #define PF8X00_ABIST_OV1 0x2c 38 #define PF8X00_ABIST_OV2 0x2d 39 #define PF8X00_ABIST_UV1 0x2e 40 #define PF8X00_ABIST_UV2 0x2f 41 #define PF8X00_TEST_FLAGS 0x30 42 #define PF8X00_ABIST_RUN 0x31 43 #define PF8X00_RANDOM_GEN 0x33 44 #define PF8X00_RANDOM_CHK 0x34 45 #define PF8X00_VMONEN1 0x35 46 #define PF8X00_VMONEN2 0x36 47 #define PF8X00_CTRL1 0x37 48 #define PF8X00_CTRL2 0x38 49 #define PF8X00_CTRL3 0x39 50 #define PF8X00_PWRUP_CTRL 0x3a 51 #define PF8X00_RESETBMCU 0x3c 52 #define PF8X00_PGOOD 0x3d 53 #define PF8X00_PWRDN_DLY1 0x3e 54 #define PF8X00_PWRDN_DLY2 0x3f 55 #define PF8X00_FREQ_CTRL 0x40 56 #define PF8X00_COINCELL_CTRL 0x41 57 #define PF8X00_PWRON 0x42 58 #define PF8X00_WD_CONFIG 0x43 59 #define PF8X00_WD_CLEAR 0x44 60 #define PF8X00_WD_EXPIRE 0x45 61 #define PF8X00_WD_COUNTER 0x46 62 #define PF8X00_FAULT_COUNTER 0x47 63 #define PF8X00_FSAFE_COUNTER 0x48 64 #define PF8X00_FAULT_TIMER 0x49 65 #define PF8X00_AMUX 0x4a 66 #define PF8X00_SW1_CONFIG1 0x4d 67 #define PF8X00_LDO1_CONFIG1 0x85 68 #define PF8X00_VSNVS_CONFIG1 0x9d 69 #define PF8X00_PAGE_SELECT 0x9f 70 71 /* regulators */ 72 enum pf8x00_regulators { 73 PF8X00_LDO1, 74 PF8X00_LDO2, 75 PF8X00_LDO3, 76 PF8X00_LDO4, 77 PF8X00_BUCK1, 78 PF8X00_BUCK2, 79 PF8X00_BUCK3, 80 PF8X00_BUCK4, 81 PF8X00_BUCK5, 82 PF8X00_BUCK6, 83 PF8X00_BUCK7, 84 PF8X00_VSNVS, 85 86 PF8X00_MAX_REGULATORS, 87 }; 88 89 enum pf8x00_buck_states { 90 SW_CONFIG1, 91 SW_CONFIG2, 92 SW_PWRUP, 93 SW_MODE1, 94 SW_RUN_VOLT, 95 SW_STBY_VOLT, 96 }; 97 #define PF8X00_SW_BASE(i) (8 * (i - PF8X00_BUCK1) + PF8X00_SW1_CONFIG1) 98 99 enum pf8x00_ldo_states { 100 LDO_CONFIG1, 101 LDO_CONFIG2, 102 LDO_PWRUP, 103 LDO_RUN_VOLT, 104 LDO_STBY_VOLT, 105 }; 106 #define PF8X00_LDO_BASE(i) (6 * (i - PF8X00_LDO1) + PF8X00_LDO1_CONFIG1) 107 108 enum swxilim_bits { 109 SWXILIM_2100_MA, 110 SWXILIM_2600_MA, 111 SWXILIM_3000_MA, 112 SWXILIM_4500_MA, 113 }; 114 #define PF8X00_SWXILIM_SHIFT 3 115 #define PF8X00_SWXILIM_MASK GENMASK(4, 3) 116 #define PF8X00_SWXPHASE_MASK GENMASK(2, 0) 117 #define PF8X00_SWXPHASE_SHIFT 7 118 119 enum pf8x00_devid { 120 PF8100 = 0x0, 121 PF8121A = BIT(1), 122 PF8200 = BIT(3), 123 }; 124 #define PF8X00_FAM BIT(6) 125 #define PF8X00_DEVICE_FAM_MASK GENMASK(7, 4) 126 #define PF8X00_DEVICE_ID_MASK GENMASK(3, 0) 127 128 struct pf8x00_regulator_data { 129 struct regulator_desc desc; 130 unsigned int suspend_enable_reg; 131 unsigned int suspend_enable_mask; 132 unsigned int suspend_voltage_reg; 133 unsigned int suspend_voltage_cache; 134 }; 135 136 struct pf8x00_chip { 137 struct regmap *regmap; 138 struct device *dev; 139 }; 140 141 static const struct regmap_config pf8x00_regmap_config = { 142 .reg_bits = 8, 143 .val_bits = 8, 144 .max_register = PF8X00_PAGE_SELECT, 145 .cache_type = REGCACHE_RBTREE, 146 }; 147 148 /* VLDOx output: 1.5V to 5.0V */ 149 static const int pf8x00_ldo_voltages[] = { 150 1500000, 1600000, 1800000, 1850000, 2150000, 2500000, 2800000, 3000000, 151 3100000, 3150000, 3200000, 3300000, 3350000, 1650000, 1700000, 5000000, 152 }; 153 154 /* Output: 2.1A to 4.5A */ 155 static const unsigned int pf8x00_sw_current_table[] = { 156 2100000, 2600000, 3000000, 4500000, 157 }; 158 159 /* Output: 0.4V to 1.8V */ 160 #define PF8XOO_SW1_6_VOLTAGE_NUM 0xB2 161 static const struct linear_range pf8x00_sw1_to_6_voltages[] = { 162 REGULATOR_LINEAR_RANGE(400000, 0x00, 0xB0, 6250), 163 REGULATOR_LINEAR_RANGE(1800000, 0xB1, 0xB1, 0), 164 }; 165 166 /* Output: 1.0V to 4.1V */ 167 static const int pf8x00_sw7_voltages[] = { 168 1000000, 1100000, 1200000, 1250000, 1300000, 1350000, 1500000, 1600000, 169 1800000, 1850000, 2000000, 2100000, 2150000, 2250000, 2300000, 2400000, 170 2500000, 2800000, 3150000, 3200000, 3250000, 3300000, 3350000, 3400000, 171 3500000, 3800000, 4000000, 4100000, 4100000, 4100000, 4100000, 4100000, 172 }; 173 174 /* Output: 1.8V, 3.0V, or 3.3V */ 175 static const int pf8x00_vsnvs_voltages[] = { 176 0, 1800000, 3000000, 3300000, 177 }; 178 179 static void swxilim_select(struct pf8x00_chip *chip, int id, int ilim) 180 { 181 u8 ilim_sel; 182 u8 reg = PF8X00_SW_BASE(id) + SW_CONFIG2; 183 184 switch (ilim) { 185 case 2100: 186 ilim_sel = SWXILIM_2100_MA; 187 break; 188 case 2600: 189 ilim_sel = SWXILIM_2600_MA; 190 break; 191 case 3000: 192 ilim_sel = SWXILIM_3000_MA; 193 break; 194 case 4500: 195 ilim_sel = SWXILIM_4500_MA; 196 break; 197 default: 198 ilim_sel = SWXILIM_2100_MA; 199 break; 200 } 201 202 regmap_update_bits(chip->regmap, reg, 203 PF8X00_SWXILIM_MASK, 204 ilim_sel << PF8X00_SWXILIM_SHIFT); 205 } 206 207 static void handle_ilim_property(struct device_node *np, 208 const struct regulator_desc *desc, 209 struct regulator_config *config) 210 { 211 struct pf8x00_chip *chip = config->driver_data; 212 int ret; 213 int val; 214 215 if ((desc->id >= PF8X00_BUCK1) && (desc->id <= PF8X00_BUCK7)) { 216 ret = of_property_read_u32(np, "nxp,ilim-ma", &val); 217 if (ret) { 218 dev_dbg(chip->dev, "unspecified ilim for BUCK%d, use value stored in OTP\n", 219 desc->id - PF8X00_LDO4); 220 return; 221 } 222 223 dev_warn(chip->dev, "nxp,ilim-ma is deprecated, please use regulator-max-microamp\n"); 224 swxilim_select(chip, desc->id, val); 225 226 } else 227 dev_warn(chip->dev, "nxp,ilim-ma used with incorrect regulator (%d)\n", desc->id); 228 } 229 230 static void handle_shift_property(struct device_node *np, 231 const struct regulator_desc *desc, 232 struct regulator_config *config) 233 { 234 unsigned char id = desc->id - PF8X00_LDO4; 235 unsigned char reg = PF8X00_SW_BASE(id) + SW_CONFIG2; 236 struct pf8x00_chip *chip = config->driver_data; 237 238 int phase; 239 int val; 240 int ret; 241 if ((desc->id >= PF8X00_BUCK1) && (desc->id <= PF8X00_BUCK7)) { 242 ret = of_property_read_u32(np, "nxp,phase-shift", &val); 243 if (ret) { 244 dev_dbg(chip->dev, 245 "unspecified phase-shift for BUCK%d, using OTP configuration\n", 246 id); 247 return; 248 } 249 250 if (val < 0 || val > 315 || val % 45 != 0) { 251 dev_warn(config->dev, 252 "invalid phase_shift %d for BUCK%d, using OTP configuration\n", 253 val, id); 254 return; 255 } 256 257 phase = val / 45; 258 259 if (phase >= 1) 260 phase -= 1; 261 else 262 phase = PF8X00_SWXPHASE_SHIFT; 263 264 regmap_update_bits(chip->regmap, reg, 265 PF8X00_SWXPHASE_MASK, 266 phase); 267 } else 268 dev_warn(chip->dev, "nxp,phase-shift used with incorrect regulator (%d)\n", id); 269 270 } 271 272 static int pf8x00_of_parse_cb(struct device_node *np, 273 const struct regulator_desc *desc, 274 struct regulator_config *config) 275 { 276 277 handle_ilim_property(np, desc, config); 278 handle_shift_property(np, desc, config); 279 280 return 0; 281 } 282 283 static int pf8x00_suspend_enable(struct regulator_dev *rdev) 284 { 285 struct pf8x00_regulator_data *regl = rdev_get_drvdata(rdev); 286 struct regmap *rmap = rdev_get_regmap(rdev); 287 288 return regmap_update_bits(rmap, regl->suspend_enable_reg, 289 regl->suspend_enable_mask, 290 regl->suspend_enable_mask); 291 } 292 293 static int pf8x00_suspend_disable(struct regulator_dev *rdev) 294 { 295 struct pf8x00_regulator_data *regl = rdev_get_drvdata(rdev); 296 struct regmap *rmap = rdev_get_regmap(rdev); 297 298 return regmap_update_bits(rmap, regl->suspend_enable_reg, 299 regl->suspend_enable_mask, 0); 300 } 301 302 static int pf8x00_set_suspend_voltage(struct regulator_dev *rdev, int uV) 303 { 304 struct pf8x00_regulator_data *regl = rdev_get_drvdata(rdev); 305 int ret; 306 307 if (regl->suspend_voltage_cache == uV) 308 return 0; 309 310 ret = regulator_map_voltage_iterate(rdev, uV, uV); 311 if (ret < 0) { 312 dev_err(rdev_get_dev(rdev), "failed to map %i uV\n", uV); 313 return ret; 314 } 315 316 dev_dbg(rdev_get_dev(rdev), "uV: %i, reg: 0x%x, msk: 0x%x, val: 0x%x\n", 317 uV, regl->suspend_voltage_reg, regl->desc.vsel_mask, ret); 318 ret = regmap_update_bits(rdev->regmap, regl->suspend_voltage_reg, 319 regl->desc.vsel_mask, ret); 320 if (ret < 0) { 321 dev_err(rdev_get_dev(rdev), "failed to set %i uV\n", uV); 322 return ret; 323 } 324 325 regl->suspend_voltage_cache = uV; 326 327 return 0; 328 } 329 330 static const struct regulator_ops pf8x00_ldo_ops = { 331 .enable = regulator_enable_regmap, 332 .disable = regulator_disable_regmap, 333 .is_enabled = regulator_is_enabled_regmap, 334 .list_voltage = regulator_list_voltage_table, 335 .set_voltage_sel = regulator_set_voltage_sel_regmap, 336 .get_voltage_sel = regulator_get_voltage_sel_regmap, 337 .set_suspend_enable = pf8x00_suspend_enable, 338 .set_suspend_disable = pf8x00_suspend_disable, 339 .set_suspend_voltage = pf8x00_set_suspend_voltage, 340 }; 341 342 343 static const struct regulator_ops pf8x00_buck1_6_ops = { 344 .enable = regulator_enable_regmap, 345 .disable = regulator_disable_regmap, 346 .is_enabled = regulator_is_enabled_regmap, 347 .list_voltage = regulator_list_voltage_linear_range, 348 .set_voltage_sel = regulator_set_voltage_sel_regmap, 349 .get_voltage_sel = regulator_get_voltage_sel_regmap, 350 .get_current_limit = regulator_get_current_limit_regmap, 351 .set_current_limit = regulator_set_current_limit_regmap, 352 .set_suspend_enable = pf8x00_suspend_enable, 353 .set_suspend_disable = pf8x00_suspend_disable, 354 .set_suspend_voltage = pf8x00_set_suspend_voltage, 355 }; 356 357 static const struct regulator_ops pf8x00_buck7_ops = { 358 .enable = regulator_enable_regmap, 359 .disable = regulator_disable_regmap, 360 .is_enabled = regulator_is_enabled_regmap, 361 .list_voltage = regulator_list_voltage_table, 362 .set_voltage_sel = regulator_set_voltage_sel_regmap, 363 .get_voltage_sel = regulator_get_voltage_sel_regmap, 364 .get_current_limit = regulator_get_current_limit_regmap, 365 .set_current_limit = regulator_set_current_limit_regmap, 366 .set_suspend_enable = pf8x00_suspend_enable, 367 .set_suspend_disable = pf8x00_suspend_disable, 368 }; 369 370 static const struct regulator_ops pf8x00_vsnvs_ops = { 371 .enable = regulator_enable_regmap, 372 .disable = regulator_disable_regmap, 373 .is_enabled = regulator_is_enabled_regmap, 374 .list_voltage = regulator_list_voltage_table, 375 .map_voltage = regulator_map_voltage_ascend, 376 .set_voltage_sel = regulator_set_voltage_sel_regmap, 377 .get_voltage_sel = regulator_get_voltage_sel_regmap, 378 }; 379 380 #define PF8X00LDO(_id, _name, base, voltages) \ 381 [PF8X00_LDO ## _id] = { \ 382 .desc = { \ 383 .name = _name, \ 384 .of_match = _name, \ 385 .regulators_node = "regulators", \ 386 .n_voltages = ARRAY_SIZE(voltages), \ 387 .ops = &pf8x00_ldo_ops, \ 388 .type = REGULATOR_VOLTAGE, \ 389 .id = PF8X00_LDO ## _id, \ 390 .owner = THIS_MODULE, \ 391 .volt_table = voltages, \ 392 .vsel_reg = (base) + LDO_RUN_VOLT, \ 393 .vsel_mask = 0xff, \ 394 .enable_reg = (base) + LDO_CONFIG2, \ 395 .enable_val = 0x2, \ 396 .disable_val = 0x0, \ 397 .enable_mask = 2, \ 398 }, \ 399 .suspend_enable_reg = (base) + LDO_CONFIG2, \ 400 .suspend_enable_mask = 1, \ 401 .suspend_voltage_reg = (base) + LDO_STBY_VOLT, \ 402 } 403 404 #define PF8X00BUCK(_id, _name, base, voltages) \ 405 [PF8X00_BUCK ## _id] = { \ 406 .desc = { \ 407 .name = _name, \ 408 .of_match = _name, \ 409 .regulators_node = "regulators", \ 410 .of_parse_cb = pf8x00_of_parse_cb, \ 411 .n_voltages = PF8XOO_SW1_6_VOLTAGE_NUM, \ 412 .ops = &pf8x00_buck1_6_ops, \ 413 .type = REGULATOR_VOLTAGE, \ 414 .id = PF8X00_BUCK ## _id, \ 415 .owner = THIS_MODULE, \ 416 .ramp_delay = 19000, \ 417 .linear_ranges = pf8x00_sw1_to_6_voltages, \ 418 .n_linear_ranges = \ 419 ARRAY_SIZE(pf8x00_sw1_to_6_voltages), \ 420 .vsel_reg = (base) + SW_RUN_VOLT, \ 421 .vsel_mask = 0xff, \ 422 .curr_table = pf8x00_sw_current_table, \ 423 .n_current_limits = \ 424 ARRAY_SIZE(pf8x00_sw_current_table), \ 425 .csel_reg = (base) + SW_CONFIG2, \ 426 .csel_mask = PF8X00_SWXILIM_MASK, \ 427 .enable_reg = (base) + SW_MODE1, \ 428 .enable_val = 0x3, \ 429 .disable_val = 0x0, \ 430 .enable_mask = 0x3, \ 431 .enable_time = 500, \ 432 }, \ 433 .suspend_enable_reg = (base) + SW_MODE1, \ 434 .suspend_enable_mask = 0xc, \ 435 .suspend_voltage_reg = (base) + SW_STBY_VOLT, \ 436 } 437 438 #define PF8X00BUCK7(_name, base, voltages) \ 439 [PF8X00_BUCK7] = { \ 440 .desc = { \ 441 .name = _name, \ 442 .of_match = _name, \ 443 .regulators_node = "regulators", \ 444 .of_parse_cb = pf8x00_of_parse_cb, \ 445 .n_voltages = ARRAY_SIZE(voltages), \ 446 .ops = &pf8x00_buck7_ops, \ 447 .type = REGULATOR_VOLTAGE, \ 448 .id = PF8X00_BUCK7, \ 449 .owner = THIS_MODULE, \ 450 .ramp_delay = 19000, \ 451 .volt_table = voltages, \ 452 .vsel_reg = (base) + SW_RUN_VOLT, \ 453 .vsel_mask = 0xff, \ 454 .curr_table = pf8x00_sw_current_table, \ 455 .n_current_limits = \ 456 ARRAY_SIZE(pf8x00_sw_current_table), \ 457 .csel_reg = (base) + SW_CONFIG2, \ 458 .csel_mask = PF8X00_SWXILIM_MASK, \ 459 .enable_reg = (base) + SW_MODE1, \ 460 .enable_val = 0x3, \ 461 .disable_val = 0x0, \ 462 .enable_mask = 0x3, \ 463 .enable_time = 500, \ 464 }, \ 465 } 466 467 468 #define PF8X00VSNVS(_name, base, voltages) \ 469 [PF8X00_VSNVS] = { \ 470 .desc = { \ 471 .name = _name, \ 472 .of_match = _name, \ 473 .regulators_node = "regulators", \ 474 .n_voltages = ARRAY_SIZE(voltages), \ 475 .ops = &pf8x00_vsnvs_ops, \ 476 .type = REGULATOR_VOLTAGE, \ 477 .id = PF8X00_VSNVS, \ 478 .owner = THIS_MODULE, \ 479 .volt_table = voltages, \ 480 .vsel_reg = (base), \ 481 .vsel_mask = 0x3, \ 482 }, \ 483 } 484 485 static struct pf8x00_regulator_data pf8x00_regs_data[PF8X00_MAX_REGULATORS] = { 486 PF8X00LDO(1, "ldo1", PF8X00_LDO_BASE(PF8X00_LDO1), pf8x00_ldo_voltages), 487 PF8X00LDO(2, "ldo2", PF8X00_LDO_BASE(PF8X00_LDO2), pf8x00_ldo_voltages), 488 PF8X00LDO(3, "ldo3", PF8X00_LDO_BASE(PF8X00_LDO3), pf8x00_ldo_voltages), 489 PF8X00LDO(4, "ldo4", PF8X00_LDO_BASE(PF8X00_LDO4), pf8x00_ldo_voltages), 490 PF8X00BUCK(1, "buck1", PF8X00_SW_BASE(PF8X00_BUCK1), pf8x00_sw1_to_6_voltages), 491 PF8X00BUCK(2, "buck2", PF8X00_SW_BASE(PF8X00_BUCK2), pf8x00_sw1_to_6_voltages), 492 PF8X00BUCK(3, "buck3", PF8X00_SW_BASE(PF8X00_BUCK3), pf8x00_sw1_to_6_voltages), 493 PF8X00BUCK(4, "buck4", PF8X00_SW_BASE(PF8X00_BUCK4), pf8x00_sw1_to_6_voltages), 494 PF8X00BUCK(5, "buck5", PF8X00_SW_BASE(PF8X00_BUCK5), pf8x00_sw1_to_6_voltages), 495 PF8X00BUCK(6, "buck6", PF8X00_SW_BASE(PF8X00_BUCK6), pf8x00_sw1_to_6_voltages), 496 PF8X00BUCK7("buck7", PF8X00_SW_BASE(PF8X00_BUCK7), pf8x00_sw7_voltages), 497 PF8X00VSNVS("vsnvs", PF8X00_VSNVS_CONFIG1, pf8x00_vsnvs_voltages), 498 }; 499 500 static int pf8x00_identify(struct pf8x00_chip *chip) 501 { 502 unsigned int value; 503 u8 dev_fam, dev_id; 504 const char *name = NULL; 505 int ret; 506 507 ret = regmap_read(chip->regmap, PF8X00_DEVICEID, &value); 508 if (ret) { 509 dev_err(chip->dev, "failed to read chip family\n"); 510 return ret; 511 } 512 513 dev_fam = value & PF8X00_DEVICE_FAM_MASK; 514 switch (dev_fam) { 515 case PF8X00_FAM: 516 break; 517 default: 518 dev_err(chip->dev, 519 "Chip 0x%x is not from PF8X00 family\n", dev_fam); 520 return ret; 521 } 522 523 dev_id = value & PF8X00_DEVICE_ID_MASK; 524 switch (dev_id) { 525 case PF8100: 526 name = "PF8100"; 527 break; 528 case PF8121A: 529 name = "PF8121A"; 530 break; 531 case PF8200: 532 name = "PF8200"; 533 break; 534 default: 535 dev_err(chip->dev, "Unknown pf8x00 device id 0x%x\n", dev_id); 536 return -ENODEV; 537 } 538 539 dev_info(chip->dev, "%s PMIC found.\n", name); 540 541 return 0; 542 } 543 544 static int pf8x00_i2c_probe(struct i2c_client *client) 545 { 546 struct regulator_config config = { NULL, }; 547 struct pf8x00_chip *chip; 548 int id; 549 int ret; 550 551 chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL); 552 if (!chip) 553 return -ENOMEM; 554 555 i2c_set_clientdata(client, chip); 556 chip->dev = &client->dev; 557 558 chip->regmap = devm_regmap_init_i2c(client, &pf8x00_regmap_config); 559 if (IS_ERR(chip->regmap)) { 560 ret = PTR_ERR(chip->regmap); 561 dev_err(&client->dev, 562 "regmap allocation failed with err %d\n", ret); 563 return ret; 564 } 565 566 ret = pf8x00_identify(chip); 567 if (ret) 568 return ret; 569 570 for (id = 0; id < ARRAY_SIZE(pf8x00_regs_data); id++) { 571 struct pf8x00_regulator_data *data = &pf8x00_regs_data[id]; 572 struct regulator_dev *rdev; 573 574 config.dev = chip->dev; 575 config.driver_data = data; 576 config.regmap = chip->regmap; 577 578 rdev = devm_regulator_register(&client->dev, &data->desc, &config); 579 if (IS_ERR(rdev)) { 580 dev_err(&client->dev, 581 "failed to register %s regulator\n", data->desc.name); 582 return PTR_ERR(rdev); 583 } 584 } 585 586 return 0; 587 } 588 589 static const struct of_device_id pf8x00_dt_ids[] = { 590 { .compatible = "nxp,pf8100",}, 591 { .compatible = "nxp,pf8121a",}, 592 { .compatible = "nxp,pf8200",}, 593 { } 594 }; 595 MODULE_DEVICE_TABLE(of, pf8x00_dt_ids); 596 597 static const struct i2c_device_id pf8x00_i2c_id[] = { 598 { "pf8100", 0 }, 599 { "pf8121a", 0 }, 600 { "pf8200", 0 }, 601 {}, 602 }; 603 MODULE_DEVICE_TABLE(i2c, pf8x00_i2c_id); 604 605 static struct i2c_driver pf8x00_regulator_driver = { 606 .id_table = pf8x00_i2c_id, 607 .driver = { 608 .name = "pf8x00", 609 .of_match_table = pf8x00_dt_ids, 610 }, 611 .probe_new = pf8x00_i2c_probe, 612 }; 613 module_i2c_driver(pf8x00_regulator_driver); 614 615 MODULE_AUTHOR("Jagan Teki <jagan@amarulasolutions.com>"); 616 MODULE_AUTHOR("Troy Kisky <troy.kisky@boundarydevices.com>"); 617 MODULE_DESCRIPTION("Regulator Driver for NXP's PF8100/PF8121A/PF8200 PMIC"); 618 MODULE_LICENSE("GPL v2"); 619