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 | |
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>
-rw-r--r-- | Documentation/devicetree/bindings/regulator/tps62360-regulator.txt | 1 | ||||
-rw-r--r-- | drivers/regulator/tps62360-regulator.c | 102 | ||||
-rw-r--r-- | include/linux/regulator/tps62360.h | 2 |
3 files changed, 65 insertions, 40 deletions
diff --git a/Documentation/devicetree/bindings/regulator/tps62360-regulator.txt b/Documentation/devicetree/bindings/regulator/tps62360-regulator.txt index f411b57c775..c8ca6b8f658 100644 --- a/Documentation/devicetree/bindings/regulator/tps62360-regulator.txt +++ b/Documentation/devicetree/bindings/regulator/tps62360-regulator.txt | |||
@@ -9,7 +9,6 @@ Required properties: | |||
9 | - reg: I2C slave address | 9 | - reg: I2C slave address |
10 | 10 | ||
11 | Optional properties: | 11 | Optional properties: |
12 | - ti,enable-force-pwm: Enable force PWM mode. This is boolean value. | ||
13 | - ti,enable-vout-discharge: Enable output discharge. This is boolean value. | 12 | - ti,enable-vout-discharge: Enable output discharge. This is boolean value. |
14 | - ti,enable-pull-down: Enable pull down. This is boolean value. | 13 | - ti,enable-pull-down: Enable pull down. This is boolean value. |
15 | - ti,vsel0-gpio: GPIO for controlling VSEL0 line. | 14 | - ti,vsel0-gpio: GPIO for controlling VSEL0 line. |
diff --git a/drivers/regulator/tps62360-regulator.c b/drivers/regulator/tps62360-regulator.c index e6e33beb72b..b5be0d0f9f1 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; |
diff --git a/include/linux/regulator/tps62360.h b/include/linux/regulator/tps62360.h index 5e11d505564..a4c49394c49 100644 --- a/include/linux/regulator/tps62360.h +++ b/include/linux/regulator/tps62360.h | |||
@@ -30,7 +30,6 @@ | |||
30 | * struct tps62360_regulator_platform_data - tps62360 regulator platform data. | 30 | * struct tps62360_regulator_platform_data - tps62360 regulator platform data. |
31 | * | 31 | * |
32 | * @reg_init_data: The regulator init data. | 32 | * @reg_init_data: The regulator init data. |
33 | * @en_force_pwm: Enable force pwm or not. | ||
34 | * @en_discharge: Enable discharge the output capacitor via internal | 33 | * @en_discharge: Enable discharge the output capacitor via internal |
35 | * register. | 34 | * register. |
36 | * @en_internal_pulldn: internal pull down enable or not. | 35 | * @en_internal_pulldn: internal pull down enable or not. |
@@ -43,7 +42,6 @@ | |||
43 | */ | 42 | */ |
44 | struct tps62360_regulator_platform_data { | 43 | struct tps62360_regulator_platform_data { |
45 | struct regulator_init_data *reg_init_data; | 44 | struct regulator_init_data *reg_init_data; |
46 | bool en_force_pwm; | ||
47 | bool en_discharge; | 45 | bool en_discharge; |
48 | bool en_internal_pulldn; | 46 | bool en_internal_pulldn; |
49 | int vsel0_gpio; | 47 | int vsel0_gpio; |