diff options
author | Laxman Dewangan <ldewangan@nvidia.com> | 2012-05-14 08:16:51 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2012-05-14 13:03:04 -0400 |
commit | 9a00630c3db8ca064a8904dbcd9632fb81244bc0 (patch) | |
tree | ecd498e18ba5353096d8d24bbd8e78dc5a2068c3 /drivers/regulator | |
parent | 70e5f6456cf561de8842be537b066a1bab1f1fee (diff) |
regulator: tps62360: support force PWM mode via regulator mode
Change the mechanism of enabling the force PWM mode through
regulator set mode. This can be dynamically configured now.
In the REGULATOR_MODE_FAST the force PWM is enabled and in
REGULATOR_MODE_NORMAL the force PWM is disabled.
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 | 102 |
1 files changed, 65 insertions, 37 deletions
diff --git a/drivers/regulator/tps62360-regulator.c b/drivers/regulator/tps62360-regulator.c index e6e33beb72b0..b5be0d0f9f12 100644 --- a/drivers/regulator/tps62360-regulator.c +++ b/drivers/regulator/tps62360-regulator.c | |||
@@ -49,6 +49,8 @@ | |||
49 | #define REG_RAMPCTRL 6 | 49 | #define REG_RAMPCTRL 6 |
50 | #define REG_CHIPID 8 | 50 | #define REG_CHIPID 8 |
51 | 51 | ||
52 | #define FORCE_PWM_ENABLE BIT(7) | ||
53 | |||
52 | enum chips {TPS62360, TPS62361, TPS62362, TPS62363}; | 54 | enum chips {TPS62360, TPS62361, TPS62362, TPS62363}; |
53 | 55 | ||
54 | #define TPS62360_BASE_VOLTAGE 770000 | 56 | #define TPS62360_BASE_VOLTAGE 770000 |
@@ -69,7 +71,6 @@ struct tps62360_chip { | |||
69 | int voltage_base; | 71 | int voltage_base; |
70 | u8 voltage_reg_mask; | 72 | u8 voltage_reg_mask; |
71 | bool en_internal_pulldn; | 73 | bool en_internal_pulldn; |
72 | bool en_force_pwm; | ||
73 | bool en_discharge; | 74 | bool en_discharge; |
74 | bool valid_gpios; | 75 | bool valid_gpios; |
75 | int lru_index[4]; | 76 | int lru_index[4]; |
@@ -191,37 +192,81 @@ static int tps62360_set_voltage_time_sel(struct regulator_dev *rdev, | |||
191 | return DIV_ROUND_UP(abs(old_uV - new_uV), tps->change_uv_per_us); | 192 | return DIV_ROUND_UP(abs(old_uV - new_uV), tps->change_uv_per_us); |
192 | } | 193 | } |
193 | 194 | ||
195 | static int tps62360_set_mode(struct regulator_dev *rdev, unsigned int mode) | ||
196 | { | ||
197 | struct tps62360_chip *tps = rdev_get_drvdata(rdev); | ||
198 | int i; | ||
199 | int val; | ||
200 | int ret; | ||
201 | |||
202 | /* Enable force PWM mode in FAST mode only. */ | ||
203 | switch (mode) { | ||
204 | case REGULATOR_MODE_FAST: | ||
205 | val = FORCE_PWM_ENABLE; | ||
206 | break; | ||
207 | |||
208 | case REGULATOR_MODE_NORMAL: | ||
209 | val = 0; | ||
210 | break; | ||
211 | |||
212 | default: | ||
213 | return -EINVAL; | ||
214 | } | ||
215 | |||
216 | if (!tps->valid_gpios) { | ||
217 | ret = regmap_update_bits(tps->regmap, | ||
218 | REG_VSET0 + tps->curr_vset_id, FORCE_PWM_ENABLE, val); | ||
219 | if (ret < 0) | ||
220 | dev_err(tps->dev, | ||
221 | "%s(): register %d update failed with err %d\n", | ||
222 | __func__, REG_VSET0 + tps->curr_vset_id, ret); | ||
223 | return ret; | ||
224 | } | ||
225 | |||
226 | /* If gpios are valid then all register set need to be control */ | ||
227 | for (i = 0; i < 4; ++i) { | ||
228 | ret = regmap_update_bits(tps->regmap, | ||
229 | REG_VSET0 + i, FORCE_PWM_ENABLE, val); | ||
230 | if (ret < 0) { | ||
231 | dev_err(tps->dev, | ||
232 | "%s(): register %d update failed with err %d\n", | ||
233 | __func__, REG_VSET0 + i, ret); | ||
234 | return ret; | ||
235 | } | ||
236 | } | ||
237 | return ret; | ||
238 | } | ||
239 | |||
240 | static unsigned int tps62360_get_mode(struct regulator_dev *rdev) | ||
241 | { | ||
242 | struct tps62360_chip *tps = rdev_get_drvdata(rdev); | ||
243 | unsigned int data; | ||
244 | int ret; | ||
245 | |||
246 | ret = regmap_read(tps->regmap, REG_VSET0 + tps->curr_vset_id, &data); | ||
247 | if (ret < 0) { | ||
248 | dev_err(tps->dev, "%s(): register %d read failed with err %d\n", | ||
249 | __func__, REG_VSET0 + tps->curr_vset_id, ret); | ||
250 | return ret; | ||
251 | } | ||
252 | return (data & FORCE_PWM_ENABLE) ? | ||
253 | REGULATOR_MODE_FAST : REGULATOR_MODE_NORMAL; | ||
254 | } | ||
255 | |||
194 | static struct regulator_ops tps62360_dcdc_ops = { | 256 | static struct regulator_ops tps62360_dcdc_ops = { |
195 | .get_voltage_sel = tps62360_dcdc_get_voltage_sel, | 257 | .get_voltage_sel = tps62360_dcdc_get_voltage_sel, |
196 | .set_voltage_sel = tps62360_dcdc_set_voltage_sel, | 258 | .set_voltage_sel = tps62360_dcdc_set_voltage_sel, |
197 | .list_voltage = regulator_list_voltage_linear, | 259 | .list_voltage = regulator_list_voltage_linear, |
198 | .map_voltage = regulator_map_voltage_linear, | 260 | .map_voltage = regulator_map_voltage_linear, |
199 | .set_voltage_time_sel = tps62360_set_voltage_time_sel, | 261 | .set_voltage_time_sel = tps62360_set_voltage_time_sel, |
262 | .set_mode = tps62360_set_mode, | ||
263 | .get_mode = tps62360_get_mode, | ||
200 | }; | 264 | }; |
201 | 265 | ||
202 | static int __devinit tps62360_init_force_pwm(struct tps62360_chip *tps, | ||
203 | struct tps62360_regulator_platform_data *pdata, | ||
204 | int vset_id) | ||
205 | { | ||
206 | int ret; | ||
207 | int bit = 0; | ||
208 | |||
209 | if (pdata->en_force_pwm) | ||
210 | bit = BIT(7); | ||
211 | |||
212 | ret = regmap_update_bits(tps->regmap, REG_VSET0 + vset_id, BIT(7), bit); | ||
213 | if (ret < 0) | ||
214 | dev_err(tps->dev, | ||
215 | "%s(): register %d update failed with err %d\n", | ||
216 | __func__, REG_VSET0 + vset_id, ret); | ||
217 | return ret; | ||
218 | } | ||
219 | |||
220 | static int __devinit tps62360_init_dcdc(struct tps62360_chip *tps, | 266 | static int __devinit tps62360_init_dcdc(struct tps62360_chip *tps, |
221 | struct tps62360_regulator_platform_data *pdata) | 267 | struct tps62360_regulator_platform_data *pdata) |
222 | { | 268 | { |
223 | int ret; | 269 | int ret; |
224 | int i; | ||
225 | unsigned int ramp_ctrl; | 270 | unsigned int ramp_ctrl; |
226 | 271 | ||
227 | /* Initialize internal pull up/down control */ | 272 | /* Initialize internal pull up/down control */ |
@@ -236,19 +281,6 @@ static int __devinit tps62360_init_dcdc(struct tps62360_chip *tps, | |||
236 | return ret; | 281 | return ret; |
237 | } | 282 | } |
238 | 283 | ||
239 | /* Initialize force PWM mode */ | ||
240 | if (tps->valid_gpios) { | ||
241 | for (i = 0; i < 4; ++i) { | ||
242 | ret = tps62360_init_force_pwm(tps, pdata, i); | ||
243 | if (ret < 0) | ||
244 | return ret; | ||
245 | } | ||
246 | } else { | ||
247 | ret = tps62360_init_force_pwm(tps, pdata, tps->curr_vset_id); | ||
248 | if (ret < 0) | ||
249 | return ret; | ||
250 | } | ||
251 | |||
252 | /* Reset output discharge path to reduce power consumption */ | 284 | /* Reset output discharge path to reduce power consumption */ |
253 | ret = regmap_update_bits(tps->regmap, REG_RAMPCTRL, BIT(2), 0); | 285 | ret = regmap_update_bits(tps->regmap, REG_RAMPCTRL, BIT(2), 0); |
254 | if (ret < 0) { | 286 | if (ret < 0) { |
@@ -310,9 +342,6 @@ static struct tps62360_regulator_platform_data * | |||
310 | if (of_find_property(np, "ti,enable-pull-down", NULL)) | 342 | if (of_find_property(np, "ti,enable-pull-down", NULL)) |
311 | pdata->en_internal_pulldn = true; | 343 | pdata->en_internal_pulldn = true; |
312 | 344 | ||
313 | if (of_find_property(np, "ti,enable-force-pwm", NULL)) | ||
314 | pdata->en_force_pwm = true; | ||
315 | |||
316 | if (of_find_property(np, "ti,enable-vout-discharge", NULL)) | 345 | if (of_find_property(np, "ti,enable-vout-discharge", NULL)) |
317 | pdata->en_discharge = true; | 346 | pdata->en_discharge = true; |
318 | 347 | ||
@@ -370,7 +399,6 @@ static int __devinit tps62360_probe(struct i2c_client *client, | |||
370 | return -ENOMEM; | 399 | return -ENOMEM; |
371 | } | 400 | } |
372 | 401 | ||
373 | tps->en_force_pwm = pdata->en_force_pwm; | ||
374 | tps->en_discharge = pdata->en_discharge; | 402 | tps->en_discharge = pdata->en_discharge; |
375 | tps->en_internal_pulldn = pdata->en_internal_pulldn; | 403 | tps->en_internal_pulldn = pdata->en_internal_pulldn; |
376 | tps->vsel0_gpio = pdata->vsel0_gpio; | 404 | tps->vsel0_gpio = pdata->vsel0_gpio; |