aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/regulator/twl-regulator.c329
1 files changed, 321 insertions, 8 deletions
diff --git a/drivers/regulator/twl-regulator.c b/drivers/regulator/twl-regulator.c
index 4702b8a7e0ef..87fe0f75a56e 100644
--- a/drivers/regulator/twl-regulator.c
+++ b/drivers/regulator/twl-regulator.c
@@ -51,8 +51,13 @@ struct twlreg_info {
51 u16 min_mV; 51 u16 min_mV;
52 u16 max_mV; 52 u16 max_mV;
53 53
54 u8 flags;
55
54 /* used by regulator core */ 56 /* used by regulator core */
55 struct regulator_desc desc; 57 struct regulator_desc desc;
58
59 /* chip specific features */
60 unsigned long features;
56}; 61};
57 62
58 63
@@ -70,6 +75,7 @@ struct twlreg_info {
70#define VREG_TRANS 1 75#define VREG_TRANS 1
71#define VREG_STATE 2 76#define VREG_STATE 2
72#define VREG_VOLTAGE 3 77#define VREG_VOLTAGE 3
78#define VREG_VOLTAGE_SMPS 4
73/* TWL6030 Misc register offsets */ 79/* TWL6030 Misc register offsets */
74#define VREG_BC_ALL 1 80#define VREG_BC_ALL 1
75#define VREG_BC_REF 2 81#define VREG_BC_REF 2
@@ -87,6 +93,17 @@ struct twlreg_info {
87#define TWL6030_CFG_STATE_APP(v) (((v) & TWL6030_CFG_STATE_APP_MASK) >>\ 93#define TWL6030_CFG_STATE_APP(v) (((v) & TWL6030_CFG_STATE_APP_MASK) >>\
88 TWL6030_CFG_STATE_APP_SHIFT) 94 TWL6030_CFG_STATE_APP_SHIFT)
89 95
96/* Flags for SMPS Voltage reading */
97#define SMPS_OFFSET_EN BIT(0)
98#define SMPS_EXTENDED_EN BIT(1)
99
100/* twl6025 SMPS EPROM values */
101#define TWL6030_SMPS_OFFSET 0xB0
102#define TWL6030_SMPS_MULT 0xB3
103#define SMPS_MULTOFFSET_SMPS4 BIT(0)
104#define SMPS_MULTOFFSET_VIO BIT(1)
105#define SMPS_MULTOFFSET_SMPS3 BIT(6)
106
90static inline int 107static inline int
91twlreg_read(struct twlreg_info *info, unsigned slave_subgp, unsigned offset) 108twlreg_read(struct twlreg_info *info, unsigned slave_subgp, unsigned offset)
92{ 109{
@@ -142,13 +159,17 @@ static int twl4030reg_is_enabled(struct regulator_dev *rdev)
142static int twl6030reg_is_enabled(struct regulator_dev *rdev) 159static int twl6030reg_is_enabled(struct regulator_dev *rdev)
143{ 160{
144 struct twlreg_info *info = rdev_get_drvdata(rdev); 161 struct twlreg_info *info = rdev_get_drvdata(rdev);
145 int grp, val; 162 int grp = 0, val;
146 163
147 grp = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_GRP); 164 if (!(twl_class_is_6030() && (info->features & TWL6025_SUBCLASS)))
165 grp = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_GRP);
148 if (grp < 0) 166 if (grp < 0)
149 return grp; 167 return grp;
150 168
151 grp &= P1_GRP_6030; 169 if (!(twl_class_is_6030() && (info->features & TWL6025_SUBCLASS)))
170 grp &= P1_GRP_6030;
171 else
172 grp = 1;
152 173
153 val = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_STATE); 174 val = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_STATE);
154 val = TWL6030_CFG_STATE_APP(val); 175 val = TWL6030_CFG_STATE_APP(val);
@@ -178,10 +199,11 @@ static int twl4030reg_enable(struct regulator_dev *rdev)
178static int twl6030reg_enable(struct regulator_dev *rdev) 199static int twl6030reg_enable(struct regulator_dev *rdev)
179{ 200{
180 struct twlreg_info *info = rdev_get_drvdata(rdev); 201 struct twlreg_info *info = rdev_get_drvdata(rdev);
181 int grp; 202 int grp = 0;
182 int ret; 203 int ret;
183 204
184 grp = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_GRP); 205 if (!(twl_class_is_6030() && (info->features & TWL6025_SUBCLASS)))
206 grp = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_GRP);
185 if (grp < 0) 207 if (grp < 0)
186 return grp; 208 return grp;
187 209
@@ -217,7 +239,8 @@ static int twl6030reg_disable(struct regulator_dev *rdev)
217 int grp = 0; 239 int grp = 0;
218 int ret; 240 int ret;
219 241
220 grp = P1_GRP_6030 | P2_GRP_6030 | P3_GRP_6030; 242 if (!(twl_class_is_6030() && (info->features & TWL6025_SUBCLASS)))
243 grp = P1_GRP_6030 | P2_GRP_6030 | P3_GRP_6030;
221 244
222 /* For 6030, set the off state for all grps enabled */ 245 /* For 6030, set the off state for all grps enabled */
223 ret = twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_STATE, 246 ret = twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_STATE,
@@ -307,10 +330,11 @@ static int twl4030reg_set_mode(struct regulator_dev *rdev, unsigned mode)
307static int twl6030reg_set_mode(struct regulator_dev *rdev, unsigned mode) 330static int twl6030reg_set_mode(struct regulator_dev *rdev, unsigned mode)
308{ 331{
309 struct twlreg_info *info = rdev_get_drvdata(rdev); 332 struct twlreg_info *info = rdev_get_drvdata(rdev);
310 int grp; 333 int grp = 0;
311 int val; 334 int val;
312 335
313 grp = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_GRP); 336 if (!(twl_class_is_6030() && (info->features & TWL6025_SUBCLASS)))
337 grp = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_GRP);
314 338
315 if (grp < 0) 339 if (grp < 0)
316 return grp; 340 return grp;
@@ -602,6 +626,209 @@ static struct regulator_ops twl6030_fixed_resource = {
602 .get_status = twl6030reg_get_status, 626 .get_status = twl6030reg_get_status,
603}; 627};
604 628
629/*
630 * SMPS status and control
631 */
632
633static int twl6030smps_list_voltage(struct regulator_dev *rdev, unsigned index)
634{
635 struct twlreg_info *info = rdev_get_drvdata(rdev);
636
637 int voltage = 0;
638
639 switch (info->flags) {
640 case SMPS_OFFSET_EN:
641 voltage = 100000;
642 /* fall through */
643 case 0:
644 switch (index) {
645 case 0:
646 voltage = 0;
647 break;
648 case 58:
649 voltage = 1350 * 1000;
650 break;
651 case 59:
652 voltage = 1500 * 1000;
653 break;
654 case 60:
655 voltage = 1800 * 1000;
656 break;
657 case 61:
658 voltage = 1900 * 1000;
659 break;
660 case 62:
661 voltage = 2100 * 1000;
662 break;
663 default:
664 voltage += (600000 + (12500 * (index - 1)));
665 }
666 break;
667 case SMPS_EXTENDED_EN:
668 switch (index) {
669 case 0:
670 voltage = 0;
671 break;
672 case 58:
673 voltage = 2084 * 1000;
674 break;
675 case 59:
676 voltage = 2315 * 1000;
677 break;
678 case 60:
679 voltage = 2778 * 1000;
680 break;
681 case 61:
682 voltage = 2932 * 1000;
683 break;
684 case 62:
685 voltage = 3241 * 1000;
686 break;
687 default:
688 voltage = (1852000 + (38600 * (index - 1)));
689 }
690 break;
691 case SMPS_OFFSET_EN | SMPS_EXTENDED_EN:
692 switch (index) {
693 case 0:
694 voltage = 0;
695 break;
696 case 58:
697 voltage = 4167 * 1000;
698 break;
699 case 59:
700 voltage = 2315 * 1000;
701 break;
702 case 60:
703 voltage = 2778 * 1000;
704 break;
705 case 61:
706 voltage = 2932 * 1000;
707 break;
708 case 62:
709 voltage = 3241 * 1000;
710 break;
711 default:
712 voltage = (2161000 + (38600 * (index - 1)));
713 }
714 break;
715 }
716
717 return voltage;
718}
719
720static int
721twl6030smps_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV,
722 unsigned int *selector)
723{
724 struct twlreg_info *info = rdev_get_drvdata(rdev);
725 int vsel = 0;
726
727 switch (info->flags) {
728 case 0:
729 if (min_uV == 0)
730 vsel = 0;
731 else if ((min_uV >= 600000) && (max_uV <= 1300000)) {
732 vsel = (min_uV - 600000) / 125;
733 if (vsel % 100)
734 vsel += 100;
735 vsel /= 100;
736 vsel++;
737 }
738 /* Values 1..57 for vsel are linear and can be calculated
739 * values 58..62 are non linear.
740 */
741 else if ((min_uV > 1900000) && (max_uV >= 2100000))
742 vsel = 62;
743 else if ((min_uV > 1800000) && (max_uV >= 1900000))
744 vsel = 61;
745 else if ((min_uV > 1500000) && (max_uV >= 1800000))
746 vsel = 60;
747 else if ((min_uV > 1350000) && (max_uV >= 1500000))
748 vsel = 59;
749 else if ((min_uV > 1300000) && (max_uV >= 1350000))
750 vsel = 58;
751 else
752 return -EINVAL;
753 break;
754 case SMPS_OFFSET_EN:
755 if (min_uV == 0)
756 vsel = 0;
757 else if ((min_uV >= 700000) && (max_uV <= 1420000)) {
758 vsel = (min_uV - 700000) / 125;
759 if (vsel % 100)
760 vsel += 100;
761 vsel /= 100;
762 vsel++;
763 }
764 /* Values 1..57 for vsel are linear and can be calculated
765 * values 58..62 are non linear.
766 */
767 else if ((min_uV > 1900000) && (max_uV >= 2100000))
768 vsel = 62;
769 else if ((min_uV > 1800000) && (max_uV >= 1900000))
770 vsel = 61;
771 else if ((min_uV > 1350000) && (max_uV >= 1800000))
772 vsel = 60;
773 else if ((min_uV > 1350000) && (max_uV >= 1500000))
774 vsel = 59;
775 else if ((min_uV > 1300000) && (max_uV >= 1350000))
776 vsel = 58;
777 else
778 return -EINVAL;
779 break;
780 case SMPS_EXTENDED_EN:
781 if (min_uV == 0)
782 vsel = 0;
783 else if ((min_uV >= 1852000) && (max_uV <= 4013600)) {
784 vsel = (min_uV - 1852000) / 386;
785 if (vsel % 100)
786 vsel += 100;
787 vsel /= 100;
788 vsel++;
789 }
790 break;
791 case SMPS_OFFSET_EN|SMPS_EXTENDED_EN:
792 if (min_uV == 0)
793 vsel = 0;
794 else if ((min_uV >= 2161000) && (max_uV <= 4321000)) {
795 vsel = (min_uV - 1852000) / 386;
796 if (vsel % 100)
797 vsel += 100;
798 vsel /= 100;
799 vsel++;
800 }
801 break;
802 }
803
804 *selector = vsel;
805
806 return twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_VOLTAGE_SMPS,
807 vsel);
808}
809
810static int twl6030smps_get_voltage_sel(struct regulator_dev *rdev)
811{
812 struct twlreg_info *info = rdev_get_drvdata(rdev);
813
814 return twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_VOLTAGE_SMPS);
815}
816
817static struct regulator_ops twlsmps_ops = {
818 .list_voltage = twl6030smps_list_voltage,
819
820 .set_voltage = twl6030smps_set_voltage,
821 .get_voltage_sel = twl6030smps_get_voltage_sel,
822
823 .enable = twl6030reg_enable,
824 .disable = twl6030reg_disable,
825 .is_enabled = twl6030reg_is_enabled,
826
827 .set_mode = twl6030reg_set_mode,
828
829 .get_status = twl6030reg_get_status,
830};
831
605/*----------------------------------------------------------------------*/ 832/*----------------------------------------------------------------------*/
606 833
607#define TWL4030_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \ 834#define TWL4030_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \
@@ -644,6 +871,20 @@ static struct regulator_ops twl6030_fixed_resource = {
644 }, \ 871 }, \
645 } 872 }
646 873
874#define TWL6025_ADJUSTABLE_LDO(label, offset, min_mVolts, max_mVolts, num) { \
875 .base = offset, \
876 .id = num, \
877 .min_mV = min_mVolts, \
878 .max_mV = max_mVolts, \
879 .desc = { \
880 .name = #label, \
881 .id = TWL6025_REG_##label, \
882 .n_voltages = ((max_mVolts - min_mVolts)/100) + 1, \
883 .ops = &twl6030ldo_ops, \
884 .type = REGULATOR_VOLTAGE, \
885 .owner = THIS_MODULE, \
886 }, \
887 }
647 888
648#define TWL_FIXED_LDO(label, offset, mVolts, num, turnon_delay, remap_conf, \ 889#define TWL_FIXED_LDO(label, offset, mVolts, num, turnon_delay, remap_conf, \
649 family, operations) { \ 890 family, operations) { \
@@ -675,6 +916,21 @@ static struct regulator_ops twl6030_fixed_resource = {
675 }, \ 916 }, \
676 } 917 }
677 918
919#define TWL6025_ADJUSTABLE_SMPS(label, offset, num) { \
920 .base = offset, \
921 .id = num, \
922 .min_mV = 600, \
923 .max_mV = 2100, \
924 .desc = { \
925 .name = #label, \
926 .id = TWL6025_REG_##label, \
927 .n_voltages = 63, \
928 .ops = &twlsmps_ops, \
929 .type = REGULATOR_VOLTAGE, \
930 .owner = THIS_MODULE, \
931 }, \
932 }
933
678/* 934/*
679 * We list regulators here if systems need some level of 935 * We list regulators here if systems need some level of
680 * software control over them after boot. 936 * software control over them after boot.
@@ -716,8 +972,41 @@ static struct twlreg_info twl_regs[] = {
716 TWL6030_FIXED_LDO(VDAC, 0x64, 1800, 17, 0), 972 TWL6030_FIXED_LDO(VDAC, 0x64, 1800, 17, 0),
717 TWL6030_FIXED_LDO(VUSB, 0x70, 3300, 18, 0), 973 TWL6030_FIXED_LDO(VUSB, 0x70, 3300, 18, 0),
718 TWL6030_FIXED_RESOURCE(CLK32KG, 0x8C, 48, 0), 974 TWL6030_FIXED_RESOURCE(CLK32KG, 0x8C, 48, 0),
975
976 /* 6025 are renamed compared to 6030 versions */
977 TWL6025_ADJUSTABLE_LDO(LDO2, 0x54, 1000, 3300, 1),
978 TWL6025_ADJUSTABLE_LDO(LDO4, 0x58, 1000, 3300, 2),
979 TWL6025_ADJUSTABLE_LDO(LDO3, 0x5c, 1000, 3300, 3),
980 TWL6025_ADJUSTABLE_LDO(LDO5, 0x68, 1000, 3300, 4),
981 TWL6025_ADJUSTABLE_LDO(LDO1, 0x6c, 1000, 3300, 5),
982 TWL6025_ADJUSTABLE_LDO(LDO7, 0x74, 1000, 3300, 7),
983 TWL6025_ADJUSTABLE_LDO(LDO6, 0x60, 1000, 3300, 16),
984 TWL6025_ADJUSTABLE_LDO(LDOLN, 0x64, 1000, 3300, 17),
985 TWL6025_ADJUSTABLE_LDO(LDOUSB, 0x70, 1000, 3300, 18),
986
987 TWL6025_ADJUSTABLE_SMPS(SMPS3, 0x34, 1),
988 TWL6025_ADJUSTABLE_SMPS(SMPS4, 0x10, 2),
989 TWL6025_ADJUSTABLE_SMPS(VIO, 0x16, 3),
719}; 990};
720 991
992static u8 twl_get_smps_offset(void)
993{
994 u8 value;
995
996 twl_i2c_read_u8(TWL_MODULE_PM_RECEIVER, &value,
997 TWL6030_SMPS_OFFSET);
998 return value;
999}
1000
1001static u8 twl_get_smps_mult(void)
1002{
1003 u8 value;
1004
1005 twl_i2c_read_u8(TWL_MODULE_PM_RECEIVER, &value,
1006 TWL6030_SMPS_MULT);
1007 return value;
1008}
1009
721static int __devinit twlreg_probe(struct platform_device *pdev) 1010static int __devinit twlreg_probe(struct platform_device *pdev)
722{ 1011{
723 int i; 1012 int i;
@@ -739,6 +1028,9 @@ static int __devinit twlreg_probe(struct platform_device *pdev)
739 if (!initdata) 1028 if (!initdata)
740 return -EINVAL; 1029 return -EINVAL;
741 1030
1031 /* copy the features into regulator data */
1032 info->features = (unsigned long)initdata->driver_data;
1033
742 /* Constrain board-specific capabilities according to what 1034 /* Constrain board-specific capabilities according to what
743 * this driver and the chip itself can actually do. 1035 * this driver and the chip itself can actually do.
744 */ 1036 */
@@ -761,6 +1053,27 @@ static int __devinit twlreg_probe(struct platform_device *pdev)
761 break; 1053 break;
762 } 1054 }
763 1055
1056 switch (pdev->id) {
1057 case TWL6025_REG_SMPS3:
1058 if (twl_get_smps_mult() & SMPS_MULTOFFSET_SMPS3)
1059 info->flags |= SMPS_EXTENDED_EN;
1060 if (twl_get_smps_offset() & SMPS_MULTOFFSET_SMPS3)
1061 info->flags |= SMPS_OFFSET_EN;
1062 break;
1063 case TWL6025_REG_SMPS4:
1064 if (twl_get_smps_mult() & SMPS_MULTOFFSET_SMPS4)
1065 info->flags |= SMPS_EXTENDED_EN;
1066 if (twl_get_smps_offset() & SMPS_MULTOFFSET_SMPS4)
1067 info->flags |= SMPS_OFFSET_EN;
1068 break;
1069 case TWL6025_REG_VIO:
1070 if (twl_get_smps_mult() & SMPS_MULTOFFSET_VIO)
1071 info->flags |= SMPS_EXTENDED_EN;
1072 if (twl_get_smps_offset() & SMPS_MULTOFFSET_VIO)
1073 info->flags |= SMPS_OFFSET_EN;
1074 break;
1075 }
1076
764 rdev = regulator_register(&info->desc, &pdev->dev, initdata, info); 1077 rdev = regulator_register(&info->desc, &pdev->dev, initdata, info);
765 if (IS_ERR(rdev)) { 1078 if (IS_ERR(rdev)) {
766 dev_err(&pdev->dev, "can't register %s, %ld\n", 1079 dev_err(&pdev->dev, "can't register %s, %ld\n",