Skip to content

Commit

Permalink
regulator: tps62360: support force PWM mode via regulator mode
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Laxman Dewangan authored and Mark Brown committed May 14, 2012
1 parent 70e5f64 commit 9a00630
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ Required properties:
- reg: I2C slave address

Optional properties:
- ti,enable-force-pwm: Enable force PWM mode. This is boolean value.
- ti,enable-vout-discharge: Enable output discharge. This is boolean value.
- ti,enable-pull-down: Enable pull down. This is boolean value.
- ti,vsel0-gpio: GPIO for controlling VSEL0 line.
Expand Down
102 changes: 65 additions & 37 deletions drivers/regulator/tps62360-regulator.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@
#define REG_RAMPCTRL 6
#define REG_CHIPID 8

#define FORCE_PWM_ENABLE BIT(7)

enum chips {TPS62360, TPS62361, TPS62362, TPS62363};

#define TPS62360_BASE_VOLTAGE 770000
Expand All @@ -69,7 +71,6 @@ struct tps62360_chip {
int voltage_base;
u8 voltage_reg_mask;
bool en_internal_pulldn;
bool en_force_pwm;
bool en_discharge;
bool valid_gpios;
int lru_index[4];
Expand Down Expand Up @@ -191,37 +192,81 @@ static int tps62360_set_voltage_time_sel(struct regulator_dev *rdev,
return DIV_ROUND_UP(abs(old_uV - new_uV), tps->change_uv_per_us);
}

static int tps62360_set_mode(struct regulator_dev *rdev, unsigned int mode)
{
struct tps62360_chip *tps = rdev_get_drvdata(rdev);
int i;
int val;
int ret;

/* Enable force PWM mode in FAST mode only. */
switch (mode) {
case REGULATOR_MODE_FAST:
val = FORCE_PWM_ENABLE;
break;

case REGULATOR_MODE_NORMAL:
val = 0;
break;

default:
return -EINVAL;
}

if (!tps->valid_gpios) {
ret = regmap_update_bits(tps->regmap,
REG_VSET0 + tps->curr_vset_id, FORCE_PWM_ENABLE, val);
if (ret < 0)
dev_err(tps->dev,
"%s(): register %d update failed with err %d\n",
__func__, REG_VSET0 + tps->curr_vset_id, ret);
return ret;
}

/* If gpios are valid then all register set need to be control */
for (i = 0; i < 4; ++i) {
ret = regmap_update_bits(tps->regmap,
REG_VSET0 + i, FORCE_PWM_ENABLE, val);
if (ret < 0) {
dev_err(tps->dev,
"%s(): register %d update failed with err %d\n",
__func__, REG_VSET0 + i, ret);
return ret;
}
}
return ret;
}

static unsigned int tps62360_get_mode(struct regulator_dev *rdev)
{
struct tps62360_chip *tps = rdev_get_drvdata(rdev);
unsigned int data;
int ret;

ret = regmap_read(tps->regmap, REG_VSET0 + tps->curr_vset_id, &data);
if (ret < 0) {
dev_err(tps->dev, "%s(): register %d read failed with err %d\n",
__func__, REG_VSET0 + tps->curr_vset_id, ret);
return ret;
}
return (data & FORCE_PWM_ENABLE) ?
REGULATOR_MODE_FAST : REGULATOR_MODE_NORMAL;
}

static struct regulator_ops tps62360_dcdc_ops = {
.get_voltage_sel = tps62360_dcdc_get_voltage_sel,
.set_voltage_sel = tps62360_dcdc_set_voltage_sel,
.list_voltage = regulator_list_voltage_linear,
.map_voltage = regulator_map_voltage_linear,
.set_voltage_time_sel = tps62360_set_voltage_time_sel,
.set_mode = tps62360_set_mode,
.get_mode = tps62360_get_mode,
};

static int __devinit tps62360_init_force_pwm(struct tps62360_chip *tps,
struct tps62360_regulator_platform_data *pdata,
int vset_id)
{
int ret;
int bit = 0;

if (pdata->en_force_pwm)
bit = BIT(7);

ret = regmap_update_bits(tps->regmap, REG_VSET0 + vset_id, BIT(7), bit);
if (ret < 0)
dev_err(tps->dev,
"%s(): register %d update failed with err %d\n",
__func__, REG_VSET0 + vset_id, ret);
return ret;
}

static int __devinit tps62360_init_dcdc(struct tps62360_chip *tps,
struct tps62360_regulator_platform_data *pdata)
{
int ret;
int i;
unsigned int ramp_ctrl;

/* Initialize internal pull up/down control */
Expand All @@ -236,19 +281,6 @@ static int __devinit tps62360_init_dcdc(struct tps62360_chip *tps,
return ret;
}

/* Initialize force PWM mode */
if (tps->valid_gpios) {
for (i = 0; i < 4; ++i) {
ret = tps62360_init_force_pwm(tps, pdata, i);
if (ret < 0)
return ret;
}
} else {
ret = tps62360_init_force_pwm(tps, pdata, tps->curr_vset_id);
if (ret < 0)
return ret;
}

/* Reset output discharge path to reduce power consumption */
ret = regmap_update_bits(tps->regmap, REG_RAMPCTRL, BIT(2), 0);
if (ret < 0) {
Expand Down Expand Up @@ -310,9 +342,6 @@ static struct tps62360_regulator_platform_data *
if (of_find_property(np, "ti,enable-pull-down", NULL))
pdata->en_internal_pulldn = true;

if (of_find_property(np, "ti,enable-force-pwm", NULL))
pdata->en_force_pwm = true;

if (of_find_property(np, "ti,enable-vout-discharge", NULL))
pdata->en_discharge = true;

Expand Down Expand Up @@ -370,7 +399,6 @@ static int __devinit tps62360_probe(struct i2c_client *client,
return -ENOMEM;
}

tps->en_force_pwm = pdata->en_force_pwm;
tps->en_discharge = pdata->en_discharge;
tps->en_internal_pulldn = pdata->en_internal_pulldn;
tps->vsel0_gpio = pdata->vsel0_gpio;
Expand Down
2 changes: 0 additions & 2 deletions include/linux/regulator/tps62360.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
* struct tps62360_regulator_platform_data - tps62360 regulator platform data.
*
* @reg_init_data: The regulator init data.
* @en_force_pwm: Enable force pwm or not.
* @en_discharge: Enable discharge the output capacitor via internal
* register.
* @en_internal_pulldn: internal pull down enable or not.
Expand All @@ -43,7 +42,6 @@
*/
struct tps62360_regulator_platform_data {
struct regulator_init_data *reg_init_data;
bool en_force_pwm;
bool en_discharge;
bool en_internal_pulldn;
int vsel0_gpio;
Expand Down

0 comments on commit 9a00630

Please sign in to comment.