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

Configure Feed

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

at v2.6.32-rc5 700 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/ab3100.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 * @ab3100: handle to the AB3100 parent chip 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 ab3100 *ab3100; 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 const ldo_e_buck_typ_voltages[] = { 85 1800000, 86 1400000, 87 1300000, 88 1200000, 89 1100000, 90 1050000, 91 900000, 92}; 93 94static const int const 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 const ldo_g_typ_voltages[] = { 106 2850000, 107 2750000, 108 1800000, 109 1500000, 110}; 111 112static const int const ldo_h_typ_voltages[] = { 113 2750000, 114 1800000, 115 1500000, 116 1200000, 117}; 118 119static const int const 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 = ab3100_get_register_interruptible(abreg->ab3100, 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 = ab3100_set_register_interruptible(abreg->ab3100, 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 if (abreg->regreg == AB3100_LDO_D) { 245 int i; 246 247 dev_info(&reg->dev, "disabling LDO D - shut down system\n"); 248 /* 249 * Set regulators to default values, ignore any errors, 250 * we're going DOWN 251 */ 252 for (i = 0; i < ARRAY_SIZE(ab3100_reg_init_order); i++) { 253 (void) ab3100_set_register_interruptible(abreg->ab3100, 254 ab3100_reg_init_order[i], 255 abreg->plfdata->reg_initvals[i]); 256 } 257 258 /* Setting LDO D to 0x00 cuts the power to the SoC */ 259 return ab3100_set_register_interruptible(abreg->ab3100, 260 AB3100_LDO_D, 0x00U); 261 262 } 263 264 /* 265 * All other regulators are handled here 266 */ 267 err = ab3100_get_register_interruptible(abreg->ab3100, abreg->regreg, 268 &regval); 269 if (err) { 270 dev_err(&reg->dev, "unable to get register 0x%x\n", 271 abreg->regreg); 272 return err; 273 } 274 regval &= ~AB3100_REG_ON_MASK; 275 return ab3100_set_register_interruptible(abreg->ab3100, abreg->regreg, 276 regval); 277} 278 279static int ab3100_is_enabled_regulator(struct regulator_dev *reg) 280{ 281 struct ab3100_regulator *abreg = reg->reg_data; 282 u8 regval; 283 int err; 284 285 err = ab3100_get_register_interruptible(abreg->ab3100, abreg->regreg, 286 &regval); 287 if (err) { 288 dev_err(&reg->dev, "unable to get register 0x%x\n", 289 abreg->regreg); 290 return err; 291 } 292 293 return regval & AB3100_REG_ON_MASK; 294} 295 296static int ab3100_list_voltage_regulator(struct regulator_dev *reg, 297 unsigned selector) 298{ 299 struct ab3100_regulator *abreg = reg->reg_data; 300 301 if (selector > abreg->voltages_len) 302 return -EINVAL; 303 return abreg->typ_voltages[selector]; 304} 305 306static int ab3100_get_voltage_regulator(struct regulator_dev *reg) 307{ 308 struct ab3100_regulator *abreg = reg->reg_data; 309 u8 regval; 310 int err; 311 312 /* Return the voltage for fixed regulators immediately */ 313 if (abreg->fixed_voltage) 314 return abreg->fixed_voltage; 315 316 /* 317 * For variable types, read out setting and index into 318 * supplied voltage list. 319 */ 320 err = ab3100_get_register_interruptible(abreg->ab3100, 321 abreg->regreg, &regval); 322 if (err) { 323 dev_warn(&reg->dev, 324 "failed to get regulator value in register %02x\n", 325 abreg->regreg); 326 return err; 327 } 328 329 /* The 3 highest bits index voltages */ 330 regval &= 0xE0; 331 regval >>= 5; 332 333 if (regval > abreg->voltages_len) { 334 dev_err(&reg->dev, 335 "regulator register %02x contains an illegal voltage setting\n", 336 abreg->regreg); 337 return -EINVAL; 338 } 339 340 return abreg->typ_voltages[regval]; 341} 342 343static int ab3100_get_best_voltage_index(struct regulator_dev *reg, 344 int min_uV, int max_uV) 345{ 346 struct ab3100_regulator *abreg = reg->reg_data; 347 int i; 348 int bestmatch; 349 int bestindex; 350 351 /* 352 * Locate the minimum voltage fitting the criteria on 353 * this regulator. The switchable voltages are not 354 * in strict falling order so we need to check them 355 * all for the best match. 356 */ 357 bestmatch = INT_MAX; 358 bestindex = -1; 359 for (i = 0; i < abreg->voltages_len; i++) { 360 if (abreg->typ_voltages[i] <= max_uV && 361 abreg->typ_voltages[i] >= min_uV && 362 abreg->typ_voltages[i] < bestmatch) { 363 bestmatch = abreg->typ_voltages[i]; 364 bestindex = i; 365 } 366 } 367 368 if (bestindex < 0) { 369 dev_warn(&reg->dev, "requested %d<=x<=%d uV, out of range!\n", 370 min_uV, max_uV); 371 return -EINVAL; 372 } 373 return bestindex; 374} 375 376static int ab3100_set_voltage_regulator(struct regulator_dev *reg, 377 int min_uV, int max_uV) 378{ 379 struct ab3100_regulator *abreg = reg->reg_data; 380 u8 regval; 381 int err; 382 int bestindex; 383 384 bestindex = ab3100_get_best_voltage_index(reg, min_uV, max_uV); 385 if (bestindex < 0) 386 return bestindex; 387 388 err = ab3100_get_register_interruptible(abreg->ab3100, 389 abreg->regreg, &regval); 390 if (err) { 391 dev_warn(&reg->dev, 392 "failed to get regulator register %02x\n", 393 abreg->regreg); 394 return err; 395 } 396 397 /* The highest three bits control the variable regulators */ 398 regval &= ~0xE0; 399 regval |= (bestindex << 5); 400 401 err = ab3100_set_register_interruptible(abreg->ab3100, 402 abreg->regreg, regval); 403 if (err) 404 dev_warn(&reg->dev, "failed to set regulator register %02x\n", 405 abreg->regreg); 406 407 return err; 408} 409 410static int ab3100_set_suspend_voltage_regulator(struct regulator_dev *reg, 411 int uV) 412{ 413 struct ab3100_regulator *abreg = reg->reg_data; 414 u8 regval; 415 int err; 416 int bestindex; 417 u8 targetreg; 418 419 if (abreg->regreg == AB3100_LDO_E) 420 targetreg = AB3100_LDO_E_SLEEP; 421 else if (abreg->regreg == AB3100_BUCK) 422 targetreg = AB3100_BUCK_SLEEP; 423 else 424 return -EINVAL; 425 426 /* LDO E and BUCK have special suspend voltages you can set */ 427 bestindex = ab3100_get_best_voltage_index(reg, uV, uV); 428 429 err = ab3100_get_register_interruptible(abreg->ab3100, 430 targetreg, &regval); 431 if (err) { 432 dev_warn(&reg->dev, 433 "failed to get regulator register %02x\n", 434 targetreg); 435 return err; 436 } 437 438 /* The highest three bits control the variable regulators */ 439 regval &= ~0xE0; 440 regval |= (bestindex << 5); 441 442 err = ab3100_set_register_interruptible(abreg->ab3100, 443 targetreg, regval); 444 if (err) 445 dev_warn(&reg->dev, "failed to set regulator register %02x\n", 446 abreg->regreg); 447 448 return err; 449} 450 451/* 452 * The external regulator can just define a fixed voltage. 453 */ 454static int ab3100_get_voltage_regulator_external(struct regulator_dev *reg) 455{ 456 struct ab3100_regulator *abreg = reg->reg_data; 457 458 return abreg->plfdata->external_voltage; 459} 460 461static struct regulator_ops regulator_ops_fixed = { 462 .enable = ab3100_enable_regulator, 463 .disable = ab3100_disable_regulator, 464 .is_enabled = ab3100_is_enabled_regulator, 465 .get_voltage = ab3100_get_voltage_regulator, 466}; 467 468static struct regulator_ops regulator_ops_variable = { 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 .list_voltage = ab3100_list_voltage_regulator, 475}; 476 477static struct regulator_ops regulator_ops_variable_sleepable = { 478 .enable = ab3100_enable_regulator, 479 .disable = ab3100_disable_regulator, 480 .is_enabled = ab3100_is_enabled_regulator, 481 .get_voltage = ab3100_get_voltage_regulator, 482 .set_voltage = ab3100_set_voltage_regulator, 483 .set_suspend_voltage = ab3100_set_suspend_voltage_regulator, 484 .list_voltage = ab3100_list_voltage_regulator, 485}; 486 487/* 488 * LDO EXT is an external regulator so it is really 489 * not possible to set any voltage locally here, AB3100 490 * is an on/off switch plain an simple. The external 491 * voltage is defined in the board set-up if any. 492 */ 493static struct regulator_ops regulator_ops_external = { 494 .enable = ab3100_enable_regulator, 495 .disable = ab3100_disable_regulator, 496 .is_enabled = ab3100_is_enabled_regulator, 497 .get_voltage = ab3100_get_voltage_regulator_external, 498}; 499 500static struct regulator_desc 501ab3100_regulator_desc[AB3100_NUM_REGULATORS] = { 502 { 503 .name = "LDO_A", 504 .id = AB3100_LDO_A, 505 .ops = &regulator_ops_fixed, 506 .type = REGULATOR_VOLTAGE, 507 }, 508 { 509 .name = "LDO_C", 510 .id = AB3100_LDO_C, 511 .ops = &regulator_ops_fixed, 512 .type = REGULATOR_VOLTAGE, 513 }, 514 { 515 .name = "LDO_D", 516 .id = AB3100_LDO_D, 517 .ops = &regulator_ops_fixed, 518 .type = REGULATOR_VOLTAGE, 519 }, 520 { 521 .name = "LDO_E", 522 .id = AB3100_LDO_E, 523 .ops = &regulator_ops_variable_sleepable, 524 .n_voltages = ARRAY_SIZE(ldo_e_buck_typ_voltages), 525 .type = REGULATOR_VOLTAGE, 526 }, 527 { 528 .name = "LDO_F", 529 .id = AB3100_LDO_F, 530 .ops = &regulator_ops_variable, 531 .n_voltages = ARRAY_SIZE(ldo_f_typ_voltages), 532 .type = REGULATOR_VOLTAGE, 533 }, 534 { 535 .name = "LDO_G", 536 .id = AB3100_LDO_G, 537 .ops = &regulator_ops_variable, 538 .n_voltages = ARRAY_SIZE(ldo_g_typ_voltages), 539 .type = REGULATOR_VOLTAGE, 540 }, 541 { 542 .name = "LDO_H", 543 .id = AB3100_LDO_H, 544 .ops = &regulator_ops_variable, 545 .n_voltages = ARRAY_SIZE(ldo_h_typ_voltages), 546 .type = REGULATOR_VOLTAGE, 547 }, 548 { 549 .name = "LDO_K", 550 .id = AB3100_LDO_K, 551 .ops = &regulator_ops_variable, 552 .n_voltages = ARRAY_SIZE(ldo_k_typ_voltages), 553 .type = REGULATOR_VOLTAGE, 554 }, 555 { 556 .name = "LDO_EXT", 557 .id = AB3100_LDO_EXT, 558 .ops = &regulator_ops_external, 559 .type = REGULATOR_VOLTAGE, 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 }, 568}; 569 570/* 571 * NOTE: the following functions are regulators pluralis - it is the 572 * binding to the AB3100 core driver and the parent platform device 573 * for all the different regulators. 574 */ 575 576static int __init ab3100_regulators_probe(struct platform_device *pdev) 577{ 578 struct ab3100_platform_data *plfdata = pdev->dev.platform_data; 579 struct ab3100 *ab3100 = platform_get_drvdata(pdev); 580 int err = 0; 581 u8 data; 582 int i; 583 584 /* Check chip state */ 585 err = ab3100_get_register_interruptible(ab3100, 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 = ab3100_set_register_interruptible(ab3100, 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 if (err) { 611 dev_err(&pdev->dev, 612 "LDO D regulator initialization failed with error %d\n", 613 err); 614 return err; 615 } 616 617 /* Register the regulators */ 618 for (i = 0; i < AB3100_NUM_REGULATORS; i++) { 619 struct ab3100_regulator *reg = &ab3100_regulators[i]; 620 struct regulator_dev *rdev; 621 622 /* 623 * Initialize per-regulator struct. 624 * Inherit platform data, this comes down from the 625 * i2c boarddata, from the machine. So if you want to 626 * see what it looks like for a certain machine, go 627 * into the machine I2C setup. 628 */ 629 reg->ab3100 = ab3100; 630 reg->plfdata = plfdata; 631 632 /* 633 * Register the regulator, pass around 634 * the ab3100_regulator struct 635 */ 636 rdev = regulator_register(&ab3100_regulator_desc[i], 637 &pdev->dev, 638 &plfdata->reg_constraints[i], 639 reg); 640 641 if (IS_ERR(rdev)) { 642 err = PTR_ERR(rdev); 643 dev_err(&pdev->dev, 644 "%s: failed to register regulator %s err %d\n", 645 __func__, ab3100_regulator_desc[i].name, 646 err); 647 i--; 648 /* remove the already registered regulators */ 649 while (i > 0) { 650 regulator_unregister(ab3100_regulators[i].rdev); 651 i--; 652 } 653 return err; 654 } 655 656 /* Then set a pointer back to the registered regulator */ 657 reg->rdev = rdev; 658 } 659 660 return 0; 661} 662 663static int __exit ab3100_regulators_remove(struct platform_device *pdev) 664{ 665 int i; 666 667 for (i = 0; i < AB3100_NUM_REGULATORS; i++) { 668 struct ab3100_regulator *reg = &ab3100_regulators[i]; 669 670 regulator_unregister(reg->rdev); 671 } 672 return 0; 673} 674 675static struct platform_driver ab3100_regulators_driver = { 676 .driver = { 677 .name = "ab3100-regulators", 678 .owner = THIS_MODULE, 679 }, 680 .probe = ab3100_regulators_probe, 681 .remove = __exit_p(ab3100_regulators_remove), 682}; 683 684static __init int ab3100_regulators_init(void) 685{ 686 return platform_driver_register(&ab3100_regulators_driver); 687} 688 689static __exit void ab3100_regulators_exit(void) 690{ 691 platform_driver_register(&ab3100_regulators_driver); 692} 693 694subsys_initcall(ab3100_regulators_init); 695module_exit(ab3100_regulators_exit); 696 697MODULE_AUTHOR("Mattias Wallin <mattias.wallin@stericsson.com>"); 698MODULE_DESCRIPTION("AB3100 Regulator driver"); 699MODULE_LICENSE("GPL"); 700MODULE_ALIAS("platform:ab3100-regulators");