diff options
| -rw-r--r-- | arch/arm/mach-ux500/board-mop500-regulators.h | 2 | ||||
| -rw-r--r-- | arch/arm/mach-ux500/board-mop500.c | 1 | ||||
| -rw-r--r-- | drivers/regulator/Kconfig | 2 | ||||
| -rw-r--r-- | drivers/regulator/ab3100.c | 51 | ||||
| -rw-r--r-- | drivers/regulator/ab8500.c | 270 | ||||
| -rw-r--r-- | drivers/regulator/core.c | 116 | ||||
| -rw-r--r-- | drivers/regulator/max8997.c | 1 | ||||
| -rw-r--r-- | drivers/regulator/max8998.c | 1 | ||||
| -rw-r--r-- | drivers/regulator/tps6524x-regulator.c | 2 | ||||
| -rw-r--r-- | drivers/regulator/wm831x-dcdc.c | 32 | ||||
| -rw-r--r-- | drivers/regulator/wm831x-isink.c | 8 | ||||
| -rw-r--r-- | drivers/regulator/wm831x-ldo.c | 17 | ||||
| -rw-r--r-- | include/linux/mfd/ab8500.h | 6 | ||||
| -rw-r--r-- | include/linux/regulator/ab8500.h | 51 | ||||
| -rw-r--r-- | include/linux/regulator/consumer.h | 2 | ||||
| -rw-r--r-- | include/linux/regulator/driver.h | 11 | ||||
| -rw-r--r-- | include/linux/regulator/machine.h | 1 |
17 files changed, 509 insertions, 65 deletions
diff --git a/arch/arm/mach-ux500/board-mop500-regulators.h b/arch/arm/mach-ux500/board-mop500-regulators.h index 2675fae5253..f979b892e4f 100644 --- a/arch/arm/mach-ux500/board-mop500-regulators.h +++ b/arch/arm/mach-ux500/board-mop500-regulators.h | |||
| @@ -14,6 +14,8 @@ | |||
| 14 | #include <linux/regulator/machine.h> | 14 | #include <linux/regulator/machine.h> |
| 15 | #include <linux/regulator/ab8500.h> | 15 | #include <linux/regulator/ab8500.h> |
| 16 | 16 | ||
| 17 | extern struct ab8500_regulator_reg_init | ||
| 18 | ab8500_regulator_reg_init[AB8500_NUM_REGULATOR_REGISTERS]; | ||
| 17 | extern struct regulator_init_data ab8500_regulators[AB8500_NUM_REGULATORS]; | 19 | extern struct regulator_init_data ab8500_regulators[AB8500_NUM_REGULATORS]; |
| 18 | 20 | ||
| 19 | #endif | 21 | #endif |
diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c index 8790d984cac..d0076453d7f 100644 --- a/arch/arm/mach-ux500/board-mop500.c +++ b/arch/arm/mach-ux500/board-mop500.c | |||
| @@ -20,6 +20,7 @@ | |||
| 20 | #include <linux/amba/serial.h> | 20 | #include <linux/amba/serial.h> |
| 21 | #include <linux/spi/spi.h> | 21 | #include <linux/spi/spi.h> |
| 22 | #include <linux/mfd/ab8500.h> | 22 | #include <linux/mfd/ab8500.h> |
| 23 | #include <linux/regulator/ab8500.h> | ||
| 23 | #include <linux/mfd/tc3589x.h> | 24 | #include <linux/mfd/tc3589x.h> |
| 24 | #include <linux/leds-lp5521.h> | 25 | #include <linux/leds-lp5521.h> |
| 25 | #include <linux/input.h> | 26 | #include <linux/input.h> |
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index de75f67f4cc..b9f29e0d429 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig | |||
| @@ -126,7 +126,7 @@ config REGULATOR_MAX8998 | |||
| 126 | and S5PC1XX chips to control VCC_CORE and VCC_USIM voltages. | 126 | and S5PC1XX chips to control VCC_CORE and VCC_USIM voltages. |
| 127 | 127 | ||
| 128 | config REGULATOR_TWL4030 | 128 | config REGULATOR_TWL4030 |
| 129 | bool "TI TWL4030/TWL5030/TWL6030/TPS695x0 PMIC" | 129 | bool "TI TWL4030/TWL5030/TWL6030/TPS659x0 PMIC" |
| 130 | depends on TWL4030_CORE | 130 | depends on TWL4030_CORE |
| 131 | help | 131 | help |
| 132 | This driver supports the voltage regulators provided by | 132 | This driver supports the voltage regulators provided by |
diff --git a/drivers/regulator/ab3100.c b/drivers/regulator/ab3100.c index 2dec589a890..b1d77946e9c 100644 --- a/drivers/regulator/ab3100.c +++ b/drivers/regulator/ab3100.c | |||
| @@ -206,29 +206,6 @@ static int ab3100_enable_regulator(struct regulator_dev *reg) | |||
| 206 | return err; | 206 | return err; |
| 207 | } | 207 | } |
| 208 | 208 | ||
| 209 | /* Per-regulator power on delay from spec */ | ||
| 210 | switch (abreg->regreg) { | ||
| 211 | case AB3100_LDO_A: /* Fallthrough */ | ||
| 212 | case AB3100_LDO_C: /* Fallthrough */ | ||
| 213 | case AB3100_LDO_D: /* Fallthrough */ | ||
| 214 | case AB3100_LDO_E: /* Fallthrough */ | ||
| 215 | case AB3100_LDO_H: /* Fallthrough */ | ||
| 216 | case AB3100_LDO_K: | ||
| 217 | udelay(200); | ||
| 218 | break; | ||
| 219 | case AB3100_LDO_F: | ||
| 220 | udelay(600); | ||
| 221 | break; | ||
| 222 | case AB3100_LDO_G: | ||
| 223 | udelay(400); | ||
| 224 | break; | ||
| 225 | case AB3100_BUCK: | ||
| 226 | mdelay(1); | ||
| 227 | break; | ||
| 228 | default: | ||
| 229 | break; | ||
| 230 | } | ||
| 231 | |||
| 232 | return 0; | 209 | return 0; |
| 233 | } | 210 | } |
| 234 | 211 | ||
| @@ -450,11 +427,37 @@ static int ab3100_get_voltage_regulator_external(struct regulator_dev *reg) | |||
| 450 | return abreg->plfdata->external_voltage; | 427 | return abreg->plfdata->external_voltage; |
| 451 | } | 428 | } |
| 452 | 429 | ||
| 430 | static int ab3100_enable_time_regulator(struct regulator_dev *reg) | ||
| 431 | { | ||
| 432 | struct ab3100_regulator *abreg = reg->reg_data; | ||
| 433 | |||
| 434 | /* Per-regulator power on delay from spec */ | ||
| 435 | switch (abreg->regreg) { | ||
| 436 | case AB3100_LDO_A: /* Fallthrough */ | ||
| 437 | case AB3100_LDO_C: /* Fallthrough */ | ||
| 438 | case AB3100_LDO_D: /* Fallthrough */ | ||
| 439 | case AB3100_LDO_E: /* Fallthrough */ | ||
| 440 | case AB3100_LDO_H: /* Fallthrough */ | ||
| 441 | case AB3100_LDO_K: | ||
| 442 | return 200; | ||
| 443 | case AB3100_LDO_F: | ||
| 444 | return 600; | ||
| 445 | case AB3100_LDO_G: | ||
| 446 | return 400; | ||
| 447 | case AB3100_BUCK: | ||
| 448 | return 1000; | ||
| 449 | default: | ||
| 450 | break; | ||
| 451 | } | ||
| 452 | return 0; | ||
| 453 | } | ||
| 454 | |||
| 453 | static struct regulator_ops regulator_ops_fixed = { | 455 | static struct regulator_ops regulator_ops_fixed = { |
| 454 | .enable = ab3100_enable_regulator, | 456 | .enable = ab3100_enable_regulator, |
| 455 | .disable = ab3100_disable_regulator, | 457 | .disable = ab3100_disable_regulator, |
| 456 | .is_enabled = ab3100_is_enabled_regulator, | 458 | .is_enabled = ab3100_is_enabled_regulator, |
| 457 | .get_voltage = ab3100_get_voltage_regulator, | 459 | .get_voltage = ab3100_get_voltage_regulator, |
| 460 | .enable_time = ab3100_enable_time_regulator, | ||
| 458 | }; | 461 | }; |
| 459 | 462 | ||
| 460 | static struct regulator_ops regulator_ops_variable = { | 463 | static struct regulator_ops regulator_ops_variable = { |
| @@ -464,6 +467,7 @@ static struct regulator_ops regulator_ops_variable = { | |||
| 464 | .get_voltage = ab3100_get_voltage_regulator, | 467 | .get_voltage = ab3100_get_voltage_regulator, |
| 465 | .set_voltage = ab3100_set_voltage_regulator, | 468 | .set_voltage = ab3100_set_voltage_regulator, |
| 466 | .list_voltage = ab3100_list_voltage_regulator, | 469 | .list_voltage = ab3100_list_voltage_regulator, |
| 470 | .enable_time = ab3100_enable_time_regulator, | ||
| 467 | }; | 471 | }; |
| 468 | 472 | ||
| 469 | static struct regulator_ops regulator_ops_variable_sleepable = { | 473 | static struct regulator_ops regulator_ops_variable_sleepable = { |
| @@ -474,6 +478,7 @@ static struct regulator_ops regulator_ops_variable_sleepable = { | |||
| 474 | .set_voltage = ab3100_set_voltage_regulator, | 478 | .set_voltage = ab3100_set_voltage_regulator, |
| 475 | .set_suspend_voltage = ab3100_set_suspend_voltage_regulator, | 479 | .set_suspend_voltage = ab3100_set_suspend_voltage_regulator, |
| 476 | .list_voltage = ab3100_list_voltage_regulator, | 480 | .list_voltage = ab3100_list_voltage_regulator, |
| 481 | .enable_time = ab3100_enable_time_regulator, | ||
| 477 | }; | 482 | }; |
| 478 | 483 | ||
| 479 | /* | 484 | /* |
diff --git a/drivers/regulator/ab8500.c b/drivers/regulator/ab8500.c index d9a052c53ae..02f3c2333c8 100644 --- a/drivers/regulator/ab8500.c +++ b/drivers/regulator/ab8500.c | |||
| @@ -9,7 +9,7 @@ | |||
| 9 | * AB8500 peripheral regulators | 9 | * AB8500 peripheral regulators |
| 10 | * | 10 | * |
| 11 | * AB8500 supports the following regulators: | 11 | * AB8500 supports the following regulators: |
| 12 | * VAUX1/2/3, VINTCORE, VTVOUT, VAUDIO, VAMIC1/2, VDMIC, VANA | 12 | * VAUX1/2/3, VINTCORE, VTVOUT, VUSB, VAUDIO, VAMIC1/2, VDMIC, VANA |
| 13 | */ | 13 | */ |
| 14 | #include <linux/init.h> | 14 | #include <linux/init.h> |
| 15 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
| @@ -38,6 +38,7 @@ | |||
| 38 | * @voltage_mask: mask to control regulator voltage | 38 | * @voltage_mask: mask to control regulator voltage |
| 39 | * @voltages: supported voltage table | 39 | * @voltages: supported voltage table |
| 40 | * @voltages_len: number of supported voltages for the regulator | 40 | * @voltages_len: number of supported voltages for the regulator |
| 41 | * @delay: startup/set voltage delay in us | ||
| 41 | */ | 42 | */ |
| 42 | struct ab8500_regulator_info { | 43 | struct ab8500_regulator_info { |
| 43 | struct device *dev; | 44 | struct device *dev; |
| @@ -55,6 +56,7 @@ struct ab8500_regulator_info { | |||
| 55 | u8 voltage_mask; | 56 | u8 voltage_mask; |
| 56 | int const *voltages; | 57 | int const *voltages; |
| 57 | int voltages_len; | 58 | int voltages_len; |
| 59 | unsigned int delay; | ||
| 58 | }; | 60 | }; |
| 59 | 61 | ||
| 60 | /* voltage tables for the vauxn/vintcore supplies */ | 62 | /* voltage tables for the vauxn/vintcore supplies */ |
| @@ -290,6 +292,29 @@ static int ab8500_regulator_set_voltage(struct regulator_dev *rdev, | |||
| 290 | return ret; | 292 | return ret; |
| 291 | } | 293 | } |
| 292 | 294 | ||
| 295 | static int ab8500_regulator_enable_time(struct regulator_dev *rdev) | ||
| 296 | { | ||
| 297 | struct ab8500_regulator_info *info = rdev_get_drvdata(rdev); | ||
| 298 | |||
| 299 | return info->delay; | ||
| 300 | } | ||
| 301 | |||
| 302 | static int ab8500_regulator_set_voltage_time_sel(struct regulator_dev *rdev, | ||
| 303 | unsigned int old_sel, | ||
| 304 | unsigned int new_sel) | ||
| 305 | { | ||
| 306 | struct ab8500_regulator_info *info = rdev_get_drvdata(rdev); | ||
| 307 | int ret; | ||
| 308 | |||
| 309 | /* If the regulator isn't on, it won't take time here */ | ||
| 310 | ret = ab8500_regulator_is_enabled(rdev); | ||
| 311 | if (ret < 0) | ||
| 312 | return ret; | ||
| 313 | if (!ret) | ||
| 314 | return 0; | ||
| 315 | return info->delay; | ||
| 316 | } | ||
| 317 | |||
| 293 | static struct regulator_ops ab8500_regulator_ops = { | 318 | static struct regulator_ops ab8500_regulator_ops = { |
| 294 | .enable = ab8500_regulator_enable, | 319 | .enable = ab8500_regulator_enable, |
| 295 | .disable = ab8500_regulator_disable, | 320 | .disable = ab8500_regulator_disable, |
| @@ -297,6 +322,8 @@ static struct regulator_ops ab8500_regulator_ops = { | |||
| 297 | .get_voltage = ab8500_regulator_get_voltage, | 322 | .get_voltage = ab8500_regulator_get_voltage, |
| 298 | .set_voltage = ab8500_regulator_set_voltage, | 323 | .set_voltage = ab8500_regulator_set_voltage, |
| 299 | .list_voltage = ab8500_list_voltage, | 324 | .list_voltage = ab8500_list_voltage, |
| 325 | .enable_time = ab8500_regulator_enable_time, | ||
| 326 | .set_voltage_time_sel = ab8500_regulator_set_voltage_time_sel, | ||
| 300 | }; | 327 | }; |
| 301 | 328 | ||
| 302 | static int ab8500_fixed_get_voltage(struct regulator_dev *rdev) | 329 | static int ab8500_fixed_get_voltage(struct regulator_dev *rdev) |
| @@ -317,6 +344,8 @@ static struct regulator_ops ab8500_regulator_fixed_ops = { | |||
| 317 | .is_enabled = ab8500_regulator_is_enabled, | 344 | .is_enabled = ab8500_regulator_is_enabled, |
| 318 | .get_voltage = ab8500_fixed_get_voltage, | 345 | .get_voltage = ab8500_fixed_get_voltage, |
| 319 | .list_voltage = ab8500_list_voltage, | 346 | .list_voltage = ab8500_list_voltage, |
| 347 | .enable_time = ab8500_regulator_enable_time, | ||
| 348 | .set_voltage_time_sel = ab8500_regulator_set_voltage_time_sel, | ||
| 320 | }; | 349 | }; |
| 321 | 350 | ||
| 322 | static struct ab8500_regulator_info | 351 | static struct ab8500_regulator_info |
| @@ -426,12 +455,28 @@ static struct ab8500_regulator_info | |||
| 426 | .owner = THIS_MODULE, | 455 | .owner = THIS_MODULE, |
| 427 | .n_voltages = 1, | 456 | .n_voltages = 1, |
| 428 | }, | 457 | }, |
| 458 | .delay = 10000, | ||
| 429 | .fixed_uV = 2000000, | 459 | .fixed_uV = 2000000, |
| 430 | .update_bank = 0x03, | 460 | .update_bank = 0x03, |
| 431 | .update_reg = 0x80, | 461 | .update_reg = 0x80, |
| 432 | .update_mask = 0x82, | 462 | .update_mask = 0x82, |
| 433 | .update_val_enable = 0x02, | 463 | .update_val_enable = 0x02, |
| 434 | }, | 464 | }, |
| 465 | [AB8500_LDO_USB] = { | ||
| 466 | .desc = { | ||
| 467 | .name = "LDO-USB", | ||
| 468 | .ops = &ab8500_regulator_fixed_ops, | ||
| 469 | .type = REGULATOR_VOLTAGE, | ||
| 470 | .id = AB8500_LDO_USB, | ||
| 471 | .owner = THIS_MODULE, | ||
| 472 | .n_voltages = 1, | ||
| 473 | }, | ||
| 474 | .fixed_uV = 3300000, | ||
| 475 | .update_bank = 0x03, | ||
| 476 | .update_reg = 0x82, | ||
| 477 | .update_mask = 0x03, | ||
| 478 | .update_val_enable = 0x01, | ||
| 479 | }, | ||
| 435 | [AB8500_LDO_AUDIO] = { | 480 | [AB8500_LDO_AUDIO] = { |
| 436 | .desc = { | 481 | .desc = { |
| 437 | .name = "LDO-AUDIO", | 482 | .name = "LDO-AUDIO", |
| @@ -511,6 +556,186 @@ static struct ab8500_regulator_info | |||
| 511 | 556 | ||
| 512 | }; | 557 | }; |
| 513 | 558 | ||
| 559 | struct ab8500_reg_init { | ||
| 560 | u8 bank; | ||
| 561 | u8 addr; | ||
| 562 | u8 mask; | ||
| 563 | }; | ||
| 564 | |||
| 565 | #define REG_INIT(_id, _bank, _addr, _mask) \ | ||
| 566 | [_id] = { \ | ||
| 567 | .bank = _bank, \ | ||
| 568 | .addr = _addr, \ | ||
| 569 | .mask = _mask, \ | ||
| 570 | } | ||
| 571 | |||
| 572 | static struct ab8500_reg_init ab8500_reg_init[] = { | ||
| 573 | /* | ||
| 574 | * 0x30, VanaRequestCtrl | ||
| 575 | * 0x0C, VpllRequestCtrl | ||
| 576 | * 0xc0, VextSupply1RequestCtrl | ||
| 577 | */ | ||
| 578 | REG_INIT(AB8500_REGUREQUESTCTRL2, 0x03, 0x04, 0xfc), | ||
| 579 | /* | ||
| 580 | * 0x03, VextSupply2RequestCtrl | ||
| 581 | * 0x0c, VextSupply3RequestCtrl | ||
| 582 | * 0x30, Vaux1RequestCtrl | ||
| 583 | * 0xc0, Vaux2RequestCtrl | ||
| 584 | */ | ||
| 585 | REG_INIT(AB8500_REGUREQUESTCTRL3, 0x03, 0x05, 0xff), | ||
| 586 | /* | ||
| 587 | * 0x03, Vaux3RequestCtrl | ||
| 588 | * 0x04, SwHPReq | ||
| 589 | */ | ||
| 590 | REG_INIT(AB8500_REGUREQUESTCTRL4, 0x03, 0x06, 0x07), | ||
| 591 | /* | ||
| 592 | * 0x08, VanaSysClkReq1HPValid | ||
| 593 | * 0x20, Vaux1SysClkReq1HPValid | ||
| 594 | * 0x40, Vaux2SysClkReq1HPValid | ||
| 595 | * 0x80, Vaux3SysClkReq1HPValid | ||
| 596 | */ | ||
| 597 | REG_INIT(AB8500_REGUSYSCLKREQ1HPVALID1, 0x03, 0x07, 0xe8), | ||
| 598 | /* | ||
| 599 | * 0x10, VextSupply1SysClkReq1HPValid | ||
| 600 | * 0x20, VextSupply2SysClkReq1HPValid | ||
| 601 | * 0x40, VextSupply3SysClkReq1HPValid | ||
| 602 | */ | ||
| 603 | REG_INIT(AB8500_REGUSYSCLKREQ1HPVALID2, 0x03, 0x08, 0x70), | ||
| 604 | /* | ||
| 605 | * 0x08, VanaHwHPReq1Valid | ||
| 606 | * 0x20, Vaux1HwHPReq1Valid | ||
| 607 | * 0x40, Vaux2HwHPReq1Valid | ||
| 608 | * 0x80, Vaux3HwHPReq1Valid | ||
| 609 | */ | ||
| 610 | REG_INIT(AB8500_REGUHWHPREQ1VALID1, 0x03, 0x09, 0xe8), | ||
| 611 | /* | ||
| 612 | * 0x01, VextSupply1HwHPReq1Valid | ||
| 613 | * 0x02, VextSupply2HwHPReq1Valid | ||
| 614 | * 0x04, VextSupply3HwHPReq1Valid | ||
| 615 | */ | ||
| 616 | REG_INIT(AB8500_REGUHWHPREQ1VALID2, 0x03, 0x0a, 0x07), | ||
| 617 | /* | ||
| 618 | * 0x08, VanaHwHPReq2Valid | ||
| 619 | * 0x20, Vaux1HwHPReq2Valid | ||
| 620 | * 0x40, Vaux2HwHPReq2Valid | ||
| 621 | * 0x80, Vaux3HwHPReq2Valid | ||
| 622 | */ | ||
| 623 | REG_INIT(AB8500_REGUHWHPREQ2VALID1, 0x03, 0x0b, 0xe8), | ||
| 624 | /* | ||
| 625 | * 0x01, VextSupply1HwHPReq2Valid | ||
| 626 | * 0x02, VextSupply2HwHPReq2Valid | ||
| 627 | * 0x04, VextSupply3HwHPReq2Valid | ||
| 628 | */ | ||
| 629 | REG_INIT(AB8500_REGUHWHPREQ2VALID2, 0x03, 0x0c, 0x07), | ||
| 630 | /* | ||
| 631 | * 0x20, VanaSwHPReqValid | ||
| 632 | * 0x80, Vaux1SwHPReqValid | ||
| 633 | */ | ||
| 634 | REG_INIT(AB8500_REGUSWHPREQVALID1, 0x03, 0x0d, 0xa0), | ||
| 635 | /* | ||
| 636 | * 0x01, Vaux2SwHPReqValid | ||
| 637 | * 0x02, Vaux3SwHPReqValid | ||
| 638 | * 0x04, VextSupply1SwHPReqValid | ||
| 639 | * 0x08, VextSupply2SwHPReqValid | ||
| 640 | * 0x10, VextSupply3SwHPReqValid | ||
| 641 | */ | ||
| 642 | REG_INIT(AB8500_REGUSWHPREQVALID2, 0x03, 0x0e, 0x1f), | ||
| 643 | /* | ||
| 644 | * 0x02, SysClkReq2Valid1 | ||
| 645 | * ... | ||
| 646 | * 0x80, SysClkReq8Valid1 | ||
| 647 | */ | ||
| 648 | REG_INIT(AB8500_REGUSYSCLKREQVALID1, 0x03, 0x0f, 0xfe), | ||
| 649 | /* | ||
| 650 | * 0x02, SysClkReq2Valid2 | ||
| 651 | * ... | ||
| 652 | * 0x80, SysClkReq8Valid2 | ||
| 653 | */ | ||
| 654 | REG_INIT(AB8500_REGUSYSCLKREQVALID2, 0x03, 0x10, 0xfe), | ||
| 655 | /* | ||
| 656 | * 0x02, VTVoutEna | ||
| 657 | * 0x04, Vintcore12Ena | ||
| 658 | * 0x38, Vintcore12Sel | ||
| 659 | * 0x40, Vintcore12LP | ||
| 660 | * 0x80, VTVoutLP | ||
| 661 | */ | ||
| 662 | REG_INIT(AB8500_REGUMISC1, 0x03, 0x80, 0xfe), | ||
| 663 | /* | ||
| 664 | * 0x02, VaudioEna | ||
| 665 | * 0x04, VdmicEna | ||
| 666 | * 0x08, Vamic1Ena | ||
| 667 | * 0x10, Vamic2Ena | ||
| 668 | */ | ||
| 669 | REG_INIT(AB8500_VAUDIOSUPPLY, 0x03, 0x83, 0x1e), | ||
| 670 | /* | ||
| 671 | * 0x01, Vamic1_dzout | ||
| 672 | * 0x02, Vamic2_dzout | ||
| 673 | */ | ||
| 674 | REG_INIT(AB8500_REGUCTRL1VAMIC, 0x03, 0x84, 0x03), | ||
| 675 | /* | ||
| 676 | * 0x0c, VanaRegu | ||
| 677 | * 0x03, VpllRegu | ||
| 678 | */ | ||
| 679 | REG_INIT(AB8500_VPLLVANAREGU, 0x04, 0x06, 0x0f), | ||
| 680 | /* | ||
| 681 | * 0x01, VrefDDREna | ||
| 682 | * 0x02, VrefDDRSleepMode | ||
| 683 | */ | ||
| 684 | REG_INIT(AB8500_VREFDDR, 0x04, 0x07, 0x03), | ||
| 685 | /* | ||
| 686 | * 0x03, VextSupply1Regu | ||
| 687 | * 0x0c, VextSupply2Regu | ||
| 688 | * 0x30, VextSupply3Regu | ||
| 689 | * 0x40, ExtSupply2Bypass | ||
| 690 | * 0x80, ExtSupply3Bypass | ||
| 691 | */ | ||
| 692 | REG_INIT(AB8500_EXTSUPPLYREGU, 0x04, 0x08, 0xff), | ||
| 693 | /* | ||
| 694 | * 0x03, Vaux1Regu | ||
| 695 | * 0x0c, Vaux2Regu | ||
| 696 | */ | ||
| 697 | REG_INIT(AB8500_VAUX12REGU, 0x04, 0x09, 0x0f), | ||
| 698 | /* | ||
| 699 | * 0x03, Vaux3Regu | ||
| 700 | */ | ||
| 701 | REG_INIT(AB8500_VRF1VAUX3REGU, 0x04, 0x0a, 0x03), | ||
| 702 | /* | ||
| 703 | * 0x3f, Vsmps1Sel1 | ||
| 704 | */ | ||
| 705 | REG_INIT(AB8500_VSMPS1SEL1, 0x04, 0x13, 0x3f), | ||
| 706 | /* | ||
| 707 | * 0x0f, Vaux1Sel | ||
| 708 | */ | ||
| 709 | REG_INIT(AB8500_VAUX1SEL, 0x04, 0x1f, 0x0f), | ||
| 710 | /* | ||
| 711 | * 0x0f, Vaux2Sel | ||
| 712 | */ | ||
| 713 | REG_INIT(AB8500_VAUX2SEL, 0x04, 0x20, 0x0f), | ||
| 714 | /* | ||
| 715 | * 0x07, Vaux3Sel | ||
| 716 | */ | ||
| 717 | REG_INIT(AB8500_VRF1VAUX3SEL, 0x04, 0x21, 0x07), | ||
| 718 | /* | ||
| 719 | * 0x01, VextSupply12LP | ||
| 720 | */ | ||
| 721 | REG_INIT(AB8500_REGUCTRL2SPARE, 0x04, 0x22, 0x01), | ||
| 722 | /* | ||
| 723 | * 0x04, Vaux1Disch | ||
| 724 | * 0x08, Vaux2Disch | ||
| 725 | * 0x10, Vaux3Disch | ||
| 726 | * 0x20, Vintcore12Disch | ||
| 727 | * 0x40, VTVoutDisch | ||
| 728 | * 0x80, VaudioDisch | ||
| 729 | */ | ||
| 730 | REG_INIT(AB8500_REGUCTRLDISCH, 0x04, 0x43, 0xfc), | ||
| 731 | /* | ||
| 732 | * 0x02, VanaDisch | ||
| 733 | * 0x04, VdmicPullDownEna | ||
| 734 | * 0x10, VdmicDisch | ||
| 735 | */ | ||
| 736 | REG_INIT(AB8500_REGUCTRLDISCH2, 0x04, 0x44, 0x16), | ||
| 737 | }; | ||
| 738 | |||
| 514 | static __devinit int ab8500_regulator_probe(struct platform_device *pdev) | 739 | static __devinit int ab8500_regulator_probe(struct platform_device *pdev) |
| 515 | { | 740 | { |
| 516 | struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent); | 741 | struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent); |
| @@ -529,10 +754,51 @@ static __devinit int ab8500_regulator_probe(struct platform_device *pdev) | |||
| 529 | 754 | ||
| 530 | /* make sure the platform data has the correct size */ | 755 | /* make sure the platform data has the correct size */ |
| 531 | if (pdata->num_regulator != ARRAY_SIZE(ab8500_regulator_info)) { | 756 | if (pdata->num_regulator != ARRAY_SIZE(ab8500_regulator_info)) { |
| 532 | dev_err(&pdev->dev, "platform configuration error\n"); | 757 | dev_err(&pdev->dev, "Configuration error: size mismatch.\n"); |
| 533 | return -EINVAL; | 758 | return -EINVAL; |
| 534 | } | 759 | } |
| 535 | 760 | ||
| 761 | /* initialize registers */ | ||
| 762 | for (i = 0; i < pdata->num_regulator_reg_init; i++) { | ||
| 763 | int id; | ||
| 764 | u8 value; | ||
| 765 | |||
| 766 | id = pdata->regulator_reg_init[i].id; | ||
| 767 | value = pdata->regulator_reg_init[i].value; | ||
| 768 | |||
| 769 | /* check for configuration errors */ | ||
| 770 | if (id >= AB8500_NUM_REGULATOR_REGISTERS) { | ||
| 771 | dev_err(&pdev->dev, | ||
| 772 | "Configuration error: id outside range.\n"); | ||
| 773 | return -EINVAL; | ||
| 774 | } | ||
| 775 | if (value & ~ab8500_reg_init[id].mask) { | ||
| 776 | dev_err(&pdev->dev, | ||
| 777 | "Configuration error: value outside mask.\n"); | ||
| 778 | return -EINVAL; | ||
| 779 | } | ||
| 780 | |||
| 781 | /* initialize register */ | ||
| 782 | err = abx500_mask_and_set_register_interruptible(&pdev->dev, | ||
| 783 | ab8500_reg_init[id].bank, | ||
| 784 | ab8500_reg_init[id].addr, | ||
| 785 | ab8500_reg_init[id].mask, | ||
| 786 | value); | ||
| 787 | if (err < 0) { | ||
| 788 | dev_err(&pdev->dev, | ||
| 789 | "Failed to initialize 0x%02x, 0x%02x.\n", | ||
| 790 | ab8500_reg_init[id].bank, | ||
| 791 | ab8500_reg_init[id].addr); | ||
| 792 | return err; | ||
| 793 | } | ||
| 794 | dev_vdbg(&pdev->dev, | ||
| 795 | " init: 0x%02x, 0x%02x, 0x%02x, 0x%02x\n", | ||
| 796 | ab8500_reg_init[id].bank, | ||
| 797 | ab8500_reg_init[id].addr, | ||
| 798 | ab8500_reg_init[id].mask, | ||
| 799 | value); | ||
| 800 | } | ||
| 801 | |||
| 536 | /* register all regulators */ | 802 | /* register all regulators */ |
| 537 | for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) { | 803 | for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) { |
| 538 | struct ab8500_regulator_info *info = NULL; | 804 | struct ab8500_regulator_info *info = NULL; |
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 9fa20957847..3ffc6979d16 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c | |||
| @@ -1629,6 +1629,7 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev, | |||
| 1629 | int min_uV, int max_uV) | 1629 | int min_uV, int max_uV) |
| 1630 | { | 1630 | { |
| 1631 | int ret; | 1631 | int ret; |
| 1632 | int delay = 0; | ||
| 1632 | unsigned int selector; | 1633 | unsigned int selector; |
| 1633 | 1634 | ||
| 1634 | trace_regulator_set_voltage(rdev_get_name(rdev), min_uV, max_uV); | 1635 | trace_regulator_set_voltage(rdev_get_name(rdev), min_uV, max_uV); |
| @@ -1662,6 +1663,22 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev, | |||
| 1662 | } | 1663 | } |
| 1663 | } | 1664 | } |
| 1664 | 1665 | ||
| 1666 | /* | ||
| 1667 | * If we can't obtain the old selector there is not enough | ||
| 1668 | * info to call set_voltage_time_sel(). | ||
| 1669 | */ | ||
| 1670 | if (rdev->desc->ops->set_voltage_time_sel && | ||
| 1671 | rdev->desc->ops->get_voltage_sel) { | ||
| 1672 | unsigned int old_selector = 0; | ||
| 1673 | |||
| 1674 | ret = rdev->desc->ops->get_voltage_sel(rdev); | ||
| 1675 | if (ret < 0) | ||
| 1676 | return ret; | ||
| 1677 | old_selector = ret; | ||
| 1678 | delay = rdev->desc->ops->set_voltage_time_sel(rdev, | ||
| 1679 | old_selector, selector); | ||
| 1680 | } | ||
| 1681 | |||
| 1665 | if (best_val != INT_MAX) { | 1682 | if (best_val != INT_MAX) { |
| 1666 | ret = rdev->desc->ops->set_voltage_sel(rdev, selector); | 1683 | ret = rdev->desc->ops->set_voltage_sel(rdev, selector); |
| 1667 | selector = best_val; | 1684 | selector = best_val; |
| @@ -1672,6 +1689,14 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev, | |||
| 1672 | ret = -EINVAL; | 1689 | ret = -EINVAL; |
| 1673 | } | 1690 | } |
| 1674 | 1691 | ||
| 1692 | /* Insert any necessary delays */ | ||
| 1693 | if (delay >= 1000) { | ||
| 1694 | mdelay(delay / 1000); | ||
| 1695 | udelay(delay % 1000); | ||
| 1696 | } else if (delay) { | ||
| 1697 | udelay(delay); | ||
| 1698 | } | ||
| 1699 | |||
| 1675 | if (ret == 0) | 1700 | if (ret == 0) |
| 1676 | _notifier_call_chain(rdev, REGULATOR_EVENT_VOLTAGE_CHANGE, | 1701 | _notifier_call_chain(rdev, REGULATOR_EVENT_VOLTAGE_CHANGE, |
| 1677 | NULL); | 1702 | NULL); |
| @@ -1740,6 +1765,51 @@ out: | |||
| 1740 | EXPORT_SYMBOL_GPL(regulator_set_voltage); | 1765 | EXPORT_SYMBOL_GPL(regulator_set_voltage); |
| 1741 | 1766 | ||
| 1742 | /** | 1767 | /** |
| 1768 | * regulator_set_voltage_time - get raise/fall time | ||
| 1769 | * @regulator: regulator source | ||
| 1770 | * @old_uV: starting voltage in microvolts | ||
| 1771 | * @new_uV: target voltage in microvolts | ||
| 1772 | * | ||
| 1773 | * Provided with the starting and ending voltage, this function attempts to | ||
| 1774 | * calculate the time in microseconds required to rise or fall to this new | ||
| 1775 | * voltage. | ||
| 1776 | */ | ||
| 1777 | int regulator_set_voltage_time(struct regulator *regulator, | ||
| 1778 | int old_uV, int new_uV) | ||
| 1779 | { | ||
| 1780 | struct regulator_dev *rdev = regulator->rdev; | ||
| 1781 | struct regulator_ops *ops = rdev->desc->ops; | ||
| 1782 | int old_sel = -1; | ||
| 1783 | int new_sel = -1; | ||
| 1784 | int voltage; | ||
| 1785 | int i; | ||
| 1786 | |||
| 1787 | /* Currently requires operations to do this */ | ||
| 1788 | if (!ops->list_voltage || !ops->set_voltage_time_sel | ||
| 1789 | || !rdev->desc->n_voltages) | ||
| 1790 | return -EINVAL; | ||
| 1791 | |||
| 1792 | for (i = 0; i < rdev->desc->n_voltages; i++) { | ||
| 1793 | /* We only look for exact voltage matches here */ | ||
| 1794 | voltage = regulator_list_voltage(regulator, i); | ||
| 1795 | if (voltage < 0) | ||
| 1796 | return -EINVAL; | ||
| 1797 | if (voltage == 0) | ||
| 1798 | continue; | ||
| 1799 | if (voltage == old_uV) | ||
| 1800 | old_sel = i; | ||
| 1801 | if (voltage == new_uV) | ||
| 1802 | new_sel = i; | ||
| 1803 | } | ||
| 1804 | |||
| 1805 | if (old_sel < 0 || new_sel < 0) | ||
| 1806 | return -EINVAL; | ||
| 1807 | |||
| 1808 | return ops->set_voltage_time_sel(rdev, old_sel, new_sel); | ||
| 1809 | } | ||
| 1810 | EXPORT_SYMBOL_GPL(regulator_set_voltage_time); | ||
| 1811 | |||
| 1812 | /** | ||
| 1743 | * regulator_sync_voltage - re-apply last regulator output voltage | 1813 | * regulator_sync_voltage - re-apply last regulator output voltage |
| 1744 | * @regulator: regulator source | 1814 | * @regulator: regulator source |
| 1745 | * | 1815 | * |
| @@ -2565,8 +2635,11 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc, | |||
| 2565 | init_data->consumer_supplies[i].dev, | 2635 | init_data->consumer_supplies[i].dev, |
| 2566 | init_data->consumer_supplies[i].dev_name, | 2636 | init_data->consumer_supplies[i].dev_name, |
| 2567 | init_data->consumer_supplies[i].supply); | 2637 | init_data->consumer_supplies[i].supply); |
| 2568 | if (ret < 0) | 2638 | if (ret < 0) { |
| 2639 | dev_err(dev, "Failed to set supply %s\n", | ||
| 2640 | init_data->consumer_supplies[i].supply); | ||
| 2569 | goto unset_supplies; | 2641 | goto unset_supplies; |
| 2642 | } | ||
| 2570 | } | 2643 | } |
| 2571 | 2644 | ||
| 2572 | list_add(&rdev->list, ®ulator_list); | 2645 | list_add(&rdev->list, ®ulator_list); |
| @@ -2653,6 +2726,47 @@ out: | |||
| 2653 | EXPORT_SYMBOL_GPL(regulator_suspend_prepare); | 2726 | EXPORT_SYMBOL_GPL(regulator_suspend_prepare); |
| 2654 | 2727 | ||
| 2655 | /** | 2728 | /** |
| 2729 | * regulator_suspend_finish - resume regulators from system wide suspend | ||
| 2730 | * | ||
| 2731 | * Turn on regulators that might be turned off by regulator_suspend_prepare | ||
| 2732 | * and that should be turned on according to the regulators properties. | ||
| 2733 | */ | ||
| 2734 | int regulator_suspend_finish(void) | ||
| 2735 | { | ||
| 2736 | struct regulator_dev *rdev; | ||
| 2737 | int ret = 0, error; | ||
| 2738 | |||
| 2739 | mutex_lock(®ulator_list_mutex); | ||
| 2740 | list_for_each_entry(rdev, ®ulator_list, list) { | ||
| 2741 | struct regulator_ops *ops = rdev->desc->ops; | ||
| 2742 | |||
| 2743 | mutex_lock(&rdev->mutex); | ||
| 2744 | if ((rdev->use_count > 0 || rdev->constraints->always_on) && | ||
| 2745 | ops->enable) { | ||
| 2746 | error = ops->enable(rdev); | ||
| 2747 | if (error) | ||
| 2748 | ret = error; | ||
| 2749 | } else { | ||
| 2750 | if (!has_full_constraints) | ||
| 2751 | goto unlock; | ||
| 2752 | if (!ops->disable) | ||
| 2753 | goto unlock; | ||
| 2754 | if (ops->is_enabled && !ops->is_enabled(rdev)) | ||
| 2755 | goto unlock; | ||
| 2756 | |||
| 2757 | error = ops->disable(rdev); | ||
| 2758 | if (error) | ||
| 2759 | ret = error; | ||
| 2760 | } | ||
| 2761 | unlock: | ||
| 2762 | mutex_unlock(&rdev->mutex); | ||
| 2763 | } | ||
| 2764 | mutex_unlock(®ulator_list_mutex); | ||
| 2765 | return ret; | ||
| 2766 | } | ||
| 2767 | EXPORT_SYMBOL_GPL(regulator_suspend_finish); | ||
| 2768 | |||
| 2769 | /** | ||
| 2656 | * regulator_has_full_constraints - the system has fully specified constraints | 2770 | * regulator_has_full_constraints - the system has fully specified constraints |
| 2657 | * | 2771 | * |
| 2658 | * Calling this function will cause the regulator API to disable all | 2772 | * Calling this function will cause the regulator API to disable all |
diff --git a/drivers/regulator/max8997.c b/drivers/regulator/max8997.c index 01ef7e9903b..77e0cfb30b2 100644 --- a/drivers/regulator/max8997.c +++ b/drivers/regulator/max8997.c | |||
| @@ -1185,6 +1185,7 @@ static const struct platform_device_id max8997_pmic_id[] = { | |||
| 1185 | { "max8997-pmic", 0}, | 1185 | { "max8997-pmic", 0}, |
| 1186 | { }, | 1186 | { }, |
| 1187 | }; | 1187 | }; |
| 1188 | MODULE_DEVICE_TABLE(platform, max8997_pmic_id); | ||
| 1188 | 1189 | ||
| 1189 | static struct platform_driver max8997_pmic_driver = { | 1190 | static struct platform_driver max8997_pmic_driver = { |
| 1190 | .driver = { | 1191 | .driver = { |
diff --git a/drivers/regulator/max8998.c b/drivers/regulator/max8998.c index 0ec49ca527a..43410266f99 100644 --- a/drivers/regulator/max8998.c +++ b/drivers/regulator/max8998.c | |||
| @@ -887,6 +887,7 @@ static const struct platform_device_id max8998_pmic_id[] = { | |||
| 887 | { "lp3974-pmic", TYPE_LP3974 }, | 887 | { "lp3974-pmic", TYPE_LP3974 }, |
| 888 | { } | 888 | { } |
| 889 | }; | 889 | }; |
| 890 | MODULE_DEVICE_TABLE(platform, max8998_pmic_id); | ||
| 890 | 891 | ||
| 891 | static struct platform_driver max8998_pmic_driver = { | 892 | static struct platform_driver max8998_pmic_driver = { |
| 892 | .driver = { | 893 | .driver = { |
diff --git a/drivers/regulator/tps6524x-regulator.c b/drivers/regulator/tps6524x-regulator.c index 176a6be5a8c..9166aa0a9df 100644 --- a/drivers/regulator/tps6524x-regulator.c +++ b/drivers/regulator/tps6524x-regulator.c | |||
| @@ -596,7 +596,7 @@ static struct regulator_ops regulator_ops = { | |||
| 596 | .get_current_limit = get_current_limit, | 596 | .get_current_limit = get_current_limit, |
| 597 | }; | 597 | }; |
| 598 | 598 | ||
| 599 | static int __devexit pmic_remove(struct spi_device *spi) | 599 | static int pmic_remove(struct spi_device *spi) |
| 600 | { | 600 | { |
| 601 | struct tps6524x *hw = spi_get_drvdata(spi); | 601 | struct tps6524x *hw = spi_get_drvdata(spi); |
| 602 | int i; | 602 | int i; |
diff --git a/drivers/regulator/wm831x-dcdc.c b/drivers/regulator/wm831x-dcdc.c index 06df898842c..e93453b1b97 100644 --- a/drivers/regulator/wm831x-dcdc.c +++ b/drivers/regulator/wm831x-dcdc.c | |||
| @@ -565,9 +565,8 @@ static __devinit int wm831x_buckv_probe(struct platform_device *pdev) | |||
| 565 | } | 565 | } |
| 566 | 566 | ||
| 567 | irq = platform_get_irq_byname(pdev, "UV"); | 567 | irq = platform_get_irq_byname(pdev, "UV"); |
| 568 | ret = wm831x_request_irq(wm831x, irq, wm831x_dcdc_uv_irq, | 568 | ret = request_threaded_irq(irq, NULL, wm831x_dcdc_uv_irq, |
| 569 | IRQF_TRIGGER_RISING, dcdc->name, | 569 | IRQF_TRIGGER_RISING, dcdc->name, dcdc); |
| 570 | dcdc); | ||
| 571 | if (ret != 0) { | 570 | if (ret != 0) { |
| 572 | dev_err(&pdev->dev, "Failed to request UV IRQ %d: %d\n", | 571 | dev_err(&pdev->dev, "Failed to request UV IRQ %d: %d\n", |
| 573 | irq, ret); | 572 | irq, ret); |
| @@ -575,9 +574,8 @@ static __devinit int wm831x_buckv_probe(struct platform_device *pdev) | |||
| 575 | } | 574 | } |
| 576 | 575 | ||
| 577 | irq = platform_get_irq_byname(pdev, "HC"); | 576 | irq = platform_get_irq_byname(pdev, "HC"); |
| 578 | ret = wm831x_request_irq(wm831x, irq, wm831x_dcdc_oc_irq, | 577 | ret = request_threaded_irq(irq, NULL, wm831x_dcdc_oc_irq, |
| 579 | IRQF_TRIGGER_RISING, dcdc->name, | 578 | IRQF_TRIGGER_RISING, dcdc->name, dcdc); |
| 580 | dcdc); | ||
| 581 | if (ret != 0) { | 579 | if (ret != 0) { |
| 582 | dev_err(&pdev->dev, "Failed to request HC IRQ %d: %d\n", | 580 | dev_err(&pdev->dev, "Failed to request HC IRQ %d: %d\n", |
| 583 | irq, ret); | 581 | irq, ret); |
| @@ -589,7 +587,7 @@ static __devinit int wm831x_buckv_probe(struct platform_device *pdev) | |||
| 589 | return 0; | 587 | return 0; |
| 590 | 588 | ||
| 591 | err_uv: | 589 | err_uv: |
| 592 | wm831x_free_irq(wm831x, platform_get_irq_byname(pdev, "UV"), dcdc); | 590 | free_irq(platform_get_irq_byname(pdev, "UV"), dcdc); |
| 593 | err_regulator: | 591 | err_regulator: |
| 594 | regulator_unregister(dcdc->regulator); | 592 | regulator_unregister(dcdc->regulator); |
| 595 | err: | 593 | err: |
| @@ -606,8 +604,8 @@ static __devexit int wm831x_buckv_remove(struct platform_device *pdev) | |||
| 606 | 604 | ||
| 607 | platform_set_drvdata(pdev, NULL); | 605 | platform_set_drvdata(pdev, NULL); |
| 608 | 606 | ||
| 609 | wm831x_free_irq(wm831x, platform_get_irq_byname(pdev, "HC"), dcdc); | 607 | free_irq(platform_get_irq_byname(pdev, "HC"), dcdc); |
| 610 | wm831x_free_irq(wm831x, platform_get_irq_byname(pdev, "UV"), dcdc); | 608 | free_irq(platform_get_irq_byname(pdev, "UV"), dcdc); |
| 611 | regulator_unregister(dcdc->regulator); | 609 | regulator_unregister(dcdc->regulator); |
| 612 | if (dcdc->dvs_gpio) | 610 | if (dcdc->dvs_gpio) |
| 613 | gpio_free(dcdc->dvs_gpio); | 611 | gpio_free(dcdc->dvs_gpio); |
| @@ -756,9 +754,8 @@ static __devinit int wm831x_buckp_probe(struct platform_device *pdev) | |||
| 756 | } | 754 | } |
| 757 | 755 | ||
| 758 | irq = platform_get_irq_byname(pdev, "UV"); | 756 | irq = platform_get_irq_byname(pdev, "UV"); |
| 759 | ret = wm831x_request_irq(wm831x, irq, wm831x_dcdc_uv_irq, | 757 | ret = request_threaded_irq(irq, NULL, wm831x_dcdc_uv_irq, |
| 760 | IRQF_TRIGGER_RISING, dcdc->name, | 758 | IRQF_TRIGGER_RISING, dcdc->name, dcdc); |
| 761 | dcdc); | ||
| 762 | if (ret != 0) { | 759 | if (ret != 0) { |
| 763 | dev_err(&pdev->dev, "Failed to request UV IRQ %d: %d\n", | 760 | dev_err(&pdev->dev, "Failed to request UV IRQ %d: %d\n", |
| 764 | irq, ret); | 761 | irq, ret); |
| @@ -783,7 +780,7 @@ static __devexit int wm831x_buckp_remove(struct platform_device *pdev) | |||
| 783 | 780 | ||
| 784 | platform_set_drvdata(pdev, NULL); | 781 | platform_set_drvdata(pdev, NULL); |
| 785 | 782 | ||
| 786 | wm831x_free_irq(wm831x, platform_get_irq_byname(pdev, "UV"), dcdc); | 783 | free_irq(platform_get_irq_byname(pdev, "UV"), dcdc); |
| 787 | regulator_unregister(dcdc->regulator); | 784 | regulator_unregister(dcdc->regulator); |
| 788 | kfree(dcdc); | 785 | kfree(dcdc); |
| 789 | 786 | ||
| @@ -885,9 +882,9 @@ static __devinit int wm831x_boostp_probe(struct platform_device *pdev) | |||
| 885 | } | 882 | } |
| 886 | 883 | ||
| 887 | irq = platform_get_irq_byname(pdev, "UV"); | 884 | irq = platform_get_irq_byname(pdev, "UV"); |
| 888 | ret = wm831x_request_irq(wm831x, irq, wm831x_dcdc_uv_irq, | 885 | ret = request_threaded_irq(irq, NULL, wm831x_dcdc_uv_irq, |
| 889 | IRQF_TRIGGER_RISING, dcdc->name, | 886 | IRQF_TRIGGER_RISING, dcdc->name, |
| 890 | dcdc); | 887 | dcdc); |
| 891 | if (ret != 0) { | 888 | if (ret != 0) { |
| 892 | dev_err(&pdev->dev, "Failed to request UV IRQ %d: %d\n", | 889 | dev_err(&pdev->dev, "Failed to request UV IRQ %d: %d\n", |
| 893 | irq, ret); | 890 | irq, ret); |
| @@ -908,11 +905,10 @@ err: | |||
| 908 | static __devexit int wm831x_boostp_remove(struct platform_device *pdev) | 905 | static __devexit int wm831x_boostp_remove(struct platform_device *pdev) |
| 909 | { | 906 | { |
| 910 | struct wm831x_dcdc *dcdc = platform_get_drvdata(pdev); | 907 | struct wm831x_dcdc *dcdc = platform_get_drvdata(pdev); |
| 911 | struct wm831x *wm831x = dcdc->wm831x; | ||
| 912 | 908 | ||
| 913 | platform_set_drvdata(pdev, NULL); | 909 | platform_set_drvdata(pdev, NULL); |
| 914 | 910 | ||
| 915 | wm831x_free_irq(wm831x, platform_get_irq_byname(pdev, "UV"), dcdc); | 911 | free_irq(platform_get_irq_byname(pdev, "UV"), dcdc); |
| 916 | regulator_unregister(dcdc->regulator); | 912 | regulator_unregister(dcdc->regulator); |
| 917 | kfree(dcdc); | 913 | kfree(dcdc); |
| 918 | 914 | ||
diff --git a/drivers/regulator/wm831x-isink.c b/drivers/regulator/wm831x-isink.c index 6c446cd6ad5..01f27c7f423 100644 --- a/drivers/regulator/wm831x-isink.c +++ b/drivers/regulator/wm831x-isink.c | |||
| @@ -198,9 +198,8 @@ static __devinit int wm831x_isink_probe(struct platform_device *pdev) | |||
| 198 | } | 198 | } |
| 199 | 199 | ||
| 200 | irq = platform_get_irq(pdev, 0); | 200 | irq = platform_get_irq(pdev, 0); |
| 201 | ret = wm831x_request_irq(wm831x, irq, wm831x_isink_irq, | 201 | ret = request_threaded_irq(irq, NULL, wm831x_isink_irq, |
| 202 | IRQF_TRIGGER_RISING, isink->name, | 202 | IRQF_TRIGGER_RISING, isink->name, isink); |
| 203 | isink); | ||
| 204 | if (ret != 0) { | 203 | if (ret != 0) { |
| 205 | dev_err(&pdev->dev, "Failed to request ISINK IRQ %d: %d\n", | 204 | dev_err(&pdev->dev, "Failed to request ISINK IRQ %d: %d\n", |
| 206 | irq, ret); | 205 | irq, ret); |
| @@ -221,11 +220,10 @@ err: | |||
| 221 | static __devexit int wm831x_isink_remove(struct platform_device *pdev) | 220 | static __devexit int wm831x_isink_remove(struct platform_device *pdev) |
| 222 | { | 221 | { |
| 223 | struct wm831x_isink *isink = platform_get_drvdata(pdev); | 222 | struct wm831x_isink *isink = platform_get_drvdata(pdev); |
| 224 | struct wm831x *wm831x = isink->wm831x; | ||
| 225 | 223 | ||
| 226 | platform_set_drvdata(pdev, NULL); | 224 | platform_set_drvdata(pdev, NULL); |
| 227 | 225 | ||
| 228 | wm831x_free_irq(wm831x, platform_get_irq(pdev, 0), isink); | 226 | free_irq(platform_get_irq(pdev, 0), isink); |
| 229 | 227 | ||
| 230 | regulator_unregister(isink->regulator); | 228 | regulator_unregister(isink->regulator); |
| 231 | kfree(isink); | 229 | kfree(isink); |
diff --git a/drivers/regulator/wm831x-ldo.c b/drivers/regulator/wm831x-ldo.c index c94fc5b7cd5..2220cf8defb 100644 --- a/drivers/regulator/wm831x-ldo.c +++ b/drivers/regulator/wm831x-ldo.c | |||
| @@ -354,9 +354,9 @@ static __devinit int wm831x_gp_ldo_probe(struct platform_device *pdev) | |||
| 354 | } | 354 | } |
| 355 | 355 | ||
| 356 | irq = platform_get_irq_byname(pdev, "UV"); | 356 | irq = platform_get_irq_byname(pdev, "UV"); |
| 357 | ret = wm831x_request_irq(wm831x, irq, wm831x_ldo_uv_irq, | 357 | ret = request_threaded_irq(irq, NULL, wm831x_ldo_uv_irq, |
| 358 | IRQF_TRIGGER_RISING, ldo->name, | 358 | IRQF_TRIGGER_RISING, ldo->name, |
| 359 | ldo); | 359 | ldo); |
| 360 | if (ret != 0) { | 360 | if (ret != 0) { |
| 361 | dev_err(&pdev->dev, "Failed to request UV IRQ %d: %d\n", | 361 | dev_err(&pdev->dev, "Failed to request UV IRQ %d: %d\n", |
| 362 | irq, ret); | 362 | irq, ret); |
| @@ -377,11 +377,10 @@ err: | |||
| 377 | static __devexit int wm831x_gp_ldo_remove(struct platform_device *pdev) | 377 | static __devexit int wm831x_gp_ldo_remove(struct platform_device *pdev) |
| 378 | { | 378 | { |
| 379 | struct wm831x_ldo *ldo = platform_get_drvdata(pdev); | 379 | struct wm831x_ldo *ldo = platform_get_drvdata(pdev); |
| 380 | struct wm831x *wm831x = ldo->wm831x; | ||
| 381 | 380 | ||
| 382 | platform_set_drvdata(pdev, NULL); | 381 | platform_set_drvdata(pdev, NULL); |
| 383 | 382 | ||
| 384 | wm831x_free_irq(wm831x, platform_get_irq_byname(pdev, "UV"), ldo); | 383 | free_irq(platform_get_irq_byname(pdev, "UV"), ldo); |
| 385 | regulator_unregister(ldo->regulator); | 384 | regulator_unregister(ldo->regulator); |
| 386 | kfree(ldo); | 385 | kfree(ldo); |
| 387 | 386 | ||
| @@ -619,9 +618,8 @@ static __devinit int wm831x_aldo_probe(struct platform_device *pdev) | |||
| 619 | } | 618 | } |
| 620 | 619 | ||
| 621 | irq = platform_get_irq_byname(pdev, "UV"); | 620 | irq = platform_get_irq_byname(pdev, "UV"); |
| 622 | ret = wm831x_request_irq(wm831x, irq, wm831x_ldo_uv_irq, | 621 | ret = request_threaded_irq(irq, NULL, wm831x_ldo_uv_irq, |
| 623 | IRQF_TRIGGER_RISING, ldo->name, | 622 | IRQF_TRIGGER_RISING, ldo->name, ldo); |
| 624 | ldo); | ||
| 625 | if (ret != 0) { | 623 | if (ret != 0) { |
| 626 | dev_err(&pdev->dev, "Failed to request UV IRQ %d: %d\n", | 624 | dev_err(&pdev->dev, "Failed to request UV IRQ %d: %d\n", |
| 627 | irq, ret); | 625 | irq, ret); |
| @@ -642,9 +640,8 @@ err: | |||
| 642 | static __devexit int wm831x_aldo_remove(struct platform_device *pdev) | 640 | static __devexit int wm831x_aldo_remove(struct platform_device *pdev) |
| 643 | { | 641 | { |
| 644 | struct wm831x_ldo *ldo = platform_get_drvdata(pdev); | 642 | struct wm831x_ldo *ldo = platform_get_drvdata(pdev); |
| 645 | struct wm831x *wm831x = ldo->wm831x; | ||
| 646 | 643 | ||
| 647 | wm831x_free_irq(wm831x, platform_get_irq_byname(pdev, "UV"), ldo); | 644 | free_irq(platform_get_irq_byname(pdev, "UV"), ldo); |
| 648 | regulator_unregister(ldo->regulator); | 645 | regulator_unregister(ldo->regulator); |
| 649 | kfree(ldo); | 646 | kfree(ldo); |
| 650 | 647 | ||
diff --git a/include/linux/mfd/ab8500.h b/include/linux/mfd/ab8500.h index 56f8dea7215..6e4f77ef4d2 100644 --- a/include/linux/mfd/ab8500.h +++ b/include/linux/mfd/ab8500.h | |||
| @@ -139,17 +139,23 @@ struct ab8500 { | |||
| 139 | u8 oldmask[AB8500_NUM_IRQ_REGS]; | 139 | u8 oldmask[AB8500_NUM_IRQ_REGS]; |
| 140 | }; | 140 | }; |
| 141 | 141 | ||
| 142 | struct regulator_reg_init; | ||
| 142 | struct regulator_init_data; | 143 | struct regulator_init_data; |
| 143 | 144 | ||
| 144 | /** | 145 | /** |
| 145 | * struct ab8500_platform_data - AB8500 platform data | 146 | * struct ab8500_platform_data - AB8500 platform data |
| 146 | * @irq_base: start of AB8500 IRQs, AB8500_NR_IRQS will be used | 147 | * @irq_base: start of AB8500 IRQs, AB8500_NR_IRQS will be used |
| 147 | * @init: board-specific initialization after detection of ab8500 | 148 | * @init: board-specific initialization after detection of ab8500 |
| 149 | * @num_regulator_reg_init: number of regulator init registers | ||
| 150 | * @regulator_reg_init: regulator init registers | ||
| 151 | * @num_regulator: number of regulators | ||
| 148 | * @regulator: machine-specific constraints for regulators | 152 | * @regulator: machine-specific constraints for regulators |
| 149 | */ | 153 | */ |
| 150 | struct ab8500_platform_data { | 154 | struct ab8500_platform_data { |
| 151 | int irq_base; | 155 | int irq_base; |
| 152 | void (*init) (struct ab8500 *); | 156 | void (*init) (struct ab8500 *); |
| 157 | int num_regulator_reg_init; | ||
| 158 | struct ab8500_regulator_reg_init *regulator_reg_init; | ||
| 153 | int num_regulator; | 159 | int num_regulator; |
| 154 | struct regulator_init_data *regulator; | 160 | struct regulator_init_data *regulator; |
| 155 | }; | 161 | }; |
diff --git a/include/linux/regulator/ab8500.h b/include/linux/regulator/ab8500.h index 6a210f1511f..76579f964a2 100644 --- a/include/linux/regulator/ab8500.h +++ b/include/linux/regulator/ab8500.h | |||
| @@ -3,8 +3,8 @@ | |||
| 3 | * | 3 | * |
| 4 | * License Terms: GNU General Public License v2 | 4 | * License Terms: GNU General Public License v2 |
| 5 | * | 5 | * |
| 6 | * Author: Sundar Iyer <sundar.iyer@stericsson.com> for ST-Ericsson | 6 | * Authors: Sundar Iyer <sundar.iyer@stericsson.com> for ST-Ericsson |
| 7 | * | 7 | * Bengt Jonsson <bengt.g.jonsson@stericsson.com> for ST-Ericsson |
| 8 | */ | 8 | */ |
| 9 | 9 | ||
| 10 | #ifndef __LINUX_MFD_AB8500_REGULATOR_H | 10 | #ifndef __LINUX_MFD_AB8500_REGULATOR_H |
| @@ -17,6 +17,7 @@ enum ab8500_regulator_id { | |||
| 17 | AB8500_LDO_AUX3, | 17 | AB8500_LDO_AUX3, |
| 18 | AB8500_LDO_INTCORE, | 18 | AB8500_LDO_INTCORE, |
| 19 | AB8500_LDO_TVOUT, | 19 | AB8500_LDO_TVOUT, |
| 20 | AB8500_LDO_USB, | ||
| 20 | AB8500_LDO_AUDIO, | 21 | AB8500_LDO_AUDIO, |
| 21 | AB8500_LDO_ANAMIC1, | 22 | AB8500_LDO_ANAMIC1, |
| 22 | AB8500_LDO_ANAMIC2, | 23 | AB8500_LDO_ANAMIC2, |
| @@ -24,4 +25,50 @@ enum ab8500_regulator_id { | |||
| 24 | AB8500_LDO_ANA, | 25 | AB8500_LDO_ANA, |
| 25 | AB8500_NUM_REGULATORS, | 26 | AB8500_NUM_REGULATORS, |
| 26 | }; | 27 | }; |
| 28 | |||
| 29 | /* AB8500 register initialization */ | ||
| 30 | struct ab8500_regulator_reg_init { | ||
| 31 | int id; | ||
| 32 | u8 value; | ||
| 33 | }; | ||
| 34 | |||
| 35 | #define INIT_REGULATOR_REGISTER(_id, _value) \ | ||
| 36 | { \ | ||
| 37 | .id = _id, \ | ||
| 38 | .value = _value, \ | ||
| 39 | } | ||
| 40 | |||
| 41 | /* AB8500 registers */ | ||
| 42 | enum ab8500_regulator_reg { | ||
| 43 | AB8500_REGUREQUESTCTRL2, | ||
| 44 | AB8500_REGUREQUESTCTRL3, | ||
| 45 | AB8500_REGUREQUESTCTRL4, | ||
| 46 | AB8500_REGUSYSCLKREQ1HPVALID1, | ||
| 47 | AB8500_REGUSYSCLKREQ1HPVALID2, | ||
| 48 | AB8500_REGUHWHPREQ1VALID1, | ||
| 49 | AB8500_REGUHWHPREQ1VALID2, | ||
| 50 | AB8500_REGUHWHPREQ2VALID1, | ||
| 51 | AB8500_REGUHWHPREQ2VALID2, | ||
| 52 | AB8500_REGUSWHPREQVALID1, | ||
| 53 | AB8500_REGUSWHPREQVALID2, | ||
| 54 | AB8500_REGUSYSCLKREQVALID1, | ||
| 55 | AB8500_REGUSYSCLKREQVALID2, | ||
| 56 | AB8500_REGUMISC1, | ||
| 57 | AB8500_VAUDIOSUPPLY, | ||
| 58 | AB8500_REGUCTRL1VAMIC, | ||
| 59 | AB8500_VPLLVANAREGU, | ||
| 60 | AB8500_VREFDDR, | ||
| 61 | AB8500_EXTSUPPLYREGU, | ||
| 62 | AB8500_VAUX12REGU, | ||
| 63 | AB8500_VRF1VAUX3REGU, | ||
| 64 | AB8500_VAUX1SEL, | ||
| 65 | AB8500_VAUX2SEL, | ||
| 66 | AB8500_VRF1VAUX3SEL, | ||
| 67 | AB8500_REGUCTRL2SPARE, | ||
| 68 | AB8500_REGUCTRLDISCH, | ||
| 69 | AB8500_REGUCTRLDISCH2, | ||
| 70 | AB8500_VSMPS1SEL1, | ||
| 71 | AB8500_NUM_REGULATOR_REGISTERS, | ||
| 72 | }; | ||
| 73 | |||
| 27 | #endif | 74 | #endif |
diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h index 7954f6bd7ed..9e87c1cb727 100644 --- a/include/linux/regulator/consumer.h +++ b/include/linux/regulator/consumer.h | |||
| @@ -153,6 +153,8 @@ int regulator_list_voltage(struct regulator *regulator, unsigned selector); | |||
| 153 | int regulator_is_supported_voltage(struct regulator *regulator, | 153 | int regulator_is_supported_voltage(struct regulator *regulator, |
| 154 | int min_uV, int max_uV); | 154 | int min_uV, int max_uV); |
| 155 | int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV); | 155 | int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV); |
| 156 | int regulator_set_voltage_time(struct regulator *regulator, | ||
| 157 | int old_uV, int new_uV); | ||
| 156 | int regulator_get_voltage(struct regulator *regulator); | 158 | int regulator_get_voltage(struct regulator *regulator); |
| 157 | int regulator_sync_voltage(struct regulator *regulator); | 159 | int regulator_sync_voltage(struct regulator *regulator); |
| 158 | int regulator_set_current_limit(struct regulator *regulator, | 160 | int regulator_set_current_limit(struct regulator *regulator, |
diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h index b8ed16a33c4..6c433b89c80 100644 --- a/include/linux/regulator/driver.h +++ b/include/linux/regulator/driver.h | |||
| @@ -63,7 +63,11 @@ enum regulator_status { | |||
| 63 | * when running with the specified parameters. | 63 | * when running with the specified parameters. |
| 64 | * | 64 | * |
| 65 | * @enable_time: Time taken for the regulator voltage output voltage to | 65 | * @enable_time: Time taken for the regulator voltage output voltage to |
| 66 | * stabalise after being enabled, in microseconds. | 66 | * stabilise after being enabled, in microseconds. |
| 67 | * @set_voltage_time_sel: Time taken for the regulator voltage output voltage | ||
| 68 | * to stabilise after being set to a new value, in microseconds. | ||
| 69 | * The function provides the from and to voltage selector, the | ||
| 70 | * function should return the worst case. | ||
| 67 | * | 71 | * |
| 68 | * @set_suspend_voltage: Set the voltage for the regulator when the system | 72 | * @set_suspend_voltage: Set the voltage for the regulator when the system |
| 69 | * is suspended. | 73 | * is suspended. |
| @@ -103,8 +107,11 @@ struct regulator_ops { | |||
| 103 | int (*set_mode) (struct regulator_dev *, unsigned int mode); | 107 | int (*set_mode) (struct regulator_dev *, unsigned int mode); |
| 104 | unsigned int (*get_mode) (struct regulator_dev *); | 108 | unsigned int (*get_mode) (struct regulator_dev *); |
| 105 | 109 | ||
| 106 | /* Time taken to enable the regulator */ | 110 | /* Time taken to enable or set voltage on the regulator */ |
| 107 | int (*enable_time) (struct regulator_dev *); | 111 | int (*enable_time) (struct regulator_dev *); |
| 112 | int (*set_voltage_time_sel) (struct regulator_dev *, | ||
| 113 | unsigned int old_selector, | ||
| 114 | unsigned int new_selector); | ||
| 108 | 115 | ||
| 109 | /* report regulator status ... most other accessors report | 116 | /* report regulator status ... most other accessors report |
| 110 | * control inputs, this reports results of combining inputs | 117 | * control inputs, this reports results of combining inputs |
diff --git a/include/linux/regulator/machine.h b/include/linux/regulator/machine.h index 761c745b9c2..c4c4fc45f85 100644 --- a/include/linux/regulator/machine.h +++ b/include/linux/regulator/machine.h | |||
| @@ -186,6 +186,7 @@ struct regulator_init_data { | |||
| 186 | }; | 186 | }; |
| 187 | 187 | ||
| 188 | int regulator_suspend_prepare(suspend_state_t state); | 188 | int regulator_suspend_prepare(suspend_state_t state); |
| 189 | int regulator_suspend_finish(void); | ||
| 189 | 190 | ||
| 190 | #ifdef CONFIG_REGULATOR | 191 | #ifdef CONFIG_REGULATOR |
| 191 | void regulator_has_full_constraints(void); | 192 | void regulator_has_full_constraints(void); |
