diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-22 10:38:37 -0500 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-22 10:38:37 -0500 |
commit | fcc9d2e5a6c89d22b8b773a64fb4ad21ac318446 (patch) | |
tree | a57612d1888735a2ec7972891b68c1ac5ec8faea /drivers/regulator/tps6591x-regulator.c | |
parent | 8dea78da5cee153b8af9c07a2745f6c55057fe12 (diff) |
Diffstat (limited to 'drivers/regulator/tps6591x-regulator.c')
-rw-r--r-- | drivers/regulator/tps6591x-regulator.c | 955 |
1 files changed, 955 insertions, 0 deletions
diff --git a/drivers/regulator/tps6591x-regulator.c b/drivers/regulator/tps6591x-regulator.c new file mode 100644 index 00000000000..5336f3d8257 --- /dev/null +++ b/drivers/regulator/tps6591x-regulator.c | |||
@@ -0,0 +1,955 @@ | |||
1 | /* | ||
2 | * driver/regulator/tps6591x-regulator.c | ||
3 | * | ||
4 | * Regulator driver for TI TPS6591x PMIC family | ||
5 | * | ||
6 | * Copyright (C) 2011 NVIDIA Corporation | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
14 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
15 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
16 | * more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License along | ||
19 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
20 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
21 | * | ||
22 | */ | ||
23 | |||
24 | #include <linux/kernel.h> | ||
25 | #include <linux/delay.h> | ||
26 | #include <linux/init.h> | ||
27 | #include <linux/err.h> | ||
28 | #include <linux/slab.h> | ||
29 | #include <linux/platform_device.h> | ||
30 | #include <linux/regulator/driver.h> | ||
31 | #include <linux/regulator/machine.h> | ||
32 | #include <linux/regulator/tps6591x-regulator.h> | ||
33 | #include <linux/mfd/tps6591x.h> | ||
34 | |||
35 | /* supply control and voltage setting */ | ||
36 | #define TPS6591X_VIO_ADD 0x20 | ||
37 | #define TPS6591X_VDD1_ADD 0x21 | ||
38 | #define TPS6591X_VDD1_OP_ADD 0x22 | ||
39 | #define TPS6591X_VDD1_SR_ADD 0x23 | ||
40 | #define TPS6591X_VDD2_ADD 0x24 | ||
41 | #define TPS6591X_VDD2_OP_ADD 0x25 | ||
42 | #define TPS6591X_VDD2_SR_ADD 0x26 | ||
43 | #define TPS6591X_VDDCTRL_ADD 0x27 | ||
44 | #define TPS6591X_VDDCTRL_OP_ADD 0x28 | ||
45 | #define TPS6591X_VDDCTRL_SR_ADD 0x29 | ||
46 | #define TPS6591X_LDO1_ADD 0x30 | ||
47 | #define TPS6591X_LDO2_ADD 0x31 | ||
48 | #define TPS6591X_LDO3_ADD 0x37 | ||
49 | #define TPS6591X_LDO4_ADD 0x36 | ||
50 | #define TPS6591X_LDO5_ADD 0x32 | ||
51 | #define TPS6591X_LDO6_ADD 0x35 | ||
52 | #define TPS6591X_LDO7_ADD 0x34 | ||
53 | #define TPS6591X_LDO8_ADD 0x33 | ||
54 | #define TPS6591X_SLEEP_SET_LDO_OFF_ADD 0x43 | ||
55 | #define TPS6591X_SLEEP_SET_RES_OFF_ADD 0x44 | ||
56 | #define TPS6591X_EN1_LDO_ADD 0x45 | ||
57 | #define TPS6591X_EN1_SMPS_ADD 0x46 | ||
58 | #define TPS6591X_EN2_LDO_ADD 0x47 | ||
59 | #define TPS6591X_EN2_SMPS_ADD 0x48 | ||
60 | #define TPS6591X_INVALID_ADD 0xFF | ||
61 | |||
62 | #define EN1_EN2_OFFSET 2 | ||
63 | |||
64 | struct tps6591x_register_info { | ||
65 | unsigned char addr; | ||
66 | unsigned char nbits; | ||
67 | unsigned char shift_bits; | ||
68 | uint8_t cache_val; | ||
69 | }; | ||
70 | |||
71 | enum { | ||
72 | supply_type_none = 0x0, | ||
73 | supply_type_single_reg, | ||
74 | supply_type_sr_op_reg | ||
75 | }; | ||
76 | |||
77 | struct tps6591x_regulator { | ||
78 | struct regulator_desc desc; | ||
79 | int supply_type; | ||
80 | |||
81 | struct tps6591x_register_info supply_reg; | ||
82 | struct tps6591x_register_info op_reg; | ||
83 | struct tps6591x_register_info sr_reg; | ||
84 | struct tps6591x_register_info en1_reg; | ||
85 | struct tps6591x_register_info slp_off_reg; | ||
86 | |||
87 | int *voltages; | ||
88 | |||
89 | int enable_delay; /* delay in us for regulator to stabilize */ | ||
90 | enum tps6591x_ext_control ectrl; | ||
91 | int current_volt_uv; | ||
92 | |||
93 | /* Time (micro sec) taken for 1uV change */ | ||
94 | int voltage_change_uv_per_us; | ||
95 | unsigned int config_flags; | ||
96 | }; | ||
97 | |||
98 | static inline struct device *to_tps6591x_dev(struct regulator_dev *rdev) | ||
99 | { | ||
100 | return rdev_get_dev(rdev)->parent->parent; | ||
101 | } | ||
102 | |||
103 | static int tps6591x_regulator_enable_time(struct regulator_dev *rdev) | ||
104 | { | ||
105 | struct tps6591x_regulator *ri = rdev_get_drvdata(rdev); | ||
106 | |||
107 | return ri->enable_delay; | ||
108 | } | ||
109 | |||
110 | static int __tps6591x_ext_control_set(struct device *parent, | ||
111 | struct tps6591x_regulator *ri, | ||
112 | enum tps6591x_ext_control ectrl) | ||
113 | { | ||
114 | int ret; | ||
115 | uint8_t mask, reg_val, addr, offset; | ||
116 | struct tps6591x_register_info *ext_reg; | ||
117 | |||
118 | /* For regulator that has separate operational and sleep register make | ||
119 | sure that operational is used and clear sleep register to turn | ||
120 | regulator off when external control is inactive */ | ||
121 | if (ri->supply_type == supply_type_sr_op_reg) { | ||
122 | reg_val = ri->op_reg.cache_val; | ||
123 | if (reg_val & 0x80) { /* boot has used sr - switch to op */ | ||
124 | reg_val = ri->sr_reg.cache_val; | ||
125 | mask = ((1 << ri->sr_reg.nbits) - 1) | ||
126 | << ri->sr_reg.shift_bits; | ||
127 | reg_val &= mask; | ||
128 | ret = tps6591x_write(parent, ri->op_reg.addr, reg_val); | ||
129 | if (ret) | ||
130 | return ret; | ||
131 | ri->op_reg.cache_val = reg_val; | ||
132 | } | ||
133 | ret = tps6591x_write(parent, ri->sr_reg.addr, 0); | ||
134 | if (ret) | ||
135 | return ret; | ||
136 | ri->sr_reg.cache_val = 0; | ||
137 | } | ||
138 | |||
139 | offset = 0; | ||
140 | switch (ectrl) { | ||
141 | case EXT_CTRL_EN2: | ||
142 | offset = EN1_EN2_OFFSET; | ||
143 | /* fall through to EXT_CTRL_EN1 */ | ||
144 | case EXT_CTRL_EN1: | ||
145 | ext_reg = &(ri->en1_reg); | ||
146 | break; | ||
147 | case EXT_CTRL_SLEEP_OFF: | ||
148 | ext_reg = &(ri->slp_off_reg); | ||
149 | break; | ||
150 | default: | ||
151 | return -EINVAL; | ||
152 | } | ||
153 | |||
154 | addr = ext_reg->addr + offset; | ||
155 | mask = ((1 << ext_reg->nbits) - 1) << ext_reg->shift_bits; | ||
156 | |||
157 | return tps6591x_update(parent, addr, mask, mask); | ||
158 | } | ||
159 | |||
160 | static void wait_for_voltage_change(struct tps6591x_regulator *ri, int uV) | ||
161 | { | ||
162 | int change_uv; | ||
163 | int change_us; | ||
164 | |||
165 | change_uv = abs(uV - ri->current_volt_uv); | ||
166 | change_us = change_uv/ri->voltage_change_uv_per_us + 1; | ||
167 | if (change_us >= 1000) { | ||
168 | mdelay(change_us/1000); | ||
169 | change_us -= (change_us/1000); | ||
170 | } | ||
171 | if (change_us) | ||
172 | udelay(change_us); | ||
173 | ri->current_volt_uv = uV; | ||
174 | } | ||
175 | |||
176 | static int __tps6591x_vio_set_voltage(struct device *parent, | ||
177 | struct tps6591x_regulator *ri, | ||
178 | int min_uV, int max_uV, | ||
179 | unsigned *selector) | ||
180 | { | ||
181 | int uV; | ||
182 | uint8_t mask; | ||
183 | uint8_t val; | ||
184 | int ret; | ||
185 | uint8_t reg_val; | ||
186 | |||
187 | for (val = 0; val < ri->desc.n_voltages; val++) { | ||
188 | uV = ri->voltages[val] * 1000; | ||
189 | |||
190 | /* use the first in-range value */ | ||
191 | if (min_uV <= uV && uV <= max_uV) { | ||
192 | if (selector) | ||
193 | *selector = val; | ||
194 | |||
195 | reg_val = ri->supply_reg.cache_val; | ||
196 | val <<= ri->supply_reg.shift_bits; | ||
197 | |||
198 | mask = ((1 << ri->supply_reg.nbits) - 1) << | ||
199 | ri->supply_reg.shift_bits; | ||
200 | reg_val = (reg_val & ~mask) | (val & mask); | ||
201 | |||
202 | ret = tps6591x_write(parent, ri->supply_reg.addr, | ||
203 | reg_val); | ||
204 | if (ret >= 0) { | ||
205 | wait_for_voltage_change(ri, uV); | ||
206 | ri->supply_reg.cache_val = reg_val; | ||
207 | } | ||
208 | return ret; | ||
209 | } | ||
210 | } | ||
211 | |||
212 | return -EINVAL; | ||
213 | } | ||
214 | |||
215 | static int tps6591x_vio_set_voltage(struct regulator_dev *rdev, | ||
216 | int min_uV, int max_uV, | ||
217 | unsigned *selector) | ||
218 | { | ||
219 | struct tps6591x_regulator *ri = rdev_get_drvdata(rdev); | ||
220 | struct device *parent = to_tps6591x_dev(rdev); | ||
221 | |||
222 | return __tps6591x_vio_set_voltage(parent, ri, min_uV, max_uV, | ||
223 | selector); | ||
224 | } | ||
225 | |||
226 | static int tps6591x_vio_get_voltage(struct regulator_dev *rdev) | ||
227 | { | ||
228 | struct tps6591x_regulator *ri = rdev_get_drvdata(rdev); | ||
229 | uint8_t val, mask; | ||
230 | |||
231 | val = ri->supply_reg.cache_val; | ||
232 | |||
233 | mask = ((1 << ri->supply_reg.nbits) - 1) << ri->supply_reg.shift_bits; | ||
234 | val = (val & mask) >> ri->supply_reg.shift_bits; | ||
235 | |||
236 | if (val >= ri->desc.n_voltages) | ||
237 | BUG(); | ||
238 | |||
239 | return ri->voltages[val] * 1000; | ||
240 | } | ||
241 | |||
242 | |||
243 | static int tps6591x_ldo_list_voltage(struct regulator_dev *rdev, | ||
244 | unsigned selector) | ||
245 | { | ||
246 | struct tps6591x_regulator *info = rdev_get_drvdata(rdev); | ||
247 | |||
248 | return info->voltages[selector] * 1000; | ||
249 | } | ||
250 | |||
251 | static int __tps6591x_ldo1_set_voltage(struct device *parent, | ||
252 | struct tps6591x_regulator *ri, | ||
253 | int min_uV, int max_uV, | ||
254 | unsigned *selector) | ||
255 | { | ||
256 | int val, uV; | ||
257 | uint8_t mask; | ||
258 | uint8_t reg_val; | ||
259 | int ret; | ||
260 | |||
261 | for (val = 0; val < ri->desc.n_voltages; val++) { | ||
262 | uV = ri->voltages[val] * 1000; | ||
263 | |||
264 | /* use the first in-range value */ | ||
265 | if (min_uV <= uV && uV <= max_uV) { | ||
266 | if (selector) | ||
267 | *selector = val; | ||
268 | reg_val = ri->supply_reg.cache_val; | ||
269 | val += 4; | ||
270 | val <<= ri->supply_reg.shift_bits; | ||
271 | mask = ((1 << ri->supply_reg.nbits) - 1) << | ||
272 | ri->supply_reg.shift_bits; | ||
273 | |||
274 | reg_val = (reg_val & ~mask) | (val & mask); | ||
275 | ret = tps6591x_write(parent, ri->supply_reg.addr, | ||
276 | reg_val); | ||
277 | if (ret >= 0) { | ||
278 | wait_for_voltage_change(ri, uV); | ||
279 | ri->supply_reg.cache_val = reg_val; | ||
280 | } | ||
281 | return ret; | ||
282 | } | ||
283 | } | ||
284 | |||
285 | return -EINVAL; | ||
286 | } | ||
287 | |||
288 | static int tps6591x_ldo1_set_voltage(struct regulator_dev *rdev, | ||
289 | int min_uV, int max_uV, | ||
290 | unsigned *selector) | ||
291 | { | ||
292 | struct tps6591x_regulator *ri = rdev_get_drvdata(rdev); | ||
293 | struct device *parent = to_tps6591x_dev(rdev); | ||
294 | |||
295 | return __tps6591x_ldo1_set_voltage(parent, ri, min_uV, max_uV, | ||
296 | selector); | ||
297 | } | ||
298 | |||
299 | static int tps6591x_ldo1_get_voltage(struct regulator_dev *rdev) | ||
300 | { | ||
301 | struct tps6591x_regulator *ri = rdev_get_drvdata(rdev); | ||
302 | uint8_t val, mask; | ||
303 | |||
304 | val = ri->supply_reg.cache_val; | ||
305 | mask = ((1 << ri->supply_reg.nbits) - 1) << ri->supply_reg.shift_bits; | ||
306 | val = (val & mask) >> ri->supply_reg.shift_bits; | ||
307 | |||
308 | if (val < 4) | ||
309 | return 1000 * 1000; | ||
310 | else if (val > 0x32) | ||
311 | return 3300 * 1000; | ||
312 | else | ||
313 | val -= 4; | ||
314 | if (val >= ri->desc.n_voltages) | ||
315 | BUG(); | ||
316 | |||
317 | return ri->voltages[val] * 1000; | ||
318 | } | ||
319 | |||
320 | static int __tps6591x_ldo3_set_voltage(struct device *parent, | ||
321 | struct tps6591x_regulator *ri, | ||
322 | int min_uV, int max_uV, | ||
323 | unsigned *selector) | ||
324 | { | ||
325 | int val, uV; | ||
326 | uint8_t mask; | ||
327 | int ret; | ||
328 | uint8_t reg_val; | ||
329 | |||
330 | for (val = 0; val < ri->desc.n_voltages; val++) { | ||
331 | uV = ri->voltages[val] * 1000; | ||
332 | |||
333 | /* use the first in-range value */ | ||
334 | if (min_uV <= uV && uV <= max_uV) { | ||
335 | if (selector) | ||
336 | *selector = val; | ||
337 | reg_val = ri->supply_reg.cache_val; | ||
338 | val += 2; | ||
339 | val <<= ri->supply_reg.shift_bits; | ||
340 | mask = ((1 << ri->supply_reg.nbits) - 1) << | ||
341 | ri->supply_reg.shift_bits; | ||
342 | |||
343 | reg_val = (reg_val & ~mask) | (val & mask); | ||
344 | |||
345 | ret = tps6591x_write(parent, ri->supply_reg.addr, | ||
346 | reg_val); | ||
347 | if (ret >= 0) { | ||
348 | wait_for_voltage_change(ri, uV); | ||
349 | ri->supply_reg.cache_val = reg_val; | ||
350 | } | ||
351 | return ret; | ||
352 | } | ||
353 | } | ||
354 | |||
355 | return -EINVAL; | ||
356 | } | ||
357 | |||
358 | static int tps6591x_ldo3_set_voltage(struct regulator_dev *rdev, | ||
359 | int min_uV, int max_uV, | ||
360 | unsigned *selector) | ||
361 | { | ||
362 | struct tps6591x_regulator *ri = rdev_get_drvdata(rdev); | ||
363 | struct device *parent = to_tps6591x_dev(rdev); | ||
364 | |||
365 | return __tps6591x_ldo3_set_voltage(parent, ri, min_uV, max_uV, | ||
366 | selector); | ||
367 | } | ||
368 | |||
369 | static int tps6591x_ldo3_get_voltage(struct regulator_dev *rdev) | ||
370 | { | ||
371 | struct tps6591x_regulator *ri = rdev_get_drvdata(rdev); | ||
372 | uint8_t val, mask; | ||
373 | |||
374 | val = ri->supply_reg.cache_val; | ||
375 | mask = ((1 << ri->supply_reg.nbits) - 1) << ri->supply_reg.shift_bits; | ||
376 | val = (val & mask) >> ri->supply_reg.shift_bits; | ||
377 | |||
378 | if (val < 2) | ||
379 | return 1000 * 1000; | ||
380 | else if (val > 0x19) | ||
381 | return 3300 * 1000; | ||
382 | else | ||
383 | val -= 2; | ||
384 | if (val >= ri->desc.n_voltages) | ||
385 | BUG(); | ||
386 | |||
387 | return ri->voltages[val] * 1000; | ||
388 | } | ||
389 | |||
390 | static int __tps6591x_vdd_set_voltage(struct device *parent, | ||
391 | struct tps6591x_regulator *ri, | ||
392 | int min_uV, int max_uV, | ||
393 | unsigned *selector) | ||
394 | { | ||
395 | int val, uV, ret; | ||
396 | uint8_t mask; | ||
397 | uint8_t op_reg_val; | ||
398 | uint8_t sr_reg_val; | ||
399 | |||
400 | for (val = 0; val < ri->desc.n_voltages; val++) { | ||
401 | uV = ri->voltages[val] * 1000; | ||
402 | |||
403 | /* use the first in-range value */ | ||
404 | if (min_uV <= uV && uV <= max_uV) { | ||
405 | if (selector) | ||
406 | *selector = val; | ||
407 | op_reg_val = ri->op_reg.cache_val; | ||
408 | val += 3; | ||
409 | if (op_reg_val & 0x80) { | ||
410 | sr_reg_val = ri->sr_reg.cache_val; | ||
411 | val <<= ri->sr_reg.shift_bits; | ||
412 | mask = ((1 << ri->sr_reg.nbits) - 1) | ||
413 | << ri->sr_reg.shift_bits; | ||
414 | sr_reg_val = (sr_reg_val & ~mask) | | ||
415 | (val & mask); | ||
416 | ret = tps6591x_write(parent, | ||
417 | ri->sr_reg.addr, sr_reg_val); | ||
418 | if (!ret) | ||
419 | ri->sr_reg.cache_val = sr_reg_val; | ||
420 | } else { | ||
421 | val <<= ri->op_reg.shift_bits; | ||
422 | mask = ((1 << ri->op_reg.nbits) - 1) | ||
423 | << ri->op_reg.shift_bits; | ||
424 | op_reg_val = (op_reg_val & ~mask) | | ||
425 | (val & mask); | ||
426 | ret = tps6591x_write(parent, | ||
427 | ri->op_reg.addr, op_reg_val); | ||
428 | if (!ret) | ||
429 | ri->op_reg.cache_val = op_reg_val; | ||
430 | } | ||
431 | if (ret >= 0) | ||
432 | wait_for_voltage_change(ri, uV); | ||
433 | return ret; | ||
434 | } | ||
435 | } | ||
436 | |||
437 | return -EINVAL; | ||
438 | } | ||
439 | |||
440 | static int tps6591x_vdd_set_voltage(struct regulator_dev *rdev, | ||
441 | int min_uV, int max_uV, | ||
442 | unsigned *selector) | ||
443 | { | ||
444 | struct tps6591x_regulator *ri = rdev_get_drvdata(rdev); | ||
445 | struct device *parent = to_tps6591x_dev(rdev); | ||
446 | |||
447 | return __tps6591x_vdd_set_voltage(parent, ri, min_uV, max_uV, | ||
448 | selector); | ||
449 | } | ||
450 | |||
451 | static int tps6591x_vdd_get_voltage(struct regulator_dev *rdev) | ||
452 | { | ||
453 | struct tps6591x_regulator *ri = rdev_get_drvdata(rdev); | ||
454 | uint8_t op_val, sr_val, val; | ||
455 | |||
456 | op_val = ri->op_reg.cache_val; | ||
457 | sr_val = ri->sr_reg.cache_val; | ||
458 | |||
459 | val = (op_val & 0x80) ? (sr_val & 0x7F) : (op_val & 0x7F); | ||
460 | |||
461 | if (!val) | ||
462 | return 0; | ||
463 | else if (val < 0x3) | ||
464 | return 600 * 1000; | ||
465 | else if (val > 0x4B) | ||
466 | return 1500 * 1000; | ||
467 | else | ||
468 | val -= 3; | ||
469 | |||
470 | if (val >= ri->desc.n_voltages) | ||
471 | BUG(); | ||
472 | |||
473 | return ri->voltages[val] * 1000; | ||
474 | } | ||
475 | |||
476 | static int tps6591x_regulator_enable(struct regulator_dev *rdev) | ||
477 | { | ||
478 | struct tps6591x_regulator *ri = rdev_get_drvdata(rdev); | ||
479 | struct device *parent = to_tps6591x_dev(rdev); | ||
480 | uint8_t reg_val; | ||
481 | int ret; | ||
482 | |||
483 | reg_val = ri->supply_reg.cache_val; | ||
484 | reg_val |= 0x1; | ||
485 | |||
486 | ret = tps6591x_write(parent, ri->supply_reg.addr, reg_val); | ||
487 | if (!ret) | ||
488 | ri->supply_reg.cache_val = reg_val; | ||
489 | return ret; | ||
490 | } | ||
491 | |||
492 | static int tps6591x_regulator_disable(struct regulator_dev *rdev) | ||
493 | { | ||
494 | struct tps6591x_regulator *ri = rdev_get_drvdata(rdev); | ||
495 | struct device *parent = to_tps6591x_dev(rdev); | ||
496 | uint8_t reg_val; | ||
497 | int ret; | ||
498 | |||
499 | reg_val = ri->supply_reg.cache_val; | ||
500 | reg_val &= ~0x1; | ||
501 | ret = tps6591x_write(parent, ri->supply_reg.addr, reg_val); | ||
502 | if (!ret) | ||
503 | ri->supply_reg.cache_val = reg_val; | ||
504 | return ret; | ||
505 | } | ||
506 | |||
507 | static int tps6591x_regulator_is_enabled(struct regulator_dev *rdev) | ||
508 | { | ||
509 | struct tps6591x_regulator *ri = rdev_get_drvdata(rdev); | ||
510 | uint8_t reg_val; | ||
511 | |||
512 | reg_val = ri->supply_reg.cache_val; | ||
513 | reg_val &= 0x1; | ||
514 | return reg_val & 0x1; | ||
515 | } | ||
516 | |||
517 | static struct regulator_ops tps6591x_regulator_vio_ops = { | ||
518 | .list_voltage = tps6591x_ldo_list_voltage, | ||
519 | .get_voltage = tps6591x_vio_get_voltage, | ||
520 | .set_voltage = tps6591x_vio_set_voltage, | ||
521 | |||
522 | .enable_time = tps6591x_regulator_enable_time, | ||
523 | .is_enabled = tps6591x_regulator_is_enabled, | ||
524 | .enable = tps6591x_regulator_enable, | ||
525 | .disable = tps6591x_regulator_disable, | ||
526 | }; | ||
527 | |||
528 | static struct regulator_ops tps6591x_regulator_ldo1_ops = { | ||
529 | .list_voltage = tps6591x_ldo_list_voltage, | ||
530 | .get_voltage = tps6591x_ldo1_get_voltage, | ||
531 | .set_voltage = tps6591x_ldo1_set_voltage, | ||
532 | |||
533 | .enable_time = tps6591x_regulator_enable_time, | ||
534 | .is_enabled = tps6591x_regulator_is_enabled, | ||
535 | .enable = tps6591x_regulator_enable, | ||
536 | .disable = tps6591x_regulator_disable, | ||
537 | }; | ||
538 | |||
539 | static struct regulator_ops tps6591x_regulator_ldo3_ops = { | ||
540 | .list_voltage = tps6591x_ldo_list_voltage, | ||
541 | .get_voltage = tps6591x_ldo3_get_voltage, | ||
542 | .set_voltage = tps6591x_ldo3_set_voltage, | ||
543 | |||
544 | .enable_time = tps6591x_regulator_enable_time, | ||
545 | .is_enabled = tps6591x_regulator_is_enabled, | ||
546 | .enable = tps6591x_regulator_enable, | ||
547 | .disable = tps6591x_regulator_disable, | ||
548 | }; | ||
549 | |||
550 | static struct regulator_ops tps6591x_regulator_vdd_ops = { | ||
551 | .list_voltage = tps6591x_ldo_list_voltage, | ||
552 | .get_voltage = tps6591x_vdd_get_voltage, | ||
553 | .set_voltage = tps6591x_vdd_set_voltage, | ||
554 | |||
555 | .enable_time = tps6591x_regulator_enable_time, | ||
556 | .is_enabled = tps6591x_regulator_is_enabled, | ||
557 | .enable = tps6591x_regulator_enable, | ||
558 | .disable = tps6591x_regulator_disable, | ||
559 | }; | ||
560 | |||
561 | static int tps6591x_vio_voltages[] = { | ||
562 | 1500, 1800, 2500, 3300, | ||
563 | }; | ||
564 | |||
565 | /* SEL[7:2]=000100:1000mV --> 110010:3300mV */ | ||
566 | static int tps6591x_ldo124_voltages[] = { | ||
567 | 1000, 1050, 1100, 1150, 1200, 1250, 1300, 1350, 1400, 1450, | ||
568 | 1500, 1550, 1600, 1650, 1700, 1750, 1800, 1850, 1900, 1950, | ||
569 | 2000, 2050, 2100, 2150, 2200, 2250, 2300, 2350, 2400, 2450, | ||
570 | 2500, 2550, 2600, 2650, 2700, 2750, 2800, 2850, 2900, 2950, | ||
571 | 3000, 3050, 3100, 3150, 3200, 3250, 3300, | ||
572 | }; | ||
573 | |||
574 | /* SEL[6:2]=00010:1000mv --> 11001:3300mV */ | ||
575 | static int tps6591x_ldo35678_voltages[] = { | ||
576 | 1000, 1100, 1200, 1300, 1400, 1500, 1600, 1700, 1800, 1900, | ||
577 | 2000, 2100, 2200, 2300, 2400, 2500, 2600, 2700, 2800, 2900, | ||
578 | 3000, 3100, 3200, 3300, | ||
579 | }; | ||
580 | |||
581 | static int tps6591x_vdd_voltages[] = { | ||
582 | 600, 612, 625, 637, 650, 662, 675, 687, 700, 712, 725, 737, | ||
583 | 750, 762, 775, 787, 800, 812, 825, 837, 850, 862, 875, 887, | ||
584 | 900, 912, 925, 937, 950, 962, 975, 987, 1000, 1012, 1025, | ||
585 | 1037, 1050, 1062, 1075, 1087, 1100, 1112, 1125, 1137, 1150, | ||
586 | 1162, 1175, 1187, 1200, 1212, 1225, 1237, 1250, 1262, 1275, | ||
587 | 1287, 1300, 1312, 1325, 1337, 1350, 1362, 1375, 1387, 1400, | ||
588 | 1412, 1425, 1437, 1450, 1462, 1475, 1487, 1500, | ||
589 | }; | ||
590 | |||
591 | static int tps6591x_vddctrl_voltages[] = { | ||
592 | 600, 612, 625, 637, 650, 662, 675, 687, 700, 712, 725, 737, | ||
593 | 750, 762, 775, 787, 800, 812, 825, 837, 850, 862, 875, 887, | ||
594 | 900, 912, 925, 937, 950, 962, 975, 987, 1000, 1012, 1025, | ||
595 | 1037, 1050, 1062, 1075, 1087, 1100, 1112, 1125, 1137, 1150, | ||
596 | 1162, 1175, 1187, 1200, 1212, 1225, 1237, 1250, 1262, 1275, | ||
597 | 1287, 1300, 1312, 1325, 1337, 1350, 1362, 1375, 1387, 1400, | ||
598 | }; | ||
599 | |||
600 | #define TPS6591X_REGULATOR(_id, vdata, _ops, s_addr, s_nbits, s_shift, \ | ||
601 | s_type, op_addr, op_nbits, op_shift, sr_addr, \ | ||
602 | sr_nbits, sr_shift, en1_addr, en1_shift, \ | ||
603 | slp_off_addr, slp_off_shift, en_time, \ | ||
604 | change_rate) \ | ||
605 | .desc = { \ | ||
606 | .name = tps6591x_rails(_id), \ | ||
607 | .ops = &tps6591x_regulator_##_ops, \ | ||
608 | .type = REGULATOR_VOLTAGE, \ | ||
609 | .id = TPS6591X_ID_##_id, \ | ||
610 | .n_voltages = ARRAY_SIZE(tps6591x_##vdata##_voltages), \ | ||
611 | .owner = THIS_MODULE, \ | ||
612 | }, \ | ||
613 | .supply_type = supply_type_##s_type, \ | ||
614 | .supply_reg = { \ | ||
615 | .addr = TPS6591X_##s_addr##_ADD, \ | ||
616 | .nbits = s_nbits, \ | ||
617 | .shift_bits = s_shift, \ | ||
618 | }, \ | ||
619 | .op_reg = { \ | ||
620 | .addr = TPS6591X_##op_addr##_ADD, \ | ||
621 | .nbits = op_nbits, \ | ||
622 | .shift_bits = op_shift, \ | ||
623 | }, \ | ||
624 | .sr_reg = { \ | ||
625 | .addr = TPS6591X_##sr_addr##_ADD, \ | ||
626 | .nbits = sr_nbits, \ | ||
627 | .shift_bits = sr_shift, \ | ||
628 | }, \ | ||
629 | .en1_reg = { \ | ||
630 | .addr = TPS6591X_##en1_addr##_ADD, \ | ||
631 | .nbits = 1, \ | ||
632 | .shift_bits = en1_shift, \ | ||
633 | }, \ | ||
634 | .slp_off_reg = { \ | ||
635 | .addr = TPS6591X_SLEEP_SET_##slp_off_addr##_ADD, \ | ||
636 | .nbits = 1, \ | ||
637 | .shift_bits = slp_off_shift, \ | ||
638 | }, \ | ||
639 | .voltages = tps6591x_##vdata##_voltages, \ | ||
640 | .enable_delay = en_time, \ | ||
641 | .voltage_change_uv_per_us = change_rate, | ||
642 | |||
643 | #define TPS6591X_VIO(_id, vdata, s_addr, s_nbits, s_shift, s_type, \ | ||
644 | en1_shift, slp_off_shift, en_time) \ | ||
645 | { \ | ||
646 | TPS6591X_REGULATOR(_id, vdata, vio_ops, s_addr, s_nbits, \ | ||
647 | s_shift, s_type, INVALID, 0, 0, INVALID, 0, 0, \ | ||
648 | EN1_SMPS, en1_shift, RES_OFF, slp_off_shift, \ | ||
649 | en_time, 10000) \ | ||
650 | } | ||
651 | |||
652 | #define TPS6591X_LDO1(_id, vdata, s_addr, s_nbits, s_shift, s_type, \ | ||
653 | en1_shift, slp_off_shift, en_time) \ | ||
654 | { \ | ||
655 | TPS6591X_REGULATOR(_id, vdata, ldo1_ops, s_addr, s_nbits, \ | ||
656 | s_shift, s_type, INVALID, 0, 0, INVALID, 0, 0, \ | ||
657 | EN1_LDO, en1_shift, LDO_OFF, slp_off_shift, \ | ||
658 | en_time, 6000) \ | ||
659 | } | ||
660 | |||
661 | #define TPS6591X_LDO3(_id, vdata, s_addr, s_nbits, s_shift, s_type, \ | ||
662 | en1_shift, slp_off_shift, en_time) \ | ||
663 | { \ | ||
664 | TPS6591X_REGULATOR(_id, vdata, ldo3_ops, s_addr, s_nbits, \ | ||
665 | s_shift, s_type, INVALID, 0, 0, INVALID, 0, 0, \ | ||
666 | EN1_LDO, en1_shift, LDO_OFF, slp_off_shift, \ | ||
667 | en_time, 11000) \ | ||
668 | } | ||
669 | |||
670 | #define TPS6591X_VDD(_id, vdata, s_addr, s_nbits, s_shift, s_type, \ | ||
671 | op_addr, op_nbits, op_shift, sr_addr, sr_nbits, \ | ||
672 | sr_shift, en1_shift, slp_off_shift, en_time) \ | ||
673 | { \ | ||
674 | TPS6591X_REGULATOR(_id, vdata, vdd_ops, s_addr, s_nbits, \ | ||
675 | s_shift, s_type, op_addr, op_nbits, op_shift, \ | ||
676 | sr_addr, sr_nbits, sr_shift, EN1_SMPS, \ | ||
677 | en1_shift, RES_OFF, slp_off_shift, en_time, \ | ||
678 | 5000) \ | ||
679 | } | ||
680 | |||
681 | static struct tps6591x_regulator tps6591x_regulator[] = { | ||
682 | TPS6591X_VIO(VIO, vio, VIO, 2, 2, single_reg, 0, 0, 350), | ||
683 | TPS6591X_LDO1(LDO_1, ldo124, LDO1, 6, 2, single_reg, 1, 1, 420), | ||
684 | TPS6591X_LDO1(LDO_2, ldo124, LDO2, 6, 2, single_reg, 2, 2, 420), | ||
685 | TPS6591X_LDO3(LDO_3, ldo35678, LDO3, 5, 2, single_reg, 7, 7, 230), | ||
686 | TPS6591X_LDO1(LDO_4, ldo124, LDO4, 6, 2, single_reg, 6, 6, 230), | ||
687 | TPS6591X_LDO3(LDO_5, ldo35678, LDO5, 5, 2, single_reg, 3, 3, 230), | ||
688 | TPS6591X_LDO3(LDO_6, ldo35678, LDO6, 5, 2, single_reg, 0, 0, 230), | ||
689 | TPS6591X_LDO3(LDO_7, ldo35678, LDO7, 5, 2, single_reg, 5, 5, 230), | ||
690 | TPS6591X_LDO3(LDO_8, ldo35678, LDO8, 5, 2, single_reg, 4, 4, 230), | ||
691 | TPS6591X_VDD(VDD_1, vdd, VDD1, 2, 0, sr_op_reg, VDD1_OP, | ||
692 | 7, 0, VDD1_SR, 7, 0, 1, 1, 350), | ||
693 | TPS6591X_VDD(VDD_2, vdd, VDD2, 2, 0, sr_op_reg, VDD2_OP, | ||
694 | 7, 0, VDD2_SR, 7, 0, 2, 2, 350), | ||
695 | TPS6591X_VDD(VDDCTRL, vddctrl, VDDCTRL, 2, 0, sr_op_reg, | ||
696 | VDDCTRL_OP, 7, 0, VDDCTRL_SR, 7, 0, 3, 3, 900), | ||
697 | }; | ||
698 | |||
699 | static inline int tps6591x_regulator_preinit(struct device *parent, | ||
700 | struct tps6591x_regulator *ri, | ||
701 | struct tps6591x_regulator_platform_data *tps6591x_pdata) | ||
702 | { | ||
703 | int ret; | ||
704 | uint8_t reg_val; | ||
705 | |||
706 | if (tps6591x_pdata->ectrl != EXT_CTRL_NONE) { | ||
707 | ret = __tps6591x_ext_control_set( | ||
708 | parent, ri, tps6591x_pdata->ectrl); | ||
709 | if (ret < 0) { | ||
710 | pr_err("Not able to configure external control %d" | ||
711 | " for rail %d err %d\n", tps6591x_pdata->ectrl, | ||
712 | ri->desc.id, ret); | ||
713 | return ret; | ||
714 | } | ||
715 | } | ||
716 | |||
717 | if (!tps6591x_pdata->init_apply) | ||
718 | return 0; | ||
719 | |||
720 | if (tps6591x_pdata->init_uV >= 0) { | ||
721 | switch (ri->desc.id) { | ||
722 | case TPS6591X_ID_VIO: | ||
723 | ret = __tps6591x_vio_set_voltage(parent, ri, | ||
724 | tps6591x_pdata->init_uV, | ||
725 | tps6591x_pdata->init_uV, 0); | ||
726 | break; | ||
727 | |||
728 | case TPS6591X_ID_LDO_1: | ||
729 | case TPS6591X_ID_LDO_2: | ||
730 | case TPS6591X_ID_LDO_4: | ||
731 | ret = __tps6591x_ldo1_set_voltage(parent, ri, | ||
732 | tps6591x_pdata->init_uV, | ||
733 | tps6591x_pdata->init_uV, 0); | ||
734 | break; | ||
735 | |||
736 | case TPS6591X_ID_LDO_3: | ||
737 | case TPS6591X_ID_LDO_5: | ||
738 | case TPS6591X_ID_LDO_6: | ||
739 | case TPS6591X_ID_LDO_7: | ||
740 | case TPS6591X_ID_LDO_8: | ||
741 | ret = __tps6591x_ldo3_set_voltage(parent, ri, | ||
742 | tps6591x_pdata->init_uV, | ||
743 | tps6591x_pdata->init_uV, 0); | ||
744 | break; | ||
745 | |||
746 | case TPS6591X_ID_VDD_1: | ||
747 | case TPS6591X_ID_VDD_2: | ||
748 | case TPS6591X_ID_VDDCTRL: | ||
749 | ret = __tps6591x_vdd_set_voltage(parent, ri, | ||
750 | tps6591x_pdata->init_uV, | ||
751 | tps6591x_pdata->init_uV, 0); | ||
752 | break; | ||
753 | |||
754 | default: | ||
755 | ret = -EINVAL; | ||
756 | break; | ||
757 | } | ||
758 | if (ret < 0) { | ||
759 | pr_err("Not able to initialize voltage %d for rail " | ||
760 | "%d err %d\n", tps6591x_pdata->init_uV, | ||
761 | ri->desc.id, ret); | ||
762 | return ret; | ||
763 | } | ||
764 | } | ||
765 | |||
766 | reg_val = ri->supply_reg.cache_val; | ||
767 | if (tps6591x_pdata->init_enable) | ||
768 | reg_val |= 0x1; | ||
769 | else | ||
770 | reg_val &= ~0x1; | ||
771 | ret = tps6591x_write(parent, ri->supply_reg.addr, reg_val); | ||
772 | |||
773 | if (ret < 0) | ||
774 | pr_err("Not able to %s rail %d err %d\n", | ||
775 | (tps6591x_pdata->init_enable) ? "enable" : "disable", | ||
776 | ri->desc.id, ret); | ||
777 | else | ||
778 | ri->supply_reg.cache_val = reg_val; | ||
779 | return ret; | ||
780 | } | ||
781 | |||
782 | static inline int tps6591x_cache_regulator_register(struct device *parent, | ||
783 | struct tps6591x_regulator *ri) | ||
784 | { | ||
785 | int ret; | ||
786 | ret = tps6591x_read(parent, ri->supply_reg.addr, | ||
787 | &ri->supply_reg.cache_val); | ||
788 | if (!ret && (ri->supply_type == supply_type_sr_op_reg)) { | ||
789 | ret = tps6591x_read(parent, ri->op_reg.addr, | ||
790 | &ri->op_reg.cache_val); | ||
791 | if (!ret) | ||
792 | ret = tps6591x_read(parent, ri->sr_reg.addr, | ||
793 | &ri->sr_reg.cache_val); | ||
794 | } | ||
795 | return ret; | ||
796 | } | ||
797 | |||
798 | static inline struct tps6591x_regulator *find_regulator_info(int id) | ||
799 | { | ||
800 | struct tps6591x_regulator *ri; | ||
801 | int i; | ||
802 | |||
803 | for (i = 0; i < ARRAY_SIZE(tps6591x_regulator); i++) { | ||
804 | ri = &tps6591x_regulator[i]; | ||
805 | if (ri->desc.id == id) | ||
806 | return ri; | ||
807 | } | ||
808 | return NULL; | ||
809 | } | ||
810 | |||
811 | |||
812 | static int __devinit tps6591x_regulator_probe(struct platform_device *pdev) | ||
813 | { | ||
814 | struct tps6591x_regulator *ri = NULL; | ||
815 | struct regulator_dev *rdev; | ||
816 | struct tps6591x_regulator_platform_data *tps_pdata; | ||
817 | int id = pdev->id; | ||
818 | int err; | ||
819 | |||
820 | dev_dbg(&pdev->dev, "Probing reulator %d\n", id); | ||
821 | |||
822 | ri = find_regulator_info(id); | ||
823 | if (ri == NULL) { | ||
824 | dev_err(&pdev->dev, "invalid regulator ID specified\n"); | ||
825 | return -EINVAL; | ||
826 | } | ||
827 | tps_pdata = pdev->dev.platform_data; | ||
828 | ri->ectrl = tps_pdata->ectrl; | ||
829 | ri->config_flags = tps_pdata->flags; | ||
830 | |||
831 | if (tps_pdata->slew_rate_uV_per_us) | ||
832 | ri->voltage_change_uv_per_us = tps_pdata->slew_rate_uV_per_us; | ||
833 | |||
834 | err = tps6591x_cache_regulator_register(pdev->dev.parent, ri); | ||
835 | if (err) { | ||
836 | dev_err(&pdev->dev, "Error in caching registers error %d\n", | ||
837 | err); | ||
838 | return err; | ||
839 | } | ||
840 | |||
841 | err = tps6591x_regulator_preinit(pdev->dev.parent, ri, tps_pdata); | ||
842 | if (err) { | ||
843 | dev_err(&pdev->dev, "Error in pre-initialization of regulator " | ||
844 | "error %d\n", err); | ||
845 | return err; | ||
846 | } | ||
847 | |||
848 | rdev = regulator_register(&ri->desc, &pdev->dev, | ||
849 | &tps_pdata->regulator, ri); | ||
850 | if (IS_ERR_OR_NULL(rdev)) { | ||
851 | dev_err(&pdev->dev, "failed to register regulator %s\n", | ||
852 | ri->desc.name); | ||
853 | return PTR_ERR(rdev); | ||
854 | } | ||
855 | ri->current_volt_uv = ri->desc.ops->get_voltage(rdev); | ||
856 | |||
857 | platform_set_drvdata(pdev, rdev); | ||
858 | |||
859 | return 0; | ||
860 | } | ||
861 | |||
862 | static int __devexit tps6591x_regulator_remove(struct platform_device *pdev) | ||
863 | { | ||
864 | struct regulator_dev *rdev = platform_get_drvdata(pdev); | ||
865 | |||
866 | regulator_unregister(rdev); | ||
867 | return 0; | ||
868 | } | ||
869 | |||
870 | static void tps6591x_regulator_shutdown(struct platform_device *pdev) | ||
871 | { | ||
872 | struct regulator_dev *rdev = platform_get_drvdata(pdev); | ||
873 | struct tps6591x_regulator *ri = rdev_get_drvdata(rdev); | ||
874 | struct device *parent = to_tps6591x_dev(rdev); | ||
875 | int ret; | ||
876 | |||
877 | if (ri->ectrl == EXT_CTRL_EN1) { | ||
878 | ret = tps6591x_clr_bits(parent, ri->en1_reg.addr, | ||
879 | (1 << ri->en1_reg.shift_bits)); | ||
880 | if (ret < 0) | ||
881 | dev_err(&pdev->dev, "Error in clearing external control\n"); | ||
882 | } | ||
883 | } | ||
884 | |||
885 | static int tps6591x_suspend(struct platform_device *pdev, pm_message_t state) | ||
886 | { | ||
887 | struct regulator_dev *rdev = platform_get_drvdata(pdev); | ||
888 | struct tps6591x_regulator *ri = rdev_get_drvdata(rdev); | ||
889 | struct device *parent = to_tps6591x_dev(rdev); | ||
890 | int ret = 0; | ||
891 | uint8_t reg_val; | ||
892 | |||
893 | if (ri->config_flags & LDO_LOW_POWER_ON_SUSPEND) { | ||
894 | ret = tps6591x_clr_bits(parent, ri->en1_reg.addr, | ||
895 | (1 << ri->en1_reg.shift_bits)); | ||
896 | reg_val = ri->supply_reg.cache_val; | ||
897 | reg_val = (reg_val & ~0x3) | (0x3); | ||
898 | ret = tps6591x_write(parent, ri->supply_reg.addr, reg_val); | ||
899 | if (ret >= 0) | ||
900 | ri->supply_reg.cache_val = reg_val; | ||
901 | else | ||
902 | dev_err(&pdev->dev, "Error in updating the supply state\n"); | ||
903 | } | ||
904 | return ret; | ||
905 | } | ||
906 | |||
907 | static int tps6591x_resume(struct platform_device *pdev) | ||
908 | { | ||
909 | struct regulator_dev *rdev = platform_get_drvdata(pdev); | ||
910 | struct tps6591x_regulator *ri = rdev_get_drvdata(rdev); | ||
911 | struct device *parent = to_tps6591x_dev(rdev); | ||
912 | int ret = 0; | ||
913 | uint8_t reg_val; | ||
914 | |||
915 | if (ri->config_flags & LDO_LOW_POWER_ON_SUSPEND) { | ||
916 | ret = tps6591x_clr_bits(parent, ri->en1_reg.addr, | ||
917 | (1 << ri->en1_reg.shift_bits)); | ||
918 | reg_val = ri->supply_reg.cache_val; | ||
919 | reg_val = (reg_val & ~0x3) | (0x1); | ||
920 | ret = tps6591x_write(parent, ri->supply_reg.addr, reg_val); | ||
921 | if (ret >= 0) | ||
922 | ri->supply_reg.cache_val = reg_val; | ||
923 | else | ||
924 | dev_err(&pdev->dev, "Error in updating the supply state\n"); | ||
925 | } | ||
926 | return ret; | ||
927 | } | ||
928 | |||
929 | static struct platform_driver tps6591x_regulator_driver = { | ||
930 | .driver = { | ||
931 | .name = "tps6591x-regulator", | ||
932 | .owner = THIS_MODULE, | ||
933 | }, | ||
934 | .probe = tps6591x_regulator_probe, | ||
935 | .remove = __devexit_p(tps6591x_regulator_remove), | ||
936 | .shutdown = tps6591x_regulator_shutdown, | ||
937 | .suspend = tps6591x_suspend, | ||
938 | .resume = tps6591x_resume, | ||
939 | }; | ||
940 | |||
941 | static int __init tps6591x_regulator_init(void) | ||
942 | { | ||
943 | return platform_driver_register(&tps6591x_regulator_driver); | ||
944 | } | ||
945 | subsys_initcall(tps6591x_regulator_init); | ||
946 | |||
947 | static void __exit tps6591x_regulator_exit(void) | ||
948 | { | ||
949 | platform_driver_unregister(&tps6591x_regulator_driver); | ||
950 | } | ||
951 | module_exit(tps6591x_regulator_exit); | ||
952 | |||
953 | MODULE_LICENSE("GPL"); | ||
954 | MODULE_DESCRIPTION("Regulator Driver for TI TPS6591X PMIC"); | ||
955 | MODULE_ALIAS("platform:tps6591x-regulator"); | ||