diff options
-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), |