diff options
author | Laxman Dewangan <ldewangan@nvidia.com> | 2012-05-07 08:38:26 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2012-05-07 10:21:53 -0400 |
commit | a60cfce051dd5e22329df1018d278bf3e52d82bc (patch) | |
tree | 5c572c312580f61aab53c4d44b771b71b1282789 /drivers/regulator | |
parent | 16ea003bd1c95ea55a0b88187ce7cbeaca760fcf (diff) |
regulator: tps62360: Provide settling time for voltage change
Settling time is require when there is voltage output change.
Implement set_voltage_time_sel() callback which returns delay time
for voltage change to settle down to new value.
Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'drivers/regulator')
-rw-r--r-- | drivers/regulator/tps62360-regulator.c | 46 |
1 files changed, 40 insertions, 6 deletions
diff --git a/drivers/regulator/tps62360-regulator.c b/drivers/regulator/tps62360-regulator.c index e8930805c52..d2f657ef508 100644 --- a/drivers/regulator/tps62360-regulator.c +++ b/drivers/regulator/tps62360-regulator.c | |||
@@ -71,6 +71,7 @@ struct tps62360_chip { | |||
71 | int lru_index[4]; | 71 | int lru_index[4]; |
72 | int curr_vset_vsel[4]; | 72 | int curr_vset_vsel[4]; |
73 | int curr_vset_id; | 73 | int curr_vset_id; |
74 | int change_uv_per_us; | ||
74 | }; | 75 | }; |
75 | 76 | ||
76 | /* | 77 | /* |
@@ -114,7 +115,7 @@ update_lru_index: | |||
114 | return found; | 115 | return found; |
115 | } | 116 | } |
116 | 117 | ||
117 | static int tps62360_dcdc_get_voltage(struct regulator_dev *dev) | 118 | static int tps62360_dcdc_get_voltage_sel(struct regulator_dev *dev) |
118 | { | 119 | { |
119 | struct tps62360_chip *tps = rdev_get_drvdata(dev); | 120 | struct tps62360_chip *tps = rdev_get_drvdata(dev); |
120 | int vsel; | 121 | int vsel; |
@@ -128,7 +129,7 @@ static int tps62360_dcdc_get_voltage(struct regulator_dev *dev) | |||
128 | return ret; | 129 | return ret; |
129 | } | 130 | } |
130 | vsel = (int)data & tps->voltage_reg_mask; | 131 | vsel = (int)data & tps->voltage_reg_mask; |
131 | return (tps->voltage_base + vsel * 10) * 1000; | 132 | return vsel; |
132 | } | 133 | } |
133 | 134 | ||
134 | static int tps62360_dcdc_set_voltage(struct regulator_dev *dev, | 135 | static int tps62360_dcdc_set_voltage(struct regulator_dev *dev, |
@@ -193,10 +194,28 @@ static int tps62360_dcdc_list_voltage(struct regulator_dev *dev, | |||
193 | return (tps->voltage_base + selector * 10) * 1000; | 194 | return (tps->voltage_base + selector * 10) * 1000; |
194 | } | 195 | } |
195 | 196 | ||
197 | static int tps62360_set_voltage_time_sel(struct regulator_dev *rdev, | ||
198 | unsigned int old_selector, unsigned int new_selector) | ||
199 | { | ||
200 | struct tps62360_chip *tps = rdev_get_drvdata(rdev); | ||
201 | int old_uV, new_uV; | ||
202 | |||
203 | old_uV = tps62360_dcdc_list_voltage(rdev, old_selector); | ||
204 | if (old_uV < 0) | ||
205 | return old_uV; | ||
206 | |||
207 | new_uV = tps62360_dcdc_list_voltage(rdev, new_selector); | ||
208 | if (new_uV < 0) | ||
209 | return new_uV; | ||
210 | |||
211 | return DIV_ROUND_UP(abs(old_uV - new_uV), tps->change_uv_per_us); | ||
212 | } | ||
213 | |||
196 | static struct regulator_ops tps62360_dcdc_ops = { | 214 | static struct regulator_ops tps62360_dcdc_ops = { |
197 | .get_voltage = tps62360_dcdc_get_voltage, | 215 | .get_voltage_sel = tps62360_dcdc_get_voltage_sel, |
198 | .set_voltage = tps62360_dcdc_set_voltage, | 216 | .set_voltage = tps62360_dcdc_set_voltage, |
199 | .list_voltage = tps62360_dcdc_list_voltage, | 217 | .list_voltage = tps62360_dcdc_list_voltage, |
218 | .set_voltage_time_sel = tps62360_set_voltage_time_sel, | ||
200 | }; | 219 | }; |
201 | 220 | ||
202 | static int tps62360_init_force_pwm(struct tps62360_chip *tps, | 221 | static int tps62360_init_force_pwm(struct tps62360_chip *tps, |
@@ -228,6 +247,7 @@ static int tps62360_init_dcdc(struct tps62360_chip *tps, | |||
228 | { | 247 | { |
229 | int ret; | 248 | int ret; |
230 | int i; | 249 | int i; |
250 | unsigned int ramp_ctrl; | ||
231 | 251 | ||
232 | /* Initailize internal pull up/down control */ | 252 | /* Initailize internal pull up/down control */ |
233 | if (tps->en_internal_pulldn) | 253 | if (tps->en_internal_pulldn) |
@@ -255,9 +275,23 @@ static int tps62360_init_dcdc(struct tps62360_chip *tps, | |||
255 | 275 | ||
256 | /* Reset output discharge path to reduce power consumption */ | 276 | /* Reset output discharge path to reduce power consumption */ |
257 | ret = regmap_update_bits(tps->regmap, REG_RAMPCTRL, BIT(2), 0); | 277 | ret = regmap_update_bits(tps->regmap, REG_RAMPCTRL, BIT(2), 0); |
258 | if (ret < 0) | 278 | if (ret < 0) { |
259 | dev_err(tps->dev, "%s() fails in updating reg %d\n", | 279 | dev_err(tps->dev, "%s() fails in updating reg %d\n", |
260 | __func__, REG_RAMPCTRL); | 280 | __func__, REG_RAMPCTRL); |
281 | return ret; | ||
282 | } | ||
283 | |||
284 | /* Get ramp value from ramp control register */ | ||
285 | ret = regmap_read(tps->regmap, REG_RAMPCTRL, &ramp_ctrl); | ||
286 | if (ret < 0) { | ||
287 | dev_err(tps->dev, "%s() fails in reading reg %d\n", | ||
288 | __func__, REG_RAMPCTRL); | ||
289 | return ret; | ||
290 | } | ||
291 | ramp_ctrl = (ramp_ctrl >> 4) & 0x7; | ||
292 | |||
293 | /* ramp mV/us = 32/(2^ramp_ctrl) */ | ||
294 | tps->change_uv_per_us = DIV_ROUND_UP(32000, BIT(ramp_ctrl)); | ||
261 | return ret; | 295 | return ret; |
262 | } | 296 | } |
263 | 297 | ||