aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/regulator
diff options
context:
space:
mode:
authorLaxman Dewangan <ldewangan@nvidia.com>2012-05-14 08:16:51 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2012-05-14 13:03:04 -0400
commit9a00630c3db8ca064a8904dbcd9632fb81244bc0 (patch)
treeecd498e18ba5353096d8d24bbd8e78dc5a2068c3 /drivers/regulator
parent70e5f6456cf561de8842be537b066a1bab1f1fee (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.c102
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
52enum chips {TPS62360, TPS62361, TPS62362, TPS62363}; 54enum 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
195static 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
240static 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
194static struct regulator_ops tps62360_dcdc_ops = { 256static 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
202static 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
220static int __devinit tps62360_init_dcdc(struct tps62360_chip *tps, 266static 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;