From 33234e791de2ac3ea915158e042907748191cabd Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 27 Nov 2012 10:24:33 +0800 Subject: [PATCH 1/8] regulator: core: Allow specific minimal selector for starting linear mapping Some drivers (at least 3 drivers) have such variant of linear mapping that the first few selectors are invalid and the reset are linear mapping. Let's support this case in core. This patch adds linear_min_sel in struct regulator_desc, so we can allow specific minimal selector for starting linear mapping. Then extends regulator_[map|list]_voltage_linear() to support this feature. Note that for selectors less than min_linear_index, we need count them to n_voltages so regulator_list_voltage() won't fail while checking the boundary for selector before calling list_voltage callback. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/core.c | 6 ++++++ include/linux/regulator/driver.h | 2 ++ 2 files changed, 8 insertions(+) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index e872c8be080..02a249b024b 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -1897,6 +1897,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); } @@ -2120,6 +2124,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) diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h index 7932a3bf21b..d9ce98a5028 100644 --- a/include/linux/regulator/driver.h +++ b/include/linux/regulator/driver.h @@ -185,6 +185,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) * @@ -207,6 +208,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; From 9119ff6af541feee1daaa5cba3a4b3b5751a2d09 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 27 Nov 2012 10:27:34 +0800 Subject: [PATCH 2/8] regulator: palmas: Use linear_min_sel and regulator_[map|list]_voltage_linear Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/palmas-regulator.c | 37 ++++------------------------ 1 file changed, 5 insertions(+), 32 deletions(-) diff --git a/drivers/regulator/palmas-regulator.c b/drivers/regulator/palmas-regulator.c index 07aee694ba9..111d76b04bb 100644 --- a/drivers/regulator/palmas-regulator.c +++ b/drivers/regulator/palmas-regulator.c @@ -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 __devinit 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; From 6b1f8a45666877d4885c03d9472657fd73edfa8b Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 27 Nov 2012 10:26:14 +0800 Subject: [PATCH 3/8] regulator: da9055: Use linear_min_sel and regulator_[map|list]_voltage_linear Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/da9055-regulator.c | 55 ++++------------------------ 1 file changed, 8 insertions(+), 47 deletions(-) diff --git a/drivers/regulator/da9055-regulator.c b/drivers/regulator/da9055-regulator.c index 121564bb541..2253559703c 100644 --- a/drivers/regulator/da9055-regulator.c +++ b/drivers/regulator/da9055-regulator.c @@ -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; }; @@ -204,41 +203,6 @@ static int da9055_buck_set_current_limit(struct regulator_dev *rdev, int min_uA, info->mode.mask, val << info->mode.shift); } -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); @@ -267,10 +231,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, @@ -331,7 +292,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; @@ -374,8 +335,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, @@ -392,8 +353,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, @@ -417,6 +378,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 = {\ @@ -428,7 +390,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),\ },\ @@ -446,6 +407,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 = {\ @@ -457,7 +419,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),\ },\ From 9997f3ffbbcde01bcd5966eeb26bc41243715021 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 26 Nov 2012 23:42:14 +0800 Subject: [PATCH 4/8] regulator: tps51632: Fix writing to wrong register when enable_pwm_dvfs is set When tps->enable_pwm_dvfs is true, write to TPS51632_VOLTAGE_BASE_REG rather than TPS51632_VOLTAGE_SELECT_REG. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/tps51632-regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/regulator/tps51632-regulator.c b/drivers/regulator/tps51632-regulator.c index 34603640d6d..e88bfe48303 100644 --- a/drivers/regulator/tps51632-regulator.c +++ b/drivers/regulator/tps51632-regulator.c @@ -128,7 +128,7 @@ static int tps51632_dcdc_set_voltage_sel(struct regulator_dev *rdev, if (vsel > TPS51632_MAX_VSEL) return -EINVAL; - ret = regmap_write(tps->regmap, TPS51632_VOLTAGE_SELECT_REG, vsel); + ret = regmap_write(tps->regmap, reg, vsel); if (ret < 0) dev_err(tps->dev, "reg write failed, err %d\n", ret); return ret; From 05cf34c1af48e2e1308a03fbc778039243bebd3a Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Wed, 28 Nov 2012 10:41:04 +0800 Subject: [PATCH 5/8] regulator: pcf50633: Use linear_min_sel and regulator_[map|list]_voltage_linear This driver can be converted to use linear_min_sel and regulator_[map|list]_voltage_linear. Below shows the equation (from Datasheet) for each LDOs. For AUTOOUT: VO(prog) = 0.625 + auto_out x 0.025 V; e.g. (00000000 to 00101110: reserved) 00101111: 1.8 V (min) 01010011: 2.7 V 01101010: 3.275 V 01101011: 3.300 V 01101100: 3.325 V 01111111 : 3.800 V (max) The linear mapping start from 0x2f selector. Thus we convert this equation to: VO(prog) = 1.8 + (selector - linear_min_sel) x 0.025 V (min_uV = 1800000, uV_step = 25000, linear_min_sel = 0x2f) For DOWNxOUT: VO(prog) = 0.625 + downx_out x 0.025 V; e.g. 00000000 : 0.625 V (min) 00010111 : 1.200 V 00101111 : 1.800 V 01011111 : 3.000 V (max) For xLDOOUT: VO(prog) = 0.9 + xldo_out x 0.1 V; e.g. 00000: 0.9 V 00001: 1.0 V 11000 : 3.3 V 11011 : 3.6 V Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/pcf50633-regulator.c | 176 ++++--------------------- 1 file changed, 28 insertions(+), 148 deletions(-) diff --git a/drivers/regulator/pcf50633-regulator.c b/drivers/regulator/pcf50633-regulator.c index 092e5cb848a..769272afff2 100644 --- a/drivers/regulator/pcf50633-regulator.c +++ b/drivers/regulator/pcf50633-regulator.c @@ -24,12 +24,15 @@ #include #include -#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, \ @@ -38,162 +41,39 @@ .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 __devinit pcf50633_regulator_probe(struct platform_device *pdev) From bd0ec7c1e52423429d9ee7b34e2c899f01db01b0 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Wed, 28 Nov 2012 07:22:54 +0800 Subject: [PATCH 6/8] regulator: tps51632: Use linear_min_sel and regulator_[map|list]_voltage_linear Signed-off-by: Axel Lin Acked-by: Laxman Dewangan Signed-off-by: Mark Brown --- drivers/regulator/tps51632-regulator.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/drivers/regulator/tps51632-regulator.c b/drivers/regulator/tps51632-regulator.c index 34603640d6d..dce5eb3fa70 100644 --- a/drivers/regulator/tps51632-regulator.c +++ b/drivers/regulator/tps51632-regulator.c @@ -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, TPS51632_VOLTAGE_SELECT_REG, selector); if (ret < 0) dev_err(tps->dev, "reg write failed, err %d\n", ret); return ret; @@ -254,7 +248,8 @@ static int __devinit 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; From 985884db501d7026257d122c3cc32a7005a9a864 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sun, 9 Dec 2012 08:05:45 +0800 Subject: [PATCH 7/8] regulator: anatop: Use linear_min_sel with linear mapping By setting linear_min_sel to anatop_reg->min_bit_val, we can avoid adjust the anatop_reg->min_bit_val offset in [set|get]_voltage_sel. With this chance we can refactor this driver to use regulator_[get|set]_voltage_sel_regmap. Signed-off-by: Axel Lin Reviewed-by: Ying-Chun Liu Signed-off-by: Mark Brown --- drivers/regulator/anatop-regulator.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/drivers/regulator/anatop-regulator.c b/drivers/regulator/anatop-regulator.c index 1af97686f44..b78b622d24c 100644 --- a/drivers/regulator/anatop-regulator.c +++ b/drivers/regulator/anatop-regulator.c @@ -48,18 +48,16 @@ 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; + u32 mask; if (!anatop_reg->control_reg) return -ENOTSUPP; - val = anatop_reg->min_bit_val + selector; - dev_dbg(®->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; + selector <<= anatop_reg->vol_bit_shift; regmap_update_bits(anatop_reg->anatop, anatop_reg->control_reg, - mask, val); + mask, selector); return 0; } @@ -77,7 +75,7 @@ static int anatop_regmap_get_voltage_sel(struct regulator_dev *reg) anatop_reg->vol_bit_shift; val = (val & mask) >> anatop_reg->vol_bit_shift; - return val - anatop_reg->min_bit_val; + return val; } static struct regulator_ops anatop_rops = { @@ -158,10 +156,11 @@ static int __devinit 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; config.dev = &pdev->dev; config.init_data = initdata; From e1b0144f9997d3d52c46785143699d82dd525f1d Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sun, 9 Dec 2012 08:07:43 +0800 Subject: [PATCH 8/8] regulator: anatop: Use regulator_[get|set]_voltage_sel_regmap Call regulator_[get|set]_voltage_sel_regmap instead of open code. Signed-off-by: Axel Lin Reviewed-by: Ying-Chun Liu Signed-off-by: Mark Brown --- drivers/regulator/anatop-regulator.c | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/drivers/regulator/anatop-regulator.c b/drivers/regulator/anatop-regulator.c index b78b622d24c..b6182e17b0d 100644 --- a/drivers/regulator/anatop-regulator.c +++ b/drivers/regulator/anatop-regulator.c @@ -48,34 +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 mask; if (!anatop_reg->control_reg) return -ENOTSUPP; - mask = ((1 << anatop_reg->vol_bit_width) - 1) << - anatop_reg->vol_bit_shift; - selector <<= anatop_reg->vol_bit_shift; - regmap_update_bits(anatop_reg->anatop, anatop_reg->control_reg, - mask, selector); - - 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; + return regulator_get_voltage_sel_regmap(reg); } static struct regulator_ops anatop_rops = { @@ -161,11 +148,15 @@ static int __devinit anatop_regulator_probe(struct platform_device *pdev) 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);