Commit 66b659e6 authored by David Brownell's avatar David Brownell Committed by Liam Girdwood

regulator: twl4030 voltage enumeration (v2)

Update previously-posted twl4030 regulator driver to export
supported voltages to upper layers using a new mechanism.
Signed-off-by: default avatarDavid Brownell <dbrownell@users.sourceforge.net>
Acked-by: default avatarMark Brown <broonie@opensource.wolfsonmicro.com>
Signed-off-by: default avatarLiam Girdwood <lrg@slimlogic.co.uk>
parent fa16a5c1
...@@ -42,7 +42,6 @@ struct twlreg_info { ...@@ -42,7 +42,6 @@ struct twlreg_info {
/* chip constraints on regulator behavior */ /* chip constraints on regulator behavior */
u16 min_mV; u16 min_mV;
u16 max_mV;
/* used by regulator core */ /* used by regulator core */
struct regulator_desc desc; struct regulator_desc desc;
...@@ -258,6 +257,14 @@ static const u16 VDAC_VSEL_table[] = { ...@@ -258,6 +257,14 @@ static const u16 VDAC_VSEL_table[] = {
}; };
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);
}
static int static int
twl4030ldo_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)
{ {
...@@ -272,6 +279,8 @@ twl4030ldo_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV) ...@@ -272,6 +279,8 @@ twl4030ldo_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV)
continue; continue;
uV = LDO_MV(mV) * 1000; uV = LDO_MV(mV) * 1000;
/* REVISIT for VAUX2, first match may not be best/lowest */
/* use the first in-range value */ /* use the first in-range value */
if (min_uV <= uV && uV <= max_uV) if (min_uV <= uV && uV <= max_uV)
return twl4030reg_write(info, VREG_DEDICATED, vsel); return twl4030reg_write(info, VREG_DEDICATED, vsel);
...@@ -293,6 +302,8 @@ static int twl4030ldo_get_voltage(struct regulator_dev *rdev) ...@@ -293,6 +302,8 @@ static int twl4030ldo_get_voltage(struct regulator_dev *rdev)
} }
static struct regulator_ops twl4030ldo_ops = { static struct regulator_ops twl4030ldo_ops = {
.list_voltage = twl4030ldo_list_voltage,
.set_voltage = twl4030ldo_set_voltage, .set_voltage = twl4030ldo_set_voltage,
.get_voltage = twl4030ldo_get_voltage, .get_voltage = twl4030ldo_get_voltage,
...@@ -310,6 +321,13 @@ static struct regulator_ops twl4030ldo_ops = { ...@@ -310,6 +321,13 @@ static struct regulator_ops twl4030ldo_ops = {
/* /*
* Fixed voltage LDOs don't have a VSEL field to update. * Fixed voltage LDOs don't have a VSEL field to update.
*/ */
static int twl4030fixed_list_voltage(struct regulator_dev *rdev, unsigned index)
{
struct twlreg_info *info = rdev_get_drvdata(rdev);
return info->min_mV * 1000;
}
static int twl4030fixed_get_voltage(struct regulator_dev *rdev) static int twl4030fixed_get_voltage(struct regulator_dev *rdev)
{ {
struct twlreg_info *info = rdev_get_drvdata(rdev); struct twlreg_info *info = rdev_get_drvdata(rdev);
...@@ -318,6 +336,8 @@ static int twl4030fixed_get_voltage(struct regulator_dev *rdev) ...@@ -318,6 +336,8 @@ static int twl4030fixed_get_voltage(struct regulator_dev *rdev)
} }
static struct regulator_ops twl4030fixed_ops = { static struct regulator_ops twl4030fixed_ops = {
.list_voltage = twl4030fixed_list_voltage,
.get_voltage = twl4030fixed_get_voltage, .get_voltage = twl4030fixed_get_voltage,
.enable = twl4030reg_enable, .enable = twl4030reg_enable,
...@@ -339,6 +359,7 @@ static struct regulator_ops twl4030fixed_ops = { ...@@ -339,6 +359,7 @@ static struct regulator_ops twl4030fixed_ops = {
.desc = { \ .desc = { \
.name = #label, \ .name = #label, \
.id = TWL4030_REG_##label, \ .id = TWL4030_REG_##label, \
.n_voltages = ARRAY_SIZE(label##_VSEL_table), \
.ops = &twl4030ldo_ops, \ .ops = &twl4030ldo_ops, \
.type = REGULATOR_VOLTAGE, \ .type = REGULATOR_VOLTAGE, \
.owner = THIS_MODULE, \ .owner = THIS_MODULE, \
...@@ -349,10 +370,10 @@ static struct regulator_ops twl4030fixed_ops = { ...@@ -349,10 +370,10 @@ static struct regulator_ops twl4030fixed_ops = {
.base = offset, \ .base = offset, \
.id = num, \ .id = num, \
.min_mV = mVolts, \ .min_mV = mVolts, \
.max_mV = mVolts, \
.desc = { \ .desc = { \
.name = #label, \ .name = #label, \
.id = TWL4030_REG_##label, \ .id = TWL4030_REG_##label, \
.n_voltages = 1, \
.ops = &twl4030fixed_ops, \ .ops = &twl4030fixed_ops, \
.type = REGULATOR_VOLTAGE, \ .type = REGULATOR_VOLTAGE, \
.owner = THIS_MODULE, \ .owner = THIS_MODULE, \
...@@ -398,14 +419,11 @@ static int twl4030reg_probe(struct platform_device *pdev) ...@@ -398,14 +419,11 @@ static int twl4030reg_probe(struct platform_device *pdev)
struct regulator_init_data *initdata; struct regulator_init_data *initdata;
struct regulation_constraints *c; struct regulation_constraints *c;
struct regulator_dev *rdev; struct regulator_dev *rdev;
int min_uV, max_uV;
for (i = 0, info = NULL; i < ARRAY_SIZE(twl4030_regs); i++) { for (i = 0, info = NULL; i < ARRAY_SIZE(twl4030_regs); i++) {
if (twl4030_regs[i].desc.id != pdev->id) if (twl4030_regs[i].desc.id != pdev->id)
continue; continue;
info = twl4030_regs + i; info = twl4030_regs + i;
min_uV = info->min_mV * 1000;
max_uV = info->max_mV * 1000;
break; break;
} }
if (!info) if (!info)
...@@ -419,10 +437,6 @@ static int twl4030reg_probe(struct platform_device *pdev) ...@@ -419,10 +437,6 @@ static int twl4030reg_probe(struct platform_device *pdev)
* this driver and the chip itself can actually do. * this driver and the chip itself can actually do.
*/ */
c = &initdata->constraints; c = &initdata->constraints;
if (!c->min_uV || c->min_uV < min_uV)
c->min_uV = min_uV;
if (!c->max_uV || c->max_uV > max_uV)
c->max_uV = max_uV;
c->valid_modes_mask &= REGULATOR_MODE_NORMAL | REGULATOR_MODE_STANDBY; c->valid_modes_mask &= REGULATOR_MODE_NORMAL | REGULATOR_MODE_STANDBY;
c->valid_ops_mask &= REGULATOR_CHANGE_VOLTAGE c->valid_ops_mask &= REGULATOR_CHANGE_VOLTAGE
| REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_MODE
...@@ -467,36 +481,6 @@ static struct platform_driver twl4030reg_driver = { ...@@ -467,36 +481,6 @@ static struct platform_driver twl4030reg_driver = {
static int __init twl4030reg_init(void) static int __init twl4030reg_init(void)
{ {
unsigned i, j;
/* determine min/max voltage constraints, taking into account
* whether set_voltage() will use the "unsupported" settings
*/
for (i = 0; i < ARRAY_SIZE(twl4030_regs); i++) {
struct twlreg_info *info = twl4030_regs + i;
const u16 *table;
/* fixed-voltage regulators */
if (!info->table_len)
continue;
/* LDO regulators: */
for (j = 0, table = info->table;
j < info->table_len;
j++, table++) {
u16 mV = *table;
if (IS_UNSUP(mV))
continue;
mV = LDO_MV(mV);
if (info->min_mV == 0 || info->min_mV > mV)
info->min_mV = mV;
if (info->max_mV < mV)
info->max_mV = mV;
}
}
return platform_driver_register(&twl4030reg_driver); return platform_driver_register(&twl4030reg_driver);
} }
subsys_initcall(twl4030reg_init); subsys_initcall(twl4030reg_init);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment