]>
Commit | Line | Data |
---|---|---|
518fb721 GG |
1 | /* |
2 | * tps65910.c -- TI tps65910 | |
3 | * | |
4 | * Copyright 2010 Texas Instruments Inc. | |
5 | * | |
6 | * Author: Graeme Gregory <gg@slimlogic.co.uk> | |
7 | * Author: Jorge Eduardo Candelaria <jedu@slimlogic.co.uk> | |
8 | * | |
9 | * This program is free software; you can redistribute it and/or modify it | |
10 | * under the terms of the GNU General Public License as published by the | |
11 | * Free Software Foundation; either version 2 of the License, or (at your | |
12 | * option) any later version. | |
13 | * | |
14 | */ | |
15 | ||
16 | #include <linux/kernel.h> | |
17 | #include <linux/module.h> | |
18 | #include <linux/init.h> | |
19 | #include <linux/err.h> | |
20 | #include <linux/platform_device.h> | |
21 | #include <linux/regulator/driver.h> | |
22 | #include <linux/regulator/machine.h> | |
23 | #include <linux/delay.h> | |
24 | #include <linux/slab.h> | |
25 | #include <linux/gpio.h> | |
26 | #include <linux/mfd/tps65910.h> | |
27 | ||
28 | #define TPS65910_REG_VRTC 0 | |
29 | #define TPS65910_REG_VIO 1 | |
30 | #define TPS65910_REG_VDD1 2 | |
31 | #define TPS65910_REG_VDD2 3 | |
32 | #define TPS65910_REG_VDD3 4 | |
33 | #define TPS65910_REG_VDIG1 5 | |
34 | #define TPS65910_REG_VDIG2 6 | |
35 | #define TPS65910_REG_VPLL 7 | |
36 | #define TPS65910_REG_VDAC 8 | |
37 | #define TPS65910_REG_VAUX1 9 | |
38 | #define TPS65910_REG_VAUX2 10 | |
39 | #define TPS65910_REG_VAUX33 11 | |
40 | #define TPS65910_REG_VMMC 12 | |
41 | ||
a320e3c3 JEC |
42 | #define TPS65911_REG_VDDCTRL 4 |
43 | #define TPS65911_REG_LDO1 5 | |
44 | #define TPS65911_REG_LDO2 6 | |
45 | #define TPS65911_REG_LDO3 7 | |
46 | #define TPS65911_REG_LDO4 8 | |
47 | #define TPS65911_REG_LDO5 9 | |
48 | #define TPS65911_REG_LDO6 10 | |
49 | #define TPS65911_REG_LDO7 11 | |
50 | #define TPS65911_REG_LDO8 12 | |
518fb721 | 51 | |
a320e3c3 | 52 | #define TPS65910_NUM_REGULATOR 13 |
518fb721 GG |
53 | #define TPS65910_SUPPLY_STATE_ENABLED 0x1 |
54 | ||
55 | /* supported VIO voltages in milivolts */ | |
56 | static const u16 VIO_VSEL_table[] = { | |
57 | 1500, 1800, 2500, 3300, | |
58 | }; | |
59 | ||
a320e3c3 JEC |
60 | /* VSEL tables for TPS65910 specific LDOs and dcdc's */ |
61 | ||
62 | /* supported VDD3 voltages in milivolts */ | |
518fb721 GG |
63 | static const u16 VDD3_VSEL_table[] = { |
64 | 5000, | |
65 | }; | |
66 | ||
67 | /* supported VDIG1 voltages in milivolts */ | |
68 | static const u16 VDIG1_VSEL_table[] = { | |
69 | 1200, 1500, 1800, 2700, | |
70 | }; | |
71 | ||
72 | /* supported VDIG2 voltages in milivolts */ | |
73 | static const u16 VDIG2_VSEL_table[] = { | |
74 | 1000, 1100, 1200, 1800, | |
75 | }; | |
76 | ||
77 | /* supported VPLL voltages in milivolts */ | |
78 | static const u16 VPLL_VSEL_table[] = { | |
79 | 1000, 1100, 1800, 2500, | |
80 | }; | |
81 | ||
82 | /* supported VDAC voltages in milivolts */ | |
83 | static const u16 VDAC_VSEL_table[] = { | |
84 | 1800, 2600, 2800, 2850, | |
85 | }; | |
86 | ||
87 | /* supported VAUX1 voltages in milivolts */ | |
88 | static const u16 VAUX1_VSEL_table[] = { | |
89 | 1800, 2500, 2800, 2850, | |
90 | }; | |
91 | ||
92 | /* supported VAUX2 voltages in milivolts */ | |
93 | static const u16 VAUX2_VSEL_table[] = { | |
94 | 1800, 2800, 2900, 3300, | |
95 | }; | |
96 | ||
97 | /* supported VAUX33 voltages in milivolts */ | |
98 | static const u16 VAUX33_VSEL_table[] = { | |
99 | 1800, 2000, 2800, 3300, | |
100 | }; | |
101 | ||
102 | /* supported VMMC voltages in milivolts */ | |
103 | static const u16 VMMC_VSEL_table[] = { | |
104 | 1800, 2800, 3000, 3300, | |
105 | }; | |
106 | ||
107 | struct tps_info { | |
108 | const char *name; | |
109 | unsigned min_uV; | |
110 | unsigned max_uV; | |
111 | u8 table_len; | |
112 | const u16 *table; | |
113 | }; | |
114 | ||
115 | static struct tps_info tps65910_regs[] = { | |
116 | { | |
117 | .name = "VRTC", | |
118 | }, | |
119 | { | |
120 | .name = "VIO", | |
121 | .min_uV = 1500000, | |
122 | .max_uV = 3300000, | |
123 | .table_len = ARRAY_SIZE(VIO_VSEL_table), | |
124 | .table = VIO_VSEL_table, | |
125 | }, | |
126 | { | |
127 | .name = "VDD1", | |
128 | .min_uV = 600000, | |
129 | .max_uV = 4500000, | |
130 | }, | |
131 | { | |
132 | .name = "VDD2", | |
133 | .min_uV = 600000, | |
134 | .max_uV = 4500000, | |
135 | }, | |
136 | { | |
137 | .name = "VDD3", | |
138 | .min_uV = 5000000, | |
139 | .max_uV = 5000000, | |
140 | .table_len = ARRAY_SIZE(VDD3_VSEL_table), | |
141 | .table = VDD3_VSEL_table, | |
142 | }, | |
143 | { | |
144 | .name = "VDIG1", | |
145 | .min_uV = 1200000, | |
146 | .max_uV = 2700000, | |
147 | .table_len = ARRAY_SIZE(VDIG1_VSEL_table), | |
148 | .table = VDIG1_VSEL_table, | |
149 | }, | |
150 | { | |
151 | .name = "VDIG2", | |
152 | .min_uV = 1000000, | |
153 | .max_uV = 1800000, | |
154 | .table_len = ARRAY_SIZE(VDIG2_VSEL_table), | |
155 | .table = VDIG2_VSEL_table, | |
156 | }, | |
157 | { | |
158 | .name = "VPLL", | |
159 | .min_uV = 1000000, | |
160 | .max_uV = 2500000, | |
161 | .table_len = ARRAY_SIZE(VPLL_VSEL_table), | |
162 | .table = VPLL_VSEL_table, | |
163 | }, | |
164 | { | |
165 | .name = "VDAC", | |
166 | .min_uV = 1800000, | |
167 | .max_uV = 2850000, | |
168 | .table_len = ARRAY_SIZE(VDAC_VSEL_table), | |
169 | .table = VDAC_VSEL_table, | |
170 | }, | |
171 | { | |
172 | .name = "VAUX1", | |
173 | .min_uV = 1800000, | |
174 | .max_uV = 2850000, | |
175 | .table_len = ARRAY_SIZE(VAUX1_VSEL_table), | |
176 | .table = VAUX1_VSEL_table, | |
177 | }, | |
178 | { | |
179 | .name = "VAUX2", | |
180 | .min_uV = 1800000, | |
181 | .max_uV = 3300000, | |
182 | .table_len = ARRAY_SIZE(VAUX2_VSEL_table), | |
183 | .table = VAUX2_VSEL_table, | |
184 | }, | |
185 | { | |
186 | .name = "VAUX33", | |
187 | .min_uV = 1800000, | |
188 | .max_uV = 3300000, | |
189 | .table_len = ARRAY_SIZE(VAUX33_VSEL_table), | |
190 | .table = VAUX33_VSEL_table, | |
191 | }, | |
192 | { | |
193 | .name = "VMMC", | |
194 | .min_uV = 1800000, | |
195 | .max_uV = 3300000, | |
196 | .table_len = ARRAY_SIZE(VMMC_VSEL_table), | |
197 | .table = VMMC_VSEL_table, | |
198 | }, | |
199 | }; | |
200 | ||
a320e3c3 JEC |
201 | static struct tps_info tps65911_regs[] = { |
202 | { | |
203 | .name = "VIO", | |
204 | .min_uV = 1500000, | |
205 | .max_uV = 3300000, | |
206 | .table_len = ARRAY_SIZE(VIO_VSEL_table), | |
207 | .table = VIO_VSEL_table, | |
208 | }, | |
209 | { | |
210 | .name = "VDD1", | |
211 | .min_uV = 600000, | |
212 | .max_uV = 4500000, | |
213 | }, | |
214 | { | |
215 | .name = "VDD2", | |
216 | .min_uV = 600000, | |
217 | .max_uV = 4500000, | |
218 | }, | |
219 | { | |
220 | .name = "VDDCTRL", | |
221 | .min_uV = 600000, | |
222 | .max_uV = 1400000, | |
223 | }, | |
224 | { | |
225 | .name = "LDO1", | |
226 | .min_uV = 1000000, | |
227 | .max_uV = 3300000, | |
228 | }, | |
229 | { | |
230 | .name = "LDO2", | |
231 | .min_uV = 1000000, | |
232 | .max_uV = 3300000, | |
233 | }, | |
234 | { | |
235 | .name = "LDO3", | |
236 | .min_uV = 1000000, | |
237 | .max_uV = 3300000, | |
238 | }, | |
239 | { | |
240 | .name = "LDO4", | |
241 | .min_uV = 1000000, | |
242 | .max_uV = 3300000, | |
243 | }, | |
244 | { | |
245 | .name = "LDO5", | |
246 | .min_uV = 1000000, | |
247 | .max_uV = 3300000, | |
248 | }, | |
249 | { | |
250 | .name = "LDO6", | |
251 | .min_uV = 1000000, | |
252 | .max_uV = 3300000, | |
253 | }, | |
254 | { | |
255 | .name = "LDO7", | |
256 | .min_uV = 1000000, | |
257 | .max_uV = 3300000, | |
258 | }, | |
259 | { | |
260 | .name = "LDO8", | |
261 | .min_uV = 1000000, | |
262 | .max_uV = 3300000, | |
263 | }, | |
264 | }; | |
265 | ||
518fb721 GG |
266 | struct tps65910_reg { |
267 | struct regulator_desc desc[TPS65910_NUM_REGULATOR]; | |
268 | struct tps65910 *mfd; | |
269 | struct regulator_dev *rdev[TPS65910_NUM_REGULATOR]; | |
270 | struct tps_info *info[TPS65910_NUM_REGULATOR]; | |
271 | struct mutex mutex; | |
272 | int mode; | |
a320e3c3 | 273 | int (*get_ctrl_reg)(int); |
518fb721 GG |
274 | }; |
275 | ||
276 | static inline int tps65910_read(struct tps65910_reg *pmic, u8 reg) | |
277 | { | |
278 | u8 val; | |
279 | int err; | |
280 | ||
281 | err = pmic->mfd->read(pmic->mfd, reg, 1, &val); | |
282 | if (err) | |
283 | return err; | |
284 | ||
285 | return val; | |
286 | } | |
287 | ||
288 | static inline int tps65910_write(struct tps65910_reg *pmic, u8 reg, u8 val) | |
289 | { | |
290 | return pmic->mfd->write(pmic->mfd, reg, 1, &val); | |
291 | } | |
292 | ||
293 | static int tps65910_modify_bits(struct tps65910_reg *pmic, u8 reg, | |
294 | u8 set_mask, u8 clear_mask) | |
295 | { | |
296 | int err, data; | |
297 | ||
298 | mutex_lock(&pmic->mutex); | |
299 | ||
300 | data = tps65910_read(pmic, reg); | |
301 | if (data < 0) { | |
302 | dev_err(pmic->mfd->dev, "Read from reg 0x%x failed\n", reg); | |
303 | err = data; | |
304 | goto out; | |
305 | } | |
306 | ||
307 | data &= ~clear_mask; | |
308 | data |= set_mask; | |
309 | err = tps65910_write(pmic, reg, data); | |
310 | if (err) | |
311 | dev_err(pmic->mfd->dev, "Write for reg 0x%x failed\n", reg); | |
312 | ||
313 | out: | |
314 | mutex_unlock(&pmic->mutex); | |
315 | return err; | |
316 | } | |
317 | ||
318 | static int tps65910_reg_read(struct tps65910_reg *pmic, u8 reg) | |
319 | { | |
320 | int data; | |
321 | ||
322 | mutex_lock(&pmic->mutex); | |
323 | ||
324 | data = tps65910_read(pmic, reg); | |
325 | if (data < 0) | |
326 | dev_err(pmic->mfd->dev, "Read from reg 0x%x failed\n", reg); | |
327 | ||
328 | mutex_unlock(&pmic->mutex); | |
329 | return data; | |
330 | } | |
331 | ||
332 | static int tps65910_reg_write(struct tps65910_reg *pmic, u8 reg, u8 val) | |
333 | { | |
334 | int err; | |
335 | ||
336 | mutex_lock(&pmic->mutex); | |
337 | ||
338 | err = tps65910_write(pmic, reg, val); | |
339 | if (err < 0) | |
340 | dev_err(pmic->mfd->dev, "Write for reg 0x%x failed\n", reg); | |
341 | ||
342 | mutex_unlock(&pmic->mutex); | |
343 | return err; | |
344 | } | |
345 | ||
346 | static int tps65910_get_ctrl_register(int id) | |
347 | { | |
348 | switch (id) { | |
349 | case TPS65910_REG_VRTC: | |
350 | return TPS65910_VRTC; | |
351 | case TPS65910_REG_VIO: | |
352 | return TPS65910_VIO; | |
353 | case TPS65910_REG_VDD1: | |
354 | return TPS65910_VDD1; | |
355 | case TPS65910_REG_VDD2: | |
356 | return TPS65910_VDD2; | |
357 | case TPS65910_REG_VDD3: | |
358 | return TPS65910_VDD3; | |
359 | case TPS65910_REG_VDIG1: | |
360 | return TPS65910_VDIG1; | |
361 | case TPS65910_REG_VDIG2: | |
362 | return TPS65910_VDIG2; | |
363 | case TPS65910_REG_VPLL: | |
364 | return TPS65910_VPLL; | |
365 | case TPS65910_REG_VDAC: | |
366 | return TPS65910_VDAC; | |
367 | case TPS65910_REG_VAUX1: | |
368 | return TPS65910_VAUX1; | |
369 | case TPS65910_REG_VAUX2: | |
370 | return TPS65910_VAUX2; | |
371 | case TPS65910_REG_VAUX33: | |
372 | return TPS65910_VAUX33; | |
373 | case TPS65910_REG_VMMC: | |
374 | return TPS65910_VMMC; | |
375 | default: | |
376 | return -EINVAL; | |
377 | } | |
378 | } | |
379 | ||
a320e3c3 JEC |
380 | static int tps65911_get_ctrl_register(int id) |
381 | { | |
382 | switch (id) { | |
383 | case TPS65910_REG_VRTC: | |
384 | return TPS65910_VRTC; | |
385 | case TPS65910_REG_VIO: | |
386 | return TPS65910_VIO; | |
387 | case TPS65910_REG_VDD1: | |
388 | return TPS65910_VDD1; | |
389 | case TPS65910_REG_VDD2: | |
390 | return TPS65910_VDD2; | |
391 | case TPS65911_REG_VDDCTRL: | |
392 | return TPS65911_VDDCTRL; | |
393 | case TPS65911_REG_LDO1: | |
394 | return TPS65911_LDO1; | |
395 | case TPS65911_REG_LDO2: | |
396 | return TPS65911_LDO2; | |
397 | case TPS65911_REG_LDO3: | |
398 | return TPS65911_LDO3; | |
399 | case TPS65911_REG_LDO4: | |
400 | return TPS65911_LDO4; | |
401 | case TPS65911_REG_LDO5: | |
402 | return TPS65911_LDO5; | |
403 | case TPS65911_REG_LDO6: | |
404 | return TPS65911_LDO6; | |
405 | case TPS65911_REG_LDO7: | |
406 | return TPS65911_LDO7; | |
407 | case TPS65911_REG_LDO8: | |
408 | return TPS65911_LDO8; | |
409 | default: | |
410 | return -EINVAL; | |
411 | } | |
412 | } | |
413 | ||
518fb721 GG |
414 | static int tps65910_is_enabled(struct regulator_dev *dev) |
415 | { | |
416 | struct tps65910_reg *pmic = rdev_get_drvdata(dev); | |
417 | int reg, value, id = rdev_get_id(dev); | |
418 | ||
a320e3c3 | 419 | reg = pmic->get_ctrl_reg(id); |
518fb721 GG |
420 | if (reg < 0) |
421 | return reg; | |
422 | ||
423 | value = tps65910_reg_read(pmic, reg); | |
424 | if (value < 0) | |
425 | return value; | |
426 | ||
427 | return value & TPS65910_SUPPLY_STATE_ENABLED; | |
428 | } | |
429 | ||
430 | static int tps65910_enable(struct regulator_dev *dev) | |
431 | { | |
432 | struct tps65910_reg *pmic = rdev_get_drvdata(dev); | |
433 | struct tps65910 *mfd = pmic->mfd; | |
434 | int reg, id = rdev_get_id(dev); | |
435 | ||
a320e3c3 | 436 | reg = pmic->get_ctrl_reg(id); |
518fb721 GG |
437 | if (reg < 0) |
438 | return reg; | |
439 | ||
440 | return tps65910_set_bits(mfd, reg, TPS65910_SUPPLY_STATE_ENABLED); | |
441 | } | |
442 | ||
443 | static int tps65910_disable(struct regulator_dev *dev) | |
444 | { | |
445 | struct tps65910_reg *pmic = rdev_get_drvdata(dev); | |
446 | struct tps65910 *mfd = pmic->mfd; | |
447 | int reg, id = rdev_get_id(dev); | |
448 | ||
a320e3c3 | 449 | reg = pmic->get_ctrl_reg(id); |
518fb721 GG |
450 | if (reg < 0) |
451 | return reg; | |
452 | ||
453 | return tps65910_clear_bits(mfd, reg, TPS65910_SUPPLY_STATE_ENABLED); | |
454 | } | |
455 | ||
456 | ||
457 | static int tps65910_set_mode(struct regulator_dev *dev, unsigned int mode) | |
458 | { | |
459 | struct tps65910_reg *pmic = rdev_get_drvdata(dev); | |
460 | struct tps65910 *mfd = pmic->mfd; | |
461 | int reg, value, id = rdev_get_id(dev); | |
a320e3c3 JEC |
462 | |
463 | reg = pmic->get_ctrl_reg(id); | |
518fb721 GG |
464 | if (reg < 0) |
465 | return reg; | |
466 | ||
467 | switch (mode) { | |
468 | case REGULATOR_MODE_NORMAL: | |
469 | return tps65910_modify_bits(pmic, reg, LDO_ST_ON_BIT, | |
470 | LDO_ST_MODE_BIT); | |
471 | case REGULATOR_MODE_IDLE: | |
472 | value = LDO_ST_ON_BIT | LDO_ST_MODE_BIT; | |
473 | return tps65910_set_bits(mfd, reg, value); | |
474 | case REGULATOR_MODE_STANDBY: | |
475 | return tps65910_clear_bits(mfd, reg, LDO_ST_ON_BIT); | |
476 | } | |
477 | ||
478 | return -EINVAL; | |
479 | } | |
480 | ||
481 | static unsigned int tps65910_get_mode(struct regulator_dev *dev) | |
482 | { | |
483 | struct tps65910_reg *pmic = rdev_get_drvdata(dev); | |
484 | int reg, value, id = rdev_get_id(dev); | |
485 | ||
a320e3c3 | 486 | reg = pmic->get_ctrl_reg(id); |
518fb721 GG |
487 | if (reg < 0) |
488 | return reg; | |
489 | ||
490 | value = tps65910_reg_read(pmic, reg); | |
491 | if (value < 0) | |
492 | return value; | |
493 | ||
494 | if (value & LDO_ST_ON_BIT) | |
495 | return REGULATOR_MODE_STANDBY; | |
496 | else if (value & LDO_ST_MODE_BIT) | |
497 | return REGULATOR_MODE_IDLE; | |
498 | else | |
499 | return REGULATOR_MODE_NORMAL; | |
500 | } | |
501 | ||
502 | static int tps65910_get_voltage_dcdc(struct regulator_dev *dev) | |
503 | { | |
504 | struct tps65910_reg *pmic = rdev_get_drvdata(dev); | |
505 | int id = rdev_get_id(dev), voltage = 0; | |
a320e3c3 | 506 | int opvsel = 0, srvsel = 0, vselmax = 0, mult = 0, sr = 0; |
518fb721 GG |
507 | |
508 | switch (id) { | |
509 | case TPS65910_REG_VDD1: | |
510 | opvsel = tps65910_reg_read(pmic, TPS65910_VDD1_OP); | |
511 | mult = tps65910_reg_read(pmic, TPS65910_VDD1); | |
512 | mult = (mult & VDD1_VGAIN_SEL_MASK) >> VDD1_VGAIN_SEL_SHIFT; | |
513 | srvsel = tps65910_reg_read(pmic, TPS65910_VDD1_SR); | |
514 | sr = opvsel & VDD1_OP_CMD_MASK; | |
515 | opvsel &= VDD1_OP_SEL_MASK; | |
516 | srvsel &= VDD1_SR_SEL_MASK; | |
a320e3c3 | 517 | vselmax = 75; |
518fb721 GG |
518 | break; |
519 | case TPS65910_REG_VDD2: | |
520 | opvsel = tps65910_reg_read(pmic, TPS65910_VDD2_OP); | |
521 | mult = tps65910_reg_read(pmic, TPS65910_VDD2); | |
522 | mult = (mult & VDD2_VGAIN_SEL_MASK) >> VDD2_VGAIN_SEL_SHIFT; | |
523 | srvsel = tps65910_reg_read(pmic, TPS65910_VDD2_SR); | |
524 | sr = opvsel & VDD2_OP_CMD_MASK; | |
525 | opvsel &= VDD2_OP_SEL_MASK; | |
526 | srvsel &= VDD2_SR_SEL_MASK; | |
a320e3c3 JEC |
527 | vselmax = 75; |
528 | break; | |
529 | case TPS65911_REG_VDDCTRL: | |
530 | opvsel = tps65910_reg_read(pmic, TPS65911_VDDCTRL_OP); | |
531 | srvsel = tps65910_reg_read(pmic, TPS65911_VDDCTRL_SR); | |
532 | sr = opvsel & VDDCTRL_OP_CMD_MASK; | |
533 | opvsel &= VDDCTRL_OP_SEL_MASK; | |
534 | srvsel &= VDDCTRL_SR_SEL_MASK; | |
535 | vselmax = 64; | |
518fb721 GG |
536 | break; |
537 | } | |
538 | ||
539 | /* multiplier 0 == 1 but 2,3 normal */ | |
540 | if (!mult) | |
541 | mult=1; | |
542 | ||
543 | if (sr) { | |
a320e3c3 JEC |
544 | /* normalise to valid range */ |
545 | if (srvsel < 3) | |
546 | srvsel = 3; | |
547 | if (srvsel > vselmax) | |
548 | srvsel = vselmax; | |
518fb721 GG |
549 | srvsel -= 3; |
550 | ||
551 | voltage = (srvsel * VDD1_2_OFFSET + VDD1_2_MIN_VOLT) * 100; | |
552 | } else { | |
553 | ||
a320e3c3 JEC |
554 | /* normalise to valid range*/ |
555 | if (opvsel < 3) | |
556 | opvsel = 3; | |
557 | if (opvsel > vselmax) | |
558 | opvsel = vselmax; | |
518fb721 GG |
559 | opvsel -= 3; |
560 | ||
561 | voltage = (opvsel * VDD1_2_OFFSET + VDD1_2_MIN_VOLT) * 100; | |
562 | } | |
563 | ||
564 | voltage *= mult; | |
565 | ||
566 | return voltage; | |
567 | } | |
568 | ||
569 | static int tps65910_get_voltage(struct regulator_dev *dev) | |
570 | { | |
571 | struct tps65910_reg *pmic = rdev_get_drvdata(dev); | |
572 | int reg, value, id = rdev_get_id(dev), voltage = 0; | |
573 | ||
a320e3c3 | 574 | reg = pmic->get_ctrl_reg(id); |
518fb721 GG |
575 | if (reg < 0) |
576 | return reg; | |
577 | ||
578 | value = tps65910_reg_read(pmic, reg); | |
579 | if (value < 0) | |
580 | return value; | |
581 | ||
582 | switch (id) { | |
583 | case TPS65910_REG_VIO: | |
584 | case TPS65910_REG_VDIG1: | |
585 | case TPS65910_REG_VDIG2: | |
586 | case TPS65910_REG_VPLL: | |
587 | case TPS65910_REG_VDAC: | |
588 | case TPS65910_REG_VAUX1: | |
589 | case TPS65910_REG_VAUX2: | |
590 | case TPS65910_REG_VAUX33: | |
591 | case TPS65910_REG_VMMC: | |
592 | value &= LDO_SEL_MASK; | |
593 | value >>= LDO_SEL_SHIFT; | |
594 | break; | |
595 | default: | |
596 | return -EINVAL; | |
597 | } | |
598 | ||
599 | voltage = pmic->info[id]->table[value] * 1000; | |
600 | ||
601 | return voltage; | |
602 | } | |
603 | ||
604 | static int tps65910_get_voltage_vdd3(struct regulator_dev *dev) | |
605 | { | |
606 | return 5 * 1000 * 1000; | |
607 | } | |
608 | ||
a320e3c3 JEC |
609 | static int tps65911_get_voltage(struct regulator_dev *dev) |
610 | { | |
611 | struct tps65910_reg *pmic = rdev_get_drvdata(dev); | |
612 | int step_mv, id = rdev_get_id(dev); | |
613 | u8 value, reg; | |
614 | ||
615 | reg = pmic->get_ctrl_reg(id); | |
616 | ||
617 | value = tps65910_reg_read(pmic, reg); | |
618 | ||
619 | switch (id) { | |
620 | case TPS65911_REG_LDO1: | |
621 | case TPS65911_REG_LDO2: | |
622 | case TPS65911_REG_LDO4: | |
623 | value &= LDO1_SEL_MASK; | |
624 | value >>= LDO_SEL_SHIFT; | |
625 | /* The first 5 values of the selector correspond to 1V */ | |
626 | if (value < 5) | |
627 | value = 0; | |
628 | else | |
629 | value -= 4; | |
630 | ||
631 | step_mv = 50; | |
632 | break; | |
633 | case TPS65911_REG_LDO3: | |
634 | case TPS65911_REG_LDO5: | |
635 | case TPS65911_REG_LDO6: | |
636 | case TPS65911_REG_LDO7: | |
637 | case TPS65911_REG_LDO8: | |
638 | value &= LDO3_SEL_MASK; | |
639 | value >>= LDO_SEL_SHIFT; | |
640 | /* The first 3 values of the selector correspond to 1V */ | |
641 | if (value < 3) | |
642 | value = 0; | |
643 | else | |
644 | value -= 2; | |
645 | ||
646 | step_mv = 100; | |
647 | break; | |
648 | case TPS65910_REG_VIO: | |
649 | return pmic->info[id]->table[value] * 1000; | |
650 | break; | |
651 | default: | |
652 | return -EINVAL; | |
653 | } | |
654 | ||
655 | return (LDO_MIN_VOLT + value * step_mv) * 1000; | |
656 | } | |
657 | ||
518fb721 GG |
658 | static int tps65910_set_voltage_dcdc(struct regulator_dev *dev, |
659 | unsigned selector) | |
660 | { | |
661 | struct tps65910_reg *pmic = rdev_get_drvdata(dev); | |
662 | int id = rdev_get_id(dev), vsel; | |
a320e3c3 | 663 | int dcdc_mult = 0; |
518fb721 | 664 | |
a320e3c3 JEC |
665 | switch (id) { |
666 | case TPS65910_REG_VDD1: | |
667 | dcdc_mult = (selector / VDD1_2_NUM_VOLTS) + 1; | |
668 | if (dcdc_mult == 1) | |
669 | dcdc_mult--; | |
670 | vsel = (selector % VDD1_2_NUM_VOLTS) + 3; | |
518fb721 | 671 | |
518fb721 GG |
672 | tps65910_modify_bits(pmic, TPS65910_VDD1, |
673 | (dcdc_mult << VDD1_VGAIN_SEL_SHIFT), | |
674 | VDD1_VGAIN_SEL_MASK); | |
675 | tps65910_reg_write(pmic, TPS65910_VDD1_OP, vsel); | |
a320e3c3 JEC |
676 | break; |
677 | case TPS65910_REG_VDD2: | |
678 | dcdc_mult = (selector / VDD1_2_NUM_VOLTS) + 1; | |
679 | if (dcdc_mult == 1) | |
680 | dcdc_mult--; | |
681 | vsel = (selector % VDD1_2_NUM_VOLTS) + 3; | |
682 | ||
518fb721 GG |
683 | tps65910_modify_bits(pmic, TPS65910_VDD2, |
684 | (dcdc_mult << VDD2_VGAIN_SEL_SHIFT), | |
685 | VDD1_VGAIN_SEL_MASK); | |
686 | tps65910_reg_write(pmic, TPS65910_VDD2_OP, vsel); | |
a320e3c3 JEC |
687 | break; |
688 | case TPS65911_REG_VDDCTRL: | |
689 | vsel = selector; | |
690 | tps65910_reg_write(pmic, TPS65911_VDDCTRL_OP, vsel); | |
518fb721 GG |
691 | } |
692 | ||
693 | return 0; | |
694 | } | |
695 | ||
696 | static int tps65910_set_voltage(struct regulator_dev *dev, unsigned selector) | |
697 | { | |
698 | struct tps65910_reg *pmic = rdev_get_drvdata(dev); | |
699 | int reg, id = rdev_get_id(dev); | |
700 | ||
a320e3c3 | 701 | reg = pmic->get_ctrl_reg(id); |
518fb721 GG |
702 | if (reg < 0) |
703 | return reg; | |
704 | ||
705 | switch (id) { | |
706 | case TPS65910_REG_VIO: | |
707 | case TPS65910_REG_VDIG1: | |
708 | case TPS65910_REG_VDIG2: | |
709 | case TPS65910_REG_VPLL: | |
710 | case TPS65910_REG_VDAC: | |
711 | case TPS65910_REG_VAUX1: | |
712 | case TPS65910_REG_VAUX2: | |
713 | case TPS65910_REG_VAUX33: | |
714 | case TPS65910_REG_VMMC: | |
715 | return tps65910_modify_bits(pmic, reg, | |
716 | (selector << LDO_SEL_SHIFT), LDO_SEL_MASK); | |
717 | } | |
718 | ||
719 | return -EINVAL; | |
720 | } | |
721 | ||
a320e3c3 JEC |
722 | static int tps65911_set_voltage(struct regulator_dev *dev, unsigned selector) |
723 | { | |
724 | struct tps65910_reg *pmic = rdev_get_drvdata(dev); | |
725 | int reg, id = rdev_get_id(dev); | |
726 | ||
727 | reg = pmic->get_ctrl_reg(id); | |
728 | if (reg < 0) | |
729 | return reg; | |
730 | ||
731 | switch (id) { | |
732 | case TPS65911_REG_LDO1: | |
733 | case TPS65911_REG_LDO2: | |
734 | case TPS65911_REG_LDO4: | |
735 | return tps65910_modify_bits(pmic, reg, | |
736 | (selector << LDO_SEL_SHIFT), LDO1_SEL_MASK); | |
737 | case TPS65911_REG_LDO3: | |
738 | case TPS65911_REG_LDO5: | |
739 | case TPS65911_REG_LDO6: | |
740 | case TPS65911_REG_LDO7: | |
741 | case TPS65911_REG_LDO8: | |
742 | case TPS65910_REG_VIO: | |
743 | return tps65910_modify_bits(pmic, reg, | |
744 | (selector << LDO_SEL_SHIFT), LDO3_SEL_MASK); | |
745 | } | |
746 | ||
747 | return -EINVAL; | |
748 | } | |
749 | ||
750 | ||
518fb721 GG |
751 | static int tps65910_list_voltage_dcdc(struct regulator_dev *dev, |
752 | unsigned selector) | |
753 | { | |
a320e3c3 | 754 | int volt, mult = 1, id = rdev_get_id(dev); |
518fb721 | 755 | |
a320e3c3 JEC |
756 | switch (id) { |
757 | case TPS65910_REG_VDD1: | |
758 | case TPS65910_REG_VDD2: | |
759 | mult = (selector / VDD1_2_NUM_VOLTS) + 1; | |
760 | volt = VDD1_2_MIN_VOLT + | |
761 | (selector % VDD1_2_NUM_VOLTS) * VDD1_2_OFFSET; | |
d04156bc | 762 | break; |
a320e3c3 JEC |
763 | case TPS65911_REG_VDDCTRL: |
764 | volt = VDDCTRL_MIN_VOLT + (selector * VDDCTRL_OFFSET); | |
d04156bc AL |
765 | break; |
766 | default: | |
767 | BUG(); | |
768 | return -EINVAL; | |
a320e3c3 | 769 | } |
518fb721 GG |
770 | |
771 | return volt * 100 * mult; | |
772 | } | |
773 | ||
774 | static int tps65910_list_voltage(struct regulator_dev *dev, | |
775 | unsigned selector) | |
776 | { | |
777 | struct tps65910_reg *pmic = rdev_get_drvdata(dev); | |
778 | int id = rdev_get_id(dev), voltage; | |
779 | ||
780 | if (id < TPS65910_REG_VIO || id > TPS65910_REG_VMMC) | |
781 | return -EINVAL; | |
782 | ||
783 | if (selector >= pmic->info[id]->table_len) | |
784 | return -EINVAL; | |
785 | else | |
786 | voltage = pmic->info[id]->table[selector] * 1000; | |
787 | ||
788 | return voltage; | |
789 | } | |
790 | ||
a320e3c3 JEC |
791 | static int tps65911_list_voltage(struct regulator_dev *dev, unsigned selector) |
792 | { | |
793 | struct tps65910_reg *pmic = rdev_get_drvdata(dev); | |
794 | int step_mv = 0, id = rdev_get_id(dev); | |
795 | ||
796 | switch(id) { | |
797 | case TPS65911_REG_LDO1: | |
798 | case TPS65911_REG_LDO2: | |
799 | case TPS65911_REG_LDO4: | |
800 | /* The first 5 values of the selector correspond to 1V */ | |
801 | if (selector < 5) | |
802 | selector = 0; | |
803 | else | |
804 | selector -= 4; | |
805 | ||
806 | step_mv = 50; | |
807 | break; | |
808 | case TPS65911_REG_LDO3: | |
809 | case TPS65911_REG_LDO5: | |
810 | case TPS65911_REG_LDO6: | |
811 | case TPS65911_REG_LDO7: | |
812 | case TPS65911_REG_LDO8: | |
813 | /* The first 3 values of the selector correspond to 1V */ | |
814 | if (selector < 3) | |
815 | selector = 0; | |
816 | else | |
817 | selector -= 2; | |
818 | ||
819 | step_mv = 100; | |
820 | break; | |
821 | case TPS65910_REG_VIO: | |
822 | return pmic->info[id]->table[selector] * 1000; | |
823 | default: | |
824 | return -EINVAL; | |
825 | } | |
826 | ||
827 | return (LDO_MIN_VOLT + selector * step_mv) * 1000; | |
828 | } | |
829 | ||
518fb721 GG |
830 | /* Regulator ops (except VRTC) */ |
831 | static struct regulator_ops tps65910_ops_dcdc = { | |
832 | .is_enabled = tps65910_is_enabled, | |
833 | .enable = tps65910_enable, | |
834 | .disable = tps65910_disable, | |
835 | .set_mode = tps65910_set_mode, | |
836 | .get_mode = tps65910_get_mode, | |
837 | .get_voltage = tps65910_get_voltage_dcdc, | |
838 | .set_voltage_sel = tps65910_set_voltage_dcdc, | |
839 | .list_voltage = tps65910_list_voltage_dcdc, | |
840 | }; | |
841 | ||
842 | static struct regulator_ops tps65910_ops_vdd3 = { | |
843 | .is_enabled = tps65910_is_enabled, | |
844 | .enable = tps65910_enable, | |
845 | .disable = tps65910_disable, | |
846 | .set_mode = tps65910_set_mode, | |
847 | .get_mode = tps65910_get_mode, | |
848 | .get_voltage = tps65910_get_voltage_vdd3, | |
849 | .list_voltage = tps65910_list_voltage, | |
850 | }; | |
851 | ||
852 | static struct regulator_ops tps65910_ops = { | |
853 | .is_enabled = tps65910_is_enabled, | |
854 | .enable = tps65910_enable, | |
855 | .disable = tps65910_disable, | |
856 | .set_mode = tps65910_set_mode, | |
857 | .get_mode = tps65910_get_mode, | |
858 | .get_voltage = tps65910_get_voltage, | |
859 | .set_voltage_sel = tps65910_set_voltage, | |
860 | .list_voltage = tps65910_list_voltage, | |
861 | }; | |
862 | ||
a320e3c3 JEC |
863 | static struct regulator_ops tps65911_ops = { |
864 | .is_enabled = tps65910_is_enabled, | |
865 | .enable = tps65910_enable, | |
866 | .disable = tps65910_disable, | |
867 | .set_mode = tps65910_set_mode, | |
868 | .get_mode = tps65910_get_mode, | |
869 | .get_voltage = tps65911_get_voltage, | |
870 | .set_voltage_sel = tps65911_set_voltage, | |
871 | .list_voltage = tps65911_list_voltage, | |
872 | }; | |
873 | ||
518fb721 GG |
874 | static __devinit int tps65910_probe(struct platform_device *pdev) |
875 | { | |
876 | struct tps65910 *tps65910 = dev_get_drvdata(pdev->dev.parent); | |
a320e3c3 | 877 | struct tps_info *info; |
518fb721 GG |
878 | struct regulator_init_data *reg_data; |
879 | struct regulator_dev *rdev; | |
880 | struct tps65910_reg *pmic; | |
881 | struct tps65910_board *pmic_plat_data; | |
518fb721 GG |
882 | int i, err; |
883 | ||
884 | pmic_plat_data = dev_get_platdata(tps65910->dev); | |
885 | if (!pmic_plat_data) | |
886 | return -EINVAL; | |
887 | ||
888 | reg_data = pmic_plat_data->tps65910_pmic_init_data; | |
889 | ||
890 | pmic = kzalloc(sizeof(*pmic), GFP_KERNEL); | |
891 | if (!pmic) | |
892 | return -ENOMEM; | |
893 | ||
894 | mutex_init(&pmic->mutex); | |
895 | pmic->mfd = tps65910; | |
896 | platform_set_drvdata(pdev, pmic); | |
897 | ||
898 | /* Give control of all register to control port */ | |
899 | tps65910_set_bits(pmic->mfd, TPS65910_DEVCTRL, | |
900 | DEVCTRL_SR_CTL_I2C_SEL_MASK); | |
901 | ||
a320e3c3 JEC |
902 | switch(tps65910_chip_id(tps65910)) { |
903 | case TPS65910: | |
904 | pmic->get_ctrl_reg = &tps65910_get_ctrl_register; | |
905 | info = tps65910_regs; | |
d04156bc | 906 | break; |
a320e3c3 JEC |
907 | case TPS65911: |
908 | pmic->get_ctrl_reg = &tps65911_get_ctrl_register; | |
909 | info = tps65911_regs; | |
d04156bc | 910 | break; |
a320e3c3 JEC |
911 | default: |
912 | pr_err("Invalid tps chip version\n"); | |
a3ee13ee | 913 | kfree(pmic); |
a320e3c3 JEC |
914 | return -ENODEV; |
915 | } | |
916 | ||
518fb721 GG |
917 | for (i = 0; i < TPS65910_NUM_REGULATOR; i++, info++, reg_data++) { |
918 | /* Register the regulators */ | |
919 | pmic->info[i] = info; | |
920 | ||
921 | pmic->desc[i].name = info->name; | |
77fa44d0 | 922 | pmic->desc[i].id = i; |
518fb721 GG |
923 | pmic->desc[i].n_voltages = info->table_len; |
924 | ||
a320e3c3 | 925 | if (i == TPS65910_REG_VDD1 || i == TPS65910_REG_VDD2) { |
518fb721 | 926 | pmic->desc[i].ops = &tps65910_ops_dcdc; |
a320e3c3 JEC |
927 | } else if (i == TPS65910_REG_VDD3) { |
928 | if (tps65910_chip_id(tps65910) == TPS65910) | |
929 | pmic->desc[i].ops = &tps65910_ops_vdd3; | |
930 | else | |
931 | pmic->desc[i].ops = &tps65910_ops_dcdc; | |
932 | } else { | |
933 | if (tps65910_chip_id(tps65910) == TPS65910) | |
934 | pmic->desc[i].ops = &tps65910_ops; | |
935 | else | |
936 | pmic->desc[i].ops = &tps65911_ops; | |
937 | } | |
518fb721 GG |
938 | |
939 | pmic->desc[i].type = REGULATOR_VOLTAGE; | |
940 | pmic->desc[i].owner = THIS_MODULE; | |
941 | ||
942 | rdev = regulator_register(&pmic->desc[i], | |
943 | tps65910->dev, reg_data, pmic); | |
944 | if (IS_ERR(rdev)) { | |
945 | dev_err(tps65910->dev, | |
946 | "failed to register %s regulator\n", | |
947 | pdev->name); | |
948 | err = PTR_ERR(rdev); | |
949 | goto err; | |
950 | } | |
951 | ||
952 | /* Save regulator for cleanup */ | |
953 | pmic->rdev[i] = rdev; | |
954 | } | |
955 | return 0; | |
956 | ||
957 | err: | |
958 | while (--i >= 0) | |
959 | regulator_unregister(pmic->rdev[i]); | |
960 | ||
961 | kfree(pmic); | |
962 | return err; | |
963 | } | |
964 | ||
965 | static int __devexit tps65910_remove(struct platform_device *pdev) | |
966 | { | |
967 | struct tps65910_reg *tps65910_reg = platform_get_drvdata(pdev); | |
968 | int i; | |
969 | ||
970 | for (i = 0; i < TPS65910_NUM_REGULATOR; i++) | |
971 | regulator_unregister(tps65910_reg->rdev[i]); | |
972 | ||
973 | kfree(tps65910_reg); | |
974 | return 0; | |
975 | } | |
976 | ||
977 | static struct platform_driver tps65910_driver = { | |
978 | .driver = { | |
979 | .name = "tps65910-pmic", | |
980 | .owner = THIS_MODULE, | |
981 | }, | |
982 | .probe = tps65910_probe, | |
983 | .remove = __devexit_p(tps65910_remove), | |
984 | }; | |
985 | ||
986 | static int __init tps65910_init(void) | |
987 | { | |
988 | return platform_driver_register(&tps65910_driver); | |
989 | } | |
990 | subsys_initcall(tps65910_init); | |
991 | ||
992 | static void __exit tps65910_cleanup(void) | |
993 | { | |
994 | platform_driver_unregister(&tps65910_driver); | |
995 | } | |
996 | module_exit(tps65910_cleanup); | |
997 | ||
998 | MODULE_AUTHOR("Graeme Gregory <gg@slimlogic.co.uk>"); | |
999 | MODULE_DESCRIPTION("TPS6507x voltage regulator driver"); | |
1000 | MODULE_LICENSE("GPL v2"); | |
1001 | MODULE_ALIAS("platform:tps65910-pmic"); |