regulator: tps62360: support force PWM mode via regulator mode
Laxman Dewangan [Mon, 14 May 2012 12:16:51 +0000 (17:16 +0530)]
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>
Cherry-picked from mainline commit 9a00630

Change-Id: I39a77dbe5d0c4c2a5b81dbfe51163a65894bc98c
Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com>
Reviewed-on: http://git-master/r/105832
Reviewed-by: Automatic_Commit_Validation_User

drivers/regulator/tps62360-regulator.c
include/linux/regulator/tps62360.h

index bc58365..7db1482 100644 (file)
@@ -46,6 +46,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
@@ -66,7 +68,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];
@@ -210,36 +211,80 @@ 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            = tps62360_dcdc_set_voltage,
-       .list_voltage           = tps62360_dcdc_list_voltage,
-       .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;
 
-       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);
+       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            = tps62360_dcdc_set_voltage,
+       .list_voltage           = tps62360_dcdc_list_voltage,
+       .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 */
@@ -254,19 +299,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) {
@@ -321,7 +353,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;
index 6a5c1b2..6475cd0 100644 (file)
@@ -32,7 +32,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.
@@ -45,7 +44,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;