diff options
author | Jiri Kosina <jkosina@suse.cz> | 2012-04-08 15:48:52 -0400 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2012-04-08 15:48:52 -0400 |
commit | e75d660672ddd11704b7f0fdb8ff21968587b266 (patch) | |
tree | ccb9c107744c10b553c0373e450bee3971d16c00 /drivers/regulator/tps65910-regulator.c | |
parent | 61282f37927143e45b03153f3e7b48d6b702147a (diff) | |
parent | 0034102808e0dbbf3a2394b82b1bb40b5778de9e (diff) |
Merge branch 'master' into for-next
Merge with latest Linus' tree, as I have incoming patches
that fix code that is newer than current HEAD of for-next.
Conflicts:
drivers/net/ethernet/realtek/r8169.c
Diffstat (limited to 'drivers/regulator/tps65910-regulator.c')
-rw-r--r-- | drivers/regulator/tps65910-regulator.c | 400 |
1 files changed, 345 insertions, 55 deletions
diff --git a/drivers/regulator/tps65910-regulator.c b/drivers/regulator/tps65910-regulator.c index 1711dbf28ea5..5478bf10cbfc 100644 --- a/drivers/regulator/tps65910-regulator.c +++ b/drivers/regulator/tps65910-regulator.c | |||
@@ -26,6 +26,10 @@ | |||
26 | #include <linux/mfd/tps65910.h> | 26 | #include <linux/mfd/tps65910.h> |
27 | 27 | ||
28 | #define TPS65910_SUPPLY_STATE_ENABLED 0x1 | 28 | #define TPS65910_SUPPLY_STATE_ENABLED 0x1 |
29 | #define EXT_SLEEP_CONTROL (TPS65910_SLEEP_CONTROL_EXT_INPUT_EN1 | \ | ||
30 | TPS65910_SLEEP_CONTROL_EXT_INPUT_EN2 | \ | ||
31 | TPS65910_SLEEP_CONTROL_EXT_INPUT_EN3 | \ | ||
32 | TPS65911_SLEEP_CONTROL_EXT_INPUT_SLEEP) | ||
29 | 33 | ||
30 | /* supported VIO voltages in millivolts */ | 34 | /* supported VIO voltages in millivolts */ |
31 | static const u16 VIO_VSEL_table[] = { | 35 | static const u16 VIO_VSEL_table[] = { |
@@ -83,161 +87,235 @@ struct tps_info { | |||
83 | const char *name; | 87 | const char *name; |
84 | unsigned min_uV; | 88 | unsigned min_uV; |
85 | unsigned max_uV; | 89 | unsigned max_uV; |
86 | u8 table_len; | 90 | u8 n_voltages; |
87 | const u16 *table; | 91 | const u16 *voltage_table; |
92 | int enable_time_us; | ||
88 | }; | 93 | }; |
89 | 94 | ||
90 | static struct tps_info tps65910_regs[] = { | 95 | static struct tps_info tps65910_regs[] = { |
91 | { | 96 | { |
92 | .name = "VRTC", | 97 | .name = "VRTC", |
98 | .enable_time_us = 2200, | ||
93 | }, | 99 | }, |
94 | { | 100 | { |
95 | .name = "VIO", | 101 | .name = "VIO", |
96 | .min_uV = 1500000, | 102 | .min_uV = 1500000, |
97 | .max_uV = 3300000, | 103 | .max_uV = 3300000, |
98 | .table_len = ARRAY_SIZE(VIO_VSEL_table), | 104 | .n_voltages = ARRAY_SIZE(VIO_VSEL_table), |
99 | .table = VIO_VSEL_table, | 105 | .voltage_table = VIO_VSEL_table, |
106 | .enable_time_us = 350, | ||
100 | }, | 107 | }, |
101 | { | 108 | { |
102 | .name = "VDD1", | 109 | .name = "VDD1", |
103 | .min_uV = 600000, | 110 | .min_uV = 600000, |
104 | .max_uV = 4500000, | 111 | .max_uV = 4500000, |
112 | .enable_time_us = 350, | ||
105 | }, | 113 | }, |
106 | { | 114 | { |
107 | .name = "VDD2", | 115 | .name = "VDD2", |
108 | .min_uV = 600000, | 116 | .min_uV = 600000, |
109 | .max_uV = 4500000, | 117 | .max_uV = 4500000, |
118 | .enable_time_us = 350, | ||
110 | }, | 119 | }, |
111 | { | 120 | { |
112 | .name = "VDD3", | 121 | .name = "VDD3", |
113 | .min_uV = 5000000, | 122 | .min_uV = 5000000, |
114 | .max_uV = 5000000, | 123 | .max_uV = 5000000, |
115 | .table_len = ARRAY_SIZE(VDD3_VSEL_table), | 124 | .n_voltages = ARRAY_SIZE(VDD3_VSEL_table), |
116 | .table = VDD3_VSEL_table, | 125 | .voltage_table = VDD3_VSEL_table, |
126 | .enable_time_us = 200, | ||
117 | }, | 127 | }, |
118 | { | 128 | { |
119 | .name = "VDIG1", | 129 | .name = "VDIG1", |
120 | .min_uV = 1200000, | 130 | .min_uV = 1200000, |
121 | .max_uV = 2700000, | 131 | .max_uV = 2700000, |
122 | .table_len = ARRAY_SIZE(VDIG1_VSEL_table), | 132 | .n_voltages = ARRAY_SIZE(VDIG1_VSEL_table), |
123 | .table = VDIG1_VSEL_table, | 133 | .voltage_table = VDIG1_VSEL_table, |
134 | .enable_time_us = 100, | ||
124 | }, | 135 | }, |
125 | { | 136 | { |
126 | .name = "VDIG2", | 137 | .name = "VDIG2", |
127 | .min_uV = 1000000, | 138 | .min_uV = 1000000, |
128 | .max_uV = 1800000, | 139 | .max_uV = 1800000, |
129 | .table_len = ARRAY_SIZE(VDIG2_VSEL_table), | 140 | .n_voltages = ARRAY_SIZE(VDIG2_VSEL_table), |
130 | .table = VDIG2_VSEL_table, | 141 | .voltage_table = VDIG2_VSEL_table, |
142 | .enable_time_us = 100, | ||
131 | }, | 143 | }, |
132 | { | 144 | { |
133 | .name = "VPLL", | 145 | .name = "VPLL", |
134 | .min_uV = 1000000, | 146 | .min_uV = 1000000, |
135 | .max_uV = 2500000, | 147 | .max_uV = 2500000, |
136 | .table_len = ARRAY_SIZE(VPLL_VSEL_table), | 148 | .n_voltages = ARRAY_SIZE(VPLL_VSEL_table), |
137 | .table = VPLL_VSEL_table, | 149 | .voltage_table = VPLL_VSEL_table, |
150 | .enable_time_us = 100, | ||
138 | }, | 151 | }, |
139 | { | 152 | { |
140 | .name = "VDAC", | 153 | .name = "VDAC", |
141 | .min_uV = 1800000, | 154 | .min_uV = 1800000, |
142 | .max_uV = 2850000, | 155 | .max_uV = 2850000, |
143 | .table_len = ARRAY_SIZE(VDAC_VSEL_table), | 156 | .n_voltages = ARRAY_SIZE(VDAC_VSEL_table), |
144 | .table = VDAC_VSEL_table, | 157 | .voltage_table = VDAC_VSEL_table, |
158 | .enable_time_us = 100, | ||
145 | }, | 159 | }, |
146 | { | 160 | { |
147 | .name = "VAUX1", | 161 | .name = "VAUX1", |
148 | .min_uV = 1800000, | 162 | .min_uV = 1800000, |
149 | .max_uV = 2850000, | 163 | .max_uV = 2850000, |
150 | .table_len = ARRAY_SIZE(VAUX1_VSEL_table), | 164 | .n_voltages = ARRAY_SIZE(VAUX1_VSEL_table), |
151 | .table = VAUX1_VSEL_table, | 165 | .voltage_table = VAUX1_VSEL_table, |
166 | .enable_time_us = 100, | ||
152 | }, | 167 | }, |
153 | { | 168 | { |
154 | .name = "VAUX2", | 169 | .name = "VAUX2", |
155 | .min_uV = 1800000, | 170 | .min_uV = 1800000, |
156 | .max_uV = 3300000, | 171 | .max_uV = 3300000, |
157 | .table_len = ARRAY_SIZE(VAUX2_VSEL_table), | 172 | .n_voltages = ARRAY_SIZE(VAUX2_VSEL_table), |
158 | .table = VAUX2_VSEL_table, | 173 | .voltage_table = VAUX2_VSEL_table, |
174 | .enable_time_us = 100, | ||
159 | }, | 175 | }, |
160 | { | 176 | { |
161 | .name = "VAUX33", | 177 | .name = "VAUX33", |
162 | .min_uV = 1800000, | 178 | .min_uV = 1800000, |
163 | .max_uV = 3300000, | 179 | .max_uV = 3300000, |
164 | .table_len = ARRAY_SIZE(VAUX33_VSEL_table), | 180 | .n_voltages = ARRAY_SIZE(VAUX33_VSEL_table), |
165 | .table = VAUX33_VSEL_table, | 181 | .voltage_table = VAUX33_VSEL_table, |
182 | .enable_time_us = 100, | ||
166 | }, | 183 | }, |
167 | { | 184 | { |
168 | .name = "VMMC", | 185 | .name = "VMMC", |
169 | .min_uV = 1800000, | 186 | .min_uV = 1800000, |
170 | .max_uV = 3300000, | 187 | .max_uV = 3300000, |
171 | .table_len = ARRAY_SIZE(VMMC_VSEL_table), | 188 | .n_voltages = ARRAY_SIZE(VMMC_VSEL_table), |
172 | .table = VMMC_VSEL_table, | 189 | .voltage_table = VMMC_VSEL_table, |
190 | .enable_time_us = 100, | ||
173 | }, | 191 | }, |
174 | }; | 192 | }; |
175 | 193 | ||
176 | static struct tps_info tps65911_regs[] = { | 194 | static struct tps_info tps65911_regs[] = { |
177 | { | 195 | { |
196 | .name = "VRTC", | ||
197 | .enable_time_us = 2200, | ||
198 | }, | ||
199 | { | ||
178 | .name = "VIO", | 200 | .name = "VIO", |
179 | .min_uV = 1500000, | 201 | .min_uV = 1500000, |
180 | .max_uV = 3300000, | 202 | .max_uV = 3300000, |
181 | .table_len = ARRAY_SIZE(VIO_VSEL_table), | 203 | .n_voltages = ARRAY_SIZE(VIO_VSEL_table), |
182 | .table = VIO_VSEL_table, | 204 | .voltage_table = VIO_VSEL_table, |
205 | .enable_time_us = 350, | ||
183 | }, | 206 | }, |
184 | { | 207 | { |
185 | .name = "VDD1", | 208 | .name = "VDD1", |
186 | .min_uV = 600000, | 209 | .min_uV = 600000, |
187 | .max_uV = 4500000, | 210 | .max_uV = 4500000, |
211 | .n_voltages = 73, | ||
212 | .enable_time_us = 350, | ||
188 | }, | 213 | }, |
189 | { | 214 | { |
190 | .name = "VDD2", | 215 | .name = "VDD2", |
191 | .min_uV = 600000, | 216 | .min_uV = 600000, |
192 | .max_uV = 4500000, | 217 | .max_uV = 4500000, |
218 | .n_voltages = 73, | ||
219 | .enable_time_us = 350, | ||
193 | }, | 220 | }, |
194 | { | 221 | { |
195 | .name = "VDDCTRL", | 222 | .name = "VDDCTRL", |
196 | .min_uV = 600000, | 223 | .min_uV = 600000, |
197 | .max_uV = 1400000, | 224 | .max_uV = 1400000, |
225 | .n_voltages = 65, | ||
226 | .enable_time_us = 900, | ||
198 | }, | 227 | }, |
199 | { | 228 | { |
200 | .name = "LDO1", | 229 | .name = "LDO1", |
201 | .min_uV = 1000000, | 230 | .min_uV = 1000000, |
202 | .max_uV = 3300000, | 231 | .max_uV = 3300000, |
232 | .n_voltages = 47, | ||
233 | .enable_time_us = 420, | ||
203 | }, | 234 | }, |
204 | { | 235 | { |
205 | .name = "LDO2", | 236 | .name = "LDO2", |
206 | .min_uV = 1000000, | 237 | .min_uV = 1000000, |
207 | .max_uV = 3300000, | 238 | .max_uV = 3300000, |
239 | .n_voltages = 47, | ||
240 | .enable_time_us = 420, | ||
208 | }, | 241 | }, |
209 | { | 242 | { |
210 | .name = "LDO3", | 243 | .name = "LDO3", |
211 | .min_uV = 1000000, | 244 | .min_uV = 1000000, |
212 | .max_uV = 3300000, | 245 | .max_uV = 3300000, |
246 | .n_voltages = 24, | ||
247 | .enable_time_us = 230, | ||
213 | }, | 248 | }, |
214 | { | 249 | { |
215 | .name = "LDO4", | 250 | .name = "LDO4", |
216 | .min_uV = 1000000, | 251 | .min_uV = 1000000, |
217 | .max_uV = 3300000, | 252 | .max_uV = 3300000, |
253 | .n_voltages = 47, | ||
254 | .enable_time_us = 230, | ||
218 | }, | 255 | }, |
219 | { | 256 | { |
220 | .name = "LDO5", | 257 | .name = "LDO5", |
221 | .min_uV = 1000000, | 258 | .min_uV = 1000000, |
222 | .max_uV = 3300000, | 259 | .max_uV = 3300000, |
260 | .n_voltages = 24, | ||
261 | .enable_time_us = 230, | ||
223 | }, | 262 | }, |
224 | { | 263 | { |
225 | .name = "LDO6", | 264 | .name = "LDO6", |
226 | .min_uV = 1000000, | 265 | .min_uV = 1000000, |
227 | .max_uV = 3300000, | 266 | .max_uV = 3300000, |
267 | .n_voltages = 24, | ||
268 | .enable_time_us = 230, | ||
228 | }, | 269 | }, |
229 | { | 270 | { |
230 | .name = "LDO7", | 271 | .name = "LDO7", |
231 | .min_uV = 1000000, | 272 | .min_uV = 1000000, |
232 | .max_uV = 3300000, | 273 | .max_uV = 3300000, |
274 | .n_voltages = 24, | ||
275 | .enable_time_us = 230, | ||
233 | }, | 276 | }, |
234 | { | 277 | { |
235 | .name = "LDO8", | 278 | .name = "LDO8", |
236 | .min_uV = 1000000, | 279 | .min_uV = 1000000, |
237 | .max_uV = 3300000, | 280 | .max_uV = 3300000, |
281 | .n_voltages = 24, | ||
282 | .enable_time_us = 230, | ||
238 | }, | 283 | }, |
239 | }; | 284 | }; |
240 | 285 | ||
286 | #define EXT_CONTROL_REG_BITS(id, regs_offs, bits) (((regs_offs) << 8) | (bits)) | ||
287 | static unsigned int tps65910_ext_sleep_control[] = { | ||
288 | 0, | ||
289 | EXT_CONTROL_REG_BITS(VIO, 1, 0), | ||
290 | EXT_CONTROL_REG_BITS(VDD1, 1, 1), | ||
291 | EXT_CONTROL_REG_BITS(VDD2, 1, 2), | ||
292 | EXT_CONTROL_REG_BITS(VDD3, 1, 3), | ||
293 | EXT_CONTROL_REG_BITS(VDIG1, 0, 1), | ||
294 | EXT_CONTROL_REG_BITS(VDIG2, 0, 2), | ||
295 | EXT_CONTROL_REG_BITS(VPLL, 0, 6), | ||
296 | EXT_CONTROL_REG_BITS(VDAC, 0, 7), | ||
297 | EXT_CONTROL_REG_BITS(VAUX1, 0, 3), | ||
298 | EXT_CONTROL_REG_BITS(VAUX2, 0, 4), | ||
299 | EXT_CONTROL_REG_BITS(VAUX33, 0, 5), | ||
300 | EXT_CONTROL_REG_BITS(VMMC, 0, 0), | ||
301 | }; | ||
302 | |||
303 | static unsigned int tps65911_ext_sleep_control[] = { | ||
304 | 0, | ||
305 | EXT_CONTROL_REG_BITS(VIO, 1, 0), | ||
306 | EXT_CONTROL_REG_BITS(VDD1, 1, 1), | ||
307 | EXT_CONTROL_REG_BITS(VDD2, 1, 2), | ||
308 | EXT_CONTROL_REG_BITS(VDDCTRL, 1, 3), | ||
309 | EXT_CONTROL_REG_BITS(LDO1, 0, 1), | ||
310 | EXT_CONTROL_REG_BITS(LDO2, 0, 2), | ||
311 | EXT_CONTROL_REG_BITS(LDO3, 0, 7), | ||
312 | EXT_CONTROL_REG_BITS(LDO4, 0, 6), | ||
313 | EXT_CONTROL_REG_BITS(LDO5, 0, 3), | ||
314 | EXT_CONTROL_REG_BITS(LDO6, 0, 0), | ||
315 | EXT_CONTROL_REG_BITS(LDO7, 0, 5), | ||
316 | EXT_CONTROL_REG_BITS(LDO8, 0, 4), | ||
317 | }; | ||
318 | |||
241 | struct tps65910_reg { | 319 | struct tps65910_reg { |
242 | struct regulator_desc *desc; | 320 | struct regulator_desc *desc; |
243 | struct tps65910 *mfd; | 321 | struct tps65910 *mfd; |
@@ -247,6 +325,8 @@ struct tps65910_reg { | |||
247 | int num_regulators; | 325 | int num_regulators; |
248 | int mode; | 326 | int mode; |
249 | int (*get_ctrl_reg)(int); | 327 | int (*get_ctrl_reg)(int); |
328 | unsigned int *ext_sleep_control; | ||
329 | unsigned int board_ext_control[TPS65910_NUM_REGS]; | ||
250 | }; | 330 | }; |
251 | 331 | ||
252 | static inline int tps65910_read(struct tps65910_reg *pmic, u8 reg) | 332 | static inline int tps65910_read(struct tps65910_reg *pmic, u8 reg) |
@@ -429,6 +509,12 @@ static int tps65910_disable(struct regulator_dev *dev) | |||
429 | return tps65910_clear_bits(mfd, reg, TPS65910_SUPPLY_STATE_ENABLED); | 509 | return tps65910_clear_bits(mfd, reg, TPS65910_SUPPLY_STATE_ENABLED); |
430 | } | 510 | } |
431 | 511 | ||
512 | static int tps65910_enable_time(struct regulator_dev *dev) | ||
513 | { | ||
514 | struct tps65910_reg *pmic = rdev_get_drvdata(dev); | ||
515 | int id = rdev_get_id(dev); | ||
516 | return pmic->info[id]->enable_time_us; | ||
517 | } | ||
432 | 518 | ||
433 | static int tps65910_set_mode(struct regulator_dev *dev, unsigned int mode) | 519 | static int tps65910_set_mode(struct regulator_dev *dev, unsigned int mode) |
434 | { | 520 | { |
@@ -467,7 +553,7 @@ static unsigned int tps65910_get_mode(struct regulator_dev *dev) | |||
467 | if (value < 0) | 553 | if (value < 0) |
468 | return value; | 554 | return value; |
469 | 555 | ||
470 | if (value & LDO_ST_ON_BIT) | 556 | if (!(value & LDO_ST_ON_BIT)) |
471 | return REGULATOR_MODE_STANDBY; | 557 | return REGULATOR_MODE_STANDBY; |
472 | else if (value & LDO_ST_MODE_BIT) | 558 | else if (value & LDO_ST_MODE_BIT) |
473 | return REGULATOR_MODE_IDLE; | 559 | return REGULATOR_MODE_IDLE; |
@@ -475,10 +561,10 @@ static unsigned int tps65910_get_mode(struct regulator_dev *dev) | |||
475 | return REGULATOR_MODE_NORMAL; | 561 | return REGULATOR_MODE_NORMAL; |
476 | } | 562 | } |
477 | 563 | ||
478 | static int tps65910_get_voltage_dcdc(struct regulator_dev *dev) | 564 | static int tps65910_get_voltage_dcdc_sel(struct regulator_dev *dev) |
479 | { | 565 | { |
480 | struct tps65910_reg *pmic = rdev_get_drvdata(dev); | 566 | struct tps65910_reg *pmic = rdev_get_drvdata(dev); |
481 | int id = rdev_get_id(dev), voltage = 0; | 567 | int id = rdev_get_id(dev); |
482 | int opvsel = 0, srvsel = 0, vselmax = 0, mult = 0, sr = 0; | 568 | int opvsel = 0, srvsel = 0, vselmax = 0, mult = 0, sr = 0; |
483 | 569 | ||
484 | switch (id) { | 570 | switch (id) { |
@@ -522,9 +608,7 @@ static int tps65910_get_voltage_dcdc(struct regulator_dev *dev) | |||
522 | srvsel = 3; | 608 | srvsel = 3; |
523 | if (srvsel > vselmax) | 609 | if (srvsel > vselmax) |
524 | srvsel = vselmax; | 610 | srvsel = vselmax; |
525 | srvsel -= 3; | 611 | return srvsel - 3; |
526 | |||
527 | voltage = (srvsel * VDD1_2_OFFSET + VDD1_2_MIN_VOLT) * 100; | ||
528 | } else { | 612 | } else { |
529 | 613 | ||
530 | /* normalise to valid range*/ | 614 | /* normalise to valid range*/ |
@@ -532,14 +616,9 @@ static int tps65910_get_voltage_dcdc(struct regulator_dev *dev) | |||
532 | opvsel = 3; | 616 | opvsel = 3; |
533 | if (opvsel > vselmax) | 617 | if (opvsel > vselmax) |
534 | opvsel = vselmax; | 618 | opvsel = vselmax; |
535 | opvsel -= 3; | 619 | return opvsel - 3; |
536 | |||
537 | voltage = (opvsel * VDD1_2_OFFSET + VDD1_2_MIN_VOLT) * 100; | ||
538 | } | 620 | } |
539 | 621 | return -EINVAL; | |
540 | voltage *= mult; | ||
541 | |||
542 | return voltage; | ||
543 | } | 622 | } |
544 | 623 | ||
545 | static int tps65910_get_voltage(struct regulator_dev *dev) | 624 | static int tps65910_get_voltage(struct regulator_dev *dev) |
@@ -572,7 +651,7 @@ static int tps65910_get_voltage(struct regulator_dev *dev) | |||
572 | return -EINVAL; | 651 | return -EINVAL; |
573 | } | 652 | } |
574 | 653 | ||
575 | voltage = pmic->info[id]->table[value] * 1000; | 654 | voltage = pmic->info[id]->voltage_table[value] * 1000; |
576 | 655 | ||
577 | return voltage; | 656 | return voltage; |
578 | } | 657 | } |
@@ -622,8 +701,9 @@ static int tps65911_get_voltage(struct regulator_dev *dev) | |||
622 | step_mv = 100; | 701 | step_mv = 100; |
623 | break; | 702 | break; |
624 | case TPS65910_REG_VIO: | 703 | case TPS65910_REG_VIO: |
625 | return pmic->info[id]->table[value] * 1000; | 704 | value &= LDO_SEL_MASK; |
626 | break; | 705 | value >>= LDO_SEL_SHIFT; |
706 | return pmic->info[id]->voltage_table[value] * 1000; | ||
627 | default: | 707 | default: |
628 | return -EINVAL; | 708 | return -EINVAL; |
629 | } | 709 | } |
@@ -631,8 +711,8 @@ static int tps65911_get_voltage(struct regulator_dev *dev) | |||
631 | return (LDO_MIN_VOLT + value * step_mv) * 1000; | 711 | return (LDO_MIN_VOLT + value * step_mv) * 1000; |
632 | } | 712 | } |
633 | 713 | ||
634 | static int tps65910_set_voltage_dcdc(struct regulator_dev *dev, | 714 | static int tps65910_set_voltage_dcdc_sel(struct regulator_dev *dev, |
635 | unsigned selector) | 715 | unsigned selector) |
636 | { | 716 | { |
637 | struct tps65910_reg *pmic = rdev_get_drvdata(dev); | 717 | struct tps65910_reg *pmic = rdev_get_drvdata(dev); |
638 | int id = rdev_get_id(dev), vsel; | 718 | int id = rdev_get_id(dev), vsel; |
@@ -662,14 +742,15 @@ static int tps65910_set_voltage_dcdc(struct regulator_dev *dev, | |||
662 | tps65910_reg_write(pmic, TPS65910_VDD2_OP, vsel); | 742 | tps65910_reg_write(pmic, TPS65910_VDD2_OP, vsel); |
663 | break; | 743 | break; |
664 | case TPS65911_REG_VDDCTRL: | 744 | case TPS65911_REG_VDDCTRL: |
665 | vsel = selector; | 745 | vsel = selector + 3; |
666 | tps65910_reg_write(pmic, TPS65911_VDDCTRL_OP, vsel); | 746 | tps65910_reg_write(pmic, TPS65911_VDDCTRL_OP, vsel); |
667 | } | 747 | } |
668 | 748 | ||
669 | return 0; | 749 | return 0; |
670 | } | 750 | } |
671 | 751 | ||
672 | static int tps65910_set_voltage(struct regulator_dev *dev, unsigned selector) | 752 | static int tps65910_set_voltage_sel(struct regulator_dev *dev, |
753 | unsigned selector) | ||
673 | { | 754 | { |
674 | struct tps65910_reg *pmic = rdev_get_drvdata(dev); | 755 | struct tps65910_reg *pmic = rdev_get_drvdata(dev); |
675 | int reg, id = rdev_get_id(dev); | 756 | int reg, id = rdev_get_id(dev); |
@@ -695,7 +776,8 @@ static int tps65910_set_voltage(struct regulator_dev *dev, unsigned selector) | |||
695 | return -EINVAL; | 776 | return -EINVAL; |
696 | } | 777 | } |
697 | 778 | ||
698 | static int tps65911_set_voltage(struct regulator_dev *dev, unsigned selector) | 779 | static int tps65911_set_voltage_sel(struct regulator_dev *dev, |
780 | unsigned selector) | ||
699 | { | 781 | { |
700 | struct tps65910_reg *pmic = rdev_get_drvdata(dev); | 782 | struct tps65910_reg *pmic = rdev_get_drvdata(dev); |
701 | int reg, id = rdev_get_id(dev); | 783 | int reg, id = rdev_get_id(dev); |
@@ -715,9 +797,11 @@ static int tps65911_set_voltage(struct regulator_dev *dev, unsigned selector) | |||
715 | case TPS65911_REG_LDO6: | 797 | case TPS65911_REG_LDO6: |
716 | case TPS65911_REG_LDO7: | 798 | case TPS65911_REG_LDO7: |
717 | case TPS65911_REG_LDO8: | 799 | case TPS65911_REG_LDO8: |
718 | case TPS65910_REG_VIO: | ||
719 | return tps65910_modify_bits(pmic, reg, | 800 | return tps65910_modify_bits(pmic, reg, |
720 | (selector << LDO_SEL_SHIFT), LDO3_SEL_MASK); | 801 | (selector << LDO_SEL_SHIFT), LDO3_SEL_MASK); |
802 | case TPS65910_REG_VIO: | ||
803 | return tps65910_modify_bits(pmic, reg, | ||
804 | (selector << LDO_SEL_SHIFT), LDO_SEL_MASK); | ||
721 | } | 805 | } |
722 | 806 | ||
723 | return -EINVAL; | 807 | return -EINVAL; |
@@ -756,10 +840,10 @@ static int tps65910_list_voltage(struct regulator_dev *dev, | |||
756 | if (id < TPS65910_REG_VIO || id > TPS65910_REG_VMMC) | 840 | if (id < TPS65910_REG_VIO || id > TPS65910_REG_VMMC) |
757 | return -EINVAL; | 841 | return -EINVAL; |
758 | 842 | ||
759 | if (selector >= pmic->info[id]->table_len) | 843 | if (selector >= pmic->info[id]->n_voltages) |
760 | return -EINVAL; | 844 | return -EINVAL; |
761 | else | 845 | else |
762 | voltage = pmic->info[id]->table[selector] * 1000; | 846 | voltage = pmic->info[id]->voltage_table[selector] * 1000; |
763 | 847 | ||
764 | return voltage; | 848 | return voltage; |
765 | } | 849 | } |
@@ -795,7 +879,7 @@ static int tps65911_list_voltage(struct regulator_dev *dev, unsigned selector) | |||
795 | step_mv = 100; | 879 | step_mv = 100; |
796 | break; | 880 | break; |
797 | case TPS65910_REG_VIO: | 881 | case TPS65910_REG_VIO: |
798 | return pmic->info[id]->table[selector] * 1000; | 882 | return pmic->info[id]->voltage_table[selector] * 1000; |
799 | default: | 883 | default: |
800 | return -EINVAL; | 884 | return -EINVAL; |
801 | } | 885 | } |
@@ -803,15 +887,42 @@ static int tps65911_list_voltage(struct regulator_dev *dev, unsigned selector) | |||
803 | return (LDO_MIN_VOLT + selector * step_mv) * 1000; | 887 | return (LDO_MIN_VOLT + selector * step_mv) * 1000; |
804 | } | 888 | } |
805 | 889 | ||
890 | static int tps65910_set_voltage_dcdc_time_sel(struct regulator_dev *dev, | ||
891 | unsigned int old_selector, unsigned int new_selector) | ||
892 | { | ||
893 | int id = rdev_get_id(dev); | ||
894 | int old_volt, new_volt; | ||
895 | |||
896 | old_volt = tps65910_list_voltage_dcdc(dev, old_selector); | ||
897 | if (old_volt < 0) | ||
898 | return old_volt; | ||
899 | |||
900 | new_volt = tps65910_list_voltage_dcdc(dev, new_selector); | ||
901 | if (new_volt < 0) | ||
902 | return new_volt; | ||
903 | |||
904 | /* VDD1 and VDD2 are 12.5mV/us, VDDCTRL is 100mV/20us */ | ||
905 | switch (id) { | ||
906 | case TPS65910_REG_VDD1: | ||
907 | case TPS65910_REG_VDD2: | ||
908 | return DIV_ROUND_UP(abs(old_volt - new_volt), 12500); | ||
909 | case TPS65911_REG_VDDCTRL: | ||
910 | return DIV_ROUND_UP(abs(old_volt - new_volt), 5000); | ||
911 | } | ||
912 | return -EINVAL; | ||
913 | } | ||
914 | |||
806 | /* Regulator ops (except VRTC) */ | 915 | /* Regulator ops (except VRTC) */ |
807 | static struct regulator_ops tps65910_ops_dcdc = { | 916 | static struct regulator_ops tps65910_ops_dcdc = { |
808 | .is_enabled = tps65910_is_enabled, | 917 | .is_enabled = tps65910_is_enabled, |
809 | .enable = tps65910_enable, | 918 | .enable = tps65910_enable, |
810 | .disable = tps65910_disable, | 919 | .disable = tps65910_disable, |
920 | .enable_time = tps65910_enable_time, | ||
811 | .set_mode = tps65910_set_mode, | 921 | .set_mode = tps65910_set_mode, |
812 | .get_mode = tps65910_get_mode, | 922 | .get_mode = tps65910_get_mode, |
813 | .get_voltage = tps65910_get_voltage_dcdc, | 923 | .get_voltage_sel = tps65910_get_voltage_dcdc_sel, |
814 | .set_voltage_sel = tps65910_set_voltage_dcdc, | 924 | .set_voltage_sel = tps65910_set_voltage_dcdc_sel, |
925 | .set_voltage_time_sel = tps65910_set_voltage_dcdc_time_sel, | ||
815 | .list_voltage = tps65910_list_voltage_dcdc, | 926 | .list_voltage = tps65910_list_voltage_dcdc, |
816 | }; | 927 | }; |
817 | 928 | ||
@@ -819,6 +930,7 @@ static struct regulator_ops tps65910_ops_vdd3 = { | |||
819 | .is_enabled = tps65910_is_enabled, | 930 | .is_enabled = tps65910_is_enabled, |
820 | .enable = tps65910_enable, | 931 | .enable = tps65910_enable, |
821 | .disable = tps65910_disable, | 932 | .disable = tps65910_disable, |
933 | .enable_time = tps65910_enable_time, | ||
822 | .set_mode = tps65910_set_mode, | 934 | .set_mode = tps65910_set_mode, |
823 | .get_mode = tps65910_get_mode, | 935 | .get_mode = tps65910_get_mode, |
824 | .get_voltage = tps65910_get_voltage_vdd3, | 936 | .get_voltage = tps65910_get_voltage_vdd3, |
@@ -829,10 +941,11 @@ static struct regulator_ops tps65910_ops = { | |||
829 | .is_enabled = tps65910_is_enabled, | 941 | .is_enabled = tps65910_is_enabled, |
830 | .enable = tps65910_enable, | 942 | .enable = tps65910_enable, |
831 | .disable = tps65910_disable, | 943 | .disable = tps65910_disable, |
944 | .enable_time = tps65910_enable_time, | ||
832 | .set_mode = tps65910_set_mode, | 945 | .set_mode = tps65910_set_mode, |
833 | .get_mode = tps65910_get_mode, | 946 | .get_mode = tps65910_get_mode, |
834 | .get_voltage = tps65910_get_voltage, | 947 | .get_voltage = tps65910_get_voltage, |
835 | .set_voltage_sel = tps65910_set_voltage, | 948 | .set_voltage_sel = tps65910_set_voltage_sel, |
836 | .list_voltage = tps65910_list_voltage, | 949 | .list_voltage = tps65910_list_voltage, |
837 | }; | 950 | }; |
838 | 951 | ||
@@ -840,13 +953,147 @@ static struct regulator_ops tps65911_ops = { | |||
840 | .is_enabled = tps65910_is_enabled, | 953 | .is_enabled = tps65910_is_enabled, |
841 | .enable = tps65910_enable, | 954 | .enable = tps65910_enable, |
842 | .disable = tps65910_disable, | 955 | .disable = tps65910_disable, |
956 | .enable_time = tps65910_enable_time, | ||
843 | .set_mode = tps65910_set_mode, | 957 | .set_mode = tps65910_set_mode, |
844 | .get_mode = tps65910_get_mode, | 958 | .get_mode = tps65910_get_mode, |
845 | .get_voltage = tps65911_get_voltage, | 959 | .get_voltage = tps65911_get_voltage, |
846 | .set_voltage_sel = tps65911_set_voltage, | 960 | .set_voltage_sel = tps65911_set_voltage_sel, |
847 | .list_voltage = tps65911_list_voltage, | 961 | .list_voltage = tps65911_list_voltage, |
848 | }; | 962 | }; |
849 | 963 | ||
964 | static int tps65910_set_ext_sleep_config(struct tps65910_reg *pmic, | ||
965 | int id, int ext_sleep_config) | ||
966 | { | ||
967 | struct tps65910 *mfd = pmic->mfd; | ||
968 | u8 regoffs = (pmic->ext_sleep_control[id] >> 8) & 0xFF; | ||
969 | u8 bit_pos = (1 << pmic->ext_sleep_control[id] & 0xFF); | ||
970 | int ret; | ||
971 | |||
972 | /* | ||
973 | * Regulator can not be control from multiple external input EN1, EN2 | ||
974 | * and EN3 together. | ||
975 | */ | ||
976 | if (ext_sleep_config & EXT_SLEEP_CONTROL) { | ||
977 | int en_count; | ||
978 | en_count = ((ext_sleep_config & | ||
979 | TPS65910_SLEEP_CONTROL_EXT_INPUT_EN1) != 0); | ||
980 | en_count += ((ext_sleep_config & | ||
981 | TPS65910_SLEEP_CONTROL_EXT_INPUT_EN2) != 0); | ||
982 | en_count += ((ext_sleep_config & | ||
983 | TPS65910_SLEEP_CONTROL_EXT_INPUT_EN3) != 0); | ||
984 | en_count += ((ext_sleep_config & | ||
985 | TPS65911_SLEEP_CONTROL_EXT_INPUT_SLEEP) != 0); | ||
986 | if (en_count > 1) { | ||
987 | dev_err(mfd->dev, | ||
988 | "External sleep control flag is not proper\n"); | ||
989 | return -EINVAL; | ||
990 | } | ||
991 | } | ||
992 | |||
993 | pmic->board_ext_control[id] = ext_sleep_config; | ||
994 | |||
995 | /* External EN1 control */ | ||
996 | if (ext_sleep_config & TPS65910_SLEEP_CONTROL_EXT_INPUT_EN1) | ||
997 | ret = tps65910_set_bits(mfd, | ||
998 | TPS65910_EN1_LDO_ASS + regoffs, bit_pos); | ||
999 | else | ||
1000 | ret = tps65910_clear_bits(mfd, | ||
1001 | TPS65910_EN1_LDO_ASS + regoffs, bit_pos); | ||
1002 | if (ret < 0) { | ||
1003 | dev_err(mfd->dev, | ||
1004 | "Error in configuring external control EN1\n"); | ||
1005 | return ret; | ||
1006 | } | ||
1007 | |||
1008 | /* External EN2 control */ | ||
1009 | if (ext_sleep_config & TPS65910_SLEEP_CONTROL_EXT_INPUT_EN2) | ||
1010 | ret = tps65910_set_bits(mfd, | ||
1011 | TPS65910_EN2_LDO_ASS + regoffs, bit_pos); | ||
1012 | else | ||
1013 | ret = tps65910_clear_bits(mfd, | ||
1014 | TPS65910_EN2_LDO_ASS + regoffs, bit_pos); | ||
1015 | if (ret < 0) { | ||
1016 | dev_err(mfd->dev, | ||
1017 | "Error in configuring external control EN2\n"); | ||
1018 | return ret; | ||
1019 | } | ||
1020 | |||
1021 | /* External EN3 control for TPS65910 LDO only */ | ||
1022 | if ((tps65910_chip_id(mfd) == TPS65910) && | ||
1023 | (id >= TPS65910_REG_VDIG1)) { | ||
1024 | if (ext_sleep_config & TPS65910_SLEEP_CONTROL_EXT_INPUT_EN3) | ||
1025 | ret = tps65910_set_bits(mfd, | ||
1026 | TPS65910_EN3_LDO_ASS + regoffs, bit_pos); | ||
1027 | else | ||
1028 | ret = tps65910_clear_bits(mfd, | ||
1029 | TPS65910_EN3_LDO_ASS + regoffs, bit_pos); | ||
1030 | if (ret < 0) { | ||
1031 | dev_err(mfd->dev, | ||
1032 | "Error in configuring external control EN3\n"); | ||
1033 | return ret; | ||
1034 | } | ||
1035 | } | ||
1036 | |||
1037 | /* Return if no external control is selected */ | ||
1038 | if (!(ext_sleep_config & EXT_SLEEP_CONTROL)) { | ||
1039 | /* Clear all sleep controls */ | ||
1040 | ret = tps65910_clear_bits(mfd, | ||
1041 | TPS65910_SLEEP_KEEP_LDO_ON + regoffs, bit_pos); | ||
1042 | if (!ret) | ||
1043 | ret = tps65910_clear_bits(mfd, | ||
1044 | TPS65910_SLEEP_SET_LDO_OFF + regoffs, bit_pos); | ||
1045 | if (ret < 0) | ||
1046 | dev_err(mfd->dev, | ||
1047 | "Error in configuring SLEEP register\n"); | ||
1048 | return ret; | ||
1049 | } | ||
1050 | |||
1051 | /* | ||
1052 | * For regulator that has separate operational and sleep register make | ||
1053 | * sure that operational is used and clear sleep register to turn | ||
1054 | * regulator off when external control is inactive | ||
1055 | */ | ||
1056 | if ((id == TPS65910_REG_VDD1) || | ||
1057 | (id == TPS65910_REG_VDD2) || | ||
1058 | ((id == TPS65911_REG_VDDCTRL) && | ||
1059 | (tps65910_chip_id(mfd) == TPS65911))) { | ||
1060 | int op_reg_add = pmic->get_ctrl_reg(id) + 1; | ||
1061 | int sr_reg_add = pmic->get_ctrl_reg(id) + 2; | ||
1062 | int opvsel = tps65910_reg_read(pmic, op_reg_add); | ||
1063 | int srvsel = tps65910_reg_read(pmic, sr_reg_add); | ||
1064 | if (opvsel & VDD1_OP_CMD_MASK) { | ||
1065 | u8 reg_val = srvsel & VDD1_OP_SEL_MASK; | ||
1066 | ret = tps65910_reg_write(pmic, op_reg_add, reg_val); | ||
1067 | if (ret < 0) { | ||
1068 | dev_err(mfd->dev, | ||
1069 | "Error in configuring op register\n"); | ||
1070 | return ret; | ||
1071 | } | ||
1072 | } | ||
1073 | ret = tps65910_reg_write(pmic, sr_reg_add, 0); | ||
1074 | if (ret < 0) { | ||
1075 | dev_err(mfd->dev, "Error in settting sr register\n"); | ||
1076 | return ret; | ||
1077 | } | ||
1078 | } | ||
1079 | |||
1080 | ret = tps65910_clear_bits(mfd, | ||
1081 | TPS65910_SLEEP_KEEP_LDO_ON + regoffs, bit_pos); | ||
1082 | if (!ret) { | ||
1083 | if (ext_sleep_config & TPS65911_SLEEP_CONTROL_EXT_INPUT_SLEEP) | ||
1084 | ret = tps65910_set_bits(mfd, | ||
1085 | TPS65910_SLEEP_SET_LDO_OFF + regoffs, bit_pos); | ||
1086 | else | ||
1087 | ret = tps65910_clear_bits(mfd, | ||
1088 | TPS65910_SLEEP_SET_LDO_OFF + regoffs, bit_pos); | ||
1089 | } | ||
1090 | if (ret < 0) | ||
1091 | dev_err(mfd->dev, | ||
1092 | "Error in configuring SLEEP register\n"); | ||
1093 | |||
1094 | return ret; | ||
1095 | } | ||
1096 | |||
850 | static __devinit int tps65910_probe(struct platform_device *pdev) | 1097 | static __devinit int tps65910_probe(struct platform_device *pdev) |
851 | { | 1098 | { |
852 | struct tps65910 *tps65910 = dev_get_drvdata(pdev->dev.parent); | 1099 | struct tps65910 *tps65910 = dev_get_drvdata(pdev->dev.parent); |
@@ -877,11 +1124,13 @@ static __devinit int tps65910_probe(struct platform_device *pdev) | |||
877 | case TPS65910: | 1124 | case TPS65910: |
878 | pmic->get_ctrl_reg = &tps65910_get_ctrl_register; | 1125 | pmic->get_ctrl_reg = &tps65910_get_ctrl_register; |
879 | pmic->num_regulators = ARRAY_SIZE(tps65910_regs); | 1126 | pmic->num_regulators = ARRAY_SIZE(tps65910_regs); |
1127 | pmic->ext_sleep_control = tps65910_ext_sleep_control; | ||
880 | info = tps65910_regs; | 1128 | info = tps65910_regs; |
881 | break; | 1129 | break; |
882 | case TPS65911: | 1130 | case TPS65911: |
883 | pmic->get_ctrl_reg = &tps65911_get_ctrl_register; | 1131 | pmic->get_ctrl_reg = &tps65911_get_ctrl_register; |
884 | pmic->num_regulators = ARRAY_SIZE(tps65911_regs); | 1132 | pmic->num_regulators = ARRAY_SIZE(tps65911_regs); |
1133 | pmic->ext_sleep_control = tps65911_ext_sleep_control; | ||
885 | info = tps65911_regs; | 1134 | info = tps65911_regs; |
886 | break; | 1135 | break; |
887 | default: | 1136 | default: |
@@ -926,7 +1175,7 @@ static __devinit int tps65910_probe(struct platform_device *pdev) | |||
926 | 1175 | ||
927 | pmic->desc[i].name = info->name; | 1176 | pmic->desc[i].name = info->name; |
928 | pmic->desc[i].id = i; | 1177 | pmic->desc[i].id = i; |
929 | pmic->desc[i].n_voltages = info->table_len; | 1178 | pmic->desc[i].n_voltages = info->n_voltages; |
930 | 1179 | ||
931 | if (i == TPS65910_REG_VDD1 || i == TPS65910_REG_VDD2) { | 1180 | if (i == TPS65910_REG_VDD1 || i == TPS65910_REG_VDD2) { |
932 | pmic->desc[i].ops = &tps65910_ops_dcdc; | 1181 | pmic->desc[i].ops = &tps65910_ops_dcdc; |
@@ -944,6 +1193,16 @@ static __devinit int tps65910_probe(struct platform_device *pdev) | |||
944 | pmic->desc[i].ops = &tps65911_ops; | 1193 | pmic->desc[i].ops = &tps65911_ops; |
945 | } | 1194 | } |
946 | 1195 | ||
1196 | err = tps65910_set_ext_sleep_config(pmic, i, | ||
1197 | pmic_plat_data->regulator_ext_sleep_control[i]); | ||
1198 | /* | ||
1199 | * Failing on regulator for configuring externally control | ||
1200 | * is not a serious issue, just throw warning. | ||
1201 | */ | ||
1202 | if (err < 0) | ||
1203 | dev_warn(tps65910->dev, | ||
1204 | "Failed to initialise ext control config\n"); | ||
1205 | |||
947 | pmic->desc[i].type = REGULATOR_VOLTAGE; | 1206 | pmic->desc[i].type = REGULATOR_VOLTAGE; |
948 | pmic->desc[i].owner = THIS_MODULE; | 1207 | pmic->desc[i].owner = THIS_MODULE; |
949 | 1208 | ||
@@ -990,6 +1249,36 @@ static int __devexit tps65910_remove(struct platform_device *pdev) | |||
990 | return 0; | 1249 | return 0; |
991 | } | 1250 | } |
992 | 1251 | ||
1252 | static void tps65910_shutdown(struct platform_device *pdev) | ||
1253 | { | ||
1254 | struct tps65910_reg *pmic = platform_get_drvdata(pdev); | ||
1255 | int i; | ||
1256 | |||
1257 | /* | ||
1258 | * Before bootloader jumps to kernel, it makes sure that required | ||
1259 | * external control signals are in desired state so that given rails | ||
1260 | * can be configure accordingly. | ||
1261 | * If rails are configured to be controlled from external control | ||
1262 | * then before shutting down/rebooting the system, the external | ||
1263 | * control configuration need to be remove from the rails so that | ||
1264 | * its output will be available as per register programming even | ||
1265 | * if external controls are removed. This is require when the POR | ||
1266 | * value of the control signals are not in active state and before | ||
1267 | * bootloader initializes it, the system requires the rail output | ||
1268 | * to be active for booting. | ||
1269 | */ | ||
1270 | for (i = 0; i < pmic->num_regulators; i++) { | ||
1271 | int err; | ||
1272 | if (!pmic->rdev[i]) | ||
1273 | continue; | ||
1274 | |||
1275 | err = tps65910_set_ext_sleep_config(pmic, i, 0); | ||
1276 | if (err < 0) | ||
1277 | dev_err(&pdev->dev, | ||
1278 | "Error in clearing external control\n"); | ||
1279 | } | ||
1280 | } | ||
1281 | |||
993 | static struct platform_driver tps65910_driver = { | 1282 | static struct platform_driver tps65910_driver = { |
994 | .driver = { | 1283 | .driver = { |
995 | .name = "tps65910-pmic", | 1284 | .name = "tps65910-pmic", |
@@ -997,6 +1286,7 @@ static struct platform_driver tps65910_driver = { | |||
997 | }, | 1286 | }, |
998 | .probe = tps65910_probe, | 1287 | .probe = tps65910_probe, |
999 | .remove = __devexit_p(tps65910_remove), | 1288 | .remove = __devexit_p(tps65910_remove), |
1289 | .shutdown = tps65910_shutdown, | ||
1000 | }; | 1290 | }; |
1001 | 1291 | ||
1002 | static int __init tps65910_init(void) | 1292 | static int __init tps65910_init(void) |
@@ -1012,6 +1302,6 @@ static void __exit tps65910_cleanup(void) | |||
1012 | module_exit(tps65910_cleanup); | 1302 | module_exit(tps65910_cleanup); |
1013 | 1303 | ||
1014 | MODULE_AUTHOR("Graeme Gregory <gg@slimlogic.co.uk>"); | 1304 | MODULE_AUTHOR("Graeme Gregory <gg@slimlogic.co.uk>"); |
1015 | MODULE_DESCRIPTION("TPS6507x voltage regulator driver"); | 1305 | MODULE_DESCRIPTION("TPS65910/TPS65911 voltage regulator driver"); |
1016 | MODULE_LICENSE("GPL v2"); | 1306 | MODULE_LICENSE("GPL v2"); |
1017 | MODULE_ALIAS("platform:tps65910-pmic"); | 1307 | MODULE_ALIAS("platform:tps65910-pmic"); |