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