1 /* 2 * pv88080-regulator.c - Regulator device driver for PV88080 3 * Copyright (C) 2016 Powerventure Semiconductor Ltd. 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/err.h> 17 #include <linux/i2c.h> 18 #include <linux/module.h> 19 #include <linux/of.h> 20 #include <linux/init.h> 21 #include <linux/slab.h> 22 #include <linux/regulator/driver.h> 23 #include <linux/regulator/machine.h> 24 #include <linux/regmap.h> 25 #include <linux/irq.h> 26 #include <linux/interrupt.h> 27 #include <linux/regulator/of_regulator.h> 28 #include "pv88080-regulator.h" 29 30 #define PV88080_MAX_REGULATORS 4 31 32 /* PV88080 REGULATOR IDs */ 33 enum { 34 /* BUCKs */ 35 PV88080_ID_BUCK1, 36 PV88080_ID_BUCK2, 37 PV88080_ID_BUCK3, 38 PV88080_ID_HVBUCK, 39 }; 40 41 enum pv88080_types { 42 TYPE_PV88080_AA, 43 TYPE_PV88080_BA, 44 }; 45 46 struct pv88080_regulator { 47 struct regulator_desc desc; 48 /* Current limiting */ 49 unsigned int n_current_limits; 50 const int *current_limits; 51 unsigned int limit_mask; 52 unsigned int mode_reg; 53 unsigned int limit_reg; 54 unsigned int conf2; 55 unsigned int conf5; 56 }; 57 58 struct pv88080 { 59 struct device *dev; 60 struct regmap *regmap; 61 struct regulator_dev *rdev[PV88080_MAX_REGULATORS]; 62 unsigned long type; 63 const struct pv88080_compatible_regmap *regmap_config; 64 }; 65 66 struct pv88080_buck_voltage { 67 int min_uV; 68 int max_uV; 69 int uV_step; 70 }; 71 72 struct pv88080_buck_regmap { 73 /* REGS */ 74 int buck_enable_reg; 75 int buck_vsel_reg; 76 int buck_mode_reg; 77 int buck_limit_reg; 78 int buck_vdac_range_reg; 79 int buck_vrange_gain_reg; 80 /* MASKS */ 81 int buck_enable_mask; 82 int buck_vsel_mask; 83 int buck_limit_mask; 84 }; 85 86 struct pv88080_compatible_regmap { 87 /* BUCK1, 2, 3 */ 88 struct pv88080_buck_regmap buck_regmap[PV88080_MAX_REGULATORS-1]; 89 /* HVBUCK */ 90 int hvbuck_enable_reg; 91 int hvbuck_vsel_reg; 92 int hvbuck_enable_mask; 93 int hvbuck_vsel_mask; 94 }; 95 96 static const struct regmap_config pv88080_regmap_config = { 97 .reg_bits = 8, 98 .val_bits = 8, 99 }; 100 101 /* Current limits array (in uA) for BUCK1, BUCK2, BUCK3. 102 * Entry indexes corresponds to register values. 103 */ 104 105 static const int pv88080_buck1_limits[] = { 106 3230000, 5130000, 6960000, 8790000 107 }; 108 109 static const int pv88080_buck23_limits[] = { 110 1496000, 2393000, 3291000, 4189000 111 }; 112 113 static const struct pv88080_buck_voltage pv88080_buck_vol[2] = { 114 { 115 .min_uV = 600000, 116 .max_uV = 1393750, 117 .uV_step = 6250, 118 }, 119 { 120 .min_uV = 1400000, 121 .max_uV = 2193750, 122 .uV_step = 6250, 123 }, 124 }; 125 126 static const struct pv88080_compatible_regmap pv88080_aa_regs = { 127 /* BUCK1 */ 128 .buck_regmap[0] = { 129 .buck_enable_reg = PV88080AA_REG_BUCK1_CONF0, 130 .buck_vsel_reg = PV88080AA_REG_BUCK1_CONF0, 131 .buck_mode_reg = PV88080AA_REG_BUCK1_CONF1, 132 .buck_limit_reg = PV88080AA_REG_BUCK1_CONF1, 133 .buck_vdac_range_reg = PV88080AA_REG_BUCK1_CONF2, 134 .buck_vrange_gain_reg = PV88080AA_REG_BUCK1_CONF5, 135 .buck_enable_mask = PV88080_BUCK1_EN, 136 .buck_vsel_mask = PV88080_VBUCK1_MASK, 137 .buck_limit_mask = PV88080_BUCK1_ILIM_MASK, 138 }, 139 /* BUCK2 */ 140 .buck_regmap[1] = { 141 .buck_enable_reg = PV88080AA_REG_BUCK2_CONF0, 142 .buck_vsel_reg = PV88080AA_REG_BUCK2_CONF0, 143 .buck_mode_reg = PV88080AA_REG_BUCK2_CONF1, 144 .buck_limit_reg = PV88080AA_REG_BUCK2_CONF1, 145 .buck_vdac_range_reg = PV88080AA_REG_BUCK2_CONF2, 146 .buck_vrange_gain_reg = PV88080AA_REG_BUCK2_CONF5, 147 .buck_enable_mask = PV88080_BUCK2_EN, 148 .buck_vsel_mask = PV88080_VBUCK2_MASK, 149 .buck_limit_mask = PV88080_BUCK2_ILIM_MASK, 150 }, 151 /* BUCK3 */ 152 .buck_regmap[2] = { 153 .buck_enable_reg = PV88080AA_REG_BUCK3_CONF0, 154 .buck_vsel_reg = PV88080AA_REG_BUCK3_CONF0, 155 .buck_mode_reg = PV88080AA_REG_BUCK3_CONF1, 156 .buck_limit_reg = PV88080AA_REG_BUCK3_CONF1, 157 .buck_vdac_range_reg = PV88080AA_REG_BUCK3_CONF2, 158 .buck_vrange_gain_reg = PV88080AA_REG_BUCK3_CONF5, 159 .buck_enable_mask = PV88080_BUCK3_EN, 160 .buck_vsel_mask = PV88080_VBUCK3_MASK, 161 .buck_limit_mask = PV88080_BUCK3_ILIM_MASK, 162 }, 163 /* HVBUCK */ 164 .hvbuck_enable_reg = PV88080AA_REG_HVBUCK_CONF2, 165 .hvbuck_vsel_reg = PV88080AA_REG_HVBUCK_CONF1, 166 .hvbuck_enable_mask = PV88080_HVBUCK_EN, 167 .hvbuck_vsel_mask = PV88080_VHVBUCK_MASK, 168 }; 169 170 static const struct pv88080_compatible_regmap pv88080_ba_regs = { 171 /* BUCK1 */ 172 .buck_regmap[0] = { 173 .buck_enable_reg = PV88080BA_REG_BUCK1_CONF0, 174 .buck_vsel_reg = PV88080BA_REG_BUCK1_CONF0, 175 .buck_mode_reg = PV88080BA_REG_BUCK1_CONF1, 176 .buck_limit_reg = PV88080BA_REG_BUCK1_CONF1, 177 .buck_vdac_range_reg = PV88080BA_REG_BUCK1_CONF2, 178 .buck_vrange_gain_reg = PV88080BA_REG_BUCK1_CONF5, 179 .buck_enable_mask = PV88080_BUCK1_EN, 180 .buck_vsel_mask = PV88080_VBUCK1_MASK, 181 .buck_limit_mask = PV88080_BUCK1_ILIM_MASK, 182 }, 183 /* BUCK2 */ 184 .buck_regmap[1] = { 185 .buck_enable_reg = PV88080BA_REG_BUCK2_CONF0, 186 .buck_vsel_reg = PV88080BA_REG_BUCK2_CONF0, 187 .buck_mode_reg = PV88080BA_REG_BUCK2_CONF1, 188 .buck_limit_reg = PV88080BA_REG_BUCK2_CONF1, 189 .buck_vdac_range_reg = PV88080BA_REG_BUCK2_CONF2, 190 .buck_vrange_gain_reg = PV88080BA_REG_BUCK2_CONF5, 191 .buck_enable_mask = PV88080_BUCK2_EN, 192 .buck_vsel_mask = PV88080_VBUCK2_MASK, 193 .buck_limit_mask = PV88080_BUCK2_ILIM_MASK, 194 }, 195 /* BUCK3 */ 196 .buck_regmap[2] = { 197 .buck_enable_reg = PV88080BA_REG_BUCK3_CONF0, 198 .buck_vsel_reg = PV88080BA_REG_BUCK3_CONF0, 199 .buck_mode_reg = PV88080BA_REG_BUCK3_CONF1, 200 .buck_limit_reg = PV88080BA_REG_BUCK3_CONF1, 201 .buck_vdac_range_reg = PV88080BA_REG_BUCK3_CONF2, 202 .buck_vrange_gain_reg = PV88080BA_REG_BUCK3_CONF5, 203 .buck_enable_mask = PV88080_BUCK3_EN, 204 .buck_vsel_mask = PV88080_VBUCK3_MASK, 205 .buck_limit_mask = PV88080_BUCK3_ILIM_MASK, 206 }, 207 /* HVBUCK */ 208 .hvbuck_enable_reg = PV88080BA_REG_HVBUCK_CONF2, 209 .hvbuck_vsel_reg = PV88080BA_REG_HVBUCK_CONF1, 210 .hvbuck_enable_mask = PV88080_HVBUCK_EN, 211 .hvbuck_vsel_mask = PV88080_VHVBUCK_MASK, 212 }; 213 214 #ifdef CONFIG_OF 215 static const struct of_device_id pv88080_dt_ids[] = { 216 { .compatible = "pvs,pv88080", .data = (void *)TYPE_PV88080_AA }, 217 { .compatible = "pvs,pv88080-aa", .data = (void *)TYPE_PV88080_AA }, 218 { .compatible = "pvs,pv88080-ba", .data = (void *)TYPE_PV88080_BA }, 219 {}, 220 }; 221 MODULE_DEVICE_TABLE(of, pv88080_dt_ids); 222 #endif 223 224 static unsigned int pv88080_buck_get_mode(struct regulator_dev *rdev) 225 { 226 struct pv88080_regulator *info = rdev_get_drvdata(rdev); 227 unsigned int data; 228 int ret, mode = 0; 229 230 ret = regmap_read(rdev->regmap, info->mode_reg, &data); 231 if (ret < 0) 232 return ret; 233 234 switch (data & PV88080_BUCK1_MODE_MASK) { 235 case PV88080_BUCK_MODE_SYNC: 236 mode = REGULATOR_MODE_FAST; 237 break; 238 case PV88080_BUCK_MODE_AUTO: 239 mode = REGULATOR_MODE_NORMAL; 240 break; 241 case PV88080_BUCK_MODE_SLEEP: 242 mode = REGULATOR_MODE_STANDBY; 243 break; 244 default: 245 return -EINVAL; 246 } 247 248 return mode; 249 } 250 251 static int pv88080_buck_set_mode(struct regulator_dev *rdev, 252 unsigned int mode) 253 { 254 struct pv88080_regulator *info = rdev_get_drvdata(rdev); 255 int val = 0; 256 257 switch (mode) { 258 case REGULATOR_MODE_FAST: 259 val = PV88080_BUCK_MODE_SYNC; 260 break; 261 case REGULATOR_MODE_NORMAL: 262 val = PV88080_BUCK_MODE_AUTO; 263 break; 264 case REGULATOR_MODE_STANDBY: 265 val = PV88080_BUCK_MODE_SLEEP; 266 break; 267 default: 268 return -EINVAL; 269 } 270 271 return regmap_update_bits(rdev->regmap, info->mode_reg, 272 PV88080_BUCK1_MODE_MASK, val); 273 } 274 275 static int pv88080_set_current_limit(struct regulator_dev *rdev, int min, 276 int max) 277 { 278 struct pv88080_regulator *info = rdev_get_drvdata(rdev); 279 int i; 280 281 /* search for closest to maximum */ 282 for (i = info->n_current_limits; i >= 0; i--) { 283 if (min <= info->current_limits[i] 284 && max >= info->current_limits[i]) { 285 return regmap_update_bits(rdev->regmap, 286 info->limit_reg, 287 info->limit_mask, 288 i << PV88080_BUCK1_ILIM_SHIFT); 289 } 290 } 291 292 return -EINVAL; 293 } 294 295 static int pv88080_get_current_limit(struct regulator_dev *rdev) 296 { 297 struct pv88080_regulator *info = rdev_get_drvdata(rdev); 298 unsigned int data; 299 int ret; 300 301 ret = regmap_read(rdev->regmap, info->limit_reg, &data); 302 if (ret < 0) 303 return ret; 304 305 data = (data & info->limit_mask) >> PV88080_BUCK1_ILIM_SHIFT; 306 return info->current_limits[data]; 307 } 308 309 static const struct regulator_ops pv88080_buck_ops = { 310 .get_mode = pv88080_buck_get_mode, 311 .set_mode = pv88080_buck_set_mode, 312 .enable = regulator_enable_regmap, 313 .disable = regulator_disable_regmap, 314 .is_enabled = regulator_is_enabled_regmap, 315 .set_voltage_sel = regulator_set_voltage_sel_regmap, 316 .get_voltage_sel = regulator_get_voltage_sel_regmap, 317 .list_voltage = regulator_list_voltage_linear, 318 .set_current_limit = pv88080_set_current_limit, 319 .get_current_limit = pv88080_get_current_limit, 320 }; 321 322 static const struct regulator_ops pv88080_hvbuck_ops = { 323 .enable = regulator_enable_regmap, 324 .disable = regulator_disable_regmap, 325 .is_enabled = regulator_is_enabled_regmap, 326 .set_voltage_sel = regulator_set_voltage_sel_regmap, 327 .get_voltage_sel = regulator_get_voltage_sel_regmap, 328 .list_voltage = regulator_list_voltage_linear, 329 }; 330 331 #define PV88080_BUCK(chip, regl_name, min, step, max, limits_array) \ 332 {\ 333 .desc = {\ 334 .id = chip##_ID_##regl_name,\ 335 .name = __stringify(chip##_##regl_name),\ 336 .of_match = of_match_ptr(#regl_name),\ 337 .regulators_node = of_match_ptr("regulators"),\ 338 .type = REGULATOR_VOLTAGE,\ 339 .owner = THIS_MODULE,\ 340 .ops = &pv88080_buck_ops,\ 341 .min_uV = min, \ 342 .uV_step = step, \ 343 .n_voltages = ((max) - (min))/(step) + 1, \ 344 },\ 345 .current_limits = limits_array, \ 346 .n_current_limits = ARRAY_SIZE(limits_array), \ 347 } 348 349 #define PV88080_HVBUCK(chip, regl_name, min, step, max) \ 350 {\ 351 .desc = {\ 352 .id = chip##_ID_##regl_name,\ 353 .name = __stringify(chip##_##regl_name),\ 354 .of_match = of_match_ptr(#regl_name),\ 355 .regulators_node = of_match_ptr("regulators"),\ 356 .type = REGULATOR_VOLTAGE,\ 357 .owner = THIS_MODULE,\ 358 .ops = &pv88080_hvbuck_ops,\ 359 .min_uV = min, \ 360 .uV_step = step, \ 361 .n_voltages = ((max) - (min))/(step) + 1, \ 362 },\ 363 } 364 365 static struct pv88080_regulator pv88080_regulator_info[] = { 366 PV88080_BUCK(PV88080, BUCK1, 600000, 6250, 1393750, 367 pv88080_buck1_limits), 368 PV88080_BUCK(PV88080, BUCK2, 600000, 6250, 1393750, 369 pv88080_buck23_limits), 370 PV88080_BUCK(PV88080, BUCK3, 600000, 6250, 1393750, 371 pv88080_buck23_limits), 372 PV88080_HVBUCK(PV88080, HVBUCK, 0, 5000, 1275000), 373 }; 374 375 static irqreturn_t pv88080_irq_handler(int irq, void *data) 376 { 377 struct pv88080 *chip = data; 378 int i, reg_val, err, ret = IRQ_NONE; 379 380 err = regmap_read(chip->regmap, PV88080_REG_EVENT_A, ®_val); 381 if (err < 0) 382 goto error_i2c; 383 384 if (reg_val & PV88080_E_VDD_FLT) { 385 for (i = 0; i < PV88080_MAX_REGULATORS; i++) { 386 if (chip->rdev[i] != NULL) { 387 regulator_notifier_call_chain(chip->rdev[i], 388 REGULATOR_EVENT_UNDER_VOLTAGE, 389 NULL); 390 } 391 } 392 393 err = regmap_write(chip->regmap, PV88080_REG_EVENT_A, 394 PV88080_E_VDD_FLT); 395 if (err < 0) 396 goto error_i2c; 397 398 ret = IRQ_HANDLED; 399 } 400 401 if (reg_val & PV88080_E_OVER_TEMP) { 402 for (i = 0; i < PV88080_MAX_REGULATORS; i++) { 403 if (chip->rdev[i] != NULL) { 404 regulator_notifier_call_chain(chip->rdev[i], 405 REGULATOR_EVENT_OVER_TEMP, 406 NULL); 407 } 408 } 409 410 err = regmap_write(chip->regmap, PV88080_REG_EVENT_A, 411 PV88080_E_OVER_TEMP); 412 if (err < 0) 413 goto error_i2c; 414 415 ret = IRQ_HANDLED; 416 } 417 418 return ret; 419 420 error_i2c: 421 dev_err(chip->dev, "I2C error : %d\n", err); 422 return IRQ_NONE; 423 } 424 425 /* 426 * I2C driver interface functions 427 */ 428 static int pv88080_i2c_probe(struct i2c_client *i2c, 429 const struct i2c_device_id *id) 430 { 431 struct regulator_init_data *init_data = dev_get_platdata(&i2c->dev); 432 struct pv88080 *chip; 433 const struct pv88080_compatible_regmap *regmap_config; 434 const struct of_device_id *match; 435 struct regulator_config config = { }; 436 int i, error, ret; 437 unsigned int conf2, conf5; 438 439 chip = devm_kzalloc(&i2c->dev, sizeof(struct pv88080), GFP_KERNEL); 440 if (!chip) 441 return -ENOMEM; 442 443 chip->dev = &i2c->dev; 444 chip->regmap = devm_regmap_init_i2c(i2c, &pv88080_regmap_config); 445 if (IS_ERR(chip->regmap)) { 446 error = PTR_ERR(chip->regmap); 447 dev_err(chip->dev, "Failed to allocate register map: %d\n", 448 error); 449 return error; 450 } 451 452 if (i2c->dev.of_node) { 453 match = of_match_node(pv88080_dt_ids, i2c->dev.of_node); 454 if (!match) { 455 dev_err(chip->dev, "Failed to get of_match_node\n"); 456 return -EINVAL; 457 } 458 chip->type = (unsigned long)match->data; 459 } else { 460 chip->type = id->driver_data; 461 } 462 463 i2c_set_clientdata(i2c, chip); 464 465 if (i2c->irq != 0) { 466 ret = regmap_write(chip->regmap, PV88080_REG_MASK_A, 0xFF); 467 if (ret < 0) { 468 dev_err(chip->dev, 469 "Failed to mask A reg: %d\n", ret); 470 return ret; 471 } 472 ret = regmap_write(chip->regmap, PV88080_REG_MASK_B, 0xFF); 473 if (ret < 0) { 474 dev_err(chip->dev, 475 "Failed to mask B reg: %d\n", ret); 476 return ret; 477 } 478 ret = regmap_write(chip->regmap, PV88080_REG_MASK_C, 0xFF); 479 if (ret < 0) { 480 dev_err(chip->dev, 481 "Failed to mask C reg: %d\n", ret); 482 return ret; 483 } 484 485 ret = devm_request_threaded_irq(&i2c->dev, i2c->irq, NULL, 486 pv88080_irq_handler, 487 IRQF_TRIGGER_LOW|IRQF_ONESHOT, 488 "pv88080", chip); 489 if (ret != 0) { 490 dev_err(chip->dev, "Failed to request IRQ: %d\n", 491 i2c->irq); 492 return ret; 493 } 494 495 ret = regmap_update_bits(chip->regmap, PV88080_REG_MASK_A, 496 PV88080_M_VDD_FLT | PV88080_M_OVER_TEMP, 0); 497 if (ret < 0) { 498 dev_err(chip->dev, 499 "Failed to update mask reg: %d\n", ret); 500 return ret; 501 } 502 } else { 503 dev_warn(chip->dev, "No IRQ configured\n"); 504 } 505 506 switch (chip->type) { 507 case TYPE_PV88080_AA: 508 chip->regmap_config = &pv88080_aa_regs; 509 break; 510 case TYPE_PV88080_BA: 511 chip->regmap_config = &pv88080_ba_regs; 512 break; 513 } 514 515 regmap_config = chip->regmap_config; 516 config.dev = chip->dev; 517 config.regmap = chip->regmap; 518 519 /* Registeration for BUCK1, 2, 3 */ 520 for (i = 0; i < PV88080_MAX_REGULATORS-1; i++) { 521 if (init_data) 522 config.init_data = &init_data[i]; 523 524 pv88080_regulator_info[i].limit_reg 525 = regmap_config->buck_regmap[i].buck_limit_reg; 526 pv88080_regulator_info[i].limit_mask 527 = regmap_config->buck_regmap[i].buck_limit_mask; 528 pv88080_regulator_info[i].mode_reg 529 = regmap_config->buck_regmap[i].buck_mode_reg; 530 pv88080_regulator_info[i].conf2 531 = regmap_config->buck_regmap[i].buck_vdac_range_reg; 532 pv88080_regulator_info[i].conf5 533 = regmap_config->buck_regmap[i].buck_vrange_gain_reg; 534 pv88080_regulator_info[i].desc.enable_reg 535 = regmap_config->buck_regmap[i].buck_enable_reg; 536 pv88080_regulator_info[i].desc.enable_mask 537 = regmap_config->buck_regmap[i].buck_enable_mask; 538 pv88080_regulator_info[i].desc.vsel_reg 539 = regmap_config->buck_regmap[i].buck_vsel_reg; 540 pv88080_regulator_info[i].desc.vsel_mask 541 = regmap_config->buck_regmap[i].buck_vsel_mask; 542 543 ret = regmap_read(chip->regmap, 544 pv88080_regulator_info[i].conf2, &conf2); 545 if (ret < 0) 546 return ret; 547 conf2 = ((conf2 >> PV88080_BUCK_VDAC_RANGE_SHIFT) & 548 PV88080_BUCK_VDAC_RANGE_MASK); 549 550 ret = regmap_read(chip->regmap, 551 pv88080_regulator_info[i].conf5, &conf5); 552 if (ret < 0) 553 return ret; 554 conf5 = ((conf5 >> PV88080_BUCK_VRANGE_GAIN_SHIFT) & 555 PV88080_BUCK_VRANGE_GAIN_MASK); 556 557 pv88080_regulator_info[i].desc.min_uV = 558 pv88080_buck_vol[conf2].min_uV * (conf5+1); 559 pv88080_regulator_info[i].desc.uV_step = 560 pv88080_buck_vol[conf2].uV_step * (conf5+1); 561 pv88080_regulator_info[i].desc.n_voltages = 562 ((pv88080_buck_vol[conf2].max_uV * (conf5+1)) 563 - (pv88080_regulator_info[i].desc.min_uV)) 564 /(pv88080_regulator_info[i].desc.uV_step) + 1; 565 566 config.driver_data = (void *)&pv88080_regulator_info[i]; 567 chip->rdev[i] = devm_regulator_register(chip->dev, 568 &pv88080_regulator_info[i].desc, &config); 569 if (IS_ERR(chip->rdev[i])) { 570 dev_err(chip->dev, 571 "Failed to register PV88080 regulator\n"); 572 return PTR_ERR(chip->rdev[i]); 573 } 574 } 575 576 pv88080_regulator_info[PV88080_ID_HVBUCK].desc.enable_reg 577 = regmap_config->hvbuck_enable_reg; 578 pv88080_regulator_info[PV88080_ID_HVBUCK].desc.enable_mask 579 = regmap_config->hvbuck_enable_mask; 580 pv88080_regulator_info[PV88080_ID_HVBUCK].desc.vsel_reg 581 = regmap_config->hvbuck_vsel_reg; 582 pv88080_regulator_info[PV88080_ID_HVBUCK].desc.vsel_mask 583 = regmap_config->hvbuck_vsel_mask; 584 585 /* Registeration for HVBUCK */ 586 if (init_data) 587 config.init_data = &init_data[PV88080_ID_HVBUCK]; 588 589 config.driver_data = (void *)&pv88080_regulator_info[PV88080_ID_HVBUCK]; 590 chip->rdev[PV88080_ID_HVBUCK] = devm_regulator_register(chip->dev, 591 &pv88080_regulator_info[PV88080_ID_HVBUCK].desc, &config); 592 if (IS_ERR(chip->rdev[PV88080_ID_HVBUCK])) { 593 dev_err(chip->dev, "Failed to register PV88080 regulator\n"); 594 return PTR_ERR(chip->rdev[PV88080_ID_HVBUCK]); 595 } 596 597 return 0; 598 } 599 600 static const struct i2c_device_id pv88080_i2c_id[] = { 601 { "pv88080", TYPE_PV88080_AA }, 602 { "pv88080-aa", TYPE_PV88080_AA }, 603 { "pv88080-ba", TYPE_PV88080_BA }, 604 {}, 605 }; 606 MODULE_DEVICE_TABLE(i2c, pv88080_i2c_id); 607 608 static struct i2c_driver pv88080_regulator_driver = { 609 .driver = { 610 .name = "pv88080", 611 .of_match_table = of_match_ptr(pv88080_dt_ids), 612 }, 613 .probe = pv88080_i2c_probe, 614 .id_table = pv88080_i2c_id, 615 }; 616 617 module_i2c_driver(pv88080_regulator_driver); 618 619 MODULE_AUTHOR("James Ban <James.Ban.opensource@diasemi.com>"); 620 MODULE_DESCRIPTION("Regulator device driver for Powerventure PV88080"); 621 MODULE_LICENSE("GPL"); 622