diff options
author | David Brownell <dbrownell@users.sourceforge.net> | 2009-02-26 14:50:14 -0500 |
---|---|---|
committer | Liam Girdwood <lrg@slimlogic.co.uk> | 2009-03-31 04:56:25 -0400 |
commit | 66b659e685bca1f2f6d6102bac74cafbc7eef5c2 (patch) | |
tree | d27f26428fac6bc5b7568fe984a311799eb351f1 | |
parent | fa16a5c13a2fc1433cfff38a083b4f8c5138d022 (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>
-rw-r--r-- | drivers/regulator/twl4030-regulator.c | 62 |
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 | ||
260 | static 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 | |||
261 | static int | 268 | static int |
262 | twl4030ldo_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV) | 269 | twl4030ldo_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 | ||
295 | static struct regulator_ops twl4030ldo_ops = { | 304 | static 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 | */ |
324 | static 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 | |||
313 | static int twl4030fixed_get_voltage(struct regulator_dev *rdev) | 331 | static 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 | ||
320 | static struct regulator_ops twl4030fixed_ops = { | 338 | static 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 | ||
468 | static int __init twl4030reg_init(void) | 482 | static 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 | } |
502 | subsys_initcall(twl4030reg_init); | 486 | subsys_initcall(twl4030reg_init); |