Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

regulator: twl: fix twl4030 support for smps regulators

SMPS regulator voltage control differs from the one of the LDO ones.
Current TWL code was using LDO regulator ops for controlling the SMPS
regulators, which fails. This was fixed fixed by adding separate
regulator type which uses correct logic and calculations for the
voltage levels.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Cc: stable@kernel.org

authored by

Tero Kristo and committed by
Mark Brown
ba305e31 58fb5cf5

+44 -2
+44 -2
drivers/regulator/twl-regulator.c
··· 71 71 #define VREG_TYPE 1 72 72 #define VREG_REMAP 2 73 73 #define VREG_DEDICATED 3 /* LDO control */ 74 + #define VREG_VOLTAGE_SMPS_4030 9 74 75 /* TWL6030 register offsets */ 75 76 #define VREG_TRANS 1 76 77 #define VREG_STATE 2 ··· 515 514 .get_status = twl4030reg_get_status, 516 515 }; 517 516 517 + static int 518 + twl4030smps_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV, 519 + unsigned *selector) 520 + { 521 + struct twlreg_info *info = rdev_get_drvdata(rdev); 522 + int vsel = DIV_ROUND_UP(min_uV - 600000, 12500); 523 + 524 + twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_VOLTAGE_SMPS_4030, 525 + vsel); 526 + return 0; 527 + } 528 + 529 + static int twl4030smps_get_voltage(struct regulator_dev *rdev) 530 + { 531 + struct twlreg_info *info = rdev_get_drvdata(rdev); 532 + int vsel = twlreg_read(info, TWL_MODULE_PM_RECEIVER, 533 + VREG_VOLTAGE_SMPS_4030); 534 + 535 + return vsel * 12500 + 600000; 536 + } 537 + 538 + static struct regulator_ops twl4030smps_ops = { 539 + .set_voltage = twl4030smps_set_voltage, 540 + .get_voltage = twl4030smps_get_voltage, 541 + }; 542 + 518 543 static int twl6030ldo_list_voltage(struct regulator_dev *rdev, unsigned index) 519 544 { 520 545 struct twlreg_info *info = rdev_get_drvdata(rdev); ··· 883 856 }, \ 884 857 } 885 858 859 + #define TWL4030_ADJUSTABLE_SMPS(label, offset, num, turnon_delay, remap_conf) \ 860 + { \ 861 + .base = offset, \ 862 + .id = num, \ 863 + .delay = turnon_delay, \ 864 + .remap = remap_conf, \ 865 + .desc = { \ 866 + .name = #label, \ 867 + .id = TWL4030_REG_##label, \ 868 + .ops = &twl4030smps_ops, \ 869 + .type = REGULATOR_VOLTAGE, \ 870 + .owner = THIS_MODULE, \ 871 + }, \ 872 + } 873 + 886 874 #define TWL6030_ADJUSTABLE_LDO(label, offset, min_mVolts, max_mVolts) { \ 887 875 .base = offset, \ 888 876 .min_mV = min_mVolts, \ ··· 989 947 TWL4030_ADJUSTABLE_LDO(VINTANA2, 0x43, 12, 100, 0x08), 990 948 TWL4030_FIXED_LDO(VINTDIG, 0x47, 1500, 13, 100, 0x08), 991 949 TWL4030_ADJUSTABLE_LDO(VIO, 0x4b, 14, 1000, 0x08), 992 - TWL4030_ADJUSTABLE_LDO(VDD1, 0x55, 15, 1000, 0x08), 993 - TWL4030_ADJUSTABLE_LDO(VDD2, 0x63, 16, 1000, 0x08), 950 + TWL4030_ADJUSTABLE_SMPS(VDD1, 0x55, 15, 1000, 0x08), 951 + TWL4030_ADJUSTABLE_SMPS(VDD2, 0x63, 16, 1000, 0x08), 994 952 TWL4030_FIXED_LDO(VUSB1V5, 0x71, 1500, 17, 100, 0x08), 995 953 TWL4030_FIXED_LDO(VUSB1V8, 0x74, 1800, 18, 100, 0x08), 996 954 TWL4030_FIXED_LDO(VUSB3V1, 0x77, 3100, 19, 150, 0x08),