]> git.karo-electronics.de Git - linux-beck.git/commitdiff
regulator: Rework s5m8767_set_voltage to support both LDOs and BUCKs
authorAxel Lin <axel.lin@gmail.com>
Tue, 10 Apr 2012 06:05:44 +0000 (14:05 +0800)
committerMark Brown <broonie@opensource.wolfsonmicro.com>
Tue, 10 Apr 2012 08:53:48 +0000 (09:53 +0100)
s5m8767_set_voltage not only implement set_voltage callbacks for LDOs,
but also for BUCKs when s5m8767->buck_gpioindex is not set.
s5m8767_set_voltage_buck actually only for buck[2|3|4] when
s5m8767->buck_gpioindex is set.
Conditionally calling s5m8767_set_voltage in s5m8767_set_voltage_buck makes
the code hard to read.

I think merging s5m8767_set_voltage_buck and s5m8767_set_voltage actually
simplifies things. It's easy to use buck234_vol pointer to differentiate if
we need to control voltage for buck[2|3|4] by DVS GPIOs.

This patch reworks s5m8767_set_voltage to support both LDOx and BUCKx in all
cases.

Signed-off-by: Axel Lin <axel.lin@gmail.com>
Acked-by: Sangbeom Kim <sbkim73@samsung.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
drivers/regulator/s5m8767.c

index c4a584c268ce7544eb50fe0eda10fe8f0c2937bf..245cc2da4fd43f3a0d51ea02ee5ab89593e15698 100644 (file)
@@ -355,14 +355,33 @@ static int s5m8767_convert_voltage_to_sel(
        return selector;
 }
 
+static inline void s5m8767_set_high(struct s5m8767_info *s5m8767)
+{
+       int temp_index = s5m8767->buck_gpioindex;
+
+       gpio_set_value(s5m8767->buck_gpios[0], (temp_index >> 2) & 0x1);
+       gpio_set_value(s5m8767->buck_gpios[1], (temp_index >> 1) & 0x1);
+       gpio_set_value(s5m8767->buck_gpios[2], temp_index & 0x1);
+}
+
+static inline void s5m8767_set_low(struct s5m8767_info *s5m8767)
+{
+       int temp_index = s5m8767->buck_gpioindex;
+
+       gpio_set_value(s5m8767->buck_gpios[2], temp_index & 0x1);
+       gpio_set_value(s5m8767->buck_gpios[1], (temp_index >> 1) & 0x1);
+       gpio_set_value(s5m8767->buck_gpios[0], (temp_index >> 2) & 0x1);
+}
+
 static int s5m8767_set_voltage(struct regulator_dev *rdev,
                                int min_uV, int max_uV, unsigned *selector)
 {
        struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev);
        const struct s5m_voltage_desc *desc;
        int reg_id = rdev_get_id(rdev);
-       int sel, reg, mask, ret;
+       int sel, reg, mask, ret = 0, old_index, index = 0;
        u8 val;
+       u8 *buck234_vol = NULL;
 
        switch (reg_id) {
        case S5M8767_LDO1 ... S5M8767_LDO28:
@@ -370,6 +389,12 @@ static int s5m8767_set_voltage(struct regulator_dev *rdev,
                break;
        case S5M8767_BUCK1 ... S5M8767_BUCK6:
                mask = 0xff;
+               if (reg_id == S5M8767_BUCK2 && s5m8767->buck2_gpiodvs)
+                       buck234_vol = &s5m8767->buck2_vol[0];
+               else if (reg_id == S5M8767_BUCK3 && s5m8767->buck3_gpiodvs)
+                       buck234_vol = &s5m8767->buck3_vol[0];
+               else if (reg_id == S5M8767_BUCK4 && s5m8767->buck4_gpiodvs)
+                       buck234_vol = &s5m8767->buck4_vol[0];
                break;
        case S5M8767_BUCK7 ... S5M8767_BUCK8:
                return -EINVAL;
@@ -386,102 +411,32 @@ static int s5m8767_set_voltage(struct regulator_dev *rdev,
        if (sel < 0)
                return sel;
 
-       ret = s5m8767_get_voltage_register(rdev, &reg);
-       if (ret)
-               return ret;
-
-       s5m_reg_read(s5m8767->iodev, reg, &val);
-       val &= ~mask;
-       val |= sel;
-
-       ret = s5m_reg_write(s5m8767->iodev, reg, val);
-       *selector = sel;
-
-       return ret;
-}
-
-static inline void s5m8767_set_high(struct s5m8767_info *s5m8767)
-{
-       int temp_index = s5m8767->buck_gpioindex;
-
-       gpio_set_value(s5m8767->buck_gpios[0], (temp_index >> 2) & 0x1);
-       gpio_set_value(s5m8767->buck_gpios[1], (temp_index >> 1) & 0x1);
-       gpio_set_value(s5m8767->buck_gpios[2], temp_index & 0x1);
-}
-
-static inline void s5m8767_set_low(struct s5m8767_info *s5m8767)
-{
-       int temp_index = s5m8767->buck_gpioindex;
-
-       gpio_set_value(s5m8767->buck_gpios[2], temp_index & 0x1);
-       gpio_set_value(s5m8767->buck_gpios[1], (temp_index >> 1) & 0x1);
-       gpio_set_value(s5m8767->buck_gpios[0], (temp_index >> 2) & 0x1);
-}
-
-static int s5m8767_set_voltage_buck(struct regulator_dev *rdev,
-                                   int min_uV, int max_uV, unsigned *selector)
-{
-       struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev);
-       int reg_id = rdev_get_id(rdev);
-       const struct s5m_voltage_desc *desc;
-       int new_val, old_val, i = 0;
-
-       if (reg_id < S5M8767_BUCK1 || reg_id > S5M8767_BUCK6)
-               return -EINVAL;
-
-       switch (reg_id) {
-       case S5M8767_BUCK1:
-               return s5m8767_set_voltage(rdev, min_uV, max_uV, selector);
-       case S5M8767_BUCK2 ... S5M8767_BUCK4:
-               break;
-       case S5M8767_BUCK5 ... S5M8767_BUCK6:
-               return s5m8767_set_voltage(rdev, min_uV, max_uV, selector);
-       case S5M8767_BUCK9:
-               return s5m8767_set_voltage(rdev, min_uV, max_uV, selector);
-       }
+       /* buck234_vol != NULL means to control buck234 voltage via DVS GPIO */
+       if (buck234_vol) {
+               while (*buck234_vol != sel) {
+                       buck234_vol++;
+                       index++;
+               }
+               old_index = s5m8767->buck_gpioindex;
+               s5m8767->buck_gpioindex = index;
+
+               if (index > old_index)
+                       s5m8767_set_high(s5m8767);
+               else
+                       s5m8767_set_low(s5m8767);
+       } else {
+               ret = s5m8767_get_voltage_register(rdev, &reg);
+               if (ret)
+                       return ret;
 
-       desc = reg_voltage_map[reg_id];
-       new_val = s5m8767_convert_voltage_to_sel(desc, min_uV, max_uV);
-       if (new_val < 0)
-               return new_val;
+               s5m_reg_read(s5m8767->iodev, reg, &val);
+               val = (val & ~mask) | sel;
 
-       switch (reg_id) {
-       case S5M8767_BUCK2:
-               if (s5m8767->buck2_gpiodvs) {
-                       while (s5m8767->buck2_vol[i] != new_val)
-                               i++;
-               } else
-                       return s5m8767_set_voltage(rdev, min_uV,
-                                                  max_uV, selector);
-               break;
-       case S5M8767_BUCK3:
-               if (s5m8767->buck3_gpiodvs) {
-                       while (s5m8767->buck3_vol[i] != new_val)
-                               i++;
-               } else
-                       return s5m8767_set_voltage(rdev, min_uV,
-                                                  max_uV, selector);
-               break;
-       case S5M8767_BUCK4:
-               if (s5m8767->buck3_gpiodvs) {
-                       while (s5m8767->buck4_vol[i] != new_val)
-                               i++;
-               } else
-                       return s5m8767_set_voltage(rdev, min_uV,
-                                                  max_uV, selector);
-               break;
+               ret = s5m_reg_write(s5m8767->iodev, reg, val);
        }
 
-       old_val = s5m8767->buck_gpioindex;
-       s5m8767->buck_gpioindex = i;
-
-       if (i > old_val)
-               s5m8767_set_high(s5m8767);
-       else
-               s5m8767_set_low(s5m8767);
-
-       *selector = new_val;
-       return 0;
+       *selector = sel;
+       return ret;
 }
 
 static int s5m8767_set_voltage_time_sel(struct regulator_dev *rdev,
@@ -516,7 +471,7 @@ static struct regulator_ops s5m8767_buck_ops = {
        .enable                 = s5m8767_reg_enable,
        .disable                = s5m8767_reg_disable,
        .get_voltage_sel        = s5m8767_get_voltage_sel,
-       .set_voltage            = s5m8767_set_voltage_buck,
+       .set_voltage            = s5m8767_set_voltage,
        .set_voltage_time_sel   = s5m8767_set_voltage_time_sel,
 };