1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * TI LP8788 MFD - buck regulator driver 4 * 5 * Copyright 2012 Texas Instruments 6 * 7 * Author: Milo(Woogyom) Kim <milo.kim@ti.com> 8 */ 9 10 #include <linux/module.h> 11 #include <linux/slab.h> 12 #include <linux/err.h> 13 #include <linux/platform_device.h> 14 #include <linux/regulator/driver.h> 15 #include <linux/mfd/lp8788.h> 16 #include <linux/gpio/consumer.h> 17 18 /* register address */ 19 #define LP8788_EN_BUCK 0x0C 20 #define LP8788_BUCK_DVS_SEL 0x1D 21 #define LP8788_BUCK1_VOUT0 0x1E 22 #define LP8788_BUCK1_VOUT1 0x1F 23 #define LP8788_BUCK1_VOUT2 0x20 24 #define LP8788_BUCK1_VOUT3 0x21 25 #define LP8788_BUCK2_VOUT0 0x22 26 #define LP8788_BUCK2_VOUT1 0x23 27 #define LP8788_BUCK2_VOUT2 0x24 28 #define LP8788_BUCK2_VOUT3 0x25 29 #define LP8788_BUCK3_VOUT 0x26 30 #define LP8788_BUCK4_VOUT 0x27 31 #define LP8788_BUCK1_TIMESTEP 0x28 32 #define LP8788_BUCK_PWM 0x2D 33 34 /* mask/shift bits */ 35 #define LP8788_EN_BUCK1_M BIT(0) /* Addr 0Ch */ 36 #define LP8788_EN_BUCK2_M BIT(1) 37 #define LP8788_EN_BUCK3_M BIT(2) 38 #define LP8788_EN_BUCK4_M BIT(3) 39 #define LP8788_BUCK1_DVS_SEL_M 0x04 /* Addr 1Dh */ 40 #define LP8788_BUCK1_DVS_M 0x03 41 #define LP8788_BUCK1_DVS_S 0 42 #define LP8788_BUCK2_DVS_SEL_M 0x40 43 #define LP8788_BUCK2_DVS_M 0x30 44 #define LP8788_BUCK2_DVS_S 4 45 #define LP8788_BUCK1_DVS_I2C BIT(2) 46 #define LP8788_BUCK2_DVS_I2C BIT(6) 47 #define LP8788_BUCK1_DVS_PIN (0 << 2) 48 #define LP8788_BUCK2_DVS_PIN (0 << 6) 49 #define LP8788_VOUT_M 0x1F /* Addr 1Eh ~ 27h */ 50 #define LP8788_STARTUP_TIME_M 0xF8 /* Addr 28h ~ 2Bh */ 51 #define LP8788_STARTUP_TIME_S 3 52 #define LP8788_FPWM_BUCK1_M BIT(0) /* Addr 2Dh */ 53 #define LP8788_FPWM_BUCK1_S 0 54 #define LP8788_FPWM_BUCK2_M BIT(1) 55 #define LP8788_FPWM_BUCK2_S 1 56 #define LP8788_FPWM_BUCK3_M BIT(2) 57 #define LP8788_FPWM_BUCK3_S 2 58 #define LP8788_FPWM_BUCK4_M BIT(3) 59 #define LP8788_FPWM_BUCK4_S 3 60 61 #define INVALID_ADDR 0xFF 62 #define LP8788_FORCE_PWM 1 63 #define LP8788_AUTO_PWM 0 64 #define PIN_LOW 0 65 #define PIN_HIGH 1 66 #define ENABLE_TIME_USEC 32 67 68 #define BUCK_FPWM_MASK(x) (1 << (x)) 69 #define BUCK_FPWM_SHIFT(x) (x) 70 71 enum lp8788_dvs_state { 72 DVS_LOW = 0, 73 DVS_HIGH = 1, 74 }; 75 76 enum lp8788_dvs_mode { 77 REGISTER, 78 EXTPIN, 79 }; 80 81 enum lp8788_buck_id { 82 BUCK1, 83 BUCK2, 84 BUCK3, 85 BUCK4, 86 }; 87 88 struct lp8788_buck { 89 struct lp8788 *lp; 90 struct regulator_dev *regulator; 91 void *dvs; 92 struct gpio_desc *gpio1; 93 struct gpio_desc *gpio2; /* Only used on BUCK2 */ 94 }; 95 96 /* BUCK 1 ~ 4 voltage ranges */ 97 static const struct linear_range buck_volt_ranges[] = { 98 REGULATOR_LINEAR_RANGE(500000, 0, 0, 0), 99 REGULATOR_LINEAR_RANGE(800000, 1, 25, 50000), 100 }; 101 102 static void lp8788_buck1_set_dvs(struct lp8788_buck *buck) 103 { 104 struct lp8788_buck1_dvs *dvs = (struct lp8788_buck1_dvs *)buck->dvs; 105 enum lp8788_dvs_state pinstate; 106 107 if (!dvs) 108 return; 109 110 pinstate = dvs->vsel == DVS_SEL_V0 ? DVS_LOW : DVS_HIGH; 111 gpiod_set_value(buck->gpio1, pinstate); 112 } 113 114 static void lp8788_buck2_set_dvs(struct lp8788_buck *buck) 115 { 116 struct lp8788_buck2_dvs *dvs = (struct lp8788_buck2_dvs *)buck->dvs; 117 enum lp8788_dvs_state pin1, pin2; 118 119 if (!dvs) 120 return; 121 122 switch (dvs->vsel) { 123 case DVS_SEL_V0: 124 pin1 = DVS_LOW; 125 pin2 = DVS_LOW; 126 break; 127 case DVS_SEL_V1: 128 pin1 = DVS_HIGH; 129 pin2 = DVS_LOW; 130 break; 131 case DVS_SEL_V2: 132 pin1 = DVS_LOW; 133 pin2 = DVS_HIGH; 134 break; 135 case DVS_SEL_V3: 136 pin1 = DVS_HIGH; 137 pin2 = DVS_HIGH; 138 break; 139 default: 140 return; 141 } 142 143 gpiod_set_value(buck->gpio1, pin1); 144 gpiod_set_value(buck->gpio2, pin2); 145 } 146 147 static void lp8788_set_dvs(struct lp8788_buck *buck, enum lp8788_buck_id id) 148 { 149 switch (id) { 150 case BUCK1: 151 lp8788_buck1_set_dvs(buck); 152 break; 153 case BUCK2: 154 lp8788_buck2_set_dvs(buck); 155 break; 156 default: 157 break; 158 } 159 } 160 161 static enum lp8788_dvs_mode 162 lp8788_get_buck_dvs_ctrl_mode(struct lp8788_buck *buck, enum lp8788_buck_id id) 163 { 164 u8 val, mask; 165 166 switch (id) { 167 case BUCK1: 168 mask = LP8788_BUCK1_DVS_SEL_M; 169 break; 170 case BUCK2: 171 mask = LP8788_BUCK2_DVS_SEL_M; 172 break; 173 default: 174 return REGISTER; 175 } 176 177 lp8788_read_byte(buck->lp, LP8788_BUCK_DVS_SEL, &val); 178 179 return val & mask ? REGISTER : EXTPIN; 180 } 181 182 static bool lp8788_is_valid_buck_addr(u8 addr) 183 { 184 switch (addr) { 185 case LP8788_BUCK1_VOUT0: 186 case LP8788_BUCK1_VOUT1: 187 case LP8788_BUCK1_VOUT2: 188 case LP8788_BUCK1_VOUT3: 189 case LP8788_BUCK2_VOUT0: 190 case LP8788_BUCK2_VOUT1: 191 case LP8788_BUCK2_VOUT2: 192 case LP8788_BUCK2_VOUT3: 193 return true; 194 default: 195 return false; 196 } 197 } 198 199 static u8 lp8788_select_buck_vout_addr(struct lp8788_buck *buck, 200 enum lp8788_buck_id id) 201 { 202 enum lp8788_dvs_mode mode = lp8788_get_buck_dvs_ctrl_mode(buck, id); 203 u8 val, idx, addr; 204 int pin1, pin2; 205 206 switch (id) { 207 case BUCK1: 208 if (mode == EXTPIN) { 209 idx = gpiod_get_value(buck->gpio1); 210 } else { 211 lp8788_read_byte(buck->lp, LP8788_BUCK_DVS_SEL, &val); 212 idx = (val & LP8788_BUCK1_DVS_M) >> LP8788_BUCK1_DVS_S; 213 } 214 addr = LP8788_BUCK1_VOUT0 + idx; 215 break; 216 case BUCK2: 217 if (mode == EXTPIN) { 218 pin1 = gpiod_get_value(buck->gpio1); 219 pin2 = gpiod_get_value(buck->gpio2); 220 221 if (pin1 == PIN_LOW && pin2 == PIN_LOW) 222 idx = 0; 223 else if (pin1 == PIN_LOW && pin2 == PIN_HIGH) 224 idx = 2; 225 else if (pin1 == PIN_HIGH && pin2 == PIN_LOW) 226 idx = 1; 227 else 228 idx = 3; 229 } else { 230 lp8788_read_byte(buck->lp, LP8788_BUCK_DVS_SEL, &val); 231 idx = (val & LP8788_BUCK2_DVS_M) >> LP8788_BUCK2_DVS_S; 232 } 233 addr = LP8788_BUCK2_VOUT0 + idx; 234 break; 235 default: 236 goto err; 237 } 238 239 return addr; 240 err: 241 return INVALID_ADDR; 242 } 243 244 static int lp8788_buck12_set_voltage_sel(struct regulator_dev *rdev, 245 unsigned selector) 246 { 247 struct lp8788_buck *buck = rdev_get_drvdata(rdev); 248 enum lp8788_buck_id id = rdev_get_id(rdev); 249 u8 addr; 250 251 if (buck->dvs) 252 lp8788_set_dvs(buck, id); 253 254 addr = lp8788_select_buck_vout_addr(buck, id); 255 if (!lp8788_is_valid_buck_addr(addr)) 256 return -EINVAL; 257 258 return lp8788_update_bits(buck->lp, addr, LP8788_VOUT_M, selector); 259 } 260 261 static int lp8788_buck12_get_voltage_sel(struct regulator_dev *rdev) 262 { 263 struct lp8788_buck *buck = rdev_get_drvdata(rdev); 264 enum lp8788_buck_id id = rdev_get_id(rdev); 265 int ret; 266 u8 val, addr; 267 268 addr = lp8788_select_buck_vout_addr(buck, id); 269 if (!lp8788_is_valid_buck_addr(addr)) 270 return -EINVAL; 271 272 ret = lp8788_read_byte(buck->lp, addr, &val); 273 if (ret) 274 return ret; 275 276 return val & LP8788_VOUT_M; 277 } 278 279 static int lp8788_buck_enable_time(struct regulator_dev *rdev) 280 { 281 struct lp8788_buck *buck = rdev_get_drvdata(rdev); 282 enum lp8788_buck_id id = rdev_get_id(rdev); 283 u8 val, addr = LP8788_BUCK1_TIMESTEP + id; 284 285 if (lp8788_read_byte(buck->lp, addr, &val)) 286 return -EINVAL; 287 288 val = (val & LP8788_STARTUP_TIME_M) >> LP8788_STARTUP_TIME_S; 289 290 return ENABLE_TIME_USEC * val; 291 } 292 293 static int lp8788_buck_set_mode(struct regulator_dev *rdev, unsigned int mode) 294 { 295 struct lp8788_buck *buck = rdev_get_drvdata(rdev); 296 enum lp8788_buck_id id = rdev_get_id(rdev); 297 u8 mask, val; 298 299 mask = BUCK_FPWM_MASK(id); 300 switch (mode) { 301 case REGULATOR_MODE_FAST: 302 val = LP8788_FORCE_PWM << BUCK_FPWM_SHIFT(id); 303 break; 304 case REGULATOR_MODE_NORMAL: 305 val = LP8788_AUTO_PWM << BUCK_FPWM_SHIFT(id); 306 break; 307 default: 308 return -EINVAL; 309 } 310 311 return lp8788_update_bits(buck->lp, LP8788_BUCK_PWM, mask, val); 312 } 313 314 static unsigned int lp8788_buck_get_mode(struct regulator_dev *rdev) 315 { 316 struct lp8788_buck *buck = rdev_get_drvdata(rdev); 317 enum lp8788_buck_id id = rdev_get_id(rdev); 318 u8 val; 319 int ret; 320 321 ret = lp8788_read_byte(buck->lp, LP8788_BUCK_PWM, &val); 322 if (ret) 323 return ret; 324 325 return val & BUCK_FPWM_MASK(id) ? 326 REGULATOR_MODE_FAST : REGULATOR_MODE_NORMAL; 327 } 328 329 static const struct regulator_ops lp8788_buck12_ops = { 330 .list_voltage = regulator_list_voltage_linear_range, 331 .map_voltage = regulator_map_voltage_linear_range, 332 .set_voltage_sel = lp8788_buck12_set_voltage_sel, 333 .get_voltage_sel = lp8788_buck12_get_voltage_sel, 334 .enable = regulator_enable_regmap, 335 .disable = regulator_disable_regmap, 336 .is_enabled = regulator_is_enabled_regmap, 337 .enable_time = lp8788_buck_enable_time, 338 .set_mode = lp8788_buck_set_mode, 339 .get_mode = lp8788_buck_get_mode, 340 }; 341 342 static const struct regulator_ops lp8788_buck34_ops = { 343 .list_voltage = regulator_list_voltage_linear_range, 344 .map_voltage = regulator_map_voltage_linear_range, 345 .set_voltage_sel = regulator_set_voltage_sel_regmap, 346 .get_voltage_sel = regulator_get_voltage_sel_regmap, 347 .enable = regulator_enable_regmap, 348 .disable = regulator_disable_regmap, 349 .is_enabled = regulator_is_enabled_regmap, 350 .enable_time = lp8788_buck_enable_time, 351 .set_mode = lp8788_buck_set_mode, 352 .get_mode = lp8788_buck_get_mode, 353 }; 354 355 static const struct regulator_desc lp8788_buck_desc[] = { 356 { 357 .name = "buck1", 358 .id = BUCK1, 359 .ops = &lp8788_buck12_ops, 360 .n_voltages = 26, 361 .linear_ranges = buck_volt_ranges, 362 .n_linear_ranges = ARRAY_SIZE(buck_volt_ranges), 363 .type = REGULATOR_VOLTAGE, 364 .owner = THIS_MODULE, 365 .enable_reg = LP8788_EN_BUCK, 366 .enable_mask = LP8788_EN_BUCK1_M, 367 }, 368 { 369 .name = "buck2", 370 .id = BUCK2, 371 .ops = &lp8788_buck12_ops, 372 .n_voltages = 26, 373 .linear_ranges = buck_volt_ranges, 374 .n_linear_ranges = ARRAY_SIZE(buck_volt_ranges), 375 .type = REGULATOR_VOLTAGE, 376 .owner = THIS_MODULE, 377 .enable_reg = LP8788_EN_BUCK, 378 .enable_mask = LP8788_EN_BUCK2_M, 379 }, 380 { 381 .name = "buck3", 382 .id = BUCK3, 383 .ops = &lp8788_buck34_ops, 384 .n_voltages = 26, 385 .linear_ranges = buck_volt_ranges, 386 .n_linear_ranges = ARRAY_SIZE(buck_volt_ranges), 387 .type = REGULATOR_VOLTAGE, 388 .owner = THIS_MODULE, 389 .vsel_reg = LP8788_BUCK3_VOUT, 390 .vsel_mask = LP8788_VOUT_M, 391 .enable_reg = LP8788_EN_BUCK, 392 .enable_mask = LP8788_EN_BUCK3_M, 393 }, 394 { 395 .name = "buck4", 396 .id = BUCK4, 397 .ops = &lp8788_buck34_ops, 398 .n_voltages = 26, 399 .linear_ranges = buck_volt_ranges, 400 .n_linear_ranges = ARRAY_SIZE(buck_volt_ranges), 401 .type = REGULATOR_VOLTAGE, 402 .owner = THIS_MODULE, 403 .vsel_reg = LP8788_BUCK4_VOUT, 404 .vsel_mask = LP8788_VOUT_M, 405 .enable_reg = LP8788_EN_BUCK, 406 .enable_mask = LP8788_EN_BUCK4_M, 407 }, 408 }; 409 410 static int lp8788_dvs_gpio_request(struct platform_device *pdev, 411 struct lp8788_buck *buck, 412 enum lp8788_buck_id id) 413 { 414 struct lp8788_platform_data *pdata = buck->lp->pdata; 415 struct device *dev = &pdev->dev; 416 417 switch (id) { 418 case BUCK1: 419 buck->gpio1 = devm_gpiod_get(dev, "dvs", GPIOD_OUT_LOW); 420 if (IS_ERR(buck->gpio1)) 421 return PTR_ERR(buck->gpio1); 422 gpiod_set_consumer_name(buck->gpio1, "LP8788_B1_DVS"); 423 424 buck->dvs = pdata->buck1_dvs; 425 break; 426 case BUCK2: 427 buck->gpio1 = devm_gpiod_get_index(dev, "dvs", 0, GPIOD_OUT_LOW); 428 if (IS_ERR(buck->gpio1)) 429 return PTR_ERR(buck->gpio1); 430 gpiod_set_consumer_name(buck->gpio1, "LP8788_B2_DVS1"); 431 432 buck->gpio2 = devm_gpiod_get_index(dev, "dvs", 1, GPIOD_OUT_LOW); 433 if (IS_ERR(buck->gpio2)) 434 return PTR_ERR(buck->gpio2); 435 gpiod_set_consumer_name(buck->gpio2, "LP8788_B2_DVS2"); 436 437 buck->dvs = pdata->buck2_dvs; 438 break; 439 default: 440 break; 441 } 442 443 return 0; 444 } 445 446 static int lp8788_init_dvs(struct platform_device *pdev, 447 struct lp8788_buck *buck, enum lp8788_buck_id id) 448 { 449 struct lp8788_platform_data *pdata = buck->lp->pdata; 450 u8 mask[] = { LP8788_BUCK1_DVS_SEL_M, LP8788_BUCK2_DVS_SEL_M }; 451 u8 val[] = { LP8788_BUCK1_DVS_PIN, LP8788_BUCK2_DVS_PIN }; 452 u8 default_dvs_mode[] = { LP8788_BUCK1_DVS_I2C, LP8788_BUCK2_DVS_I2C }; 453 454 /* no dvs for buck3, 4 */ 455 if (id > BUCK2) 456 return 0; 457 458 /* no dvs platform data, then dvs will be selected by I2C registers */ 459 if (!pdata) 460 goto set_default_dvs_mode; 461 462 if ((id == BUCK1 && !pdata->buck1_dvs) || 463 (id == BUCK2 && !pdata->buck2_dvs)) 464 goto set_default_dvs_mode; 465 466 if (lp8788_dvs_gpio_request(pdev, buck, id)) 467 goto set_default_dvs_mode; 468 469 return lp8788_update_bits(buck->lp, LP8788_BUCK_DVS_SEL, mask[id], 470 val[id]); 471 472 set_default_dvs_mode: 473 return lp8788_update_bits(buck->lp, LP8788_BUCK_DVS_SEL, mask[id], 474 default_dvs_mode[id]); 475 } 476 477 static int lp8788_buck_probe(struct platform_device *pdev) 478 { 479 struct lp8788 *lp = dev_get_drvdata(pdev->dev.parent); 480 int id = pdev->id; 481 struct lp8788_buck *buck; 482 struct regulator_config cfg = { }; 483 struct regulator_dev *rdev; 484 int ret; 485 486 if (id >= LP8788_NUM_BUCKS) 487 return -EINVAL; 488 489 buck = devm_kzalloc(&pdev->dev, sizeof(struct lp8788_buck), GFP_KERNEL); 490 if (!buck) 491 return -ENOMEM; 492 493 buck->lp = lp; 494 495 ret = lp8788_init_dvs(pdev, buck, id); 496 if (ret) 497 return ret; 498 499 cfg.dev = pdev->dev.parent; 500 cfg.init_data = lp->pdata ? lp->pdata->buck_data[id] : NULL; 501 cfg.driver_data = buck; 502 cfg.regmap = lp->regmap; 503 504 rdev = devm_regulator_register(&pdev->dev, &lp8788_buck_desc[id], &cfg); 505 if (IS_ERR(rdev)) { 506 ret = PTR_ERR(rdev); 507 dev_err(&pdev->dev, "BUCK%d regulator register err = %d\n", 508 id + 1, ret); 509 return ret; 510 } 511 512 buck->regulator = rdev; 513 platform_set_drvdata(pdev, buck); 514 515 return 0; 516 } 517 518 static struct platform_driver lp8788_buck_driver = { 519 .probe = lp8788_buck_probe, 520 .driver = { 521 .name = LP8788_DEV_BUCK, 522 .probe_type = PROBE_PREFER_ASYNCHRONOUS, 523 }, 524 }; 525 526 static int __init lp8788_buck_init(void) 527 { 528 return platform_driver_register(&lp8788_buck_driver); 529 } 530 subsys_initcall(lp8788_buck_init); 531 532 static void __exit lp8788_buck_exit(void) 533 { 534 platform_driver_unregister(&lp8788_buck_driver); 535 } 536 module_exit(lp8788_buck_exit); 537 538 MODULE_DESCRIPTION("TI LP8788 BUCK Driver"); 539 MODULE_AUTHOR("Milo Kim"); 540 MODULE_LICENSE("GPL"); 541 MODULE_ALIAS("platform:lp8788-buck"); 542