da9055-regulator.c (15671B)
1// SPDX-License-Identifier: GPL-2.0+ 2// 3// Regulator driver for DA9055 PMIC 4// 5// Copyright(c) 2012 Dialog Semiconductor Ltd. 6// 7// Author: David Dajun Chen <dchen@diasemi.com> 8 9#include <linux/module.h> 10#include <linux/init.h> 11#include <linux/err.h> 12#include <linux/gpio.h> 13#include <linux/gpio/consumer.h> 14#include <linux/platform_device.h> 15#include <linux/regulator/driver.h> 16#include <linux/regulator/machine.h> 17#include <linux/of.h> 18#include <linux/regulator/of_regulator.h> 19 20#include <linux/mfd/da9055/core.h> 21#include <linux/mfd/da9055/reg.h> 22#include <linux/mfd/da9055/pdata.h> 23 24#define DA9055_MIN_UA 0 25#define DA9055_MAX_UA 3 26 27#define DA9055_LDO_MODE_SYNC 0 28#define DA9055_LDO_MODE_SLEEP 1 29 30#define DA9055_BUCK_MODE_SLEEP 1 31#define DA9055_BUCK_MODE_SYNC 2 32#define DA9055_BUCK_MODE_AUTO 3 33 34/* DA9055 REGULATOR IDs */ 35#define DA9055_ID_BUCK1 0 36#define DA9055_ID_BUCK2 1 37#define DA9055_ID_LDO1 2 38#define DA9055_ID_LDO2 3 39#define DA9055_ID_LDO3 4 40#define DA9055_ID_LDO4 5 41#define DA9055_ID_LDO5 6 42#define DA9055_ID_LDO6 7 43 44/* DA9055 BUCK current limit */ 45static const unsigned int da9055_current_limits[] = { 46 500000, 600000, 700000, 800000 47}; 48 49struct da9055_conf_reg { 50 int reg; 51 int sel_mask; 52 int en_mask; 53}; 54 55struct da9055_volt_reg { 56 int reg_a; 57 int reg_b; 58 int sl_shift; 59 int v_mask; 60}; 61 62struct da9055_mode_reg { 63 int reg; 64 int mask; 65 int shift; 66}; 67 68struct da9055_regulator_info { 69 struct regulator_desc reg_desc; 70 struct da9055_conf_reg conf; 71 struct da9055_volt_reg volt; 72 struct da9055_mode_reg mode; 73}; 74 75struct da9055_regulator { 76 struct da9055 *da9055; 77 struct da9055_regulator_info *info; 78 struct regulator_dev *rdev; 79 enum gpio_select reg_rselect; 80}; 81 82static unsigned int da9055_buck_get_mode(struct regulator_dev *rdev) 83{ 84 struct da9055_regulator *regulator = rdev_get_drvdata(rdev); 85 struct da9055_regulator_info *info = regulator->info; 86 int ret, mode = 0; 87 88 ret = da9055_reg_read(regulator->da9055, info->mode.reg); 89 if (ret < 0) 90 return ret; 91 92 switch ((ret & info->mode.mask) >> info->mode.shift) { 93 case DA9055_BUCK_MODE_SYNC: 94 mode = REGULATOR_MODE_FAST; 95 break; 96 case DA9055_BUCK_MODE_AUTO: 97 mode = REGULATOR_MODE_NORMAL; 98 break; 99 case DA9055_BUCK_MODE_SLEEP: 100 mode = REGULATOR_MODE_STANDBY; 101 break; 102 } 103 104 return mode; 105} 106 107static int da9055_buck_set_mode(struct regulator_dev *rdev, 108 unsigned int mode) 109{ 110 struct da9055_regulator *regulator = rdev_get_drvdata(rdev); 111 struct da9055_regulator_info *info = regulator->info; 112 int val = 0; 113 114 switch (mode) { 115 case REGULATOR_MODE_FAST: 116 val = DA9055_BUCK_MODE_SYNC << info->mode.shift; 117 break; 118 case REGULATOR_MODE_NORMAL: 119 val = DA9055_BUCK_MODE_AUTO << info->mode.shift; 120 break; 121 case REGULATOR_MODE_STANDBY: 122 val = DA9055_BUCK_MODE_SLEEP << info->mode.shift; 123 break; 124 } 125 126 return da9055_reg_update(regulator->da9055, info->mode.reg, 127 info->mode.mask, val); 128} 129 130static unsigned int da9055_ldo_get_mode(struct regulator_dev *rdev) 131{ 132 struct da9055_regulator *regulator = rdev_get_drvdata(rdev); 133 struct da9055_regulator_info *info = regulator->info; 134 int ret; 135 136 ret = da9055_reg_read(regulator->da9055, info->volt.reg_b); 137 if (ret < 0) 138 return ret; 139 140 if (ret >> info->volt.sl_shift) 141 return REGULATOR_MODE_STANDBY; 142 else 143 return REGULATOR_MODE_NORMAL; 144} 145 146static int da9055_ldo_set_mode(struct regulator_dev *rdev, unsigned int mode) 147{ 148 struct da9055_regulator *regulator = rdev_get_drvdata(rdev); 149 struct da9055_regulator_info *info = regulator->info; 150 struct da9055_volt_reg volt = info->volt; 151 int val = 0; 152 153 switch (mode) { 154 case REGULATOR_MODE_NORMAL: 155 case REGULATOR_MODE_FAST: 156 val = DA9055_LDO_MODE_SYNC; 157 break; 158 case REGULATOR_MODE_STANDBY: 159 val = DA9055_LDO_MODE_SLEEP; 160 break; 161 } 162 163 return da9055_reg_update(regulator->da9055, volt.reg_b, 164 1 << volt.sl_shift, 165 val << volt.sl_shift); 166} 167 168static int da9055_regulator_get_voltage_sel(struct regulator_dev *rdev) 169{ 170 struct da9055_regulator *regulator = rdev_get_drvdata(rdev); 171 struct da9055_regulator_info *info = regulator->info; 172 struct da9055_volt_reg volt = info->volt; 173 int ret, sel; 174 175 /* 176 * There are two voltage register set A & B for voltage ramping but 177 * either one of then can be active therefore we first determine 178 * the active register set. 179 */ 180 ret = da9055_reg_read(regulator->da9055, info->conf.reg); 181 if (ret < 0) 182 return ret; 183 184 ret &= info->conf.sel_mask; 185 186 /* Get the voltage for the active register set A/B */ 187 if (ret == DA9055_REGUALTOR_SET_A) 188 ret = da9055_reg_read(regulator->da9055, volt.reg_a); 189 else 190 ret = da9055_reg_read(regulator->da9055, volt.reg_b); 191 192 if (ret < 0) 193 return ret; 194 195 sel = (ret & volt.v_mask); 196 return sel; 197} 198 199static int da9055_regulator_set_voltage_sel(struct regulator_dev *rdev, 200 unsigned int selector) 201{ 202 struct da9055_regulator *regulator = rdev_get_drvdata(rdev); 203 struct da9055_regulator_info *info = regulator->info; 204 int ret; 205 206 /* 207 * Regulator register set A/B is not selected through GPIO therefore 208 * we use default register set A for voltage ramping. 209 */ 210 if (regulator->reg_rselect == NO_GPIO) { 211 /* Select register set A */ 212 ret = da9055_reg_update(regulator->da9055, info->conf.reg, 213 info->conf.sel_mask, DA9055_SEL_REG_A); 214 if (ret < 0) 215 return ret; 216 217 /* Set the voltage */ 218 return da9055_reg_update(regulator->da9055, info->volt.reg_a, 219 info->volt.v_mask, selector); 220 } 221 222 /* 223 * Here regulator register set A/B is selected through GPIO. 224 * Therefore we first determine the selected register set A/B and 225 * then set the desired voltage for that register set A/B. 226 */ 227 ret = da9055_reg_read(regulator->da9055, info->conf.reg); 228 if (ret < 0) 229 return ret; 230 231 ret &= info->conf.sel_mask; 232 233 /* Set the voltage */ 234 if (ret == DA9055_REGUALTOR_SET_A) 235 return da9055_reg_update(regulator->da9055, info->volt.reg_a, 236 info->volt.v_mask, selector); 237 else 238 return da9055_reg_update(regulator->da9055, info->volt.reg_b, 239 info->volt.v_mask, selector); 240} 241 242static int da9055_regulator_set_suspend_voltage(struct regulator_dev *rdev, 243 int uV) 244{ 245 struct da9055_regulator *regulator = rdev_get_drvdata(rdev); 246 struct da9055_regulator_info *info = regulator->info; 247 int ret; 248 249 /* Select register set B for suspend voltage ramping. */ 250 if (regulator->reg_rselect == NO_GPIO) { 251 ret = da9055_reg_update(regulator->da9055, info->conf.reg, 252 info->conf.sel_mask, DA9055_SEL_REG_B); 253 if (ret < 0) 254 return ret; 255 } 256 257 ret = regulator_map_voltage_linear(rdev, uV, uV); 258 if (ret < 0) 259 return ret; 260 261 return da9055_reg_update(regulator->da9055, info->volt.reg_b, 262 info->volt.v_mask, ret); 263} 264 265static int da9055_suspend_enable(struct regulator_dev *rdev) 266{ 267 struct da9055_regulator *regulator = rdev_get_drvdata(rdev); 268 struct da9055_regulator_info *info = regulator->info; 269 270 /* Select register set B for voltage ramping. */ 271 if (regulator->reg_rselect == NO_GPIO) 272 return da9055_reg_update(regulator->da9055, info->conf.reg, 273 info->conf.sel_mask, DA9055_SEL_REG_B); 274 else 275 return 0; 276} 277 278static int da9055_suspend_disable(struct regulator_dev *rdev) 279{ 280 struct da9055_regulator *regulator = rdev_get_drvdata(rdev); 281 struct da9055_regulator_info *info = regulator->info; 282 283 /* Diselect register set B. */ 284 if (regulator->reg_rselect == NO_GPIO) 285 return da9055_reg_update(regulator->da9055, info->conf.reg, 286 info->conf.sel_mask, DA9055_SEL_REG_A); 287 else 288 return 0; 289} 290 291static const struct regulator_ops da9055_buck_ops = { 292 .get_mode = da9055_buck_get_mode, 293 .set_mode = da9055_buck_set_mode, 294 295 .get_current_limit = regulator_get_current_limit_regmap, 296 .set_current_limit = regulator_set_current_limit_regmap, 297 298 .get_voltage_sel = da9055_regulator_get_voltage_sel, 299 .set_voltage_sel = da9055_regulator_set_voltage_sel, 300 .list_voltage = regulator_list_voltage_linear, 301 .map_voltage = regulator_map_voltage_linear, 302 .is_enabled = regulator_is_enabled_regmap, 303 .enable = regulator_enable_regmap, 304 .disable = regulator_disable_regmap, 305 306 .set_suspend_voltage = da9055_regulator_set_suspend_voltage, 307 .set_suspend_enable = da9055_suspend_enable, 308 .set_suspend_disable = da9055_suspend_disable, 309 .set_suspend_mode = da9055_buck_set_mode, 310}; 311 312static const struct regulator_ops da9055_ldo_ops = { 313 .get_mode = da9055_ldo_get_mode, 314 .set_mode = da9055_ldo_set_mode, 315 316 .get_voltage_sel = da9055_regulator_get_voltage_sel, 317 .set_voltage_sel = da9055_regulator_set_voltage_sel, 318 .list_voltage = regulator_list_voltage_linear, 319 .map_voltage = regulator_map_voltage_linear, 320 .is_enabled = regulator_is_enabled_regmap, 321 .enable = regulator_enable_regmap, 322 .disable = regulator_disable_regmap, 323 324 .set_suspend_voltage = da9055_regulator_set_suspend_voltage, 325 .set_suspend_enable = da9055_suspend_enable, 326 .set_suspend_disable = da9055_suspend_disable, 327 .set_suspend_mode = da9055_ldo_set_mode, 328 329}; 330 331#define DA9055_LDO(_id, step, min, max, vbits, voffset) \ 332{\ 333 .reg_desc = {\ 334 .name = #_id,\ 335 .of_match = of_match_ptr(#_id),\ 336 .regulators_node = of_match_ptr("regulators"),\ 337 .ops = &da9055_ldo_ops,\ 338 .type = REGULATOR_VOLTAGE,\ 339 .id = DA9055_ID_##_id,\ 340 .n_voltages = (max - min) / step + 1 + (voffset), \ 341 .enable_reg = DA9055_REG_BCORE_CONT + DA9055_ID_##_id, \ 342 .enable_mask = 1, \ 343 .min_uV = (min) * 1000,\ 344 .uV_step = (step) * 1000,\ 345 .linear_min_sel = (voffset),\ 346 .owner = THIS_MODULE,\ 347 },\ 348 .conf = {\ 349 .reg = DA9055_REG_BCORE_CONT + DA9055_ID_##_id, \ 350 .sel_mask = (1 << 4),\ 351 .en_mask = 1,\ 352 },\ 353 .volt = {\ 354 .reg_a = DA9055_REG_VBCORE_A + DA9055_ID_##_id, \ 355 .reg_b = DA9055_REG_VBCORE_B + DA9055_ID_##_id, \ 356 .sl_shift = 7,\ 357 .v_mask = (1 << (vbits)) - 1,\ 358 },\ 359} 360 361#define DA9055_BUCK(_id, step, min, max, vbits, voffset, mbits, sbits) \ 362{\ 363 .reg_desc = {\ 364 .name = #_id,\ 365 .of_match = of_match_ptr(#_id),\ 366 .regulators_node = of_match_ptr("regulators"),\ 367 .ops = &da9055_buck_ops,\ 368 .type = REGULATOR_VOLTAGE,\ 369 .id = DA9055_ID_##_id,\ 370 .n_voltages = (max - min) / step + 1 + (voffset), \ 371 .enable_reg = DA9055_REG_BCORE_CONT + DA9055_ID_##_id, \ 372 .enable_mask = 1,\ 373 .min_uV = (min) * 1000,\ 374 .uV_step = (step) * 1000,\ 375 .linear_min_sel = (voffset),\ 376 .owner = THIS_MODULE,\ 377 .curr_table = da9055_current_limits,\ 378 .n_current_limits = ARRAY_SIZE(da9055_current_limits),\ 379 .csel_reg = DA9055_REG_BUCK_LIM,\ 380 .csel_mask = (mbits),\ 381 },\ 382 .conf = {\ 383 .reg = DA9055_REG_BCORE_CONT + DA9055_ID_##_id, \ 384 .sel_mask = (1 << 4),\ 385 .en_mask = 1,\ 386 },\ 387 .volt = {\ 388 .reg_a = DA9055_REG_VBCORE_A + DA9055_ID_##_id, \ 389 .reg_b = DA9055_REG_VBCORE_B + DA9055_ID_##_id, \ 390 .sl_shift = 7,\ 391 .v_mask = (1 << (vbits)) - 1,\ 392 },\ 393 .mode = {\ 394 .reg = DA9055_REG_BCORE_MODE,\ 395 .mask = (mbits),\ 396 .shift = (sbits),\ 397 },\ 398} 399 400static struct da9055_regulator_info da9055_regulator_info[] = { 401 DA9055_BUCK(BUCK1, 25, 725, 2075, 6, 9, 0xc, 2), 402 DA9055_BUCK(BUCK2, 25, 925, 2500, 6, 0, 3, 0), 403 DA9055_LDO(LDO1, 50, 900, 3300, 6, 2), 404 DA9055_LDO(LDO2, 50, 900, 3300, 6, 3), 405 DA9055_LDO(LDO3, 50, 900, 3300, 6, 2), 406 DA9055_LDO(LDO4, 50, 900, 3300, 6, 2), 407 DA9055_LDO(LDO5, 50, 900, 2750, 6, 2), 408 DA9055_LDO(LDO6, 20, 900, 3300, 7, 0), 409}; 410 411/* 412 * Configures regulator to be controlled either through GPIO 1 or 2. 413 * GPIO can control regulator state and/or select the regulator register 414 * set A/B for voltage ramping. 415 */ 416static int da9055_gpio_init(struct da9055_regulator *regulator, 417 struct regulator_config *config, 418 struct da9055_pdata *pdata, int id) 419{ 420 struct da9055_regulator_info *info = regulator->info; 421 int ret = 0; 422 423 if (!pdata) 424 return 0; 425 426 if (pdata->gpio_ren && pdata->gpio_ren[id]) { 427 char name[18]; 428 int gpio_mux = pdata->gpio_ren[id]; 429 430 config->ena_gpiod = pdata->ena_gpiods[id]; 431 432 /* 433 * GPI pin is muxed with regulator to control the 434 * regulator state. 435 */ 436 sprintf(name, "DA9055 GPI %d", gpio_mux); 437 ret = devm_gpio_request_one(config->dev, gpio_mux, GPIOF_DIR_IN, 438 name); 439 if (ret < 0) 440 goto err; 441 442 /* 443 * Let the regulator know that its state is controlled 444 * through GPI. 445 */ 446 ret = da9055_reg_update(regulator->da9055, info->conf.reg, 447 DA9055_E_GPI_MASK, 448 pdata->reg_ren[id] 449 << DA9055_E_GPI_SHIFT); 450 if (ret < 0) 451 goto err; 452 } 453 454 if (pdata->gpio_rsel && pdata->gpio_rsel[id]) { 455 char name[18]; 456 int gpio_mux = pdata->gpio_rsel[id]; 457 458 regulator->reg_rselect = pdata->reg_rsel[id]; 459 460 /* 461 * GPI pin is muxed with regulator to select the 462 * regulator register set A/B for voltage ramping. 463 */ 464 sprintf(name, "DA9055 GPI %d", gpio_mux); 465 ret = devm_gpio_request_one(config->dev, gpio_mux, GPIOF_DIR_IN, 466 name); 467 if (ret < 0) 468 goto err; 469 470 /* 471 * Let the regulator know that its register set A/B 472 * will be selected through GPI for voltage ramping. 473 */ 474 ret = da9055_reg_update(regulator->da9055, info->conf.reg, 475 DA9055_V_GPI_MASK, 476 pdata->reg_rsel[id] 477 << DA9055_V_GPI_SHIFT); 478 } 479 480err: 481 return ret; 482} 483 484static irqreturn_t da9055_ldo5_6_oc_irq(int irq, void *data) 485{ 486 struct da9055_regulator *regulator = data; 487 488 regulator_notifier_call_chain(regulator->rdev, 489 REGULATOR_EVENT_OVER_CURRENT, NULL); 490 491 return IRQ_HANDLED; 492} 493 494static inline struct da9055_regulator_info *find_regulator_info(int id) 495{ 496 struct da9055_regulator_info *info; 497 int i; 498 499 for (i = 0; i < ARRAY_SIZE(da9055_regulator_info); i++) { 500 info = &da9055_regulator_info[i]; 501 if (info->reg_desc.id == id) 502 return info; 503 } 504 505 return NULL; 506} 507 508static int da9055_regulator_probe(struct platform_device *pdev) 509{ 510 struct regulator_config config = { }; 511 struct da9055_regulator *regulator; 512 struct da9055 *da9055 = dev_get_drvdata(pdev->dev.parent); 513 struct da9055_pdata *pdata = dev_get_platdata(da9055->dev); 514 int ret, irq; 515 516 regulator = devm_kzalloc(&pdev->dev, sizeof(struct da9055_regulator), 517 GFP_KERNEL); 518 if (!regulator) 519 return -ENOMEM; 520 521 regulator->info = find_regulator_info(pdev->id); 522 if (regulator->info == NULL) { 523 dev_err(&pdev->dev, "invalid regulator ID specified\n"); 524 return -EINVAL; 525 } 526 527 regulator->da9055 = da9055; 528 config.dev = da9055->dev; 529 config.driver_data = regulator; 530 config.regmap = da9055->regmap; 531 532 if (pdata) 533 config.init_data = pdata->regulators[pdev->id]; 534 535 ret = da9055_gpio_init(regulator, &config, pdata, pdev->id); 536 if (ret < 0) 537 return ret; 538 539 regulator->rdev = devm_regulator_register(&pdev->dev, 540 ®ulator->info->reg_desc, 541 &config); 542 if (IS_ERR(regulator->rdev)) { 543 dev_err(&pdev->dev, "Failed to register regulator %s\n", 544 regulator->info->reg_desc.name); 545 return PTR_ERR(regulator->rdev); 546 } 547 548 /* Only LDO 5 and 6 has got the over current interrupt */ 549 if (pdev->id == DA9055_ID_LDO5 || pdev->id == DA9055_ID_LDO6) { 550 irq = platform_get_irq_byname(pdev, "REGULATOR"); 551 if (irq < 0) 552 return irq; 553 554 ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, 555 da9055_ldo5_6_oc_irq, 556 IRQF_TRIGGER_HIGH | 557 IRQF_ONESHOT | 558 IRQF_PROBE_SHARED, 559 pdev->name, regulator); 560 if (ret != 0) { 561 if (ret != -EBUSY) { 562 dev_err(&pdev->dev, 563 "Failed to request Regulator IRQ %d: %d\n", 564 irq, ret); 565 return ret; 566 } 567 } 568 } 569 570 platform_set_drvdata(pdev, regulator); 571 572 return 0; 573} 574 575static struct platform_driver da9055_regulator_driver = { 576 .probe = da9055_regulator_probe, 577 .driver = { 578 .name = "da9055-regulator", 579 }, 580}; 581 582static int __init da9055_regulator_init(void) 583{ 584 return platform_driver_register(&da9055_regulator_driver); 585} 586subsys_initcall(da9055_regulator_init); 587 588static void __exit da9055_regulator_exit(void) 589{ 590 platform_driver_unregister(&da9055_regulator_driver); 591} 592module_exit(da9055_regulator_exit); 593 594MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>"); 595MODULE_DESCRIPTION("Power Regulator driver for Dialog DA9055 PMIC"); 596MODULE_LICENSE("GPL"); 597MODULE_ALIAS("platform:da9055-regulator");