Merge remote-tracking branch 'regulator/topic/min' into regulator-next
authorMark Brown <broonie@opensource.wolfsonmicro.com>
Mon, 10 Dec 2012 03:43:00 +0000 (12:43 +0900)
committerMark Brown <broonie@opensource.wolfsonmicro.com>
Mon, 10 Dec 2012 03:43:00 +0000 (12:43 +0900)
drivers/regulator/anatop-regulator.c
drivers/regulator/core.c
drivers/regulator/da9055-regulator.c
drivers/regulator/palmas-regulator.c
drivers/regulator/pcf50633-regulator.c
drivers/regulator/tps51632-regulator.c
include/linux/regulator/driver.h

index 1aa5246c79d90741a0ad56f8aacca2203e2f82f0..0199eeea63b13f6d770b49897d14bb3da1173290 100644 (file)
@@ -48,36 +48,21 @@ static int anatop_regmap_set_voltage_sel(struct regulator_dev *reg,
                                        unsigned selector)
 {
        struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg);
-       u32 val, mask;
 
        if (!anatop_reg->control_reg)
                return -ENOTSUPP;
 
-       val = anatop_reg->min_bit_val + selector;
-       dev_dbg(&reg->dev, "%s: calculated val %d\n", __func__, val);
-       mask = ((1 << anatop_reg->vol_bit_width) - 1) <<
-               anatop_reg->vol_bit_shift;
-       val <<= anatop_reg->vol_bit_shift;
-       regmap_update_bits(anatop_reg->anatop, anatop_reg->control_reg,
-                               mask, val);
-
-       return 0;
+       return regulator_set_voltage_sel_regmap(reg, selector);
 }
 
 static int anatop_regmap_get_voltage_sel(struct regulator_dev *reg)
 {
        struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg);
-       u32 val, mask;
 
        if (!anatop_reg->control_reg)
                return -ENOTSUPP;
 
-       regmap_read(anatop_reg->anatop, anatop_reg->control_reg, &val);
-       mask = ((1 << anatop_reg->vol_bit_width) - 1) <<
-               anatop_reg->vol_bit_shift;
-       val = (val & mask) >> anatop_reg->vol_bit_shift;
-
-       return val - anatop_reg->min_bit_val;
+       return regulator_get_voltage_sel_regmap(reg);
 }
 
 static struct regulator_ops anatop_rops = {
@@ -158,15 +143,20 @@ static int anatop_regulator_probe(struct platform_device *pdev)
                goto anatop_probe_end;
        }
 
-       rdesc->n_voltages = (sreg->max_voltage - sreg->min_voltage)
-               / 25000 + 1;
+       rdesc->n_voltages = (sreg->max_voltage - sreg->min_voltage) / 25000 + 1
+                           + sreg->min_bit_val;
        rdesc->min_uV = sreg->min_voltage;
        rdesc->uV_step = 25000;
+       rdesc->linear_min_sel = sreg->min_bit_val;
+       rdesc->vsel_reg = sreg->control_reg;
+       rdesc->vsel_mask = ((1 << sreg->vol_bit_width) - 1) <<
+                          sreg->vol_bit_shift;
 
        config.dev = &pdev->dev;
        config.init_data = initdata;
        config.driver_data = sreg;
        config.of_node = pdev->dev.of_node;
+       config.regmap = sreg->anatop;
 
        /* register regulator */
        rdev = regulator_register(rdesc, &config);
index 35c149bb2ad36a662f2eb8e13b6c2dab44b8b584..cd1b201c91e2e8faacff620a5686f9efd9dc9ddf 100644 (file)
@@ -1924,6 +1924,10 @@ int regulator_list_voltage_linear(struct regulator_dev *rdev,
 {
        if (selector >= rdev->desc->n_voltages)
                return -EINVAL;
+       if (selector < rdev->desc->linear_min_sel)
+               return 0;
+
+       selector -= rdev->desc->linear_min_sel;
 
        return rdev->desc->min_uV + (rdev->desc->uV_step * selector);
 }
@@ -2152,6 +2156,8 @@ int regulator_map_voltage_linear(struct regulator_dev *rdev,
        if (ret < 0)
                return ret;
 
+       ret += rdev->desc->linear_min_sel;
+
        /* Map back into a voltage to verify we're still in bounds */
        voltage = rdev->desc->ops->list_voltage(rdev, ret);
        if (voltage < min_uV || voltage > max_uV)
index db59ce7534cdc12227dd837942718ef0e16d9a79..a4b9cb8c43175343bdfaa2a04bc51038e4003c05 100644 (file)
@@ -57,7 +57,6 @@ struct da9055_volt_reg {
        int reg_a;
        int reg_b;
        int sl_shift;
-       int v_offset;
        int v_mask;
        int v_shift;
 };
@@ -201,41 +200,6 @@ static int da9055_buck_set_current_limit(struct regulator_dev *rdev, int min_uA,
        return -EINVAL;
 }
 
-static int da9055_list_voltage(struct regulator_dev *rdev, unsigned selector)
-{
-       struct da9055_regulator *regulator = rdev_get_drvdata(rdev);
-       struct da9055_regulator_info *info = regulator->info;
-
-       if (selector >= rdev->desc->n_voltages)
-               return -EINVAL;
-
-       if (selector < info->volt.v_offset)
-               return 0;
-
-       selector -= info->volt.v_offset;
-       return rdev->desc->min_uV + (rdev->desc->uV_step * selector);
-}
-
-static int da9055_map_voltage(struct regulator_dev *rdev, int min_uV,
-                             int max_uV)
-{
-       struct da9055_regulator *regulator = rdev_get_drvdata(rdev);
-       struct da9055_regulator_info *info = regulator->info;
-       int sel, voltage;
-
-       if (min_uV < rdev->desc->min_uV)
-               min_uV = rdev->desc->min_uV;
-
-       sel = DIV_ROUND_UP(min_uV - rdev->desc->min_uV, rdev->desc->uV_step);
-       sel += info->volt.v_offset;
-
-       voltage = da9055_list_voltage(rdev, sel);
-       if (voltage < min_uV || voltage > max_uV)
-               return -EINVAL;
-
-       return sel;
-}
-
 static int da9055_regulator_get_voltage_sel(struct regulator_dev *rdev)
 {
        struct da9055_regulator *regulator = rdev_get_drvdata(rdev);
@@ -264,10 +228,7 @@ static int da9055_regulator_get_voltage_sel(struct regulator_dev *rdev)
                return ret;
 
        sel = (ret & volt.v_mask);
-       if (sel <= volt.v_offset)
-               return 0;
-       else
-               return sel;
+       return sel;
 }
 
 static int da9055_regulator_set_voltage_sel(struct regulator_dev *rdev,
@@ -328,7 +289,7 @@ static int da9055_regulator_set_suspend_voltage(struct regulator_dev *rdev,
                        return ret;
        }
 
-       ret = da9055_map_voltage(rdev, uV, uV);
+       ret = regulator_map_voltage_linear(rdev, uV, uV);
        if (ret < 0)
                return ret;
 
@@ -371,8 +332,8 @@ static struct regulator_ops da9055_buck_ops = {
 
        .get_voltage_sel = da9055_regulator_get_voltage_sel,
        .set_voltage_sel = da9055_regulator_set_voltage_sel,
-       .list_voltage = da9055_list_voltage,
-       .map_voltage = da9055_map_voltage,
+       .list_voltage = regulator_list_voltage_linear,
+       .map_voltage = regulator_map_voltage_linear,
        .is_enabled = regulator_is_enabled_regmap,
        .enable = regulator_enable_regmap,
        .disable = regulator_disable_regmap,
@@ -389,8 +350,8 @@ static struct regulator_ops da9055_ldo_ops = {
 
        .get_voltage_sel = da9055_regulator_get_voltage_sel,
        .set_voltage_sel = da9055_regulator_set_voltage_sel,
-       .list_voltage = da9055_list_voltage,
-       .map_voltage = da9055_map_voltage,
+       .list_voltage = regulator_list_voltage_linear,
+       .map_voltage = regulator_map_voltage_linear,
        .is_enabled = regulator_is_enabled_regmap,
        .enable = regulator_enable_regmap,
        .disable = regulator_disable_regmap,
@@ -414,6 +375,7 @@ static struct regulator_ops da9055_ldo_ops = {
                .enable_mask = 1, \
                .min_uV = (min) * 1000,\
                .uV_step = (step) * 1000,\
+               .linear_min_sel = (voffset),\
                .owner = THIS_MODULE,\
        },\
        .conf = {\
@@ -425,7 +387,6 @@ static struct regulator_ops da9055_ldo_ops = {
                .reg_a = DA9055_REG_VBCORE_A + DA9055_ID_##_id, \
                .reg_b = DA9055_REG_VBCORE_B + DA9055_ID_##_id, \
                .sl_shift = 7,\
-               .v_offset = (voffset),\
                .v_mask = (1 << (vbits)) - 1,\
                .v_shift = (vbits),\
        },\
@@ -443,6 +404,7 @@ static struct regulator_ops da9055_ldo_ops = {
                .enable_mask = 1,\
                .min_uV = (min) * 1000,\
                .uV_step = (step) * 1000,\
+               .linear_min_sel = (voffset),\
                .owner = THIS_MODULE,\
        },\
        .conf = {\
@@ -454,7 +416,6 @@ static struct regulator_ops da9055_ldo_ops = {
                .reg_a = DA9055_REG_VBCORE_A + DA9055_ID_##_id, \
                .reg_b = DA9055_REG_VBCORE_B + DA9055_ID_##_id, \
                .sl_shift = 7,\
-               .v_offset = (voffset),\
                .v_mask = (1 << (vbits)) - 1,\
                .v_shift = (vbits),\
        },\
index 3d445929cc80d8d6f9bbb199b0ceadb205edba0e..fd27a43a9fbcfef96504ffe34103b8907925a513 100644 (file)
@@ -436,44 +436,14 @@ static int palmas_is_enabled_ldo(struct regulator_dev *dev)
        return !!(reg);
 }
 
-static int palmas_list_voltage_ldo(struct regulator_dev *dev,
-                                       unsigned selector)
-{
-       if (!selector)
-               return 0;
-
-       /* voltage is 0.85V + (selector * 0.05v) */
-       return  850000 + (selector * 50000);
-}
-
-static int palmas_map_voltage_ldo(struct regulator_dev *rdev,
-               int min_uV, int max_uV)
-{
-       int ret, voltage;
-
-       if (min_uV == 0)
-               return 0;
-
-       if (min_uV < 900000)
-               min_uV = 900000;
-       ret = DIV_ROUND_UP(min_uV - 900000, 50000) + 1;
-
-       /* Map back into a voltage to verify we're still in bounds */
-       voltage = palmas_list_voltage_ldo(rdev, ret);
-       if (voltage < min_uV || voltage > max_uV)
-               return -EINVAL;
-
-       return ret;
-}
-
 static struct regulator_ops palmas_ops_ldo = {
        .is_enabled             = palmas_is_enabled_ldo,
        .enable                 = regulator_enable_regmap,
        .disable                = regulator_disable_regmap,
        .get_voltage_sel        = regulator_get_voltage_sel_regmap,
        .set_voltage_sel        = regulator_set_voltage_sel_regmap,
-       .list_voltage           = palmas_list_voltage_ldo,
-       .map_voltage            = palmas_map_voltage_ldo,
+       .list_voltage           = regulator_list_voltage_linear,
+       .map_voltage            = regulator_map_voltage_linear,
 };
 
 /*
@@ -821,6 +791,9 @@ static int palmas_probe(struct platform_device *pdev)
 
                pmic->desc[id].type = REGULATOR_VOLTAGE;
                pmic->desc[id].owner = THIS_MODULE;
+               pmic->desc[id].min_uV = 900000;
+               pmic->desc[id].uV_step = 50000;
+               pmic->desc[id].linear_min_sel = 1;
                pmic->desc[id].vsel_reg = PALMAS_BASE_TO_REG(PALMAS_LDO_BASE,
                                                palmas_regs_info[id].vsel_addr);
                pmic->desc[id].vsel_mask = PALMAS_LDO1_VOLTAGE_VSEL_MASK;
index d776f518aa0dc0a41259844dacd98bd5d92a377c..534075e13d6dba59e5f21b4db91fb3b0d9acdb25 100644 (file)
 #include <linux/mfd/pcf50633/core.h>
 #include <linux/mfd/pcf50633/pmic.h>
 
-#define PCF50633_REGULATOR(_name, _id, _n)                     \
+#define PCF50633_REGULATOR(_name, _id, _min_uV, _uV_step, _min_sel, _n) \
        {                                                       \
                .name = _name,                                  \
                .id = PCF50633_REGULATOR_##_id,                 \
                .ops = &pcf50633_regulator_ops,                 \
                .n_voltages = _n,                               \
+               .min_uV = _min_uV,                              \
+               .uV_step = _uV_step,                            \
+               .linear_min_sel = _min_sel,                     \
                .type = REGULATOR_VOLTAGE,                      \
                .owner = THIS_MODULE,                           \
                .vsel_reg = PCF50633_REG_##_id##OUT,            \
                .enable_mask = PCF50633_REGULATOR_ON,           \
        }
 
-/* Bits from voltage value */
-static u8 auto_voltage_bits(unsigned int millivolts)
-{
-       if (millivolts < 1800)
-               return 0x2f;
-       if (millivolts > 3800)
-               return 0xff;
-
-       millivolts -= 625;
-
-       return millivolts / 25;
-}
-
-static u8 down_voltage_bits(unsigned int millivolts)
-{
-       if (millivolts < 625)
-               return 0;
-       else if (millivolts > 3000)
-               return 0xff;
-
-       millivolts -= 625;
-
-       return millivolts / 25;
-}
-
-static u8 ldo_voltage_bits(unsigned int millivolts)
-{
-       if (millivolts < 900)
-               return 0;
-       else if (millivolts > 3600)
-               return 0x1f;
-
-       millivolts -= 900;
-       return millivolts / 100;
-}
-
-/* Obtain voltage value from bits */
-static unsigned int auto_voltage_value(u8 bits)
-{
-       /* AUTOOUT: 00000000 to 00101110 are reserved.
-        * Return 0 for bits in reserved range, which means this selector code
-        * can't be used on this system */
-       if (bits < 0x2f)
-               return 0;
-
-       return 625 + (bits * 25);
-}
-
-
-static unsigned int down_voltage_value(u8 bits)
-{
-       return 625 + (bits * 25);
-}
-
-
-static unsigned int ldo_voltage_value(u8 bits)
-{
-       bits &= 0x1f;
-
-       return 900 + (bits * 100);
-}
-
-static int pcf50633_regulator_map_voltage(struct regulator_dev *rdev,
-                                         int min_uV, int max_uV)
-{
-       struct pcf50633 *pcf;
-       int regulator_id, millivolts;
-       u8 volt_bits;
-
-       pcf = rdev_get_drvdata(rdev);
-
-       regulator_id = rdev_get_id(rdev);
-       if (regulator_id >= PCF50633_NUM_REGULATORS)
-               return -EINVAL;
-
-       millivolts = min_uV / 1000;
-
-       switch (regulator_id) {
-       case PCF50633_REGULATOR_AUTO:
-               volt_bits = auto_voltage_bits(millivolts);
-               break;
-       case PCF50633_REGULATOR_DOWN1:
-       case PCF50633_REGULATOR_DOWN2:
-               volt_bits = down_voltage_bits(millivolts);
-               break;
-       case PCF50633_REGULATOR_LDO1:
-       case PCF50633_REGULATOR_LDO2:
-       case PCF50633_REGULATOR_LDO3:
-       case PCF50633_REGULATOR_LDO4:
-       case PCF50633_REGULATOR_LDO5:
-       case PCF50633_REGULATOR_LDO6:
-       case PCF50633_REGULATOR_HCLDO:
-       case PCF50633_REGULATOR_MEMLDO:
-               volt_bits = ldo_voltage_bits(millivolts);
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       return volt_bits;
-}
-
-static int pcf50633_regulator_list_voltage(struct regulator_dev *rdev,
-                                               unsigned int index)
-{
-       int regulator_id = rdev_get_id(rdev);
-
-       int millivolts;
-
-       switch (regulator_id) {
-       case PCF50633_REGULATOR_AUTO:
-               millivolts = auto_voltage_value(index);
-               break;
-       case PCF50633_REGULATOR_DOWN1:
-       case PCF50633_REGULATOR_DOWN2:
-               millivolts = down_voltage_value(index);
-               break;
-       case PCF50633_REGULATOR_LDO1:
-       case PCF50633_REGULATOR_LDO2:
-       case PCF50633_REGULATOR_LDO3:
-       case PCF50633_REGULATOR_LDO4:
-       case PCF50633_REGULATOR_LDO5:
-       case PCF50633_REGULATOR_LDO6:
-       case PCF50633_REGULATOR_HCLDO:
-       case PCF50633_REGULATOR_MEMLDO:
-               millivolts = ldo_voltage_value(index);
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       return millivolts * 1000;
-}
-
 static struct regulator_ops pcf50633_regulator_ops = {
        .set_voltage_sel = regulator_set_voltage_sel_regmap,
        .get_voltage_sel = regulator_get_voltage_sel_regmap,
-       .list_voltage = pcf50633_regulator_list_voltage,
-       .map_voltage = pcf50633_regulator_map_voltage,
+       .list_voltage = regulator_list_voltage_linear,
+       .map_voltage = regulator_map_voltage_linear,
        .enable = regulator_enable_regmap,
        .disable = regulator_disable_regmap,
        .is_enabled = regulator_is_enabled_regmap,
 };
 
 static const struct regulator_desc regulators[] = {
-       [PCF50633_REGULATOR_AUTO] = PCF50633_REGULATOR("auto", AUTO, 128),
-       [PCF50633_REGULATOR_DOWN1] = PCF50633_REGULATOR("down1", DOWN1, 96),
-       [PCF50633_REGULATOR_DOWN2] = PCF50633_REGULATOR("down2", DOWN2, 96),
-       [PCF50633_REGULATOR_LDO1] = PCF50633_REGULATOR("ldo1", LDO1, 28),
-       [PCF50633_REGULATOR_LDO2] = PCF50633_REGULATOR("ldo2", LDO2, 28),
-       [PCF50633_REGULATOR_LDO3] = PCF50633_REGULATOR("ldo3", LDO3, 28),
-       [PCF50633_REGULATOR_LDO4] = PCF50633_REGULATOR("ldo4", LDO4, 28),
-       [PCF50633_REGULATOR_LDO5] = PCF50633_REGULATOR("ldo5", LDO5, 28),
-       [PCF50633_REGULATOR_LDO6] = PCF50633_REGULATOR("ldo6", LDO6, 28),
-       [PCF50633_REGULATOR_HCLDO] = PCF50633_REGULATOR("hcldo", HCLDO, 28),
-       [PCF50633_REGULATOR_MEMLDO] = PCF50633_REGULATOR("memldo", MEMLDO, 28),
+       [PCF50633_REGULATOR_AUTO] =
+               PCF50633_REGULATOR("auto", AUTO, 1800000, 25000, 0x2f, 128),
+       [PCF50633_REGULATOR_DOWN1] =
+               PCF50633_REGULATOR("down1", DOWN1, 625000, 25000, 0, 96),
+       [PCF50633_REGULATOR_DOWN2] =
+               PCF50633_REGULATOR("down2", DOWN2, 625000, 25000, 0, 96),
+       [PCF50633_REGULATOR_LDO1] =
+               PCF50633_REGULATOR("ldo1", LDO1, 900000, 100000, 0, 28),
+       [PCF50633_REGULATOR_LDO2] =
+               PCF50633_REGULATOR("ldo2", LDO2, 900000, 100000, 0, 28),
+       [PCF50633_REGULATOR_LDO3] =
+               PCF50633_REGULATOR("ldo3", LDO3, 900000, 100000, 0, 28),
+       [PCF50633_REGULATOR_LDO4] =
+               PCF50633_REGULATOR("ldo4", LDO4, 900000, 100000, 0, 28),
+       [PCF50633_REGULATOR_LDO5] =
+               PCF50633_REGULATOR("ldo5", LDO5, 900000, 100000, 0, 28),
+       [PCF50633_REGULATOR_LDO6] =
+               PCF50633_REGULATOR("ldo6", LDO6, 900000, 100000, 0, 28),
+       [PCF50633_REGULATOR_HCLDO] =
+               PCF50633_REGULATOR("hcldo", HCLDO, 900000, 100000, 0, 28),
+       [PCF50633_REGULATOR_MEMLDO] =
+               PCF50633_REGULATOR("memldo", MEMLDO, 900000, 100000, 0, 28),
 };
 
 static int pcf50633_regulator_probe(struct platform_device *pdev)
index a9c3a4a6cca07ce5e92372a2f18ea9d3050ea61a..523b1e5e0b4c5137cb47bdebc6fa36992bb816cd 100644 (file)
@@ -106,29 +106,23 @@ static int tps51632_dcdc_get_voltage_sel(struct regulator_dev *rdev)
        }
 
        vsel = data & TPS51632_VOUT_MASK;
-
-       if (vsel < TPS51632_MIN_VSEL)
-               return 0;
-       else
-               return vsel - TPS51632_MIN_VSEL;
+       return vsel;
 }
 
 static int tps51632_dcdc_set_voltage_sel(struct regulator_dev *rdev,
                unsigned selector)
 {
        struct tps51632_chip *tps = rdev_get_drvdata(rdev);
-       int vsel;
        int ret;
        unsigned int reg = TPS51632_VOLTAGE_SELECT_REG;
 
        if (tps->enable_pwm_dvfs)
                reg = TPS51632_VOLTAGE_BASE_REG;
 
-       vsel = selector + TPS51632_MIN_VSEL;
-       if (vsel > TPS51632_MAX_VSEL)
+       if (selector > TPS51632_MAX_VSEL)
                return -EINVAL;
 
-       ret = regmap_write(tps->regmap, TPS51632_VOLTAGE_SELECT_REG, vsel);
+       ret = regmap_write(tps->regmap, reg, selector);
        if (ret < 0)
                dev_err(tps->dev, "reg write failed, err %d\n", ret);
        return ret;
@@ -254,7 +248,8 @@ static int tps51632_probe(struct i2c_client *client,
        tps->desc.ramp_delay = TPS51632_DEFAULT_RAMP_DELAY;
        tps->desc.min_uV = TPS51632_MIN_VOLATGE;
        tps->desc.uV_step = TPS51632_VOLATGE_STEP_10mV;
-       tps->desc.n_voltages = (TPS51632_MAX_VSEL - TPS51632_MIN_VSEL) + 1;
+       tps->desc.linear_min_sel = TPS51632_MIN_VSEL;
+       tps->desc.n_voltages = TPS51632_MAX_VSEL + 1;
        tps->desc.ops = &tps51632_dcdc_ops;
        tps->desc.type = REGULATOR_VOLTAGE;
        tps->desc.owner = THIS_MODULE;
index f2b72b230b9ba495965c1b5fa4ddd1d619e10608..d10bb0f39c5e72fd6bb7747e47761d062f75c981 100644 (file)
@@ -187,6 +187,7 @@ enum regulator_type {
  *
  * @min_uV: Voltage given by the lowest selector (if linear mapping)
  * @uV_step: Voltage increase with each selector (if linear mapping)
+ * @linear_min_sel: Minimal selector for starting linear mapping
  * @ramp_delay: Time to settle down after voltage change (unit: uV/us)
  * @volt_table: Voltage mapping table (if table based mapping)
  *
@@ -210,6 +211,7 @@ struct regulator_desc {
 
        unsigned int min_uV;
        unsigned int uV_step;
+       unsigned int linear_min_sel;
        unsigned int ramp_delay;
 
        const unsigned int *volt_table;