]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/regulator/wm8350-regulator.c
Merge tag 'stable/for-linus-3.6-rc0-tag' of git://git.kernel.org/pub/scm/linux/kernel...
[karo-tx-linux.git] / drivers / regulator / wm8350-regulator.c
index 53bf3df02975cda2b5490eb6041f1dab28a5ef51..7f0fa22ef2aab4e85e71693358737ee099b537e2 100644 (file)
@@ -108,33 +108,6 @@ static int get_isink_val(int min_uA, int max_uA, u16 *setting)
        return -EINVAL;
 }
 
-static inline int wm8350_ldo_val_to_mvolts(unsigned int val)
-{
-       if (val < 16)
-               return (val * 50) + 900;
-       else
-               return ((val - 16) * 100) + 1800;
-
-}
-
-static inline unsigned int wm8350_ldo_mvolts_to_val(int mV)
-{
-       if (mV < 1800)
-               return (mV - 900) / 50;
-       else
-               return ((mV - 1800) / 100) + 16;
-}
-
-static inline int wm8350_dcdc_val_to_mvolts(unsigned int val)
-{
-       return (val * 25) + 850;
-}
-
-static inline unsigned int wm8350_dcdc_mvolts_to_val(int mV)
-{
-       return (mV - 850) / 25;
-}
-
 static int wm8350_isink_set_current(struct regulator_dev *rdev, int min_uA,
        int max_uA)
 {
@@ -362,19 +335,10 @@ EXPORT_SYMBOL_GPL(wm8350_isink_set_flash);
 static int wm8350_dcdc_set_suspend_voltage(struct regulator_dev *rdev, int uV)
 {
        struct wm8350 *wm8350 = rdev_get_drvdata(rdev);
-       int volt_reg, mV = uV / 1000, dcdc = rdev_get_id(rdev);
+       int sel, volt_reg, dcdc = rdev_get_id(rdev);
        u16 val;
 
-       dev_dbg(wm8350->dev, "%s %d mV %d\n", __func__, dcdc, mV);
-
-       if (mV && (mV < 850 || mV > 4025)) {
-               dev_err(wm8350->dev,
-                       "DCDC%d suspend voltage %d mV out of range\n",
-                       dcdc, mV);
-               return -EINVAL;
-       }
-       if (mV == 0)
-               mV = 850;
+       dev_dbg(wm8350->dev, "%s %d mV %d\n", __func__, dcdc, uV / 1000);
 
        switch (dcdc) {
        case WM8350_DCDC_1:
@@ -395,10 +359,13 @@ static int wm8350_dcdc_set_suspend_voltage(struct regulator_dev *rdev, int uV)
                return -EINVAL;
        }
 
+       sel = regulator_map_voltage_linear(rdev, uV, uV);
+       if (sel < 0)
+               return -EINVAL;
+
        /* all DCDCs have same mV bits */
        val = wm8350_reg_read(wm8350, volt_reg) & ~WM8350_DC1_VSEL_MASK;
-       wm8350_reg_write(wm8350, volt_reg,
-                        val | wm8350_dcdc_mvolts_to_val(mV));
+       wm8350_reg_write(wm8350, volt_reg, val | sel);
        return 0;
 }
 
@@ -575,19 +542,49 @@ static int wm8350_dcdc_set_suspend_mode(struct regulator_dev *rdev,
        return 0;
 }
 
+static int wm8350_ldo_list_voltage(struct regulator_dev *rdev,
+                                   unsigned selector)
+{
+       if (selector > WM8350_LDO1_VSEL_MASK)
+               return -EINVAL;
+
+       if (selector < 16)
+               return (selector * 50000) + 900000;
+       else
+               return ((selector - 16) * 100000) + 1800000;
+}
+
+static int wm8350_ldo_map_voltage(struct regulator_dev *rdev, int min_uV,
+                                 int max_uV)
+{
+       int volt, sel;
+       int min_mV = min_uV / 1000;
+       int max_mV = max_uV / 1000;
+
+       if (min_mV < 900 || min_mV > 3300)
+               return -EINVAL;
+       if (max_mV < 900 || max_mV > 3300)
+               return -EINVAL;
+
+       if (min_mV < 1800) /* step size is 50mV < 1800mV */
+               sel = DIV_ROUND_UP(min_uV - 900, 50);
+       else /* step size is 100mV > 1800mV */
+               sel = DIV_ROUND_UP(min_uV - 1800, 100) + 16;
+
+       volt = wm8350_ldo_list_voltage(rdev, sel);
+       if (volt < min_uV || volt > max_uV)
+               return -EINVAL;
+
+       return sel;
+}
+
 static int wm8350_ldo_set_suspend_voltage(struct regulator_dev *rdev, int uV)
 {
        struct wm8350 *wm8350 = rdev_get_drvdata(rdev);
-       int volt_reg, mV = uV / 1000, ldo = rdev_get_id(rdev);
+       int sel, volt_reg, ldo = rdev_get_id(rdev);
        u16 val;
 
-       dev_dbg(wm8350->dev, "%s %d mV %d\n", __func__, ldo, mV);
-
-       if (mV < 900 || mV > 3300) {
-               dev_err(wm8350->dev, "LDO%d voltage %d mV out of range\n",
-                       ldo, mV);
-               return -EINVAL;
-       }
+       dev_dbg(wm8350->dev, "%s %d mV %d\n", __func__, ldo, uV / 1000);
 
        switch (ldo) {
        case WM8350_LDO_1:
@@ -606,10 +603,13 @@ static int wm8350_ldo_set_suspend_voltage(struct regulator_dev *rdev, int uV)
                return -EINVAL;
        }
 
+       sel = wm8350_ldo_map_voltage(rdev, uV, uV);
+       if (sel < 0)
+               return -EINVAL;
+
        /* all LDOs have same mV bits */
        val = wm8350_reg_read(wm8350, volt_reg) & ~WM8350_LDO1_VSEL_MASK;
-       wm8350_reg_write(wm8350, volt_reg,
-                        val | wm8350_ldo_mvolts_to_val(mV));
+       wm8350_reg_write(wm8350, volt_reg, val | sel);
        return 0;
 }
 
@@ -671,43 +671,6 @@ static int wm8350_ldo_set_suspend_disable(struct regulator_dev *rdev)
        return 0;
 }
 
-static int wm8350_ldo_map_voltage(struct regulator_dev *rdev, int min_uV,
-                                 int max_uV)
-{
-       int mV;
-       int min_mV = min_uV / 1000;
-       int max_mV = max_uV / 1000;
-
-       if (min_mV < 900 || min_mV > 3300)
-               return -EINVAL;
-       if (max_mV < 900 || max_mV > 3300)
-               return -EINVAL;
-
-       if (min_mV < 1800) {
-               /* step size is 50mV < 1800mV */
-               mV = (min_mV - 851) / 50;
-               if (wm8350_ldo_val_to_mvolts(mV) > max_mV)
-                       return -EINVAL;
-               BUG_ON(wm8350_ldo_val_to_mvolts(mV) < min_mV);
-       } else {
-               /* step size is 100mV > 1800mV */
-               mV = ((min_mV - 1701) / 100) + 16;
-               if (wm8350_ldo_val_to_mvolts(mV) > max_mV)
-                       return -EINVAL;
-               BUG_ON(wm8350_ldo_val_to_mvolts(mV) < min_mV);
-       }
-
-       return mV;
-}
-
-static int wm8350_ldo_list_voltage(struct regulator_dev *rdev,
-                                   unsigned selector)
-{
-       if (selector > WM8350_LDO1_VSEL_MASK)
-               return -EINVAL;
-       return wm8350_ldo_val_to_mvolts(selector) * 1000;
-}
-
 int wm8350_dcdc_set_slot(struct wm8350 *wm8350, int dcdc, u16 start,
                         u16 stop, u16 fault)
 {