diff options
author | Laxman Dewangan <ldewangan@nvidia.com> | 2013-02-05 17:58:24 +0530 |
---|---|---|
committer | Riham Haidar <rhaidar@nvidia.com> | 2013-02-05 14:59:03 -0800 |
commit | 73faa77091b48b89f2c71e1a027fcc82d2a14d73 (patch) | |
tree | 9b4cd49522e9fd18717434bd2e048669d8269dd3 /drivers/regulator | |
parent | 13afbff407cea4fc4dcc6166bd711e336fd55695 (diff) |
regulator: palmas: Add ramp delay
Add ramp delay configuration and handling so that when SMPS
voltage gets change, proper settling time can be handle by
driver.
bug 1195226
bug 1210989
Change-Id: I2520230f9d3cbe7e9d6b1f1375c86e1b1af2456a
Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com>
Reviewed-on: http://git-master/r/197460
Reviewed-by: Automatic_Commit_Validation_User
Diffstat (limited to 'drivers/regulator')
-rw-r--r-- | drivers/regulator/palmas-regulator.c | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/drivers/regulator/palmas-regulator.c b/drivers/regulator/palmas-regulator.c index 2d119e96976f..7ac6fdb20639 100644 --- a/drivers/regulator/palmas-regulator.c +++ b/drivers/regulator/palmas-regulator.c @@ -198,6 +198,8 @@ static const struct regs_info palmas_regs_info[] = { }, }; +static unsigned int palmas_smps_ramp_delay[4] = {0, 10000, 5000, 2500}; + #define SMPS_CTRL_MODE_OFF 0x00 #define SMPS_CTRL_MODE_ON 0x01 #define SMPS_CTRL_MODE_ECO 0x02 @@ -446,6 +448,58 @@ static int palmas_set_voltage_smps_sel(struct regulator_dev *dev, return 0; } +static int palma_smps_set_voltage_smps_time_sel(struct regulator_dev *rdev, + unsigned int old_selector, unsigned int new_selector) +{ + struct palmas_pmic *pmic = rdev_get_drvdata(rdev); + int id = rdev_get_id(rdev); + int old_uV, new_uV; + unsigned int ramp_delay = pmic->ramp_delay[id]; + + /* ES2.1, have the 1.5X slower slew rate than configured */ + ramp_delay = (ramp_delay * 15)/10; + if (!ramp_delay) + return 0; + + old_uV = palmas_list_voltage_smps(rdev, old_selector); + if (old_uV < 0) + return old_uV; + + new_uV = palmas_list_voltage_smps(rdev, new_selector); + if (new_uV < 0) + return new_uV; + + return DIV_ROUND_UP(abs(old_uV - new_uV), ramp_delay); +} + +static int palmas_smps_set_ramp_delay(struct regulator_dev *rdev, + int ramp_delay) +{ + struct palmas_pmic *pmic = rdev_get_drvdata(rdev); + int id = rdev_get_id(rdev); + unsigned int reg = 0; + unsigned int addr = palmas_regs_info[id].tstep_addr; + int ret; + + if (ramp_delay <= 0) + reg = 0; + else if (ramp_delay < 2500) + reg = 3; + else if (ramp_delay < 5000) + reg = 2; + else + reg = 1; + + ret = palmas_smps_write(pmic->palmas, addr, reg); + if (ret < 0) { + dev_err(pmic->palmas->dev, "TSTEP write failed: %d\n", ret); + return ret; + } + + pmic->ramp_delay[id] = palmas_smps_ramp_delay[reg]; + return ret; +} + static struct regulator_ops palmas_ops_smps = { .is_enabled = palmas_is_enabled_smps, .enable = palmas_enable_smps, @@ -455,6 +509,8 @@ static struct regulator_ops palmas_ops_smps = { .get_voltage_sel = palmas_get_voltage_smps_sel, .set_voltage_sel = palmas_set_voltage_smps_sel, .list_voltage = palmas_list_voltage_smps, + .set_voltage_time_sel = palma_smps_set_voltage_smps_time_sel, + .set_ramp_delay = palmas_smps_set_ramp_delay, }; static int palmas_is_enabled_smps10(struct regulator_dev *dev) @@ -1186,6 +1242,8 @@ static __devinit int palmas_probe(struct platform_device *pdev) pmic->smps457 = 1; for (id = 0; id < PALMAS_REG_LDO1; id++) { + bool ramp_delay_support = false; + reg_data = pdata->reg_data[id]; /* @@ -1197,19 +1255,41 @@ static __devinit int palmas_probe(struct platform_device *pdev) case PALMAS_REG_SMPS3: if (pmic->smps123) continue; + if (id == PALMAS_REG_SMPS12) + ramp_delay_support = true; break; case PALMAS_REG_SMPS123: if (!pmic->smps123) continue; + ramp_delay_support = true; break; case PALMAS_REG_SMPS45: case PALMAS_REG_SMPS7: if (pmic->smps457) continue; + if (id == PALMAS_REG_SMPS45) + ramp_delay_support = true; break; case PALMAS_REG_SMPS457: if (!pmic->smps457) continue; + ramp_delay_support = true; + break; + } + if ((id == PALMAS_REG_SMPS6) && (id == PALMAS_REG_SMPS8)) + ramp_delay_support = true; + + if (ramp_delay_support) { + addr = palmas_regs_info[id].tstep_addr; + ret = palmas_smps_read(pmic->palmas, addr, ®); + if (ret < 0) { + dev_err(&pdev->dev, + "reading TSTEP reg failed: %d\n", ret); + goto err_unregister_regulator; + } + pmic->desc[id].ramp_delay = + palmas_smps_ramp_delay[reg & 0x3]; + pmic->ramp_delay[id] = pmic->desc[id].ramp_delay; } /* Register the regulators */ |