Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9a00630c authored by Laxman Dewangan's avatar Laxman Dewangan Committed by Mark Brown
Browse files

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: default avatarLaxman Dewangan <ldewangan@nvidia.com>
Signed-off-by: default avatarMark Brown <broonie@opensource.wolfsonmicro.com>
parent 70e5f645
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -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.
+65 −37
Original line number Diff line number Diff line
@@ -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
@@ -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];
@@ -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 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,
};

static int __devinit tps62360_init_force_pwm(struct tps62360_chip *tps,
	struct tps62360_regulator_platform_data *pdata,
	int vset_id)
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;
	int bit = 0;

	if (pdata->en_force_pwm)
		bit = BIT(7);
	/* 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;
	}

	ret = regmap_update_bits(tps->regmap, REG_VSET0 + vset_id, BIT(7), bit);
	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 + vset_id, ret);
				__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_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 */
@@ -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) {
@@ -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;

@@ -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;
+0 −2
Original line number Diff line number Diff line
@@ -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.
@@ -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;