From e97d92e2ebe834576a772e2b1ae74b68344b1283 Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Tue, 29 Nov 2011 15:11:41 +0530 Subject: regulator: tps6236x: Enable output discharge in shutdown Enable the output discharge path in shutdown of the regulator. bug 871944 Reviewed-on: http://git-master/r/67101 (cherry picked from commit 20f19e525d9f680236c80050e4ae97a86979dd78) Change-Id: Ib88a15546d1402bdf93d624d566dd28e990e7209 Signed-off-by: Laxman Dewangan Reviewed-on: http://git-master/r/68427 --- drivers/regulator/tps6236x-regulator.c | 61 ++++++++++++++++++++++++++-------- 1 file changed, 48 insertions(+), 13 deletions(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/tps6236x-regulator.c b/drivers/regulator/tps6236x-regulator.c index 0d2d48f1e916..1928b30c8802 100644 --- a/drivers/regulator/tps6236x-regulator.c +++ b/drivers/regulator/tps6236x-regulator.c @@ -89,6 +89,7 @@ struct tps6236x_chip { const u16 *voltages; u8 voltage_reg_mask; bool is_force_pwm; + bool enable_discharge; }; static inline int tps6236x_read(struct tps6236x_chip *tps, u8 reg) { @@ -129,6 +130,33 @@ static int tps6236x_reg_write(struct tps6236x_chip *tps, u8 reg, u8 val) return err; } + +static int tps6236x_reg_update(struct tps6236x_chip *tps, u8 reg, u8 val, + u8 mask) +{ + int err; + int data; + u8 reg_val; + + mutex_lock(&tps->io_lock); + data = tps6236x_read(tps, reg); + if (data < 0) { + dev_err(tps->dev, "Read from reg 0x%x failed\n", reg); + err = data; + goto out; + } + reg_val = (u8)data; + reg_val = (reg_val & ~mask) | (val & mask); + + err = tps6236x_write(tps, reg, reg_val); + if (err < 0) + dev_err(tps->dev, "Write for reg 0x%x failed\n", reg); + +out: + mutex_unlock(&tps->io_lock); + return err; +} + static int __tps6236x_dcdc_set_voltage(struct tps6236x_chip *tps, int min_uV, int max_uV, unsigned *selector) @@ -312,20 +340,10 @@ static int tps6236x_init_dcdc(struct i2c_client *client, return st; } - /* Configure the output discharge path */ - data = tps6236x_reg_read(tps, REG_RAMPCTRL); - if (data < 0) { - dev_err(tps->dev, "%s() fails in reading reg %d\n", - __func__, REG_RAMPCTRL); - return data; - } - if (pdata->enable_discharge) - data |= (1 << 2); - else - data &= ~(1 << 2); - st = tps6236x_write(tps, REG_RAMPCTRL, data); + /* Reset output discharge path */ + st = tps6236x_reg_update(tps, REG_RAMPCTRL, 0, 1 << 2); if (st < 0) { - dev_err(tps->dev, "%s() fails in writing reg %d\n", + dev_err(tps->dev, "%s() fails in updating reg %d\n", __func__, REG_RAMPCTRL); return st; } @@ -376,6 +394,7 @@ static int __devinit tps6236x_probe(struct i2c_client *client, mutex_init(&tps->io_lock); tps->is_force_pwm = pdata->is_force_pwm; + tps->enable_discharge = pdata->enable_discharge; tps->chip_id = id->driver_data; tps->client = client; tps->dev = &client->dev; @@ -453,6 +472,21 @@ static int __devexit tps6236x_remove(struct i2c_client *client) return 0; } +static void tps6236x_shutdown(struct i2c_client *client) +{ + struct tps6236x_chip *tps = i2c_get_clientdata(client); + int st; + + if (!tps->enable_discharge) + return; + + /* Configure the output discharge path */ + st = tps6236x_reg_update(tps, REG_RAMPCTRL, (1 << 2), (1 << 2)); + if (st < 0) + dev_err(tps->dev, "%s() fails in updating reg %d\n", + __func__, REG_RAMPCTRL); +} + static const struct i2c_device_id tps6236x_id[] = { {.name = "tps62360", .driver_data = TPS62360}, {.name = "tps62361B", .driver_data = TPS62361B}, @@ -468,6 +502,7 @@ static struct i2c_driver tps6236x_i2c_driver = { }, .probe = tps6236x_probe, .remove = __devexit_p(tps6236x_remove), + .shutdown = tps6236x_shutdown, .id_table = tps6236x_id, }; -- cgit v1.2.3