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