1/* 2* da9052-regulator.c: Regulator driver for DA9052 3* 4* Copyright(c) 2011 Dialog Semiconductor Ltd. 5* 6* Author: David Dajun Chen <dchen@diasemi.com> 7* 8* This program is free software; you can redistribute it and/or modify 9* it under the terms of the GNU General Public License as published by 10* the Free Software Foundation; either version 2 of the License, or 11* (at your option) any later version. 12* 13*/ 14 15#include <linux/module.h> 16#include <linux/moduleparam.h> 17#include <linux/init.h> 18#include <linux/err.h> 19#include <linux/platform_device.h> 20#include <linux/regulator/driver.h> 21#include <linux/regulator/machine.h> 22 23#include <linux/mfd/da9052/da9052.h> 24#include <linux/mfd/da9052/reg.h> 25#include <linux/mfd/da9052/pdata.h> 26 27/* Buck step size */ 28#define DA9052_BUCK_PERI_3uV_STEP 100000 29#define DA9052_BUCK_PERI_REG_MAP_UPTO_3uV 24 30#define DA9052_CONST_3uV 3000000 31 32#define DA9052_MIN_UA 0 33#define DA9052_MAX_UA 3 34#define DA9052_CURRENT_RANGE 4 35 36/* Bit masks */ 37#define DA9052_BUCK_ILIM_MASK_EVEN 0x0c 38#define DA9052_BUCK_ILIM_MASK_ODD 0xc0 39 40static const u32 da9052_current_limits[3][4] = { 41 {700000, 800000, 1000000, 1200000}, /* DA9052-BC BUCKs */ 42 {1600000, 2000000, 2400000, 3000000}, /* DA9053-AA/Bx BUCK-CORE */ 43 {800000, 1000000, 1200000, 1500000}, /* DA9053-AA/Bx BUCK-PRO, 44 * BUCK-MEM and BUCK-PERI 45 */ 46}; 47 48struct da9052_regulator_info { 49 struct regulator_desc reg_desc; 50 int step_uV; 51 int min_uV; 52 int max_uV; 53 unsigned char volt_shift; 54 unsigned char en_bit; 55 unsigned char activate_bit; 56}; 57 58struct da9052_regulator { 59 struct da9052 *da9052; 60 struct da9052_regulator_info *info; 61 struct regulator_dev *rdev; 62}; 63 64static int verify_range(struct da9052_regulator_info *info, 65 int min_uV, int max_uV) 66{ 67 if (min_uV > info->max_uV || max_uV < info->min_uV) 68 return -EINVAL; 69 70 return 0; 71} 72 73static int da9052_regulator_enable(struct regulator_dev *rdev) 74{ 75 struct da9052_regulator *regulator = rdev_get_drvdata(rdev); 76 struct da9052_regulator_info *info = regulator->info; 77 int offset = rdev_get_id(rdev); 78 79 return da9052_reg_update(regulator->da9052, 80 DA9052_BUCKCORE_REG + offset, 81 1 << info->en_bit, 1 << info->en_bit); 82} 83 84static int da9052_regulator_disable(struct regulator_dev *rdev) 85{ 86 struct da9052_regulator *regulator = rdev_get_drvdata(rdev); 87 struct da9052_regulator_info *info = regulator->info; 88 int offset = rdev_get_id(rdev); 89 90 return da9052_reg_update(regulator->da9052, 91 DA9052_BUCKCORE_REG + offset, 92 1 << info->en_bit, 0); 93} 94 95static int da9052_regulator_is_enabled(struct regulator_dev *rdev) 96{ 97 struct da9052_regulator *regulator = rdev_get_drvdata(rdev); 98 struct da9052_regulator_info *info = regulator->info; 99 int offset = rdev_get_id(rdev); 100 int ret; 101 102 ret = da9052_reg_read(regulator->da9052, DA9052_BUCKCORE_REG + offset); 103 if (ret < 0) 104 return ret; 105 106 return ret & (1 << info->en_bit); 107} 108 109static int da9052_dcdc_get_current_limit(struct regulator_dev *rdev) 110{ 111 struct da9052_regulator *regulator = rdev_get_drvdata(rdev); 112 int offset = rdev_get_id(rdev); 113 int ret, row = 2; 114 115 ret = da9052_reg_read(regulator->da9052, DA9052_BUCKA_REG + offset/2); 116 if (ret < 0) 117 return ret; 118 119 /* Determine the even or odd position of the buck current limit 120 * register field 121 */ 122 if (offset % 2 == 0) 123 ret = (ret & DA9052_BUCK_ILIM_MASK_EVEN) >> 2; 124 else 125 ret = (ret & DA9052_BUCK_ILIM_MASK_ODD) >> 6; 126 127 /* Select the appropriate current limit range */ 128 if (regulator->da9052->chip_id == DA9052) 129 row = 0; 130 else if (offset == 0) 131 row = 1; 132 133 return da9052_current_limits[row][ret]; 134} 135 136static int da9052_dcdc_set_current_limit(struct regulator_dev *rdev, int min_uA, 137 int max_uA) 138{ 139 struct da9052_regulator *regulator = rdev_get_drvdata(rdev); 140 int offset = rdev_get_id(rdev); 141 int reg_val = 0; 142 int i, row = 2; 143 144 /* Select the appropriate current limit range */ 145 if (regulator->da9052->chip_id == DA9052) 146 row = 0; 147 else if (offset == 0) 148 row = 1; 149 150 if (min_uA > da9052_current_limits[row][DA9052_MAX_UA] || 151 max_uA < da9052_current_limits[row][DA9052_MIN_UA]) 152 return -EINVAL; 153 154 for (i = 0; i < DA9052_CURRENT_RANGE; i++) { 155 if (min_uA <= da9052_current_limits[row][i]) { 156 reg_val = i; 157 break; 158 } 159 } 160 161 /* Determine the even or odd position of the buck current limit 162 * register field 163 */ 164 if (offset % 2 == 0) 165 return da9052_reg_update(regulator->da9052, 166 DA9052_BUCKA_REG + offset/2, 167 DA9052_BUCK_ILIM_MASK_EVEN, 168 reg_val << 2); 169 else 170 return da9052_reg_update(regulator->da9052, 171 DA9052_BUCKA_REG + offset/2, 172 DA9052_BUCK_ILIM_MASK_ODD, 173 reg_val << 6); 174} 175 176static int da9052_list_buckperi_voltage(struct regulator_dev *rdev, 177 unsigned int selector) 178{ 179 struct da9052_regulator *regulator = rdev_get_drvdata(rdev); 180 struct da9052_regulator_info *info = regulator->info; 181 int volt_uV; 182 183 if ((regulator->da9052->chip_id == DA9052) && 184 (selector >= DA9052_BUCK_PERI_REG_MAP_UPTO_3uV)) { 185 volt_uV = ((DA9052_BUCK_PERI_REG_MAP_UPTO_3uV * info->step_uV) 186 + info->min_uV); 187 volt_uV += (selector - DA9052_BUCK_PERI_REG_MAP_UPTO_3uV) 188 * (DA9052_BUCK_PERI_3uV_STEP); 189 } else 190 volt_uV = (selector * info->step_uV) + info->min_uV; 191 192 if (volt_uV > info->max_uV) 193 return -EINVAL; 194 195 return volt_uV; 196} 197 198static int da9052_list_voltage(struct regulator_dev *rdev, 199 unsigned int selector) 200{ 201 struct da9052_regulator *regulator = rdev_get_drvdata(rdev); 202 struct da9052_regulator_info *info = regulator->info; 203 int volt_uV; 204 205 volt_uV = info->min_uV + info->step_uV * selector; 206 207 if (volt_uV > info->max_uV) 208 return -EINVAL; 209 210 return volt_uV; 211} 212 213static int da9052_regulator_set_voltage_int(struct regulator_dev *rdev, 214 int min_uV, int max_uV, 215 unsigned int *selector) 216{ 217 struct da9052_regulator *regulator = rdev_get_drvdata(rdev); 218 struct da9052_regulator_info *info = regulator->info; 219 int offset = rdev_get_id(rdev); 220 int ret; 221 222 ret = verify_range(info, min_uV, max_uV); 223 if (ret < 0) 224 return ret; 225 226 if (min_uV < info->min_uV) 227 min_uV = info->min_uV; 228 229 *selector = DIV_ROUND_UP(min_uV - info->min_uV, info->step_uV); 230 231 ret = da9052_list_voltage(rdev, *selector); 232 if (ret < 0) 233 return ret; 234 235 return da9052_reg_update(regulator->da9052, 236 DA9052_BUCKCORE_REG + offset, 237 (1 << info->volt_shift) - 1, *selector); 238} 239 240static int da9052_set_ldo_voltage(struct regulator_dev *rdev, 241 int min_uV, int max_uV, 242 unsigned int *selector) 243{ 244 return da9052_regulator_set_voltage_int(rdev, min_uV, max_uV, selector); 245} 246 247static int da9052_set_ldo5_6_voltage(struct regulator_dev *rdev, 248 int min_uV, int max_uV, 249 unsigned int *selector) 250{ 251 struct da9052_regulator *regulator = rdev_get_drvdata(rdev); 252 struct da9052_regulator_info *info = regulator->info; 253 int ret; 254 255 ret = da9052_regulator_set_voltage_int(rdev, min_uV, max_uV, selector); 256 if (ret < 0) 257 return ret; 258 259 /* Some LDOs are DVC controlled which requires enabling of 260 * the LDO activate bit to implment the changes on the 261 * LDO output. 262 */ 263 return da9052_reg_update(regulator->da9052, DA9052_SUPPLY_REG, 264 info->activate_bit, info->activate_bit); 265} 266 267static int da9052_set_dcdc_voltage(struct regulator_dev *rdev, 268 int min_uV, int max_uV, 269 unsigned int *selector) 270{ 271 struct da9052_regulator *regulator = rdev_get_drvdata(rdev); 272 struct da9052_regulator_info *info = regulator->info; 273 int ret; 274 275 ret = da9052_regulator_set_voltage_int(rdev, min_uV, max_uV, selector); 276 if (ret < 0) 277 return ret; 278 279 /* Some DCDCs are DVC controlled which requires enabling of 280 * the DCDC activate bit to implment the changes on the 281 * DCDC output. 282 */ 283 return da9052_reg_update(regulator->da9052, DA9052_SUPPLY_REG, 284 info->activate_bit, info->activate_bit); 285} 286 287static int da9052_get_regulator_voltage_sel(struct regulator_dev *rdev) 288{ 289 struct da9052_regulator *regulator = rdev_get_drvdata(rdev); 290 struct da9052_regulator_info *info = regulator->info; 291 int offset = rdev_get_id(rdev); 292 int ret; 293 294 ret = da9052_reg_read(regulator->da9052, DA9052_BUCKCORE_REG + offset); 295 if (ret < 0) 296 return ret; 297 298 ret &= ((1 << info->volt_shift) - 1); 299 300 return ret; 301} 302 303static int da9052_set_buckperi_voltage(struct regulator_dev *rdev, int min_uV, 304 int max_uV, unsigned int *selector) 305{ 306 struct da9052_regulator *regulator = rdev_get_drvdata(rdev); 307 struct da9052_regulator_info *info = regulator->info; 308 int offset = rdev_get_id(rdev); 309 int ret; 310 311 ret = verify_range(info, min_uV, max_uV); 312 if (ret < 0) 313 return ret; 314 315 if (min_uV < info->min_uV) 316 min_uV = info->min_uV; 317 318 if ((regulator->da9052->chip_id == DA9052) && 319 (min_uV >= DA9052_CONST_3uV)) 320 *selector = DA9052_BUCK_PERI_REG_MAP_UPTO_3uV + 321 DIV_ROUND_UP(min_uV - DA9052_CONST_3uV, 322 DA9052_BUCK_PERI_3uV_STEP); 323 else 324 *selector = DIV_ROUND_UP(min_uV - info->min_uV, info->step_uV); 325 326 ret = da9052_list_buckperi_voltage(rdev, *selector); 327 if (ret < 0) 328 return ret; 329 330 return da9052_reg_update(regulator->da9052, 331 DA9052_BUCKCORE_REG + offset, 332 (1 << info->volt_shift) - 1, *selector); 333} 334 335static int da9052_get_buckperi_voltage_sel(struct regulator_dev *rdev) 336{ 337 struct da9052_regulator *regulator = rdev_get_drvdata(rdev); 338 struct da9052_regulator_info *info = regulator->info; 339 int offset = rdev_get_id(rdev); 340 int ret; 341 342 ret = da9052_reg_read(regulator->da9052, DA9052_BUCKCORE_REG + offset); 343 if (ret < 0) 344 return ret; 345 346 ret &= ((1 << info->volt_shift) - 1); 347 348 return ret; 349} 350 351static struct regulator_ops da9052_buckperi_ops = { 352 .list_voltage = da9052_list_buckperi_voltage, 353 .get_voltage_sel = da9052_get_buckperi_voltage_sel, 354 .set_voltage = da9052_set_buckperi_voltage, 355 356 .get_current_limit = da9052_dcdc_get_current_limit, 357 .set_current_limit = da9052_dcdc_set_current_limit, 358 359 .is_enabled = da9052_regulator_is_enabled, 360 .enable = da9052_regulator_enable, 361 .disable = da9052_regulator_disable, 362}; 363 364static struct regulator_ops da9052_dcdc_ops = { 365 .set_voltage = da9052_set_dcdc_voltage, 366 .get_current_limit = da9052_dcdc_get_current_limit, 367 .set_current_limit = da9052_dcdc_set_current_limit, 368 369 .list_voltage = da9052_list_voltage, 370 .get_voltage_sel = da9052_get_regulator_voltage_sel, 371 .is_enabled = da9052_regulator_is_enabled, 372 .enable = da9052_regulator_enable, 373 .disable = da9052_regulator_disable, 374}; 375 376static struct regulator_ops da9052_ldo5_6_ops = { 377 .set_voltage = da9052_set_ldo5_6_voltage, 378 379 .list_voltage = da9052_list_voltage, 380 .get_voltage_sel = da9052_get_regulator_voltage_sel, 381 .is_enabled = da9052_regulator_is_enabled, 382 .enable = da9052_regulator_enable, 383 .disable = da9052_regulator_disable, 384}; 385 386static struct regulator_ops da9052_ldo_ops = { 387 .set_voltage = da9052_set_ldo_voltage, 388 389 .list_voltage = da9052_list_voltage, 390 .get_voltage_sel = da9052_get_regulator_voltage_sel, 391 .is_enabled = da9052_regulator_is_enabled, 392 .enable = da9052_regulator_enable, 393 .disable = da9052_regulator_disable, 394}; 395 396#define DA9052_LDO5_6(_id, step, min, max, sbits, ebits, abits) \ 397{\ 398 .reg_desc = {\ 399 .name = "LDO" #_id,\ 400 .ops = &da9052_ldo5_6_ops,\ 401 .type = REGULATOR_VOLTAGE,\ 402 .id = _id,\ 403 .n_voltages = (max - min) / step + 1, \ 404 .owner = THIS_MODULE,\ 405 },\ 406 .min_uV = (min) * 1000,\ 407 .max_uV = (max) * 1000,\ 408 .step_uV = (step) * 1000,\ 409 .volt_shift = (sbits),\ 410 .en_bit = (ebits),\ 411 .activate_bit = (abits),\ 412} 413 414#define DA9052_LDO(_id, step, min, max, sbits, ebits, abits) \ 415{\ 416 .reg_desc = {\ 417 .name = "LDO" #_id,\ 418 .ops = &da9052_ldo_ops,\ 419 .type = REGULATOR_VOLTAGE,\ 420 .id = _id,\ 421 .n_voltages = (max - min) / step + 1, \ 422 .owner = THIS_MODULE,\ 423 },\ 424 .min_uV = (min) * 1000,\ 425 .max_uV = (max) * 1000,\ 426 .step_uV = (step) * 1000,\ 427 .volt_shift = (sbits),\ 428 .en_bit = (ebits),\ 429 .activate_bit = (abits),\ 430} 431 432#define DA9052_DCDC(_id, step, min, max, sbits, ebits, abits) \ 433{\ 434 .reg_desc = {\ 435 .name = "BUCK" #_id,\ 436 .ops = &da9052_dcdc_ops,\ 437 .type = REGULATOR_VOLTAGE,\ 438 .id = _id,\ 439 .n_voltages = (max - min) / step + 1, \ 440 .owner = THIS_MODULE,\ 441 },\ 442 .min_uV = (min) * 1000,\ 443 .max_uV = (max) * 1000,\ 444 .step_uV = (step) * 1000,\ 445 .volt_shift = (sbits),\ 446 .en_bit = (ebits),\ 447 .activate_bit = (abits),\ 448} 449 450#define DA9052_BUCKPERI(_id, step, min, max, sbits, ebits, abits) \ 451{\ 452 .reg_desc = {\ 453 .name = "BUCK" #_id,\ 454 .ops = &da9052_buckperi_ops,\ 455 .type = REGULATOR_VOLTAGE,\ 456 .id = _id,\ 457 .n_voltages = (max - min) / step + 1, \ 458 .owner = THIS_MODULE,\ 459 },\ 460 .min_uV = (min) * 1000,\ 461 .max_uV = (max) * 1000,\ 462 .step_uV = (step) * 1000,\ 463 .volt_shift = (sbits),\ 464 .en_bit = (ebits),\ 465 .activate_bit = (abits),\ 466} 467 468static struct da9052_regulator_info da9052_regulator_info[] = { 469 /* Buck1 - 4 */ 470 DA9052_DCDC(0, 25, 500, 2075, 6, 6, DA9052_SUPPLY_VBCOREGO), 471 DA9052_DCDC(1, 25, 500, 2075, 6, 6, DA9052_SUPPLY_VBPROGO), 472 DA9052_DCDC(2, 25, 925, 2500, 6, 6, DA9052_SUPPLY_VBMEMGO), 473 DA9052_BUCKPERI(3, 50, 1800, 3600, 5, 6, 0), 474 /* LD01 - LDO10 */ 475 DA9052_LDO(4, 50, 600, 1800, 5, 6, 0), 476 DA9052_LDO5_6(5, 25, 600, 1800, 6, 6, DA9052_SUPPLY_VLDO2GO), 477 DA9052_LDO5_6(6, 25, 1725, 3300, 6, 6, DA9052_SUPPLY_VLDO3GO), 478 DA9052_LDO(7, 25, 1725, 3300, 6, 6, 0), 479 DA9052_LDO(8, 50, 1200, 3600, 6, 6, 0), 480 DA9052_LDO(9, 50, 1200, 3600, 6, 6, 0), 481 DA9052_LDO(10, 50, 1200, 3600, 6, 6, 0), 482 DA9052_LDO(11, 50, 1200, 3600, 6, 6, 0), 483 DA9052_LDO(12, 50, 1250, 3650, 6, 6, 0), 484 DA9052_LDO(13, 50, 1200, 3600, 6, 6, 0), 485}; 486 487static struct da9052_regulator_info da9053_regulator_info[] = { 488 /* Buck1 - 4 */ 489 DA9052_DCDC(0, 25, 500, 2075, 6, 6, DA9052_SUPPLY_VBCOREGO), 490 DA9052_DCDC(1, 25, 500, 2075, 6, 6, DA9052_SUPPLY_VBPROGO), 491 DA9052_DCDC(2, 25, 925, 2500, 6, 6, DA9052_SUPPLY_VBMEMGO), 492 DA9052_BUCKPERI(3, 25, 925, 2500, 6, 6, 0), 493 /* LD01 - LDO10 */ 494 DA9052_LDO(4, 50, 600, 1800, 5, 6, 0), 495 DA9052_LDO5_6(5, 25, 600, 1800, 6, 6, DA9052_SUPPLY_VLDO2GO), 496 DA9052_LDO5_6(6, 25, 1725, 3300, 6, 6, DA9052_SUPPLY_VLDO3GO), 497 DA9052_LDO(7, 25, 1725, 3300, 6, 6, 0), 498 DA9052_LDO(8, 50, 1200, 3600, 6, 6, 0), 499 DA9052_LDO(9, 50, 1200, 3600, 6, 6, 0), 500 DA9052_LDO(10, 50, 1200, 3600, 6, 6, 0), 501 DA9052_LDO(11, 50, 1200, 3600, 6, 6, 0), 502 DA9052_LDO(12, 50, 1250, 3650, 6, 6, 0), 503 DA9052_LDO(13, 50, 1200, 3600, 6, 6, 0), 504}; 505 506static inline struct da9052_regulator_info *find_regulator_info(u8 chip_id, 507 int id) 508{ 509 struct da9052_regulator_info *info; 510 int i; 511 512 switch (chip_id) { 513 case DA9052: 514 for (i = 0; i < ARRAY_SIZE(da9052_regulator_info); i++) { 515 info = &da9052_regulator_info[i]; 516 if (info->reg_desc.id == id) 517 return info; 518 } 519 break; 520 case DA9053_AA: 521 case DA9053_BA: 522 case DA9053_BB: 523 for (i = 0; i < ARRAY_SIZE(da9053_regulator_info); i++) { 524 info = &da9053_regulator_info[i]; 525 if (info->reg_desc.id == id) 526 return info; 527 } 528 break; 529 } 530 531 return NULL; 532} 533 534static int __devinit da9052_regulator_probe(struct platform_device *pdev) 535{ 536 struct da9052_regulator *regulator; 537 struct da9052 *da9052; 538 struct da9052_pdata *pdata; 539 int ret; 540 541 regulator = devm_kzalloc(&pdev->dev, sizeof(struct da9052_regulator), 542 GFP_KERNEL); 543 if (!regulator) 544 return -ENOMEM; 545 546 da9052 = dev_get_drvdata(pdev->dev.parent); 547 pdata = da9052->dev->platform_data; 548 regulator->da9052 = da9052; 549 550 regulator->info = find_regulator_info(regulator->da9052->chip_id, 551 pdev->id); 552 if (regulator->info == NULL) { 553 dev_err(&pdev->dev, "invalid regulator ID specified\n"); 554 ret = -EINVAL; 555 goto err; 556 } 557 regulator->rdev = regulator_register(®ulator->info->reg_desc, 558 &pdev->dev, 559 pdata->regulators[pdev->id], 560 regulator, NULL); 561 if (IS_ERR(regulator->rdev)) { 562 dev_err(&pdev->dev, "failed to register regulator %s\n", 563 regulator->info->reg_desc.name); 564 ret = PTR_ERR(regulator->rdev); 565 goto err; 566 } 567 568 platform_set_drvdata(pdev, regulator); 569 570 return 0; 571err: 572 devm_kfree(&pdev->dev, regulator); 573 return ret; 574} 575 576static int __devexit da9052_regulator_remove(struct platform_device *pdev) 577{ 578 struct da9052_regulator *regulator = platform_get_drvdata(pdev); 579 580 regulator_unregister(regulator->rdev); 581 devm_kfree(&pdev->dev, regulator); 582 583 return 0; 584} 585 586static struct platform_driver da9052_regulator_driver = { 587 .probe = da9052_regulator_probe, 588 .remove = __devexit_p(da9052_regulator_remove), 589 .driver = { 590 .name = "da9052-regulator", 591 .owner = THIS_MODULE, 592 }, 593}; 594 595static int __init da9052_regulator_init(void) 596{ 597 return platform_driver_register(&da9052_regulator_driver); 598} 599subsys_initcall(da9052_regulator_init); 600 601static void __exit da9052_regulator_exit(void) 602{ 603 platform_driver_unregister(&da9052_regulator_driver); 604} 605module_exit(da9052_regulator_exit); 606 607MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>"); 608MODULE_DESCRIPTION("Power Regulator driver for Dialog DA9052 PMIC"); 609MODULE_LICENSE("GPL"); 610MODULE_ALIAS("platform:da9052-regulator"); 611