diff options
| -rw-r--r-- | drivers/regulator/palmas-regulator.c | 93 | ||||
| -rw-r--r-- | include/linux/mfd/palmas.h | 14 |
2 files changed, 79 insertions, 28 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 */ |
diff --git a/include/linux/mfd/palmas.h b/include/linux/mfd/palmas.h index 10daa8c1e73c..a58c579e8cf4 100644 --- a/include/linux/mfd/palmas.h +++ b/include/linux/mfd/palmas.h | |||
| @@ -109,19 +109,6 @@ struct palmas_reg_init { | |||
| 109 | */ | 109 | */ |
| 110 | int mode_sleep; | 110 | int mode_sleep; |
| 111 | 111 | ||
| 112 | /* tstep is the timestep loaded to the TSTEP register | ||
| 113 | * | ||
| 114 | * For SMPS | ||
| 115 | * | ||
| 116 | * 0: Jump (no slope control) | ||
| 117 | * 1: 10mV/us | ||
| 118 | * 2: 5mV/us | ||
| 119 | * 3: 2.5mV/us | ||
| 120 | * | ||
| 121 | * For LDO unused | ||
| 122 | */ | ||
| 123 | int tstep; | ||
| 124 | |||
| 125 | /* voltage_sel is the bitfield loaded onto the SMPSX_VOLTAGE | 112 | /* voltage_sel is the bitfield loaded onto the SMPSX_VOLTAGE |
| 126 | * register. Set this is the default voltage set in OTP needs | 113 | * register. Set this is the default voltage set in OTP needs |
| 127 | * to be overridden. | 114 | * to be overridden. |
| @@ -339,6 +326,7 @@ struct palmas_pmic { | |||
| 339 | int smps457; | 326 | int smps457; |
| 340 | 327 | ||
| 341 | int range[PALMAS_REG_SMPS10]; | 328 | int range[PALMAS_REG_SMPS10]; |
| 329 | unsigned int ramp_delay[PALMAS_REG_SMPS10]; | ||
| 342 | }; | 330 | }; |
| 343 | 331 | ||
| 344 | struct palmas_resource { | 332 | struct palmas_resource { |
