aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDavid Brownell <dbrownell@users.sourceforge.net>2009-02-26 14:50:14 -0500
committerLiam Girdwood <lrg@slimlogic.co.uk>2009-03-31 04:56:25 -0400
commit66b659e685bca1f2f6d6102bac74cafbc7eef5c2 (patch)
treed27f26428fac6bc5b7568fe984a311799eb351f1 /drivers
parentfa16a5c13a2fc1433cfff38a083b4f8c5138d022 (diff)
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: David Brownell <dbrownell@users.sourceforge.net> Acked-by: Mark Brown <broonie@opensource.wolfsonmicro.com> Signed-off-by: Liam Girdwood <lrg@slimlogic.co.uk>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/regulator/twl4030-regulator.c62
1 files changed, 23 insertions, 39 deletions
diff --git a/drivers/regulator/twl4030-regulator.c b/drivers/regulator/twl4030-regulator.c
index 23f282670db5..663a4162b2a1 100644
--- a/drivers/regulator/twl4030-regulator.c
+++ b/drivers/regulator/twl4030-regulator.c
@@ -42,7 +42,6 @@ struct twlreg_info {
42 42
43 /* chip constraints on regulator behavior */ 43 /* chip constraints on regulator behavior */
44 u16 min_mV; 44 u16 min_mV;
45 u16 max_mV;
46 45
47 /* used by regulator core */ 46 /* used by regulator core */
48 struct regulator_desc desc; 47 struct regulator_desc desc;
@@ -258,6 +257,14 @@ static const u16 VDAC_VSEL_table[] = {
258}; 257};
259 258
260 259
260static int twl4030ldo_list_voltage(struct regulator_dev *rdev, unsigned index)
261{
262 struct twlreg_info *info = rdev_get_drvdata(rdev);
263 int mV = info->table[index];
264
265 return IS_UNSUP(mV) ? 0 : (LDO_MV(mV) * 1000);
266}
267
261static int 268static int
262twl4030ldo_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV) 269twl4030ldo_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV)
263{ 270{
@@ -272,6 +279,8 @@ twl4030ldo_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV)
272 continue; 279 continue;
273 uV = LDO_MV(mV) * 1000; 280 uV = LDO_MV(mV) * 1000;
274 281
282 /* REVISIT for VAUX2, first match may not be best/lowest */
283
275 /* use the first in-range value */ 284 /* use the first in-range value */
276 if (min_uV <= uV && uV <= max_uV) 285 if (min_uV <= uV && uV <= max_uV)
277 return twl4030reg_write(info, VREG_DEDICATED, vsel); 286 return twl4030reg_write(info, VREG_DEDICATED, vsel);
@@ -293,6 +302,8 @@ static int twl4030ldo_get_voltage(struct regulator_dev *rdev)
293} 302}
294 303
295static struct regulator_ops twl4030ldo_ops = { 304static struct regulator_ops twl4030ldo_ops = {
305 .list_voltage = twl4030ldo_list_voltage,
306
296 .set_voltage = twl4030ldo_set_voltage, 307 .set_voltage = twl4030ldo_set_voltage,
297 .get_voltage = twl4030ldo_get_voltage, 308 .get_voltage = twl4030ldo_get_voltage,
298 309
@@ -310,6 +321,13 @@ static struct regulator_ops twl4030ldo_ops = {
310/* 321/*
311 * Fixed voltage LDOs don't have a VSEL field to update. 322 * Fixed voltage LDOs don't have a VSEL field to update.
312 */ 323 */
324static int twl4030fixed_list_voltage(struct regulator_dev *rdev, unsigned index)
325{
326 struct twlreg_info *info = rdev_get_drvdata(rdev);
327
328 return info->min_mV * 1000;
329}
330
313static int twl4030fixed_get_voltage(struct regulator_dev *rdev) 331static int twl4030fixed_get_voltage(struct regulator_dev *rdev)
314{ 332{
315 struct twlreg_info *info = rdev_get_drvdata(rdev); 333 struct twlreg_info *info = rdev_get_drvdata(rdev);
@@ -318,6 +336,8 @@ static int twl4030fixed_get_voltage(struct regulator_dev *rdev)
318} 336}
319 337
320static struct regulator_ops twl4030fixed_ops = { 338static struct regulator_ops twl4030fixed_ops = {
339 .list_voltage = twl4030fixed_list_voltage,
340
321 .get_voltage = twl4030fixed_get_voltage, 341 .get_voltage = twl4030fixed_get_voltage,
322 342
323 .enable = twl4030reg_enable, 343 .enable = twl4030reg_enable,
@@ -339,6 +359,7 @@ static struct regulator_ops twl4030fixed_ops = {
339 .desc = { \ 359 .desc = { \
340 .name = #label, \ 360 .name = #label, \
341 .id = TWL4030_REG_##label, \ 361 .id = TWL4030_REG_##label, \
362 .n_voltages = ARRAY_SIZE(label##_VSEL_table), \
342 .ops = &twl4030ldo_ops, \ 363 .ops = &twl4030ldo_ops, \
343 .type = REGULATOR_VOLTAGE, \ 364 .type = REGULATOR_VOLTAGE, \
344 .owner = THIS_MODULE, \ 365 .owner = THIS_MODULE, \
@@ -349,10 +370,10 @@ static struct regulator_ops twl4030fixed_ops = {
349 .base = offset, \ 370 .base = offset, \
350 .id = num, \ 371 .id = num, \
351 .min_mV = mVolts, \ 372 .min_mV = mVolts, \
352 .max_mV = mVolts, \
353 .desc = { \ 373 .desc = { \
354 .name = #label, \ 374 .name = #label, \
355 .id = TWL4030_REG_##label, \ 375 .id = TWL4030_REG_##label, \
376 .n_voltages = 1, \
356 .ops = &twl4030fixed_ops, \ 377 .ops = &twl4030fixed_ops, \
357 .type = REGULATOR_VOLTAGE, \ 378 .type = REGULATOR_VOLTAGE, \
358 .owner = THIS_MODULE, \ 379 .owner = THIS_MODULE, \
@@ -398,14 +419,11 @@ static int twl4030reg_probe(struct platform_device *pdev)
398 struct regulator_init_data *initdata; 419 struct regulator_init_data *initdata;
399 struct regulation_constraints *c; 420 struct regulation_constraints *c;
400 struct regulator_dev *rdev; 421 struct regulator_dev *rdev;
401 int min_uV, max_uV;
402 422
403 for (i = 0, info = NULL; i < ARRAY_SIZE(twl4030_regs); i++) { 423 for (i = 0, info = NULL; i < ARRAY_SIZE(twl4030_regs); i++) {
404 if (twl4030_regs[i].desc.id != pdev->id) 424 if (twl4030_regs[i].desc.id != pdev->id)
405 continue; 425 continue;
406 info = twl4030_regs + i; 426 info = twl4030_regs + i;
407 min_uV = info->min_mV * 1000;
408 max_uV = info->max_mV * 1000;
409 break; 427 break;
410 } 428 }
411 if (!info) 429 if (!info)
@@ -419,10 +437,6 @@ static int twl4030reg_probe(struct platform_device *pdev)
419 * this driver and the chip itself can actually do. 437 * this driver and the chip itself can actually do.
420 */ 438 */
421 c = &initdata->constraints; 439 c = &initdata->constraints;
422 if (!c->min_uV || c->min_uV < min_uV)
423 c->min_uV = min_uV;
424 if (!c->max_uV || c->max_uV > max_uV)
425 c->max_uV = max_uV;
426 c->valid_modes_mask &= REGULATOR_MODE_NORMAL | REGULATOR_MODE_STANDBY; 440 c->valid_modes_mask &= REGULATOR_MODE_NORMAL | REGULATOR_MODE_STANDBY;
427 c->valid_ops_mask &= REGULATOR_CHANGE_VOLTAGE 441 c->valid_ops_mask &= REGULATOR_CHANGE_VOLTAGE
428 | REGULATOR_CHANGE_MODE 442 | REGULATOR_CHANGE_MODE
@@ -467,36 +481,6 @@ static struct platform_driver twl4030reg_driver = {
467 481
468static int __init twl4030reg_init(void) 482static int __init twl4030reg_init(void)
469{ 483{
470 unsigned i, j;
471
472 /* determine min/max voltage constraints, taking into account
473 * whether set_voltage() will use the "unsupported" settings
474 */
475 for (i = 0; i < ARRAY_SIZE(twl4030_regs); i++) {
476 struct twlreg_info *info = twl4030_regs + i;
477 const u16 *table;
478
479 /* fixed-voltage regulators */
480 if (!info->table_len)
481 continue;
482
483 /* LDO regulators: */
484 for (j = 0, table = info->table;
485 j < info->table_len;
486 j++, table++) {
487 u16 mV = *table;
488
489 if (IS_UNSUP(mV))
490 continue;
491 mV = LDO_MV(mV);
492
493 if (info->min_mV == 0 || info->min_mV > mV)
494 info->min_mV = mV;
495 if (info->max_mV < mV)
496 info->max_mV = mV;
497 }
498 }
499
500 return platform_driver_register(&twl4030reg_driver); 484 return platform_driver_register(&twl4030reg_driver);
501} 485}
502subsys_initcall(twl4030reg_init); 486subsys_initcall(twl4030reg_init);