diff options
author | Rajendra Nayak <rnayak@ti.com> | 2010-04-22 04:48:32 -0400 |
---|---|---|
committer | Liam Girdwood <lrg@slimlogic.co.uk> | 2010-05-25 05:16:02 -0400 |
commit | 3e3d3be79c75a214cd81454bb891980532d8ca89 (patch) | |
tree | 650b9ad61377fee33ab68254556c169351fbc476 /drivers/regulator/twl-regulator.c | |
parent | 1dcc434b52ff25416b225f6ac229fc775867303a (diff) |
twl6030: regulator: Remove vsel tables and use formula for calculation
All twl6030 regulators can be programmed from 1.0v to 3.3v
with 100mV steps.
The below formula can be used to calculate the vsel values
to be programmed in the VREG_VOLTAGE registers.
Voltage(in mV) = 1000mv + 100mv * (vsel - 1)
Ex: if vsel = 0x9, mV = 1000 + 100 * (9 -1) = 1800mV.
This patch removes all existing VSEL tables for twl6030 adjustable
regulators and just uses the formula directly for vsel calculations
after verifing they fall in the allowed range.
Signed-off-by: Rajendra Nayak <rnayak@ti.com>
Cc: Liam Girdwood <lrg@slimlogic.co.uk>
Cc: Samuel Ortiz <sameo@linux.intel.com>
Cc: Mark Brown <broonie@opensource.wolfsonmicro.com>
Acked-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Signed-off-by: Liam Girdwood <lrg@slimlogic.co.uk>
Diffstat (limited to 'drivers/regulator/twl-regulator.c')
-rw-r--r-- | drivers/regulator/twl-regulator.c | 138 |
1 files changed, 91 insertions, 47 deletions
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 { | |||
49 | 49 | ||
50 | /* chip constraints on regulator behavior */ | 50 | /* chip constraints on regulator behavior */ |
51 | u16 min_mV; | 51 | u16 min_mV; |
52 | u16 max_mV; | ||
52 | 53 | ||
53 | /* used by regulator core */ | 54 | /* used by regulator core */ |
54 | struct regulator_desc desc; | 55 | struct regulator_desc desc; |
@@ -318,31 +319,8 @@ static const u16 VIO_VSEL_table[] = { | |||
318 | static const u16 VINTANA2_VSEL_table[] = { | 319 | static const u16 VINTANA2_VSEL_table[] = { |
319 | 2500, 2750, | 320 | 2500, 2750, |
320 | }; | 321 | }; |
321 | static const u16 VAUX1_6030_VSEL_table[] = { | ||
322 | 1000, 1300, 1800, 2500, | ||
323 | 2800, 2900, 3000, 3000, | ||
324 | }; | ||
325 | static const u16 VAUX2_6030_VSEL_table[] = { | ||
326 | 1200, 1800, 2500, 2750, | ||
327 | 2800, 2800, 2800, 2800, | ||
328 | }; | ||
329 | static const u16 VAUX3_6030_VSEL_table[] = { | ||
330 | 1000, 1200, 1300, 1800, | ||
331 | 2500, 2800, 3000, 3000, | ||
332 | }; | ||
333 | static const u16 VMMC_VSEL_table[] = { | ||
334 | 1200, 1800, 2800, 2900, | ||
335 | 3000, 3000, 3000, 3000, | ||
336 | }; | ||
337 | static const u16 VPP_VSEL_table[] = { | ||
338 | 1800, 1900, 2000, 2100, | ||
339 | 2200, 2300, 2400, 2500, | ||
340 | }; | ||
341 | static const u16 VUSIM_VSEL_table[] = { | ||
342 | 1200, 1800, 2500, 2900, | ||
343 | }; | ||
344 | 322 | ||
345 | static int twlldo_list_voltage(struct regulator_dev *rdev, unsigned index) | 323 | static int twl4030ldo_list_voltage(struct regulator_dev *rdev, unsigned index) |
346 | { | 324 | { |
347 | struct twlreg_info *info = rdev_get_drvdata(rdev); | 325 | struct twlreg_info *info = rdev_get_drvdata(rdev); |
348 | int mV = info->table[index]; | 326 | int mV = info->table[index]; |
@@ -351,7 +329,7 @@ static int twlldo_list_voltage(struct regulator_dev *rdev, unsigned index) | |||
351 | } | 329 | } |
352 | 330 | ||
353 | static int | 331 | static int |
354 | twlldo_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV) | 332 | twl4030ldo_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV) |
355 | { | 333 | { |
356 | struct twlreg_info *info = rdev_get_drvdata(rdev); | 334 | struct twlreg_info *info = rdev_get_drvdata(rdev); |
357 | int vsel; | 335 | int vsel; |
@@ -375,7 +353,7 @@ twlldo_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV) | |||
375 | return -EDOM; | 353 | return -EDOM; |
376 | } | 354 | } |
377 | 355 | ||
378 | static int twlldo_get_voltage(struct regulator_dev *rdev) | 356 | static int twl4030ldo_get_voltage(struct regulator_dev *rdev) |
379 | { | 357 | { |
380 | struct twlreg_info *info = rdev_get_drvdata(rdev); | 358 | struct twlreg_info *info = rdev_get_drvdata(rdev); |
381 | int vsel = twlreg_read(info, TWL_MODULE_PM_RECEIVER, | 359 | int vsel = twlreg_read(info, TWL_MODULE_PM_RECEIVER, |
@@ -388,11 +366,67 @@ static int twlldo_get_voltage(struct regulator_dev *rdev) | |||
388 | return LDO_MV(info->table[vsel]) * 1000; | 366 | return LDO_MV(info->table[vsel]) * 1000; |
389 | } | 367 | } |
390 | 368 | ||
391 | static struct regulator_ops twlldo_ops = { | 369 | static struct regulator_ops twl4030ldo_ops = { |
392 | .list_voltage = twlldo_list_voltage, | 370 | .list_voltage = twl4030ldo_list_voltage, |
393 | 371 | ||
394 | .set_voltage = twlldo_set_voltage, | 372 | .set_voltage = twl4030ldo_set_voltage, |
395 | .get_voltage = twlldo_get_voltage, | 373 | .get_voltage = twl4030ldo_get_voltage, |
374 | |||
375 | .enable = twlreg_enable, | ||
376 | .disable = twlreg_disable, | ||
377 | .is_enabled = twlreg_is_enabled, | ||
378 | |||
379 | .set_mode = twlreg_set_mode, | ||
380 | |||
381 | .get_status = twlreg_get_status, | ||
382 | }; | ||
383 | |||
384 | static int twl6030ldo_list_voltage(struct regulator_dev *rdev, unsigned index) | ||
385 | { | ||
386 | struct twlreg_info *info = rdev_get_drvdata(rdev); | ||
387 | |||
388 | return ((info->min_mV + (index * 100)) * 1000); | ||
389 | } | ||
390 | |||
391 | static int | ||
392 | twl6030ldo_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV) | ||
393 | { | ||
394 | struct twlreg_info *info = rdev_get_drvdata(rdev); | ||
395 | int vsel; | ||
396 | |||
397 | if ((min_uV/1000 < info->min_mV) || (max_uV/1000 > info->max_mV)) | ||
398 | return -EDOM; | ||
399 | |||
400 | /* | ||
401 | * Use the below formula to calculate vsel | ||
402 | * mV = 1000mv + 100mv * (vsel - 1) | ||
403 | */ | ||
404 | vsel = (min_uV/1000 - 1000)/100 + 1; | ||
405 | return twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_VOLTAGE, vsel); | ||
406 | |||
407 | } | ||
408 | |||
409 | static int twl6030ldo_get_voltage(struct regulator_dev *rdev) | ||
410 | { | ||
411 | struct twlreg_info *info = rdev_get_drvdata(rdev); | ||
412 | int vsel = twlreg_read(info, TWL_MODULE_PM_RECEIVER, | ||
413 | VREG_VOLTAGE); | ||
414 | |||
415 | if (vsel < 0) | ||
416 | return vsel; | ||
417 | |||
418 | /* | ||
419 | * Use the below formula to calculate vsel | ||
420 | * mV = 1000mv + 100mv * (vsel - 1) | ||
421 | */ | ||
422 | return (1000 + (100 * (vsel - 1))) * 1000; | ||
423 | } | ||
424 | |||
425 | static struct regulator_ops twl6030ldo_ops = { | ||
426 | .list_voltage = twl6030ldo_list_voltage, | ||
427 | |||
428 | .set_voltage = twl6030ldo_set_voltage, | ||
429 | .get_voltage = twl6030ldo_get_voltage, | ||
396 | 430 | ||
397 | .enable = twlreg_enable, | 431 | .enable = twlreg_enable, |
398 | .disable = twlreg_disable, | 432 | .disable = twlreg_disable, |
@@ -438,24 +472,16 @@ static struct regulator_ops twlfixed_ops = { | |||
438 | 472 | ||
439 | /*----------------------------------------------------------------------*/ | 473 | /*----------------------------------------------------------------------*/ |
440 | 474 | ||
441 | #define TWL4030_ADJUSTABLE_LDO(label, offset, num, turnon_delay, remap_conf) \ | ||
442 | TWL_ADJUSTABLE_LDO(label, offset, num, turnon_delay, \ | ||
443 | remap_conf, TWL4030) | ||
444 | #define TWL4030_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \ | 475 | #define TWL4030_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \ |
445 | remap_conf) \ | 476 | remap_conf) \ |
446 | TWL_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \ | 477 | TWL_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \ |
447 | remap_conf, TWL4030) | 478 | remap_conf, TWL4030) |
448 | #define TWL6030_ADJUSTABLE_LDO(label, offset, num, turnon_delay, \ | ||
449 | remap_conf) \ | ||
450 | TWL_ADJUSTABLE_LDO(label, offset, num, turnon_delay, \ | ||
451 | remap_conf, TWL6030) | ||
452 | #define TWL6030_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \ | 479 | #define TWL6030_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \ |
453 | remap_conf) \ | 480 | remap_conf) \ |
454 | TWL_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \ | 481 | TWL_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \ |
455 | remap_conf, TWL6030) | 482 | remap_conf, TWL6030) |
456 | 483 | ||
457 | #define TWL_ADJUSTABLE_LDO(label, offset, num, turnon_delay, remap_conf, \ | 484 | #define TWL4030_ADJUSTABLE_LDO(label, offset, num, turnon_delay, remap_conf) { \ |
458 | family) { \ | ||
459 | .base = offset, \ | 485 | .base = offset, \ |
460 | .id = num, \ | 486 | .id = num, \ |
461 | .table_len = ARRAY_SIZE(label##_VSEL_table), \ | 487 | .table_len = ARRAY_SIZE(label##_VSEL_table), \ |
@@ -464,14 +490,32 @@ static struct regulator_ops twlfixed_ops = { | |||
464 | .remap = remap_conf, \ | 490 | .remap = remap_conf, \ |
465 | .desc = { \ | 491 | .desc = { \ |
466 | .name = #label, \ | 492 | .name = #label, \ |
467 | .id = family##_REG_##label, \ | 493 | .id = TWL4030_REG_##label, \ |
468 | .n_voltages = ARRAY_SIZE(label##_VSEL_table), \ | 494 | .n_voltages = ARRAY_SIZE(label##_VSEL_table), \ |
469 | .ops = &twlldo_ops, \ | 495 | .ops = &twl4030ldo_ops, \ |
470 | .type = REGULATOR_VOLTAGE, \ | 496 | .type = REGULATOR_VOLTAGE, \ |
471 | .owner = THIS_MODULE, \ | 497 | .owner = THIS_MODULE, \ |
472 | }, \ | 498 | }, \ |
473 | } | 499 | } |
474 | 500 | ||
501 | #define TWL6030_ADJUSTABLE_LDO(label, offset, min_mVolts, max_mVolts, num, \ | ||
502 | remap_conf) { \ | ||
503 | .base = offset, \ | ||
504 | .id = num, \ | ||
505 | .min_mV = min_mVolts, \ | ||
506 | .max_mV = max_mVolts, \ | ||
507 | .remap = remap_conf, \ | ||
508 | .desc = { \ | ||
509 | .name = #label, \ | ||
510 | .id = TWL6030_REG_##label, \ | ||
511 | .n_voltages = (max_mVolts - min_mVolts)/100, \ | ||
512 | .ops = &twl6030ldo_ops, \ | ||
513 | .type = REGULATOR_VOLTAGE, \ | ||
514 | .owner = THIS_MODULE, \ | ||
515 | }, \ | ||
516 | } | ||
517 | |||
518 | |||
475 | #define TWL_FIXED_LDO(label, offset, mVolts, num, turnon_delay, remap_conf, \ | 519 | #define TWL_FIXED_LDO(label, offset, mVolts, num, turnon_delay, remap_conf, \ |
476 | family) { \ | 520 | family) { \ |
477 | .base = offset, \ | 521 | .base = offset, \ |
@@ -519,12 +563,12 @@ static struct twlreg_info twl_regs[] = { | |||
519 | /* 6030 REG with base as PMC Slave Misc : 0x0030 */ | 563 | /* 6030 REG with base as PMC Slave Misc : 0x0030 */ |
520 | /* Turnon-delay and remap configuration values for 6030 are not | 564 | /* Turnon-delay and remap configuration values for 6030 are not |
521 | verified since the specification is not public */ | 565 | verified since the specification is not public */ |
522 | TWL6030_ADJUSTABLE_LDO(VAUX1_6030, 0x54, 1, 0, 0x21), | 566 | TWL6030_ADJUSTABLE_LDO(VAUX1_6030, 0x54, 1000, 3300, 1, 0x21), |
523 | TWL6030_ADJUSTABLE_LDO(VAUX2_6030, 0x58, 2, 0, 0x21), | 567 | TWL6030_ADJUSTABLE_LDO(VAUX2_6030, 0x58, 1000, 3300, 2, 0x21), |
524 | TWL6030_ADJUSTABLE_LDO(VAUX3_6030, 0x5c, 3, 0, 0x21), | 568 | TWL6030_ADJUSTABLE_LDO(VAUX3_6030, 0x5c, 1000, 3300, 3, 0x21), |
525 | TWL6030_ADJUSTABLE_LDO(VMMC, 0x68, 4, 0, 0x21), | 569 | TWL6030_ADJUSTABLE_LDO(VMMC, 0x68, 1000, 3300, 4, 0x21), |
526 | TWL6030_ADJUSTABLE_LDO(VPP, 0x6c, 5, 0, 0x21), | 570 | TWL6030_ADJUSTABLE_LDO(VPP, 0x6c, 1000, 3300, 5, 0x21), |
527 | TWL6030_ADJUSTABLE_LDO(VUSIM, 0x74, 7, 0, 0x21), | 571 | TWL6030_ADJUSTABLE_LDO(VUSIM, 0x74, 1000, 3300, 7, 0x21), |
528 | TWL6030_FIXED_LDO(VANA, 0x50, 2100, 15, 0, 0x21), | 572 | TWL6030_FIXED_LDO(VANA, 0x50, 2100, 15, 0, 0x21), |
529 | TWL6030_FIXED_LDO(VCXIO, 0x60, 1800, 16, 0, 0x21), | 573 | TWL6030_FIXED_LDO(VCXIO, 0x60, 1800, 16, 0, 0x21), |
530 | TWL6030_FIXED_LDO(VDAC, 0x64, 1800, 17, 0, 0x21), | 574 | TWL6030_FIXED_LDO(VDAC, 0x64, 1800, 17, 0, 0x21), |