Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Laxman Dewangan and committed by
Mark Brown
9a00630c 70e5f645

+65 -40
-1
Documentation/devicetree/bindings/regulator/tps62360-regulator.txt
··· 9 9 - reg: I2C slave address 10 10 11 11 Optional properties: 12 - - ti,enable-force-pwm: Enable force PWM mode. This is boolean value. 13 12 - ti,enable-vout-discharge: Enable output discharge. This is boolean value. 14 13 - ti,enable-pull-down: Enable pull down. This is boolean value. 15 14 - ti,vsel0-gpio: GPIO for controlling VSEL0 line.
+65 -37
drivers/regulator/tps62360-regulator.c
··· 49 49 #define REG_RAMPCTRL 6 50 50 #define REG_CHIPID 8 51 51 52 + #define FORCE_PWM_ENABLE BIT(7) 53 + 52 54 enum chips {TPS62360, TPS62361, TPS62362, TPS62363}; 53 55 54 56 #define TPS62360_BASE_VOLTAGE 770000 ··· 71 69 int voltage_base; 72 70 u8 voltage_reg_mask; 73 71 bool en_internal_pulldn; 74 - bool en_force_pwm; 75 72 bool en_discharge; 76 73 bool valid_gpios; 77 74 int lru_index[4]; ··· 192 191 return DIV_ROUND_UP(abs(old_uV - new_uV), tps->change_uv_per_us); 193 192 } 194 193 194 + static int tps62360_set_mode(struct regulator_dev *rdev, unsigned int mode) 195 + { 196 + struct tps62360_chip *tps = rdev_get_drvdata(rdev); 197 + int i; 198 + int val; 199 + int ret; 200 + 201 + /* Enable force PWM mode in FAST mode only. */ 202 + switch (mode) { 203 + case REGULATOR_MODE_FAST: 204 + val = FORCE_PWM_ENABLE; 205 + break; 206 + 207 + case REGULATOR_MODE_NORMAL: 208 + val = 0; 209 + break; 210 + 211 + default: 212 + return -EINVAL; 213 + } 214 + 215 + if (!tps->valid_gpios) { 216 + ret = regmap_update_bits(tps->regmap, 217 + REG_VSET0 + tps->curr_vset_id, FORCE_PWM_ENABLE, val); 218 + if (ret < 0) 219 + dev_err(tps->dev, 220 + "%s(): register %d update failed with err %d\n", 221 + __func__, REG_VSET0 + tps->curr_vset_id, ret); 222 + return ret; 223 + } 224 + 225 + /* If gpios are valid then all register set need to be control */ 226 + for (i = 0; i < 4; ++i) { 227 + ret = regmap_update_bits(tps->regmap, 228 + REG_VSET0 + i, FORCE_PWM_ENABLE, val); 229 + if (ret < 0) { 230 + dev_err(tps->dev, 231 + "%s(): register %d update failed with err %d\n", 232 + __func__, REG_VSET0 + i, ret); 233 + return ret; 234 + } 235 + } 236 + return ret; 237 + } 238 + 239 + static unsigned int tps62360_get_mode(struct regulator_dev *rdev) 240 + { 241 + struct tps62360_chip *tps = rdev_get_drvdata(rdev); 242 + unsigned int data; 243 + int ret; 244 + 245 + ret = regmap_read(tps->regmap, REG_VSET0 + tps->curr_vset_id, &data); 246 + if (ret < 0) { 247 + dev_err(tps->dev, "%s(): register %d read failed with err %d\n", 248 + __func__, REG_VSET0 + tps->curr_vset_id, ret); 249 + return ret; 250 + } 251 + return (data & FORCE_PWM_ENABLE) ? 252 + REGULATOR_MODE_FAST : REGULATOR_MODE_NORMAL; 253 + } 254 + 195 255 static struct regulator_ops tps62360_dcdc_ops = { 196 256 .get_voltage_sel = tps62360_dcdc_get_voltage_sel, 197 257 .set_voltage_sel = tps62360_dcdc_set_voltage_sel, 198 258 .list_voltage = regulator_list_voltage_linear, 199 259 .map_voltage = regulator_map_voltage_linear, 200 260 .set_voltage_time_sel = tps62360_set_voltage_time_sel, 261 + .set_mode = tps62360_set_mode, 262 + .get_mode = tps62360_get_mode, 201 263 }; 202 - 203 - static int __devinit tps62360_init_force_pwm(struct tps62360_chip *tps, 204 - struct tps62360_regulator_platform_data *pdata, 205 - int vset_id) 206 - { 207 - int ret; 208 - int bit = 0; 209 - 210 - if (pdata->en_force_pwm) 211 - bit = BIT(7); 212 - 213 - ret = regmap_update_bits(tps->regmap, REG_VSET0 + vset_id, BIT(7), bit); 214 - if (ret < 0) 215 - dev_err(tps->dev, 216 - "%s(): register %d update failed with err %d\n", 217 - __func__, REG_VSET0 + vset_id, ret); 218 - return ret; 219 - } 220 264 221 265 static int __devinit tps62360_init_dcdc(struct tps62360_chip *tps, 222 266 struct tps62360_regulator_platform_data *pdata) 223 267 { 224 268 int ret; 225 - int i; 226 269 unsigned int ramp_ctrl; 227 270 228 271 /* Initialize internal pull up/down control */ ··· 279 234 "%s(): register %d write failed with err %d\n", 280 235 __func__, REG_CONTROL, ret); 281 236 return ret; 282 - } 283 - 284 - /* Initialize force PWM mode */ 285 - if (tps->valid_gpios) { 286 - for (i = 0; i < 4; ++i) { 287 - ret = tps62360_init_force_pwm(tps, pdata, i); 288 - if (ret < 0) 289 - return ret; 290 - } 291 - } else { 292 - ret = tps62360_init_force_pwm(tps, pdata, tps->curr_vset_id); 293 - if (ret < 0) 294 - return ret; 295 237 } 296 238 297 239 /* Reset output discharge path to reduce power consumption */ ··· 342 310 if (of_find_property(np, "ti,enable-pull-down", NULL)) 343 311 pdata->en_internal_pulldn = true; 344 312 345 - if (of_find_property(np, "ti,enable-force-pwm", NULL)) 346 - pdata->en_force_pwm = true; 347 - 348 313 if (of_find_property(np, "ti,enable-vout-discharge", NULL)) 349 314 pdata->en_discharge = true; 350 315 ··· 399 370 return -ENOMEM; 400 371 } 401 372 402 - tps->en_force_pwm = pdata->en_force_pwm; 403 373 tps->en_discharge = pdata->en_discharge; 404 374 tps->en_internal_pulldn = pdata->en_internal_pulldn; 405 375 tps->vsel0_gpio = pdata->vsel0_gpio;
-2
include/linux/regulator/tps62360.h
··· 30 30 * struct tps62360_regulator_platform_data - tps62360 regulator platform data. 31 31 * 32 32 * @reg_init_data: The regulator init data. 33 - * @en_force_pwm: Enable force pwm or not. 34 33 * @en_discharge: Enable discharge the output capacitor via internal 35 34 * register. 36 35 * @en_internal_pulldn: internal pull down enable or not. ··· 42 43 */ 43 44 struct tps62360_regulator_platform_data { 44 45 struct regulator_init_data *reg_init_data; 45 - bool en_force_pwm; 46 46 bool en_discharge; 47 47 bool en_internal_pulldn; 48 48 int vsel0_gpio;