diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-22 03:49:16 +0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-22 03:49:16 +0400 |
commit | ac1806572df55b6125ad9d117906820dacfa3145 (patch) | |
tree | 6831707507d54e20d561a6403d2ff3e8469909ce /drivers/regulator/twl-regulator.c | |
parent | ae82a8282031e3c31a4f68c5381ee459e42908f8 (diff) | |
parent | 84df8c1241beb87fec73415ef4f6e627aca34835 (diff) | |
download | linux-ac1806572df55b6125ad9d117906820dacfa3145.tar.xz |
Merge tag 'regulator-3.5' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator
Pull regulator updates from Mark Brown:
"The major thing here is the addition of some helpers to factor code
out of drivers, making a fair proportion of regulators much more just
data rather than code which is nice.
- Helpers in the core for regulators using regmap, providing generic
implementations of the enable and voltage selection operations which
just need data to describe them in the drivers.
- Split out voltage mapping and voltage setting, allowing many more
drivers to take advantage of the infrastructure for selectors.
- Loads and loads of cleanups from Axel Lin once again, including many
changes to take advantage of the above new framework features
- New drivers for Ricoh RC5T583, TI TPS62362, TI TPS62363, TI
TPS65913, TI TWL6035 and TI TWL6037.
Some of the registration changes to support the core refactoring
caused so many conflicts that eventually topic branches were abandoned
for this release."
* tag 'regulator-3.5' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator: (227 commits)
regulator: tps65910: use of_node of matched regulator being register
regulator: tps65910: dt: support when "regulators" node found
regulator: tps65910: add error message in case of failure
regulator: tps62360: dt: initialize of_node param for regulator register.
regulator: tps65910: use devm_* for memory allocation
regulator: tps65910: use small letter for regulator names
mfd: tpx6586x: Depend on regulator
regulator: regulator for Palmas Kconfig
regulator: regulator driver for Palmas series chips
regulator: Enable Device Tree for the db8500-prcmu regulator driver
regulator: db8500-prcmu: Separate regulator registration from probe
regulator: ab3100: Use regulator_map_voltage_iterate()
regulator: tps65217: Convert to set_voltage_sel and map_voltage
regulator: Enable the ab8500 for Device Tree
regulator: ab8500: Split up probe() into manageable pieces
regulator: max8925: Remove check_range function and max_uV from struct rc5t583_regulator_info
regulator: max8649: Remove unused check_range() function
regulator: rc5t583: Remove max_uV from struct rc5t583_regulator_info
regulator: da9052: Convert to set_voltage_sel and map_voltage
regulator: max8952: Use devm_kzalloc
...
Diffstat (limited to 'drivers/regulator/twl-regulator.c')
-rw-r--r-- | drivers/regulator/twl-regulator.c | 127 |
1 files changed, 57 insertions, 70 deletions
diff --git a/drivers/regulator/twl-regulator.c b/drivers/regulator/twl-regulator.c index 9cdfc389ca26..c7390711d954 100644 --- a/drivers/regulator/twl-regulator.c +++ b/drivers/regulator/twl-regulator.c @@ -12,7 +12,6 @@ #include <linux/module.h> #include <linux/init.h> #include <linux/err.h> -#include <linux/delay.h> #include <linux/platform_device.h> #include <linux/of.h> #include <linux/of_device.h> @@ -175,15 +174,14 @@ static int twl6030reg_is_enabled(struct regulator_dev *rdev) struct twlreg_info *info = rdev_get_drvdata(rdev); int grp = 0, val; - if (!(twl_class_is_6030() && (info->features & TWL6025_SUBCLASS))) - grp = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_GRP); - if (grp < 0) - return grp; - - if (!(twl_class_is_6030() && (info->features & TWL6025_SUBCLASS))) + if (!(twl_class_is_6030() && (info->features & TWL6025_SUBCLASS))) { + grp = twlreg_grp(rdev); + if (grp < 0) + return grp; grp &= P1_GRP_6030; - else + } else { grp = 1; + } val = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_STATE); val = TWL6030_CFG_STATE_APP(val); @@ -197,7 +195,7 @@ static int twl4030reg_enable(struct regulator_dev *rdev) int grp; int ret; - grp = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_GRP); + grp = twlreg_grp(rdev); if (grp < 0) return grp; @@ -205,8 +203,6 @@ static int twl4030reg_enable(struct regulator_dev *rdev) ret = twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_GRP, grp); - udelay(info->delay); - return ret; } @@ -217,17 +213,28 @@ static int twl6030reg_enable(struct regulator_dev *rdev) int ret; if (!(twl_class_is_6030() && (info->features & TWL6025_SUBCLASS))) - grp = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_GRP); + grp = twlreg_grp(rdev); if (grp < 0) return grp; ret = twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_STATE, grp << TWL6030_CFG_STATE_GRP_SHIFT | TWL6030_CFG_STATE_ON); + return ret; +} - udelay(info->delay); +static int twl4030reg_enable_time(struct regulator_dev *rdev) +{ + struct twlreg_info *info = rdev_get_drvdata(rdev); - return ret; + return info->delay; +} + +static int twl6030reg_enable_time(struct regulator_dev *rdev) +{ + struct twlreg_info *info = rdev_get_drvdata(rdev); + + return info->delay; } static int twl4030reg_disable(struct regulator_dev *rdev) @@ -236,7 +243,7 @@ static int twl4030reg_disable(struct regulator_dev *rdev) int grp; int ret; - grp = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_GRP); + grp = twlreg_grp(rdev); if (grp < 0) return grp; @@ -348,7 +355,7 @@ static int twl6030reg_set_mode(struct regulator_dev *rdev, unsigned mode) int val; if (!(twl_class_is_6030() && (info->features & TWL6025_SUBCLASS))) - grp = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_GRP); + grp = twlreg_grp(rdev); if (grp < 0) return grp; @@ -388,14 +395,12 @@ static int twl6030reg_set_mode(struct regulator_dev *rdev, unsigned mode) * VAUX3 at 3V is incorrectly listed in some TI manuals as unsupported. * TI are revising the twl5030/tps659x0 specs to support that 3.0V setting. */ -#ifdef CONFIG_TWL4030_ALLOW_UNSUPPORTED -#define UNSUP_MASK 0x0000 -#else #define UNSUP_MASK 0x8000 -#endif #define UNSUP(x) (UNSUP_MASK | (x)) -#define IS_UNSUP(x) (UNSUP_MASK & (x)) +#define IS_UNSUP(info, x) \ + ((UNSUP_MASK & (x)) && \ + !((info)->features & TWL4030_ALLOW_UNSUPPORTED)) #define LDO_MV(x) (~UNSUP_MASK & (x)) @@ -469,35 +474,16 @@ static int twl4030ldo_list_voltage(struct regulator_dev *rdev, unsigned index) struct twlreg_info *info = rdev_get_drvdata(rdev); int mV = info->table[index]; - return IS_UNSUP(mV) ? 0 : (LDO_MV(mV) * 1000); + return IS_UNSUP(info, mV) ? 0 : (LDO_MV(mV) * 1000); } static int -twl4030ldo_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV, - unsigned *selector) +twl4030ldo_set_voltage_sel(struct regulator_dev *rdev, unsigned selector) { struct twlreg_info *info = rdev_get_drvdata(rdev); - int vsel; - for (vsel = 0; vsel < info->table_len; vsel++) { - int mV = info->table[vsel]; - int uV; - - if (IS_UNSUP(mV)) - continue; - uV = LDO_MV(mV) * 1000; - - /* REVISIT for VAUX2, first match may not be best/lowest */ - - /* use the first in-range value */ - if (min_uV <= uV && uV <= max_uV) { - *selector = vsel; - return twlreg_write(info, TWL_MODULE_PM_RECEIVER, - VREG_VOLTAGE, vsel); - } - } - - return -EDOM; + return twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_VOLTAGE, + selector); } static int twl4030ldo_get_voltage(struct regulator_dev *rdev) @@ -516,12 +502,13 @@ static int twl4030ldo_get_voltage(struct regulator_dev *rdev) static struct regulator_ops twl4030ldo_ops = { .list_voltage = twl4030ldo_list_voltage, - .set_voltage = twl4030ldo_set_voltage, + .set_voltage_sel = twl4030ldo_set_voltage_sel, .get_voltage = twl4030ldo_get_voltage, .enable = twl4030reg_enable, .disable = twl4030reg_disable, .is_enabled = twl4030reg_is_enabled, + .enable_time = twl4030reg_enable_time, .set_mode = twl4030reg_set_mode, @@ -642,6 +629,7 @@ static struct regulator_ops twl6030ldo_ops = { .enable = twl6030reg_enable, .disable = twl6030reg_disable, .is_enabled = twl6030reg_is_enabled, + .enable_time = twl6030reg_enable_time, .set_mode = twl6030reg_set_mode, @@ -675,6 +663,7 @@ static struct regulator_ops twl4030fixed_ops = { .enable = twl4030reg_enable, .disable = twl4030reg_disable, .is_enabled = twl4030reg_is_enabled, + .enable_time = twl4030reg_enable_time, .set_mode = twl4030reg_set_mode, @@ -689,6 +678,7 @@ static struct regulator_ops twl6030fixed_ops = { .enable = twl6030reg_enable, .disable = twl6030reg_disable, .is_enabled = twl6030reg_is_enabled, + .enable_time = twl6030reg_enable_time, .set_mode = twl6030reg_set_mode, @@ -699,6 +689,7 @@ static struct regulator_ops twl6030_fixed_resource = { .enable = twl6030reg_enable, .disable = twl6030reg_disable, .is_enabled = twl6030reg_is_enabled, + .enable_time = twl6030reg_enable_time, .get_status = twl6030reg_get_status, }; @@ -806,10 +797,7 @@ twl6030smps_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV, vsel = 0; else if ((min_uV >= 600000) && (min_uV <= 1300000)) { int calc_uV; - vsel = (min_uV - 600000) / 125; - if (vsel % 100) - vsel += 100; - vsel /= 100; + vsel = DIV_ROUND_UP(min_uV - 600000, 12500); vsel++; calc_uV = twl6030smps_list_voltage(rdev, vsel); if (calc_uV > max_uV) @@ -836,10 +824,7 @@ twl6030smps_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV, vsel = 0; else if ((min_uV >= 700000) && (min_uV <= 1420000)) { int calc_uV; - vsel = (min_uV - 700000) / 125; - if (vsel % 100) - vsel += 100; - vsel /= 100; + vsel = DIV_ROUND_UP(min_uV - 700000, 12500); vsel++; calc_uV = twl6030smps_list_voltage(rdev, vsel); if (calc_uV > max_uV) @@ -862,24 +847,18 @@ twl6030smps_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV, return -EINVAL; break; case SMPS_EXTENDED_EN: - if (min_uV == 0) + if (min_uV == 0) { vsel = 0; - else if ((min_uV >= 1852000) && (max_uV <= 4013600)) { - vsel = (min_uV - 1852000) / 386; - if (vsel % 100) - vsel += 100; - vsel /= 100; + } else if ((min_uV >= 1852000) && (max_uV <= 4013600)) { + vsel = DIV_ROUND_UP(min_uV - 1852000, 38600); vsel++; } break; case SMPS_OFFSET_EN|SMPS_EXTENDED_EN: - if (min_uV == 0) + if (min_uV == 0) { vsel = 0; - else if ((min_uV >= 2161000) && (max_uV <= 4321000)) { - vsel = (min_uV - 2161000) / 386; - if (vsel % 100) - vsel += 100; - vsel /= 100; + } else if ((min_uV >= 2161000) && (max_uV <= 4321000)) { + vsel = DIV_ROUND_UP(min_uV - 2161000, 38600); vsel++; } break; @@ -907,6 +886,7 @@ static struct regulator_ops twlsmps_ops = { .enable = twl6030reg_enable, .disable = twl6030reg_disable, .is_enabled = twl6030reg_is_enabled, + .enable_time = twl6030reg_enable_time, .set_mode = twl6030reg_set_mode, @@ -1194,6 +1174,7 @@ static int __devinit twlreg_probe(struct platform_device *pdev) struct regulator_dev *rdev; struct twl_regulator_driver_data *drvdata; const struct of_device_id *match; + struct regulator_config config = { }; match = of_match_device(twl_of_match, &pdev->dev); if (match) { @@ -1207,10 +1188,12 @@ static int __devinit twlreg_probe(struct platform_device *pdev) initdata = pdev->dev.platform_data; for (i = 0, info = NULL; i < ARRAY_SIZE(twl_of_match); i++) { info = twl_of_match[i].data; - if (!info || info->desc.id != id) - continue; - break; + if (info && info->desc.id == id) + break; } + if (i == ARRAY_SIZE(twl_of_match)) + return -ENODEV; + drvdata = initdata->driver_data; if (!drvdata) return -EINVAL; @@ -1273,8 +1256,12 @@ static int __devinit twlreg_probe(struct platform_device *pdev) break; } - rdev = regulator_register(&info->desc, &pdev->dev, initdata, info, - pdev->dev.of_node); + config.dev = &pdev->dev; + config.init_data = initdata; + config.driver_data = info; + config.of_node = pdev->dev.of_node; + + rdev = regulator_register(&info->desc, &config); if (IS_ERR(rdev)) { dev_err(&pdev->dev, "can't register %s, %ld\n", info->desc.name, PTR_ERR(rdev)); |