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