diff options
Diffstat (limited to 'drivers/regulator')
-rw-r--r-- | drivers/regulator/palmas-regulator.c | 93 |
1 files changed, 78 insertions, 15 deletions
diff --git a/drivers/regulator/palmas-regulator.c b/drivers/regulator/palmas-regulator.c index 6538b339e441..33369160b770 100644 --- a/drivers/regulator/palmas-regulator.c +++ b/drivers/regulator/palmas-regulator.c | |||
@@ -187,6 +187,8 @@ static const struct regs_info palmas_regs_info[] = { | |||
187 | }, | 187 | }, |
188 | }; | 188 | }; |
189 | 189 | ||
190 | static unsigned int palmas_smps_ramp_delay[4] = {0, 10000, 5000, 2500}; | ||
191 | |||
190 | #define SMPS_CTRL_MODE_OFF 0x00 | 192 | #define SMPS_CTRL_MODE_OFF 0x00 |
191 | #define SMPS_CTRL_MODE_ON 0x01 | 193 | #define SMPS_CTRL_MODE_ON 0x01 |
192 | #define SMPS_CTRL_MODE_ECO 0x02 | 194 | #define SMPS_CTRL_MODE_ECO 0x02 |
@@ -397,6 +399,56 @@ static int palmas_map_voltage_smps(struct regulator_dev *rdev, | |||
397 | return ret; | 399 | return ret; |
398 | } | 400 | } |
399 | 401 | ||
402 | static int palma_smps_set_voltage_smps_time_sel(struct regulator_dev *rdev, | ||
403 | unsigned int old_selector, unsigned int new_selector) | ||
404 | { | ||
405 | struct palmas_pmic *pmic = rdev_get_drvdata(rdev); | ||
406 | int id = rdev_get_id(rdev); | ||
407 | int old_uv, new_uv; | ||
408 | unsigned int ramp_delay = pmic->ramp_delay[id]; | ||
409 | |||
410 | if (!ramp_delay) | ||
411 | return 0; | ||
412 | |||
413 | old_uv = palmas_list_voltage_smps(rdev, old_selector); | ||
414 | if (old_uv < 0) | ||
415 | return old_uv; | ||
416 | |||
417 | new_uv = palmas_list_voltage_smps(rdev, new_selector); | ||
418 | if (new_uv < 0) | ||
419 | return new_uv; | ||
420 | |||
421 | return DIV_ROUND_UP(abs(old_uv - new_uv), ramp_delay); | ||
422 | } | ||
423 | |||
424 | static int palmas_smps_set_ramp_delay(struct regulator_dev *rdev, | ||
425 | int ramp_delay) | ||
426 | { | ||
427 | struct palmas_pmic *pmic = rdev_get_drvdata(rdev); | ||
428 | int id = rdev_get_id(rdev); | ||
429 | unsigned int reg = 0; | ||
430 | unsigned int addr = palmas_regs_info[id].tstep_addr; | ||
431 | int ret; | ||
432 | |||
433 | if (ramp_delay <= 0) | ||
434 | reg = 0; | ||
435 | else if (ramp_delay < 2500) | ||
436 | reg = 3; | ||
437 | else if (ramp_delay < 5000) | ||
438 | reg = 2; | ||
439 | else | ||
440 | reg = 1; | ||
441 | |||
442 | ret = palmas_smps_write(pmic->palmas, addr, reg); | ||
443 | if (ret < 0) { | ||
444 | dev_err(pmic->palmas->dev, "TSTEP write failed: %d\n", ret); | ||
445 | return ret; | ||
446 | } | ||
447 | |||
448 | pmic->ramp_delay[id] = palmas_smps_ramp_delay[reg]; | ||
449 | return ret; | ||
450 | } | ||
451 | |||
400 | static struct regulator_ops palmas_ops_smps = { | 452 | static struct regulator_ops palmas_ops_smps = { |
401 | .is_enabled = palmas_is_enabled_smps, | 453 | .is_enabled = palmas_is_enabled_smps, |
402 | .enable = palmas_enable_smps, | 454 | .enable = palmas_enable_smps, |
@@ -407,6 +459,8 @@ static struct regulator_ops palmas_ops_smps = { | |||
407 | .set_voltage_sel = regulator_set_voltage_sel_regmap, | 459 | .set_voltage_sel = regulator_set_voltage_sel_regmap, |
408 | .list_voltage = palmas_list_voltage_smps, | 460 | .list_voltage = palmas_list_voltage_smps, |
409 | .map_voltage = palmas_map_voltage_smps, | 461 | .map_voltage = palmas_map_voltage_smps, |
462 | .set_voltage_time_sel = palma_smps_set_voltage_smps_time_sel, | ||
463 | .set_ramp_delay = palmas_smps_set_ramp_delay, | ||
410 | }; | 464 | }; |
411 | 465 | ||
412 | static struct regulator_ops palmas_ops_smps10 = { | 466 | static struct regulator_ops palmas_ops_smps10 = { |
@@ -495,16 +549,6 @@ static int palmas_smps_init(struct palmas *palmas, int id, | |||
495 | if (ret) | 549 | if (ret) |
496 | return ret; | 550 | return ret; |
497 | 551 | ||
498 | if (palmas_regs_info[id].tstep_addr && reg_init->tstep) { | ||
499 | addr = palmas_regs_info[id].tstep_addr; | ||
500 | |||
501 | reg = reg_init->tstep & PALMAS_SMPS12_TSTEP_TSTEP_MASK; | ||
502 | |||
503 | ret = palmas_smps_write(palmas, addr, reg); | ||
504 | if (ret) | ||
505 | return ret; | ||
506 | } | ||
507 | |||
508 | if (palmas_regs_info[id].vsel_addr && reg_init->vsel) { | 552 | if (palmas_regs_info[id].vsel_addr && reg_init->vsel) { |
509 | addr = palmas_regs_info[id].vsel_addr; | 553 | addr = palmas_regs_info[id].vsel_addr; |
510 | 554 | ||
@@ -686,11 +730,6 @@ static void palmas_dt_to_pdata(struct device *dev, | |||
686 | if (!ret) | 730 | if (!ret) |
687 | pdata->reg_init[idx]->mode_sleep = prop; | 731 | pdata->reg_init[idx]->mode_sleep = prop; |
688 | 732 | ||
689 | ret = of_property_read_u32(palmas_matches[idx].of_node, | ||
690 | "ti,tstep", &prop); | ||
691 | if (!ret) | ||
692 | pdata->reg_init[idx]->tstep = prop; | ||
693 | |||
694 | ret = of_property_read_bool(palmas_matches[idx].of_node, | 733 | ret = of_property_read_bool(palmas_matches[idx].of_node, |
695 | "ti,smps-range"); | 734 | "ti,smps-range"); |
696 | if (ret) | 735 | if (ret) |
@@ -752,6 +791,7 @@ static int palmas_regulators_probe(struct platform_device *pdev) | |||
752 | config.driver_data = pmic; | 791 | config.driver_data = pmic; |
753 | 792 | ||
754 | for (id = 0; id < PALMAS_REG_LDO1; id++) { | 793 | for (id = 0; id < PALMAS_REG_LDO1; id++) { |
794 | bool ramp_delay_support = false; | ||
755 | 795 | ||
756 | /* | 796 | /* |
757 | * Miss out regulators which are not available due | 797 | * Miss out regulators which are not available due |
@@ -762,19 +802,42 @@ static int palmas_regulators_probe(struct platform_device *pdev) | |||
762 | case PALMAS_REG_SMPS3: | 802 | case PALMAS_REG_SMPS3: |
763 | if (pmic->smps123) | 803 | if (pmic->smps123) |
764 | continue; | 804 | continue; |
805 | if (id == PALMAS_REG_SMPS12) | ||
806 | ramp_delay_support = true; | ||
765 | break; | 807 | break; |
766 | case PALMAS_REG_SMPS123: | 808 | case PALMAS_REG_SMPS123: |
767 | if (!pmic->smps123) | 809 | if (!pmic->smps123) |
768 | continue; | 810 | continue; |
811 | ramp_delay_support = true; | ||
769 | break; | 812 | break; |
770 | case PALMAS_REG_SMPS45: | 813 | case PALMAS_REG_SMPS45: |
771 | case PALMAS_REG_SMPS7: | 814 | case PALMAS_REG_SMPS7: |
772 | if (pmic->smps457) | 815 | if (pmic->smps457) |
773 | continue; | 816 | continue; |
817 | if (id == PALMAS_REG_SMPS45) | ||
818 | ramp_delay_support = true; | ||
774 | break; | 819 | break; |
775 | case PALMAS_REG_SMPS457: | 820 | case PALMAS_REG_SMPS457: |
776 | if (!pmic->smps457) | 821 | if (!pmic->smps457) |
777 | continue; | 822 | continue; |
823 | ramp_delay_support = true; | ||
824 | break; | ||
825 | } | ||
826 | |||
827 | if ((id == PALMAS_REG_SMPS6) && (id == PALMAS_REG_SMPS8)) | ||
828 | ramp_delay_support = true; | ||
829 | |||
830 | if (ramp_delay_support) { | ||
831 | addr = palmas_regs_info[id].tstep_addr; | ||
832 | ret = palmas_smps_read(pmic->palmas, addr, ®); | ||
833 | if (ret < 0) { | ||
834 | dev_err(&pdev->dev, | ||
835 | "reading TSTEP reg failed: %d\n", ret); | ||
836 | goto err_unregister_regulator; | ||
837 | } | ||
838 | pmic->desc[id].ramp_delay = | ||
839 | palmas_smps_ramp_delay[reg & 0x3]; | ||
840 | pmic->ramp_delay[id] = pmic->desc[id].ramp_delay; | ||
778 | } | 841 | } |
779 | 842 | ||
780 | /* Initialise sleep/init values from platform data */ | 843 | /* Initialise sleep/init values from platform data */ |