Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.38-rc2 690 lines 17 kB view raw
1/* 2 * drivers/regulator/ab3100.c 3 * 4 * Copyright (C) 2008-2009 ST-Ericsson AB 5 * License terms: GNU General Public License (GPL) version 2 6 * Low-level control of the AB3100 IC Low Dropout (LDO) 7 * regulators, external regulator and buck converter 8 * Author: Mattias Wallin <mattias.wallin@stericsson.com> 9 * Author: Linus Walleij <linus.walleij@stericsson.com> 10 */ 11 12#include <linux/module.h> 13#include <linux/kernel.h> 14#include <linux/init.h> 15#include <linux/err.h> 16#include <linux/delay.h> 17#include <linux/platform_device.h> 18#include <linux/regulator/driver.h> 19#include <linux/mfd/abx500.h> 20 21/* LDO registers and some handy masking definitions for AB3100 */ 22#define AB3100_LDO_A 0x40 23#define AB3100_LDO_C 0x41 24#define AB3100_LDO_D 0x42 25#define AB3100_LDO_E 0x43 26#define AB3100_LDO_E_SLEEP 0x44 27#define AB3100_LDO_F 0x45 28#define AB3100_LDO_G 0x46 29#define AB3100_LDO_H 0x47 30#define AB3100_LDO_H_SLEEP_MODE 0 31#define AB3100_LDO_H_SLEEP_EN 2 32#define AB3100_LDO_ON 4 33#define AB3100_LDO_H_VSEL_AC 5 34#define AB3100_LDO_K 0x48 35#define AB3100_LDO_EXT 0x49 36#define AB3100_BUCK 0x4A 37#define AB3100_BUCK_SLEEP 0x4B 38#define AB3100_REG_ON_MASK 0x10 39 40/** 41 * struct ab3100_regulator 42 * A struct passed around the individual regulator functions 43 * @platform_device: platform device holding this regulator 44 * @dev: handle to the device 45 * @plfdata: AB3100 platform data passed in at probe time 46 * @regreg: regulator register number in the AB3100 47 * @fixed_voltage: a fixed voltage for this regulator, if this 48 * 0 the voltages array is used instead. 49 * @typ_voltages: an array of available typical voltages for 50 * this regulator 51 * @voltages_len: length of the array of available voltages 52 */ 53struct ab3100_regulator { 54 struct regulator_dev *rdev; 55 struct device *dev; 56 struct ab3100_platform_data *plfdata; 57 u8 regreg; 58 int fixed_voltage; 59 int const *typ_voltages; 60 u8 voltages_len; 61}; 62 63/* The order in which registers are initialized */ 64static const u8 ab3100_reg_init_order[AB3100_NUM_REGULATORS+2] = { 65 AB3100_LDO_A, 66 AB3100_LDO_C, 67 AB3100_LDO_E, 68 AB3100_LDO_E_SLEEP, 69 AB3100_LDO_F, 70 AB3100_LDO_G, 71 AB3100_LDO_H, 72 AB3100_LDO_K, 73 AB3100_LDO_EXT, 74 AB3100_BUCK, 75 AB3100_BUCK_SLEEP, 76 AB3100_LDO_D, 77}; 78 79/* Preset (hardware defined) voltages for these regulators */ 80#define LDO_A_VOLTAGE 2750000 81#define LDO_C_VOLTAGE 2650000 82#define LDO_D_VOLTAGE 2650000 83 84static const int ldo_e_buck_typ_voltages[] = { 85 1800000, 86 1400000, 87 1300000, 88 1200000, 89 1100000, 90 1050000, 91 900000, 92}; 93 94static const int ldo_f_typ_voltages[] = { 95 1800000, 96 1400000, 97 1300000, 98 1200000, 99 1100000, 100 1050000, 101 2500000, 102 2650000, 103}; 104 105static const int ldo_g_typ_voltages[] = { 106 2850000, 107 2750000, 108 1800000, 109 1500000, 110}; 111 112static const int ldo_h_typ_voltages[] = { 113 2750000, 114 1800000, 115 1500000, 116 1200000, 117}; 118 119static const int ldo_k_typ_voltages[] = { 120 2750000, 121 1800000, 122}; 123 124 125/* The regulator devices */ 126static struct ab3100_regulator 127ab3100_regulators[AB3100_NUM_REGULATORS] = { 128 { 129 .regreg = AB3100_LDO_A, 130 .fixed_voltage = LDO_A_VOLTAGE, 131 }, 132 { 133 .regreg = AB3100_LDO_C, 134 .fixed_voltage = LDO_C_VOLTAGE, 135 }, 136 { 137 .regreg = AB3100_LDO_D, 138 .fixed_voltage = LDO_D_VOLTAGE, 139 }, 140 { 141 .regreg = AB3100_LDO_E, 142 .typ_voltages = ldo_e_buck_typ_voltages, 143 .voltages_len = ARRAY_SIZE(ldo_e_buck_typ_voltages), 144 }, 145 { 146 .regreg = AB3100_LDO_F, 147 .typ_voltages = ldo_f_typ_voltages, 148 .voltages_len = ARRAY_SIZE(ldo_f_typ_voltages), 149 }, 150 { 151 .regreg = AB3100_LDO_G, 152 .typ_voltages = ldo_g_typ_voltages, 153 .voltages_len = ARRAY_SIZE(ldo_g_typ_voltages), 154 }, 155 { 156 .regreg = AB3100_LDO_H, 157 .typ_voltages = ldo_h_typ_voltages, 158 .voltages_len = ARRAY_SIZE(ldo_h_typ_voltages), 159 }, 160 { 161 .regreg = AB3100_LDO_K, 162 .typ_voltages = ldo_k_typ_voltages, 163 .voltages_len = ARRAY_SIZE(ldo_k_typ_voltages), 164 }, 165 { 166 .regreg = AB3100_LDO_EXT, 167 /* No voltages for the external regulator */ 168 }, 169 { 170 .regreg = AB3100_BUCK, 171 .typ_voltages = ldo_e_buck_typ_voltages, 172 .voltages_len = ARRAY_SIZE(ldo_e_buck_typ_voltages), 173 }, 174}; 175 176/* 177 * General functions for enable, disable and is_enabled used for 178 * LDO: A,C,E,F,G,H,K,EXT and BUCK 179 */ 180static int ab3100_enable_regulator(struct regulator_dev *reg) 181{ 182 struct ab3100_regulator *abreg = reg->reg_data; 183 int err; 184 u8 regval; 185 186 err = abx500_get_register_interruptible(abreg->dev, 0, abreg->regreg, 187 &regval); 188 if (err) { 189 dev_warn(&reg->dev, "failed to get regid %d value\n", 190 abreg->regreg); 191 return err; 192 } 193 194 /* The regulator is already on, no reason to go further */ 195 if (regval & AB3100_REG_ON_MASK) 196 return 0; 197 198 regval |= AB3100_REG_ON_MASK; 199 200 err = abx500_set_register_interruptible(abreg->dev, 0, abreg->regreg, 201 regval); 202 if (err) { 203 dev_warn(&reg->dev, "failed to set regid %d value\n", 204 abreg->regreg); 205 return err; 206 } 207 208 /* Per-regulator power on delay from spec */ 209 switch (abreg->regreg) { 210 case AB3100_LDO_A: /* Fallthrough */ 211 case AB3100_LDO_C: /* Fallthrough */ 212 case AB3100_LDO_D: /* Fallthrough */ 213 case AB3100_LDO_E: /* Fallthrough */ 214 case AB3100_LDO_H: /* Fallthrough */ 215 case AB3100_LDO_K: 216 udelay(200); 217 break; 218 case AB3100_LDO_F: 219 udelay(600); 220 break; 221 case AB3100_LDO_G: 222 udelay(400); 223 break; 224 case AB3100_BUCK: 225 mdelay(1); 226 break; 227 default: 228 break; 229 } 230 231 return 0; 232} 233 234static int ab3100_disable_regulator(struct regulator_dev *reg) 235{ 236 struct ab3100_regulator *abreg = reg->reg_data; 237 int err; 238 u8 regval; 239 240 /* 241 * LDO D is a special regulator. When it is disabled, the entire 242 * system is shut down. So this is handled specially. 243 */ 244 pr_info("Called ab3100_disable_regulator\n"); 245 if (abreg->regreg == AB3100_LDO_D) { 246 dev_info(&reg->dev, "disabling LDO D - shut down system\n"); 247 /* Setting LDO D to 0x00 cuts the power to the SoC */ 248 return abx500_set_register_interruptible(abreg->dev, 0, 249 AB3100_LDO_D, 0x00U); 250 } 251 252 /* 253 * All other regulators are handled here 254 */ 255 err = abx500_get_register_interruptible(abreg->dev, 0, abreg->regreg, 256 &regval); 257 if (err) { 258 dev_err(&reg->dev, "unable to get register 0x%x\n", 259 abreg->regreg); 260 return err; 261 } 262 regval &= ~AB3100_REG_ON_MASK; 263 return abx500_set_register_interruptible(abreg->dev, 0, abreg->regreg, 264 regval); 265} 266 267static int ab3100_is_enabled_regulator(struct regulator_dev *reg) 268{ 269 struct ab3100_regulator *abreg = reg->reg_data; 270 u8 regval; 271 int err; 272 273 err = abx500_get_register_interruptible(abreg->dev, 0, abreg->regreg, 274 &regval); 275 if (err) { 276 dev_err(&reg->dev, "unable to get register 0x%x\n", 277 abreg->regreg); 278 return err; 279 } 280 281 return regval & AB3100_REG_ON_MASK; 282} 283 284static int ab3100_list_voltage_regulator(struct regulator_dev *reg, 285 unsigned selector) 286{ 287 struct ab3100_regulator *abreg = reg->reg_data; 288 289 if (selector >= abreg->voltages_len) 290 return -EINVAL; 291 return abreg->typ_voltages[selector]; 292} 293 294static int ab3100_get_voltage_regulator(struct regulator_dev *reg) 295{ 296 struct ab3100_regulator *abreg = reg->reg_data; 297 u8 regval; 298 int err; 299 300 /* Return the voltage for fixed regulators immediately */ 301 if (abreg->fixed_voltage) 302 return abreg->fixed_voltage; 303 304 /* 305 * For variable types, read out setting and index into 306 * supplied voltage list. 307 */ 308 err = abx500_get_register_interruptible(abreg->dev, 0, 309 abreg->regreg, &regval); 310 if (err) { 311 dev_warn(&reg->dev, 312 "failed to get regulator value in register %02x\n", 313 abreg->regreg); 314 return err; 315 } 316 317 /* The 3 highest bits index voltages */ 318 regval &= 0xE0; 319 regval >>= 5; 320 321 if (regval >= abreg->voltages_len) { 322 dev_err(&reg->dev, 323 "regulator register %02x contains an illegal voltage setting\n", 324 abreg->regreg); 325 return -EINVAL; 326 } 327 328 return abreg->typ_voltages[regval]; 329} 330 331static int ab3100_get_best_voltage_index(struct regulator_dev *reg, 332 int min_uV, int max_uV) 333{ 334 struct ab3100_regulator *abreg = reg->reg_data; 335 int i; 336 int bestmatch; 337 int bestindex; 338 339 /* 340 * Locate the minimum voltage fitting the criteria on 341 * this regulator. The switchable voltages are not 342 * in strict falling order so we need to check them 343 * all for the best match. 344 */ 345 bestmatch = INT_MAX; 346 bestindex = -1; 347 for (i = 0; i < abreg->voltages_len; i++) { 348 if (abreg->typ_voltages[i] <= max_uV && 349 abreg->typ_voltages[i] >= min_uV && 350 abreg->typ_voltages[i] < bestmatch) { 351 bestmatch = abreg->typ_voltages[i]; 352 bestindex = i; 353 } 354 } 355 356 if (bestindex < 0) { 357 dev_warn(&reg->dev, "requested %d<=x<=%d uV, out of range!\n", 358 min_uV, max_uV); 359 return -EINVAL; 360 } 361 return bestindex; 362} 363 364static int ab3100_set_voltage_regulator(struct regulator_dev *reg, 365 int min_uV, int max_uV, 366 unsigned *selector) 367{ 368 struct ab3100_regulator *abreg = reg->reg_data; 369 u8 regval; 370 int err; 371 int bestindex; 372 373 bestindex = ab3100_get_best_voltage_index(reg, min_uV, max_uV); 374 if (bestindex < 0) 375 return bestindex; 376 377 *selector = bestindex; 378 379 err = abx500_get_register_interruptible(abreg->dev, 0, 380 abreg->regreg, &regval); 381 if (err) { 382 dev_warn(&reg->dev, 383 "failed to get regulator register %02x\n", 384 abreg->regreg); 385 return err; 386 } 387 388 /* The highest three bits control the variable regulators */ 389 regval &= ~0xE0; 390 regval |= (bestindex << 5); 391 392 err = abx500_set_register_interruptible(abreg->dev, 0, 393 abreg->regreg, regval); 394 if (err) 395 dev_warn(&reg->dev, "failed to set regulator register %02x\n", 396 abreg->regreg); 397 398 return err; 399} 400 401static int ab3100_set_suspend_voltage_regulator(struct regulator_dev *reg, 402 int uV) 403{ 404 struct ab3100_regulator *abreg = reg->reg_data; 405 u8 regval; 406 int err; 407 int bestindex; 408 u8 targetreg; 409 410 if (abreg->regreg == AB3100_LDO_E) 411 targetreg = AB3100_LDO_E_SLEEP; 412 else if (abreg->regreg == AB3100_BUCK) 413 targetreg = AB3100_BUCK_SLEEP; 414 else 415 return -EINVAL; 416 417 /* LDO E and BUCK have special suspend voltages you can set */ 418 bestindex = ab3100_get_best_voltage_index(reg, uV, uV); 419 420 err = abx500_get_register_interruptible(abreg->dev, 0, 421 targetreg, &regval); 422 if (err) { 423 dev_warn(&reg->dev, 424 "failed to get regulator register %02x\n", 425 targetreg); 426 return err; 427 } 428 429 /* The highest three bits control the variable regulators */ 430 regval &= ~0xE0; 431 regval |= (bestindex << 5); 432 433 err = abx500_set_register_interruptible(abreg->dev, 0, 434 targetreg, regval); 435 if (err) 436 dev_warn(&reg->dev, "failed to set regulator register %02x\n", 437 abreg->regreg); 438 439 return err; 440} 441 442/* 443 * The external regulator can just define a fixed voltage. 444 */ 445static int ab3100_get_voltage_regulator_external(struct regulator_dev *reg) 446{ 447 struct ab3100_regulator *abreg = reg->reg_data; 448 449 return abreg->plfdata->external_voltage; 450} 451 452static struct regulator_ops regulator_ops_fixed = { 453 .enable = ab3100_enable_regulator, 454 .disable = ab3100_disable_regulator, 455 .is_enabled = ab3100_is_enabled_regulator, 456 .get_voltage = ab3100_get_voltage_regulator, 457}; 458 459static struct regulator_ops regulator_ops_variable = { 460 .enable = ab3100_enable_regulator, 461 .disable = ab3100_disable_regulator, 462 .is_enabled = ab3100_is_enabled_regulator, 463 .get_voltage = ab3100_get_voltage_regulator, 464 .set_voltage = ab3100_set_voltage_regulator, 465 .list_voltage = ab3100_list_voltage_regulator, 466}; 467 468static struct regulator_ops regulator_ops_variable_sleepable = { 469 .enable = ab3100_enable_regulator, 470 .disable = ab3100_disable_regulator, 471 .is_enabled = ab3100_is_enabled_regulator, 472 .get_voltage = ab3100_get_voltage_regulator, 473 .set_voltage = ab3100_set_voltage_regulator, 474 .set_suspend_voltage = ab3100_set_suspend_voltage_regulator, 475 .list_voltage = ab3100_list_voltage_regulator, 476}; 477 478/* 479 * LDO EXT is an external regulator so it is really 480 * not possible to set any voltage locally here, AB3100 481 * is an on/off switch plain an simple. The external 482 * voltage is defined in the board set-up if any. 483 */ 484static struct regulator_ops regulator_ops_external = { 485 .enable = ab3100_enable_regulator, 486 .disable = ab3100_disable_regulator, 487 .is_enabled = ab3100_is_enabled_regulator, 488 .get_voltage = ab3100_get_voltage_regulator_external, 489}; 490 491static struct regulator_desc 492ab3100_regulator_desc[AB3100_NUM_REGULATORS] = { 493 { 494 .name = "LDO_A", 495 .id = AB3100_LDO_A, 496 .ops = &regulator_ops_fixed, 497 .type = REGULATOR_VOLTAGE, 498 .owner = THIS_MODULE, 499 }, 500 { 501 .name = "LDO_C", 502 .id = AB3100_LDO_C, 503 .ops = &regulator_ops_fixed, 504 .type = REGULATOR_VOLTAGE, 505 .owner = THIS_MODULE, 506 }, 507 { 508 .name = "LDO_D", 509 .id = AB3100_LDO_D, 510 .ops = &regulator_ops_fixed, 511 .type = REGULATOR_VOLTAGE, 512 .owner = THIS_MODULE, 513 }, 514 { 515 .name = "LDO_E", 516 .id = AB3100_LDO_E, 517 .ops = &regulator_ops_variable_sleepable, 518 .n_voltages = ARRAY_SIZE(ldo_e_buck_typ_voltages), 519 .type = REGULATOR_VOLTAGE, 520 .owner = THIS_MODULE, 521 }, 522 { 523 .name = "LDO_F", 524 .id = AB3100_LDO_F, 525 .ops = &regulator_ops_variable, 526 .n_voltages = ARRAY_SIZE(ldo_f_typ_voltages), 527 .type = REGULATOR_VOLTAGE, 528 .owner = THIS_MODULE, 529 }, 530 { 531 .name = "LDO_G", 532 .id = AB3100_LDO_G, 533 .ops = &regulator_ops_variable, 534 .n_voltages = ARRAY_SIZE(ldo_g_typ_voltages), 535 .type = REGULATOR_VOLTAGE, 536 .owner = THIS_MODULE, 537 }, 538 { 539 .name = "LDO_H", 540 .id = AB3100_LDO_H, 541 .ops = &regulator_ops_variable, 542 .n_voltages = ARRAY_SIZE(ldo_h_typ_voltages), 543 .type = REGULATOR_VOLTAGE, 544 .owner = THIS_MODULE, 545 }, 546 { 547 .name = "LDO_K", 548 .id = AB3100_LDO_K, 549 .ops = &regulator_ops_variable, 550 .n_voltages = ARRAY_SIZE(ldo_k_typ_voltages), 551 .type = REGULATOR_VOLTAGE, 552 .owner = THIS_MODULE, 553 }, 554 { 555 .name = "LDO_EXT", 556 .id = AB3100_LDO_EXT, 557 .ops = &regulator_ops_external, 558 .type = REGULATOR_VOLTAGE, 559 .owner = THIS_MODULE, 560 }, 561 { 562 .name = "BUCK", 563 .id = AB3100_BUCK, 564 .ops = &regulator_ops_variable_sleepable, 565 .n_voltages = ARRAY_SIZE(ldo_e_buck_typ_voltages), 566 .type = REGULATOR_VOLTAGE, 567 .owner = THIS_MODULE, 568 }, 569}; 570 571/* 572 * NOTE: the following functions are regulators pluralis - it is the 573 * binding to the AB3100 core driver and the parent platform device 574 * for all the different regulators. 575 */ 576 577static int __devinit ab3100_regulators_probe(struct platform_device *pdev) 578{ 579 struct ab3100_platform_data *plfdata = pdev->dev.platform_data; 580 int err = 0; 581 u8 data; 582 int i; 583 584 /* Check chip state */ 585 err = abx500_get_register_interruptible(&pdev->dev, 0, 586 AB3100_LDO_D, &data); 587 if (err) { 588 dev_err(&pdev->dev, "could not read initial status of LDO_D\n"); 589 return err; 590 } 591 if (data & 0x10) 592 dev_notice(&pdev->dev, 593 "chip is already in active mode (Warm start)\n"); 594 else 595 dev_notice(&pdev->dev, 596 "chip is in inactive mode (Cold start)\n"); 597 598 /* Set up regulators */ 599 for (i = 0; i < ARRAY_SIZE(ab3100_reg_init_order); i++) { 600 err = abx500_set_register_interruptible(&pdev->dev, 0, 601 ab3100_reg_init_order[i], 602 plfdata->reg_initvals[i]); 603 if (err) { 604 dev_err(&pdev->dev, "regulator initialization failed with error %d\n", 605 err); 606 return err; 607 } 608 } 609 610 /* Register the regulators */ 611 for (i = 0; i < AB3100_NUM_REGULATORS; i++) { 612 struct ab3100_regulator *reg = &ab3100_regulators[i]; 613 struct regulator_dev *rdev; 614 615 /* 616 * Initialize per-regulator struct. 617 * Inherit platform data, this comes down from the 618 * i2c boarddata, from the machine. So if you want to 619 * see what it looks like for a certain machine, go 620 * into the machine I2C setup. 621 */ 622 reg->dev = &pdev->dev; 623 reg->plfdata = plfdata; 624 625 /* 626 * Register the regulator, pass around 627 * the ab3100_regulator struct 628 */ 629 rdev = regulator_register(&ab3100_regulator_desc[i], 630 &pdev->dev, 631 &plfdata->reg_constraints[i], 632 reg); 633 634 if (IS_ERR(rdev)) { 635 err = PTR_ERR(rdev); 636 dev_err(&pdev->dev, 637 "%s: failed to register regulator %s err %d\n", 638 __func__, ab3100_regulator_desc[i].name, 639 err); 640 /* remove the already registered regulators */ 641 while (--i >= 0) 642 regulator_unregister(ab3100_regulators[i].rdev); 643 return err; 644 } 645 646 /* Then set a pointer back to the registered regulator */ 647 reg->rdev = rdev; 648 } 649 650 return 0; 651} 652 653static int __devexit ab3100_regulators_remove(struct platform_device *pdev) 654{ 655 int i; 656 657 for (i = 0; i < AB3100_NUM_REGULATORS; i++) { 658 struct ab3100_regulator *reg = &ab3100_regulators[i]; 659 660 regulator_unregister(reg->rdev); 661 } 662 return 0; 663} 664 665static struct platform_driver ab3100_regulators_driver = { 666 .driver = { 667 .name = "ab3100-regulators", 668 .owner = THIS_MODULE, 669 }, 670 .probe = ab3100_regulators_probe, 671 .remove = __devexit_p(ab3100_regulators_remove), 672}; 673 674static __init int ab3100_regulators_init(void) 675{ 676 return platform_driver_register(&ab3100_regulators_driver); 677} 678 679static __exit void ab3100_regulators_exit(void) 680{ 681 platform_driver_unregister(&ab3100_regulators_driver); 682} 683 684subsys_initcall(ab3100_regulators_init); 685module_exit(ab3100_regulators_exit); 686 687MODULE_AUTHOR("Mattias Wallin <mattias.wallin@stericsson.com>"); 688MODULE_DESCRIPTION("AB3100 Regulator driver"); 689MODULE_LICENSE("GPL"); 690MODULE_ALIAS("platform:ab3100-regulators");