diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/regulator/twl-regulator.c | 31 |
1 files changed, 30 insertions, 1 deletions
diff --git a/drivers/regulator/twl-regulator.c b/drivers/regulator/twl-regulator.c index 6a292852a358..2c6660583769 100644 --- a/drivers/regulator/twl-regulator.c +++ b/drivers/regulator/twl-regulator.c | |||
@@ -76,6 +76,11 @@ struct twlreg_info { | |||
76 | #define VREG_BC_PROC 3 | 76 | #define VREG_BC_PROC 3 |
77 | #define VREG_BC_CLK_RST 4 | 77 | #define VREG_BC_CLK_RST 4 |
78 | 78 | ||
79 | /* TWL6030 LDO register values for CFG_STATE */ | ||
80 | #define TWL6030_CFG_STATE_OFF 0x00 | ||
81 | #define TWL6030_CFG_STATE_ON 0x01 | ||
82 | #define TWL6030_CFG_STATE_GRP_SHIFT 5 | ||
83 | |||
79 | static inline int | 84 | static inline int |
80 | twlreg_read(struct twlreg_info *info, unsigned slave_subgp, unsigned offset) | 85 | twlreg_read(struct twlreg_info *info, unsigned slave_subgp, unsigned offset) |
81 | { | 86 | { |
@@ -149,6 +154,11 @@ static int twlreg_enable(struct regulator_dev *rdev) | |||
149 | 154 | ||
150 | ret = twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_GRP, grp); | 155 | ret = twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_GRP, grp); |
151 | 156 | ||
157 | if (!ret && twl_class_is_6030()) | ||
158 | ret = twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_STATE, | ||
159 | grp << TWL6030_CFG_STATE_GRP_SHIFT | | ||
160 | TWL6030_CFG_STATE_ON); | ||
161 | |||
152 | udelay(info->delay); | 162 | udelay(info->delay); |
153 | 163 | ||
154 | return ret; | 164 | return ret; |
@@ -158,17 +168,36 @@ static int twlreg_disable(struct regulator_dev *rdev) | |||
158 | { | 168 | { |
159 | struct twlreg_info *info = rdev_get_drvdata(rdev); | 169 | struct twlreg_info *info = rdev_get_drvdata(rdev); |
160 | int grp; | 170 | int grp; |
171 | int ret; | ||
161 | 172 | ||
162 | grp = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_GRP); | 173 | grp = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_GRP); |
163 | if (grp < 0) | 174 | if (grp < 0) |
164 | return grp; | 175 | return grp; |
165 | 176 | ||
177 | /* For 6030, set the off state for all grps enabled */ | ||
178 | if (twl_class_is_6030()) { | ||
179 | ret = twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_STATE, | ||
180 | (grp & (P1_GRP_6030 | P2_GRP_6030 | P3_GRP_6030)) << | ||
181 | TWL6030_CFG_STATE_GRP_SHIFT | | ||
182 | TWL6030_CFG_STATE_OFF); | ||
183 | if (ret) | ||
184 | return ret; | ||
185 | } | ||
186 | |||
166 | if (twl_class_is_4030()) | 187 | if (twl_class_is_4030()) |
167 | grp &= ~(P1_GRP_4030 | P2_GRP_4030 | P3_GRP_4030); | 188 | grp &= ~(P1_GRP_4030 | P2_GRP_4030 | P3_GRP_4030); |
168 | else | 189 | else |
169 | grp &= ~(P1_GRP_6030 | P2_GRP_6030 | P3_GRP_6030); | 190 | grp &= ~(P1_GRP_6030 | P2_GRP_6030 | P3_GRP_6030); |
170 | 191 | ||
171 | return twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_GRP, grp); | 192 | ret = twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_GRP, grp); |
193 | |||
194 | /* Next, associate cleared grp in state register */ | ||
195 | if (!ret && twl_class_is_6030()) | ||
196 | ret = twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_STATE, | ||
197 | grp << TWL6030_CFG_STATE_GRP_SHIFT | | ||
198 | TWL6030_CFG_STATE_OFF); | ||
199 | |||
200 | return ret; | ||
172 | } | 201 | } |
173 | 202 | ||
174 | static int twlreg_get_status(struct regulator_dev *rdev) | 203 | static int twlreg_get_status(struct regulator_dev *rdev) |