diff options
author | Stephen Rothwell <sfr@canb.auug.org.au> | 2010-05-18 14:10:17 +1000 |
---|---|---|
committer | Stephen Rothwell <sfr@canb.auug.org.au> | 2010-05-18 14:10:17 +1000 |
commit | 96c2dd2b5d4128cd5dfc5b038593be7c7fd5742b (patch) | |
tree | 6fdd49369a90bf1498390c29cec8250679eedde3 /drivers | |
parent | ab66bfb0d342a348fb94234cbbfb81d2e6ccb050 (diff) | |
parent | 70d12bfcd0ce6da5f318a68aa8abae7f715bfb6e (diff) |
Merge remote branch 'voltage/for-next'
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/regulator/ab3100.c | 10 | ||||
-rw-r--r-- | drivers/regulator/bq24022.c | 1 | ||||
-rw-r--r-- | drivers/regulator/core.c | 83 | ||||
-rw-r--r-- | drivers/regulator/mc13783-regulator.c | 6 | ||||
-rw-r--r-- | drivers/regulator/twl-regulator.c | 138 |
5 files changed, 156 insertions, 82 deletions
diff --git a/drivers/regulator/ab3100.c b/drivers/regulator/ab3100.c index 6580e261cd09..7b14a67bdca2 100644 --- a/drivers/regulator/ab3100.c +++ b/drivers/regulator/ab3100.c @@ -492,18 +492,21 @@ ab3100_regulator_desc[AB3100_NUM_REGULATORS] = { .id = AB3100_LDO_A, .ops = ®ulator_ops_fixed, .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, }, { .name = "LDO_C", .id = AB3100_LDO_C, .ops = ®ulator_ops_fixed, .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, }, { .name = "LDO_D", .id = AB3100_LDO_D, .ops = ®ulator_ops_fixed, .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, }, { .name = "LDO_E", @@ -511,6 +514,7 @@ ab3100_regulator_desc[AB3100_NUM_REGULATORS] = { .ops = ®ulator_ops_variable_sleepable, .n_voltages = ARRAY_SIZE(ldo_e_buck_typ_voltages), .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, }, { .name = "LDO_F", @@ -518,6 +522,7 @@ ab3100_regulator_desc[AB3100_NUM_REGULATORS] = { .ops = ®ulator_ops_variable, .n_voltages = ARRAY_SIZE(ldo_f_typ_voltages), .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, }, { .name = "LDO_G", @@ -525,6 +530,7 @@ ab3100_regulator_desc[AB3100_NUM_REGULATORS] = { .ops = ®ulator_ops_variable, .n_voltages = ARRAY_SIZE(ldo_g_typ_voltages), .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, }, { .name = "LDO_H", @@ -532,6 +538,7 @@ ab3100_regulator_desc[AB3100_NUM_REGULATORS] = { .ops = ®ulator_ops_variable, .n_voltages = ARRAY_SIZE(ldo_h_typ_voltages), .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, }, { .name = "LDO_K", @@ -539,12 +546,14 @@ ab3100_regulator_desc[AB3100_NUM_REGULATORS] = { .ops = ®ulator_ops_variable, .n_voltages = ARRAY_SIZE(ldo_k_typ_voltages), .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, }, { .name = "LDO_EXT", .id = AB3100_LDO_EXT, .ops = ®ulator_ops_external, .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, }, { .name = "BUCK", @@ -552,6 +561,7 @@ ab3100_regulator_desc[AB3100_NUM_REGULATORS] = { .ops = ®ulator_ops_variable_sleepable, .n_voltages = ARRAY_SIZE(ldo_e_buck_typ_voltages), .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, }, }; diff --git a/drivers/regulator/bq24022.c b/drivers/regulator/bq24022.c index d08cd9b66c6d..068d488a4f71 100644 --- a/drivers/regulator/bq24022.c +++ b/drivers/regulator/bq24022.c @@ -78,6 +78,7 @@ static struct regulator_desc bq24022_desc = { .name = "bq24022", .ops = &bq24022_ops, .type = REGULATOR_CURRENT, + .owner = THIS_MODULE, }; static int __init bq24022_probe(struct platform_device *pdev) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 2b4e40d31190..521c9b1a40ef 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -944,8 +944,13 @@ static int set_consumer_device_supply(struct regulator_dev *rdev, has_dev = 0; list_for_each_entry(node, ®ulator_map_list, list) { - if (consumer_dev_name != node->dev_name) + if (node->dev_name && consumer_dev_name) { + if (strcmp(node->dev_name, consumer_dev_name) != 0) + continue; + } else if (node->dev_name || consumer_dev_name) { continue; + } + if (strcmp(node->supply, supply) != 0) continue; @@ -976,29 +981,6 @@ static int set_consumer_device_supply(struct regulator_dev *rdev, return 0; } -static void unset_consumer_device_supply(struct regulator_dev *rdev, - const char *consumer_dev_name, struct device *consumer_dev) -{ - struct regulator_map *node, *n; - - if (consumer_dev && !consumer_dev_name) - consumer_dev_name = dev_name(consumer_dev); - - list_for_each_entry_safe(node, n, ®ulator_map_list, list) { - if (rdev != node->regulator) - continue; - - if (consumer_dev_name && node->dev_name && - strcmp(consumer_dev_name, node->dev_name)) - continue; - - list_del(&node->list); - kfree(node->dev_name); - kfree(node); - return; - } -} - static void unset_regulator_supplies(struct regulator_dev *rdev) { struct regulator_map *node, *n; @@ -1008,7 +990,6 @@ static void unset_regulator_supplies(struct regulator_dev *rdev) list_del(&node->list); kfree(node->dev_name); kfree(node); - return; } } } @@ -1764,6 +1745,7 @@ int regulator_set_mode(struct regulator *regulator, unsigned int mode) { struct regulator_dev *rdev = regulator->rdev; int ret; + int regulator_curr_mode; mutex_lock(&rdev->mutex); @@ -1773,6 +1755,15 @@ int regulator_set_mode(struct regulator *regulator, unsigned int mode) goto out; } + /* return if the same mode is requested */ + if (rdev->desc->ops->get_mode) { + regulator_curr_mode = rdev->desc->ops->get_mode(rdev); + if (regulator_curr_mode == mode) { + ret = 0; + goto out; + } + } + /* constraints check */ ret = regulator_check_mode(rdev, mode); if (ret < 0) @@ -2328,7 +2319,37 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc, goto scrub; /* set supply regulator if it exists */ + if (init_data->supply_regulator && init_data->supply_regulator_dev) { + dev_err(dev, + "Supply regulator specified by both name and dev\n"); + goto scrub; + } + + if (init_data->supply_regulator) { + struct regulator_dev *r; + int found = 0; + + list_for_each_entry(r, ®ulator_list, list) { + if (strcmp(rdev_get_name(r), + init_data->supply_regulator) == 0) { + found = 1; + break; + } + } + + if (!found) { + dev_err(dev, "Failed to find supply %s\n", + init_data->supply_regulator); + goto scrub; + } + + ret = set_supply(rdev, r); + if (ret < 0) + goto scrub; + } + if (init_data->supply_regulator_dev) { + dev_warn(dev, "Uses supply_regulator_dev instead of regulator_supply\n"); ret = set_supply(rdev, dev_get_drvdata(init_data->supply_regulator_dev)); if (ret < 0) @@ -2341,13 +2362,8 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc, init_data->consumer_supplies[i].dev, init_data->consumer_supplies[i].dev_name, init_data->consumer_supplies[i].supply); - if (ret < 0) { - for (--i; i >= 0; i--) - unset_consumer_device_supply(rdev, - init_data->consumer_supplies[i].dev_name, - init_data->consumer_supplies[i].dev); - goto scrub; - } + if (ret < 0) + goto unset_supplies; } list_add(&rdev->list, ®ulator_list); @@ -2355,6 +2371,9 @@ out: mutex_unlock(®ulator_list_mutex); return rdev; +unset_supplies: + unset_regulator_supplies(rdev); + scrub: device_unregister(&rdev->dev); /* device core frees rdev */ diff --git a/drivers/regulator/mc13783-regulator.c b/drivers/regulator/mc13783-regulator.c index ad036dd8da13..4597d508a229 100644 --- a/drivers/regulator/mc13783-regulator.c +++ b/drivers/regulator/mc13783-regulator.c @@ -440,8 +440,8 @@ static int mc13783_fixed_regulator_set_voltage(struct regulator_dev *rdev, dev_dbg(rdev_get_dev(rdev), "%s id: %d min_uV: %d max_uV: %d\n", __func__, id, min_uV, max_uV); - if (min_uV > mc13783_regulators[id].voltages[0] && - max_uV < mc13783_regulators[id].voltages[0]) + if (min_uV >= mc13783_regulators[id].voltages[0] && + max_uV <= mc13783_regulators[id].voltages[0]) return 0; else return -EINVAL; @@ -649,6 +649,6 @@ static void __exit mc13783_regulator_exit(void) module_exit(mc13783_regulator_exit); MODULE_LICENSE("GPL v2"); -MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de"); +MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>"); MODULE_DESCRIPTION("Regulator Driver for Freescale MC13783 PMIC"); MODULE_ALIAS("platform:mc13783-regulator"); diff --git a/drivers/regulator/twl-regulator.c b/drivers/regulator/twl-regulator.c index 9729d760fb4d..7e5892efc437 100644 --- a/drivers/regulator/twl-regulator.c +++ b/drivers/regulator/twl-regulator.c @@ -49,6 +49,7 @@ struct twlreg_info { /* chip constraints on regulator behavior */ u16 min_mV; + u16 max_mV; /* used by regulator core */ struct regulator_desc desc; @@ -318,31 +319,8 @@ static const u16 VIO_VSEL_table[] = { static const u16 VINTANA2_VSEL_table[] = { 2500, 2750, }; -static const u16 VAUX1_6030_VSEL_table[] = { - 1000, 1300, 1800, 2500, - 2800, 2900, 3000, 3000, -}; -static const u16 VAUX2_6030_VSEL_table[] = { - 1200, 1800, 2500, 2750, - 2800, 2800, 2800, 2800, -}; -static const u16 VAUX3_6030_VSEL_table[] = { - 1000, 1200, 1300, 1800, - 2500, 2800, 3000, 3000, -}; -static const u16 VMMC_VSEL_table[] = { - 1200, 1800, 2800, 2900, - 3000, 3000, 3000, 3000, -}; -static const u16 VPP_VSEL_table[] = { - 1800, 1900, 2000, 2100, - 2200, 2300, 2400, 2500, -}; -static const u16 VUSIM_VSEL_table[] = { - 1200, 1800, 2500, 2900, -}; -static int twlldo_list_voltage(struct regulator_dev *rdev, unsigned index) +static int twl4030ldo_list_voltage(struct regulator_dev *rdev, unsigned index) { struct twlreg_info *info = rdev_get_drvdata(rdev); int mV = info->table[index]; @@ -351,7 +329,7 @@ static int twlldo_list_voltage(struct regulator_dev *rdev, unsigned index) } static int -twlldo_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV) +twl4030ldo_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV) { struct twlreg_info *info = rdev_get_drvdata(rdev); int vsel; @@ -375,7 +353,7 @@ twlldo_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV) return -EDOM; } -static int twlldo_get_voltage(struct regulator_dev *rdev) +static int twl4030ldo_get_voltage(struct regulator_dev *rdev) { struct twlreg_info *info = rdev_get_drvdata(rdev); int vsel = twlreg_read(info, TWL_MODULE_PM_RECEIVER, @@ -388,11 +366,67 @@ static int twlldo_get_voltage(struct regulator_dev *rdev) return LDO_MV(info->table[vsel]) * 1000; } -static struct regulator_ops twlldo_ops = { - .list_voltage = twlldo_list_voltage, +static struct regulator_ops twl4030ldo_ops = { + .list_voltage = twl4030ldo_list_voltage, - .set_voltage = twlldo_set_voltage, - .get_voltage = twlldo_get_voltage, + .set_voltage = twl4030ldo_set_voltage, + .get_voltage = twl4030ldo_get_voltage, + + .enable = twlreg_enable, + .disable = twlreg_disable, + .is_enabled = twlreg_is_enabled, + + .set_mode = twlreg_set_mode, + + .get_status = twlreg_get_status, +}; + +static int twl6030ldo_list_voltage(struct regulator_dev *rdev, unsigned index) +{ + struct twlreg_info *info = rdev_get_drvdata(rdev); + + return ((info->min_mV + (index * 100)) * 1000); +} + +static int +twl6030ldo_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV) +{ + struct twlreg_info *info = rdev_get_drvdata(rdev); + int vsel; + + if ((min_uV/1000 < info->min_mV) || (max_uV/1000 > info->max_mV)) + return -EDOM; + + /* + * Use the below formula to calculate vsel + * mV = 1000mv + 100mv * (vsel - 1) + */ + vsel = (min_uV/1000 - 1000)/100 + 1; + return twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_VOLTAGE, vsel); + +} + +static int twl6030ldo_get_voltage(struct regulator_dev *rdev) +{ + struct twlreg_info *info = rdev_get_drvdata(rdev); + int vsel = twlreg_read(info, TWL_MODULE_PM_RECEIVER, + VREG_VOLTAGE); + + if (vsel < 0) + return vsel; + + /* + * Use the below formula to calculate vsel + * mV = 1000mv + 100mv * (vsel - 1) + */ + return (1000 + (100 * (vsel - 1))) * 1000; +} + +static struct regulator_ops twl6030ldo_ops = { + .list_voltage = twl6030ldo_list_voltage, + + .set_voltage = twl6030ldo_set_voltage, + .get_voltage = twl6030ldo_get_voltage, .enable = twlreg_enable, .disable = twlreg_disable, @@ -438,24 +472,16 @@ static struct regulator_ops twlfixed_ops = { /*----------------------------------------------------------------------*/ -#define TWL4030_ADJUSTABLE_LDO(label, offset, num, turnon_delay, remap_conf) \ - TWL_ADJUSTABLE_LDO(label, offset, num, turnon_delay, \ - remap_conf, TWL4030) #define TWL4030_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \ remap_conf) \ TWL_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \ remap_conf, TWL4030) -#define TWL6030_ADJUSTABLE_LDO(label, offset, num, turnon_delay, \ - remap_conf) \ - TWL_ADJUSTABLE_LDO(label, offset, num, turnon_delay, \ - remap_conf, TWL6030) #define TWL6030_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \ remap_conf) \ TWL_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \ remap_conf, TWL6030) -#define TWL_ADJUSTABLE_LDO(label, offset, num, turnon_delay, remap_conf, \ - family) { \ +#define TWL4030_ADJUSTABLE_LDO(label, offset, num, turnon_delay, remap_conf) { \ .base = offset, \ .id = num, \ .table_len = ARRAY_SIZE(label##_VSEL_table), \ @@ -464,14 +490,32 @@ static struct regulator_ops twlfixed_ops = { .remap = remap_conf, \ .desc = { \ .name = #label, \ - .id = family##_REG_##label, \ + .id = TWL4030_REG_##label, \ .n_voltages = ARRAY_SIZE(label##_VSEL_table), \ - .ops = &twlldo_ops, \ + .ops = &twl4030ldo_ops, \ .type = REGULATOR_VOLTAGE, \ .owner = THIS_MODULE, \ }, \ } +#define TWL6030_ADJUSTABLE_LDO(label, offset, min_mVolts, max_mVolts, num, \ + remap_conf) { \ + .base = offset, \ + .id = num, \ + .min_mV = min_mVolts, \ + .max_mV = max_mVolts, \ + .remap = remap_conf, \ + .desc = { \ + .name = #label, \ + .id = TWL6030_REG_##label, \ + .n_voltages = (max_mVolts - min_mVolts)/100, \ + .ops = &twl6030ldo_ops, \ + .type = REGULATOR_VOLTAGE, \ + .owner = THIS_MODULE, \ + }, \ + } + + #define TWL_FIXED_LDO(label, offset, mVolts, num, turnon_delay, remap_conf, \ family) { \ .base = offset, \ @@ -519,12 +563,12 @@ static struct twlreg_info twl_regs[] = { /* 6030 REG with base as PMC Slave Misc : 0x0030 */ /* Turnon-delay and remap configuration values for 6030 are not verified since the specification is not public */ - TWL6030_ADJUSTABLE_LDO(VAUX1_6030, 0x54, 1, 0, 0x21), - TWL6030_ADJUSTABLE_LDO(VAUX2_6030, 0x58, 2, 0, 0x21), - TWL6030_ADJUSTABLE_LDO(VAUX3_6030, 0x5c, 3, 0, 0x21), - TWL6030_ADJUSTABLE_LDO(VMMC, 0x68, 4, 0, 0x21), - TWL6030_ADJUSTABLE_LDO(VPP, 0x6c, 5, 0, 0x21), - TWL6030_ADJUSTABLE_LDO(VUSIM, 0x74, 7, 0, 0x21), + TWL6030_ADJUSTABLE_LDO(VAUX1_6030, 0x54, 1000, 3300, 1, 0x21), + TWL6030_ADJUSTABLE_LDO(VAUX2_6030, 0x58, 1000, 3300, 2, 0x21), + TWL6030_ADJUSTABLE_LDO(VAUX3_6030, 0x5c, 1000, 3300, 3, 0x21), + TWL6030_ADJUSTABLE_LDO(VMMC, 0x68, 1000, 3300, 4, 0x21), + TWL6030_ADJUSTABLE_LDO(VPP, 0x6c, 1000, 3300, 5, 0x21), + TWL6030_ADJUSTABLE_LDO(VUSIM, 0x74, 1000, 3300, 7, 0x21), TWL6030_FIXED_LDO(VANA, 0x50, 2100, 15, 0, 0x21), TWL6030_FIXED_LDO(VCXIO, 0x60, 1800, 16, 0, 0x21), TWL6030_FIXED_LDO(VDAC, 0x64, 1800, 17, 0, 0x21), |