blob: 67424185b365d9f22a7dad9439e1c88a05651e69 [file] [log] [blame]
Graeme Gregory518fb722011-05-02 16:20:08 -05001/*
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
Graeme Gregory518fb722011-05-02 16:20:08 -050028#define TPS65910_SUPPLY_STATE_ENABLED 0x1
29
30/* supported VIO voltages in milivolts */
31static const u16 VIO_VSEL_table[] = {
32 1500, 1800, 2500, 3300,
33};
34
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -050035/* VSEL tables for TPS65910 specific LDOs and dcdc's */
36
37/* supported VDD3 voltages in milivolts */
Graeme Gregory518fb722011-05-02 16:20:08 -050038static const u16 VDD3_VSEL_table[] = {
39 5000,
40};
41
42/* supported VDIG1 voltages in milivolts */
43static const u16 VDIG1_VSEL_table[] = {
44 1200, 1500, 1800, 2700,
45};
46
47/* supported VDIG2 voltages in milivolts */
48static const u16 VDIG2_VSEL_table[] = {
49 1000, 1100, 1200, 1800,
50};
51
52/* supported VPLL voltages in milivolts */
53static const u16 VPLL_VSEL_table[] = {
54 1000, 1100, 1800, 2500,
55};
56
57/* supported VDAC voltages in milivolts */
58static const u16 VDAC_VSEL_table[] = {
59 1800, 2600, 2800, 2850,
60};
61
62/* supported VAUX1 voltages in milivolts */
63static const u16 VAUX1_VSEL_table[] = {
64 1800, 2500, 2800, 2850,
65};
66
67/* supported VAUX2 voltages in milivolts */
68static const u16 VAUX2_VSEL_table[] = {
69 1800, 2800, 2900, 3300,
70};
71
72/* supported VAUX33 voltages in milivolts */
73static const u16 VAUX33_VSEL_table[] = {
74 1800, 2000, 2800, 3300,
75};
76
77/* supported VMMC voltages in milivolts */
78static const u16 VMMC_VSEL_table[] = {
79 1800, 2800, 3000, 3300,
80};
81
82struct tps_info {
83 const char *name;
84 unsigned min_uV;
85 unsigned max_uV;
86 u8 table_len;
87 const u16 *table;
88};
89
90static 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
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500176static struct tps_info tps65911_regs[] = {
177 {
Laxman Dewanganc2f8efd2012-01-18 20:46:56 +0530178 .name = "VRTC",
179 },
180 {
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500181 .name = "VIO",
182 .min_uV = 1500000,
183 .max_uV = 3300000,
184 .table_len = ARRAY_SIZE(VIO_VSEL_table),
185 .table = VIO_VSEL_table,
186 },
187 {
188 .name = "VDD1",
189 .min_uV = 600000,
190 .max_uV = 4500000,
191 },
192 {
193 .name = "VDD2",
194 .min_uV = 600000,
195 .max_uV = 4500000,
196 },
197 {
198 .name = "VDDCTRL",
199 .min_uV = 600000,
200 .max_uV = 1400000,
201 },
202 {
203 .name = "LDO1",
204 .min_uV = 1000000,
205 .max_uV = 3300000,
206 },
207 {
208 .name = "LDO2",
209 .min_uV = 1000000,
210 .max_uV = 3300000,
211 },
212 {
213 .name = "LDO3",
214 .min_uV = 1000000,
215 .max_uV = 3300000,
216 },
217 {
218 .name = "LDO4",
219 .min_uV = 1000000,
220 .max_uV = 3300000,
221 },
222 {
223 .name = "LDO5",
224 .min_uV = 1000000,
225 .max_uV = 3300000,
226 },
227 {
228 .name = "LDO6",
229 .min_uV = 1000000,
230 .max_uV = 3300000,
231 },
232 {
233 .name = "LDO7",
234 .min_uV = 1000000,
235 .max_uV = 3300000,
236 },
237 {
238 .name = "LDO8",
239 .min_uV = 1000000,
240 .max_uV = 3300000,
241 },
242};
243
Graeme Gregory518fb722011-05-02 16:20:08 -0500244struct tps65910_reg {
Axel Lin39aa9b62011-07-11 09:57:43 +0800245 struct regulator_desc *desc;
Graeme Gregory518fb722011-05-02 16:20:08 -0500246 struct tps65910 *mfd;
Axel Lin39aa9b62011-07-11 09:57:43 +0800247 struct regulator_dev **rdev;
248 struct tps_info **info;
Graeme Gregory518fb722011-05-02 16:20:08 -0500249 struct mutex mutex;
Axel Lin39aa9b62011-07-11 09:57:43 +0800250 int num_regulators;
Graeme Gregory518fb722011-05-02 16:20:08 -0500251 int mode;
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500252 int (*get_ctrl_reg)(int);
Graeme Gregory518fb722011-05-02 16:20:08 -0500253};
254
255static inline int tps65910_read(struct tps65910_reg *pmic, u8 reg)
256{
257 u8 val;
258 int err;
259
260 err = pmic->mfd->read(pmic->mfd, reg, 1, &val);
261 if (err)
262 return err;
263
264 return val;
265}
266
267static inline int tps65910_write(struct tps65910_reg *pmic, u8 reg, u8 val)
268{
269 return pmic->mfd->write(pmic->mfd, reg, 1, &val);
270}
271
272static int tps65910_modify_bits(struct tps65910_reg *pmic, u8 reg,
273 u8 set_mask, u8 clear_mask)
274{
275 int err, data;
276
277 mutex_lock(&pmic->mutex);
278
279 data = tps65910_read(pmic, reg);
280 if (data < 0) {
281 dev_err(pmic->mfd->dev, "Read from reg 0x%x failed\n", reg);
282 err = data;
283 goto out;
284 }
285
286 data &= ~clear_mask;
287 data |= set_mask;
288 err = tps65910_write(pmic, reg, data);
289 if (err)
290 dev_err(pmic->mfd->dev, "Write for reg 0x%x failed\n", reg);
291
292out:
293 mutex_unlock(&pmic->mutex);
294 return err;
295}
296
297static int tps65910_reg_read(struct tps65910_reg *pmic, u8 reg)
298{
299 int data;
300
301 mutex_lock(&pmic->mutex);
302
303 data = tps65910_read(pmic, reg);
304 if (data < 0)
305 dev_err(pmic->mfd->dev, "Read from reg 0x%x failed\n", reg);
306
307 mutex_unlock(&pmic->mutex);
308 return data;
309}
310
311static int tps65910_reg_write(struct tps65910_reg *pmic, u8 reg, u8 val)
312{
313 int err;
314
315 mutex_lock(&pmic->mutex);
316
317 err = tps65910_write(pmic, reg, val);
318 if (err < 0)
319 dev_err(pmic->mfd->dev, "Write for reg 0x%x failed\n", reg);
320
321 mutex_unlock(&pmic->mutex);
322 return err;
323}
324
325static int tps65910_get_ctrl_register(int id)
326{
327 switch (id) {
328 case TPS65910_REG_VRTC:
329 return TPS65910_VRTC;
330 case TPS65910_REG_VIO:
331 return TPS65910_VIO;
332 case TPS65910_REG_VDD1:
333 return TPS65910_VDD1;
334 case TPS65910_REG_VDD2:
335 return TPS65910_VDD2;
336 case TPS65910_REG_VDD3:
337 return TPS65910_VDD3;
338 case TPS65910_REG_VDIG1:
339 return TPS65910_VDIG1;
340 case TPS65910_REG_VDIG2:
341 return TPS65910_VDIG2;
342 case TPS65910_REG_VPLL:
343 return TPS65910_VPLL;
344 case TPS65910_REG_VDAC:
345 return TPS65910_VDAC;
346 case TPS65910_REG_VAUX1:
347 return TPS65910_VAUX1;
348 case TPS65910_REG_VAUX2:
349 return TPS65910_VAUX2;
350 case TPS65910_REG_VAUX33:
351 return TPS65910_VAUX33;
352 case TPS65910_REG_VMMC:
353 return TPS65910_VMMC;
354 default:
355 return -EINVAL;
356 }
357}
358
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500359static int tps65911_get_ctrl_register(int id)
360{
361 switch (id) {
362 case TPS65910_REG_VRTC:
363 return TPS65910_VRTC;
364 case TPS65910_REG_VIO:
365 return TPS65910_VIO;
366 case TPS65910_REG_VDD1:
367 return TPS65910_VDD1;
368 case TPS65910_REG_VDD2:
369 return TPS65910_VDD2;
370 case TPS65911_REG_VDDCTRL:
371 return TPS65911_VDDCTRL;
372 case TPS65911_REG_LDO1:
373 return TPS65911_LDO1;
374 case TPS65911_REG_LDO2:
375 return TPS65911_LDO2;
376 case TPS65911_REG_LDO3:
377 return TPS65911_LDO3;
378 case TPS65911_REG_LDO4:
379 return TPS65911_LDO4;
380 case TPS65911_REG_LDO5:
381 return TPS65911_LDO5;
382 case TPS65911_REG_LDO6:
383 return TPS65911_LDO6;
384 case TPS65911_REG_LDO7:
385 return TPS65911_LDO7;
386 case TPS65911_REG_LDO8:
387 return TPS65911_LDO8;
388 default:
389 return -EINVAL;
390 }
391}
392
Graeme Gregory518fb722011-05-02 16:20:08 -0500393static int tps65910_is_enabled(struct regulator_dev *dev)
394{
395 struct tps65910_reg *pmic = rdev_get_drvdata(dev);
396 int reg, value, id = rdev_get_id(dev);
397
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500398 reg = pmic->get_ctrl_reg(id);
Graeme Gregory518fb722011-05-02 16:20:08 -0500399 if (reg < 0)
400 return reg;
401
402 value = tps65910_reg_read(pmic, reg);
403 if (value < 0)
404 return value;
405
406 return value & TPS65910_SUPPLY_STATE_ENABLED;
407}
408
409static int tps65910_enable(struct regulator_dev *dev)
410{
411 struct tps65910_reg *pmic = rdev_get_drvdata(dev);
412 struct tps65910 *mfd = pmic->mfd;
413 int reg, id = rdev_get_id(dev);
414
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500415 reg = pmic->get_ctrl_reg(id);
Graeme Gregory518fb722011-05-02 16:20:08 -0500416 if (reg < 0)
417 return reg;
418
419 return tps65910_set_bits(mfd, reg, TPS65910_SUPPLY_STATE_ENABLED);
420}
421
422static int tps65910_disable(struct regulator_dev *dev)
423{
424 struct tps65910_reg *pmic = rdev_get_drvdata(dev);
425 struct tps65910 *mfd = pmic->mfd;
426 int reg, id = rdev_get_id(dev);
427
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500428 reg = pmic->get_ctrl_reg(id);
Graeme Gregory518fb722011-05-02 16:20:08 -0500429 if (reg < 0)
430 return reg;
431
432 return tps65910_clear_bits(mfd, reg, TPS65910_SUPPLY_STATE_ENABLED);
433}
434
435
436static int tps65910_set_mode(struct regulator_dev *dev, unsigned int mode)
437{
438 struct tps65910_reg *pmic = rdev_get_drvdata(dev);
439 struct tps65910 *mfd = pmic->mfd;
440 int reg, value, id = rdev_get_id(dev);
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500441
442 reg = pmic->get_ctrl_reg(id);
Graeme Gregory518fb722011-05-02 16:20:08 -0500443 if (reg < 0)
444 return reg;
445
446 switch (mode) {
447 case REGULATOR_MODE_NORMAL:
448 return tps65910_modify_bits(pmic, reg, LDO_ST_ON_BIT,
449 LDO_ST_MODE_BIT);
450 case REGULATOR_MODE_IDLE:
451 value = LDO_ST_ON_BIT | LDO_ST_MODE_BIT;
452 return tps65910_set_bits(mfd, reg, value);
453 case REGULATOR_MODE_STANDBY:
454 return tps65910_clear_bits(mfd, reg, LDO_ST_ON_BIT);
455 }
456
457 return -EINVAL;
458}
459
460static unsigned int tps65910_get_mode(struct regulator_dev *dev)
461{
462 struct tps65910_reg *pmic = rdev_get_drvdata(dev);
463 int reg, value, id = rdev_get_id(dev);
464
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500465 reg = pmic->get_ctrl_reg(id);
Graeme Gregory518fb722011-05-02 16:20:08 -0500466 if (reg < 0)
467 return reg;
468
469 value = tps65910_reg_read(pmic, reg);
470 if (value < 0)
471 return value;
472
473 if (value & LDO_ST_ON_BIT)
474 return REGULATOR_MODE_STANDBY;
475 else if (value & LDO_ST_MODE_BIT)
476 return REGULATOR_MODE_IDLE;
477 else
478 return REGULATOR_MODE_NORMAL;
479}
480
481static int tps65910_get_voltage_dcdc(struct regulator_dev *dev)
482{
483 struct tps65910_reg *pmic = rdev_get_drvdata(dev);
484 int id = rdev_get_id(dev), voltage = 0;
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500485 int opvsel = 0, srvsel = 0, vselmax = 0, mult = 0, sr = 0;
Graeme Gregory518fb722011-05-02 16:20:08 -0500486
487 switch (id) {
488 case TPS65910_REG_VDD1:
489 opvsel = tps65910_reg_read(pmic, TPS65910_VDD1_OP);
490 mult = tps65910_reg_read(pmic, TPS65910_VDD1);
491 mult = (mult & VDD1_VGAIN_SEL_MASK) >> VDD1_VGAIN_SEL_SHIFT;
492 srvsel = tps65910_reg_read(pmic, TPS65910_VDD1_SR);
493 sr = opvsel & VDD1_OP_CMD_MASK;
494 opvsel &= VDD1_OP_SEL_MASK;
495 srvsel &= VDD1_SR_SEL_MASK;
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500496 vselmax = 75;
Graeme Gregory518fb722011-05-02 16:20:08 -0500497 break;
498 case TPS65910_REG_VDD2:
499 opvsel = tps65910_reg_read(pmic, TPS65910_VDD2_OP);
500 mult = tps65910_reg_read(pmic, TPS65910_VDD2);
501 mult = (mult & VDD2_VGAIN_SEL_MASK) >> VDD2_VGAIN_SEL_SHIFT;
502 srvsel = tps65910_reg_read(pmic, TPS65910_VDD2_SR);
503 sr = opvsel & VDD2_OP_CMD_MASK;
504 opvsel &= VDD2_OP_SEL_MASK;
505 srvsel &= VDD2_SR_SEL_MASK;
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500506 vselmax = 75;
507 break;
508 case TPS65911_REG_VDDCTRL:
509 opvsel = tps65910_reg_read(pmic, TPS65911_VDDCTRL_OP);
510 srvsel = tps65910_reg_read(pmic, TPS65911_VDDCTRL_SR);
511 sr = opvsel & VDDCTRL_OP_CMD_MASK;
512 opvsel &= VDDCTRL_OP_SEL_MASK;
513 srvsel &= VDDCTRL_SR_SEL_MASK;
514 vselmax = 64;
Graeme Gregory518fb722011-05-02 16:20:08 -0500515 break;
516 }
517
518 /* multiplier 0 == 1 but 2,3 normal */
519 if (!mult)
520 mult=1;
521
522 if (sr) {
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500523 /* normalise to valid range */
524 if (srvsel < 3)
525 srvsel = 3;
526 if (srvsel > vselmax)
527 srvsel = vselmax;
Graeme Gregory518fb722011-05-02 16:20:08 -0500528 srvsel -= 3;
529
530 voltage = (srvsel * VDD1_2_OFFSET + VDD1_2_MIN_VOLT) * 100;
531 } else {
532
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500533 /* normalise to valid range*/
534 if (opvsel < 3)
535 opvsel = 3;
536 if (opvsel > vselmax)
537 opvsel = vselmax;
Graeme Gregory518fb722011-05-02 16:20:08 -0500538 opvsel -= 3;
539
540 voltage = (opvsel * VDD1_2_OFFSET + VDD1_2_MIN_VOLT) * 100;
541 }
542
543 voltage *= mult;
544
545 return voltage;
546}
547
548static int tps65910_get_voltage(struct regulator_dev *dev)
549{
550 struct tps65910_reg *pmic = rdev_get_drvdata(dev);
551 int reg, value, id = rdev_get_id(dev), voltage = 0;
552
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500553 reg = pmic->get_ctrl_reg(id);
Graeme Gregory518fb722011-05-02 16:20:08 -0500554 if (reg < 0)
555 return reg;
556
557 value = tps65910_reg_read(pmic, reg);
558 if (value < 0)
559 return value;
560
561 switch (id) {
562 case TPS65910_REG_VIO:
563 case TPS65910_REG_VDIG1:
564 case TPS65910_REG_VDIG2:
565 case TPS65910_REG_VPLL:
566 case TPS65910_REG_VDAC:
567 case TPS65910_REG_VAUX1:
568 case TPS65910_REG_VAUX2:
569 case TPS65910_REG_VAUX33:
570 case TPS65910_REG_VMMC:
571 value &= LDO_SEL_MASK;
572 value >>= LDO_SEL_SHIFT;
573 break;
574 default:
575 return -EINVAL;
576 }
577
578 voltage = pmic->info[id]->table[value] * 1000;
579
580 return voltage;
581}
582
583static int tps65910_get_voltage_vdd3(struct regulator_dev *dev)
584{
585 return 5 * 1000 * 1000;
586}
587
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500588static int tps65911_get_voltage(struct regulator_dev *dev)
589{
590 struct tps65910_reg *pmic = rdev_get_drvdata(dev);
591 int step_mv, id = rdev_get_id(dev);
592 u8 value, reg;
593
594 reg = pmic->get_ctrl_reg(id);
595
596 value = tps65910_reg_read(pmic, reg);
597
598 switch (id) {
599 case TPS65911_REG_LDO1:
600 case TPS65911_REG_LDO2:
601 case TPS65911_REG_LDO4:
602 value &= LDO1_SEL_MASK;
603 value >>= LDO_SEL_SHIFT;
604 /* The first 5 values of the selector correspond to 1V */
605 if (value < 5)
606 value = 0;
607 else
608 value -= 4;
609
610 step_mv = 50;
611 break;
612 case TPS65911_REG_LDO3:
613 case TPS65911_REG_LDO5:
614 case TPS65911_REG_LDO6:
615 case TPS65911_REG_LDO7:
616 case TPS65911_REG_LDO8:
617 value &= LDO3_SEL_MASK;
618 value >>= LDO_SEL_SHIFT;
619 /* The first 3 values of the selector correspond to 1V */
620 if (value < 3)
621 value = 0;
622 else
623 value -= 2;
624
625 step_mv = 100;
626 break;
627 case TPS65910_REG_VIO:
628 return pmic->info[id]->table[value] * 1000;
629 break;
630 default:
631 return -EINVAL;
632 }
633
634 return (LDO_MIN_VOLT + value * step_mv) * 1000;
635}
636
Graeme Gregory518fb722011-05-02 16:20:08 -0500637static int tps65910_set_voltage_dcdc(struct regulator_dev *dev,
638 unsigned selector)
639{
640 struct tps65910_reg *pmic = rdev_get_drvdata(dev);
641 int id = rdev_get_id(dev), vsel;
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500642 int dcdc_mult = 0;
Graeme Gregory518fb722011-05-02 16:20:08 -0500643
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500644 switch (id) {
645 case TPS65910_REG_VDD1:
Afzal Mohammed780dc9b2011-11-08 18:54:10 +0530646 dcdc_mult = (selector / VDD1_2_NUM_VOLT_FINE) + 1;
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500647 if (dcdc_mult == 1)
648 dcdc_mult--;
Afzal Mohammed780dc9b2011-11-08 18:54:10 +0530649 vsel = (selector % VDD1_2_NUM_VOLT_FINE) + 3;
Graeme Gregory518fb722011-05-02 16:20:08 -0500650
Graeme Gregory518fb722011-05-02 16:20:08 -0500651 tps65910_modify_bits(pmic, TPS65910_VDD1,
652 (dcdc_mult << VDD1_VGAIN_SEL_SHIFT),
653 VDD1_VGAIN_SEL_MASK);
654 tps65910_reg_write(pmic, TPS65910_VDD1_OP, vsel);
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500655 break;
656 case TPS65910_REG_VDD2:
Afzal Mohammed780dc9b2011-11-08 18:54:10 +0530657 dcdc_mult = (selector / VDD1_2_NUM_VOLT_FINE) + 1;
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500658 if (dcdc_mult == 1)
659 dcdc_mult--;
Afzal Mohammed780dc9b2011-11-08 18:54:10 +0530660 vsel = (selector % VDD1_2_NUM_VOLT_FINE) + 3;
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500661
Graeme Gregory518fb722011-05-02 16:20:08 -0500662 tps65910_modify_bits(pmic, TPS65910_VDD2,
663 (dcdc_mult << VDD2_VGAIN_SEL_SHIFT),
664 VDD1_VGAIN_SEL_MASK);
665 tps65910_reg_write(pmic, TPS65910_VDD2_OP, vsel);
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500666 break;
667 case TPS65911_REG_VDDCTRL:
668 vsel = selector;
669 tps65910_reg_write(pmic, TPS65911_VDDCTRL_OP, vsel);
Graeme Gregory518fb722011-05-02 16:20:08 -0500670 }
671
672 return 0;
673}
674
675static int tps65910_set_voltage(struct regulator_dev *dev, unsigned selector)
676{
677 struct tps65910_reg *pmic = rdev_get_drvdata(dev);
678 int reg, id = rdev_get_id(dev);
679
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500680 reg = pmic->get_ctrl_reg(id);
Graeme Gregory518fb722011-05-02 16:20:08 -0500681 if (reg < 0)
682 return reg;
683
684 switch (id) {
685 case TPS65910_REG_VIO:
686 case TPS65910_REG_VDIG1:
687 case TPS65910_REG_VDIG2:
688 case TPS65910_REG_VPLL:
689 case TPS65910_REG_VDAC:
690 case TPS65910_REG_VAUX1:
691 case TPS65910_REG_VAUX2:
692 case TPS65910_REG_VAUX33:
693 case TPS65910_REG_VMMC:
694 return tps65910_modify_bits(pmic, reg,
695 (selector << LDO_SEL_SHIFT), LDO_SEL_MASK);
696 }
697
698 return -EINVAL;
699}
700
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500701static int tps65911_set_voltage(struct regulator_dev *dev, unsigned selector)
702{
703 struct tps65910_reg *pmic = rdev_get_drvdata(dev);
704 int reg, id = rdev_get_id(dev);
705
706 reg = pmic->get_ctrl_reg(id);
707 if (reg < 0)
708 return reg;
709
710 switch (id) {
711 case TPS65911_REG_LDO1:
712 case TPS65911_REG_LDO2:
713 case TPS65911_REG_LDO4:
714 return tps65910_modify_bits(pmic, reg,
715 (selector << LDO_SEL_SHIFT), LDO1_SEL_MASK);
716 case TPS65911_REG_LDO3:
717 case TPS65911_REG_LDO5:
718 case TPS65911_REG_LDO6:
719 case TPS65911_REG_LDO7:
720 case TPS65911_REG_LDO8:
721 case TPS65910_REG_VIO:
722 return tps65910_modify_bits(pmic, reg,
723 (selector << LDO_SEL_SHIFT), LDO3_SEL_MASK);
724 }
725
726 return -EINVAL;
727}
728
729
Graeme Gregory518fb722011-05-02 16:20:08 -0500730static int tps65910_list_voltage_dcdc(struct regulator_dev *dev,
731 unsigned selector)
732{
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500733 int volt, mult = 1, id = rdev_get_id(dev);
Graeme Gregory518fb722011-05-02 16:20:08 -0500734
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500735 switch (id) {
736 case TPS65910_REG_VDD1:
737 case TPS65910_REG_VDD2:
Afzal Mohammed780dc9b2011-11-08 18:54:10 +0530738 mult = (selector / VDD1_2_NUM_VOLT_FINE) + 1;
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500739 volt = VDD1_2_MIN_VOLT +
Afzal Mohammed780dc9b2011-11-08 18:54:10 +0530740 (selector % VDD1_2_NUM_VOLT_FINE) * VDD1_2_OFFSET;
Axel Lind04156b2011-07-10 21:44:09 +0800741 break;
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500742 case TPS65911_REG_VDDCTRL:
743 volt = VDDCTRL_MIN_VOLT + (selector * VDDCTRL_OFFSET);
Axel Lind04156b2011-07-10 21:44:09 +0800744 break;
745 default:
746 BUG();
747 return -EINVAL;
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500748 }
Graeme Gregory518fb722011-05-02 16:20:08 -0500749
750 return volt * 100 * mult;
751}
752
753static int tps65910_list_voltage(struct regulator_dev *dev,
754 unsigned selector)
755{
756 struct tps65910_reg *pmic = rdev_get_drvdata(dev);
757 int id = rdev_get_id(dev), voltage;
758
759 if (id < TPS65910_REG_VIO || id > TPS65910_REG_VMMC)
760 return -EINVAL;
761
762 if (selector >= pmic->info[id]->table_len)
763 return -EINVAL;
764 else
765 voltage = pmic->info[id]->table[selector] * 1000;
766
767 return voltage;
768}
769
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500770static int tps65911_list_voltage(struct regulator_dev *dev, unsigned selector)
771{
772 struct tps65910_reg *pmic = rdev_get_drvdata(dev);
773 int step_mv = 0, id = rdev_get_id(dev);
774
775 switch(id) {
776 case TPS65911_REG_LDO1:
777 case TPS65911_REG_LDO2:
778 case TPS65911_REG_LDO4:
779 /* The first 5 values of the selector correspond to 1V */
780 if (selector < 5)
781 selector = 0;
782 else
783 selector -= 4;
784
785 step_mv = 50;
786 break;
787 case TPS65911_REG_LDO3:
788 case TPS65911_REG_LDO5:
789 case TPS65911_REG_LDO6:
790 case TPS65911_REG_LDO7:
791 case TPS65911_REG_LDO8:
792 /* The first 3 values of the selector correspond to 1V */
793 if (selector < 3)
794 selector = 0;
795 else
796 selector -= 2;
797
798 step_mv = 100;
799 break;
800 case TPS65910_REG_VIO:
801 return pmic->info[id]->table[selector] * 1000;
802 default:
803 return -EINVAL;
804 }
805
806 return (LDO_MIN_VOLT + selector * step_mv) * 1000;
807}
808
Graeme Gregory518fb722011-05-02 16:20:08 -0500809/* Regulator ops (except VRTC) */
810static struct regulator_ops tps65910_ops_dcdc = {
811 .is_enabled = tps65910_is_enabled,
812 .enable = tps65910_enable,
813 .disable = tps65910_disable,
814 .set_mode = tps65910_set_mode,
815 .get_mode = tps65910_get_mode,
816 .get_voltage = tps65910_get_voltage_dcdc,
817 .set_voltage_sel = tps65910_set_voltage_dcdc,
818 .list_voltage = tps65910_list_voltage_dcdc,
819};
820
821static struct regulator_ops tps65910_ops_vdd3 = {
822 .is_enabled = tps65910_is_enabled,
823 .enable = tps65910_enable,
824 .disable = tps65910_disable,
825 .set_mode = tps65910_set_mode,
826 .get_mode = tps65910_get_mode,
827 .get_voltage = tps65910_get_voltage_vdd3,
828 .list_voltage = tps65910_list_voltage,
829};
830
831static struct regulator_ops tps65910_ops = {
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,
838 .set_voltage_sel = tps65910_set_voltage,
839 .list_voltage = tps65910_list_voltage,
840};
841
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500842static struct regulator_ops tps65911_ops = {
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 = tps65911_get_voltage,
849 .set_voltage_sel = tps65911_set_voltage,
850 .list_voltage = tps65911_list_voltage,
851};
852
Graeme Gregory518fb722011-05-02 16:20:08 -0500853static __devinit int tps65910_probe(struct platform_device *pdev)
854{
855 struct tps65910 *tps65910 = dev_get_drvdata(pdev->dev.parent);
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500856 struct tps_info *info;
Graeme Gregory518fb722011-05-02 16:20:08 -0500857 struct regulator_init_data *reg_data;
858 struct regulator_dev *rdev;
859 struct tps65910_reg *pmic;
860 struct tps65910_board *pmic_plat_data;
Graeme Gregory518fb722011-05-02 16:20:08 -0500861 int i, err;
862
863 pmic_plat_data = dev_get_platdata(tps65910->dev);
864 if (!pmic_plat_data)
865 return -EINVAL;
866
Graeme Gregory518fb722011-05-02 16:20:08 -0500867 pmic = kzalloc(sizeof(*pmic), GFP_KERNEL);
868 if (!pmic)
869 return -ENOMEM;
870
871 mutex_init(&pmic->mutex);
872 pmic->mfd = tps65910;
873 platform_set_drvdata(pdev, pmic);
874
875 /* Give control of all register to control port */
876 tps65910_set_bits(pmic->mfd, TPS65910_DEVCTRL,
877 DEVCTRL_SR_CTL_I2C_SEL_MASK);
878
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500879 switch(tps65910_chip_id(tps65910)) {
880 case TPS65910:
881 pmic->get_ctrl_reg = &tps65910_get_ctrl_register;
Axel Lin39aa9b62011-07-11 09:57:43 +0800882 pmic->num_regulators = ARRAY_SIZE(tps65910_regs);
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500883 info = tps65910_regs;
Axel Lind04156b2011-07-10 21:44:09 +0800884 break;
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500885 case TPS65911:
886 pmic->get_ctrl_reg = &tps65911_get_ctrl_register;
Axel Lin39aa9b62011-07-11 09:57:43 +0800887 pmic->num_regulators = ARRAY_SIZE(tps65911_regs);
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500888 info = tps65911_regs;
Axel Lind04156b2011-07-10 21:44:09 +0800889 break;
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500890 default:
891 pr_err("Invalid tps chip version\n");
Axel Lina3ee13e2011-07-10 18:52:07 +0800892 kfree(pmic);
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500893 return -ENODEV;
894 }
895
Axel Lin39aa9b62011-07-11 09:57:43 +0800896 pmic->desc = kcalloc(pmic->num_regulators,
897 sizeof(struct regulator_desc), GFP_KERNEL);
898 if (!pmic->desc) {
899 err = -ENOMEM;
900 goto err_free_pmic;
901 }
902
903 pmic->info = kcalloc(pmic->num_regulators,
904 sizeof(struct tps_info *), GFP_KERNEL);
905 if (!pmic->info) {
906 err = -ENOMEM;
907 goto err_free_desc;
908 }
909
910 pmic->rdev = kcalloc(pmic->num_regulators,
911 sizeof(struct regulator_dev *), GFP_KERNEL);
912 if (!pmic->rdev) {
913 err = -ENOMEM;
914 goto err_free_info;
915 }
916
Kyle Mannac1fc1482011-11-03 12:08:06 -0500917 for (i = 0; i < pmic->num_regulators && i < TPS65910_NUM_REGS;
918 i++, info++) {
919
920 reg_data = pmic_plat_data->tps65910_pmic_init_data[i];
921
922 /* Regulator API handles empty constraints but not NULL
923 * constraints */
924 if (!reg_data)
925 continue;
926
Graeme Gregory518fb722011-05-02 16:20:08 -0500927 /* Register the regulators */
928 pmic->info[i] = info;
929
930 pmic->desc[i].name = info->name;
Axel Lin77fa44d2011-05-12 13:47:50 +0800931 pmic->desc[i].id = i;
Graeme Gregory518fb722011-05-02 16:20:08 -0500932 pmic->desc[i].n_voltages = info->table_len;
933
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500934 if (i == TPS65910_REG_VDD1 || i == TPS65910_REG_VDD2) {
Graeme Gregory518fb722011-05-02 16:20:08 -0500935 pmic->desc[i].ops = &tps65910_ops_dcdc;
Afzal Mohammed780dc9b2011-11-08 18:54:10 +0530936 pmic->desc[i].n_voltages = VDD1_2_NUM_VOLT_FINE *
937 VDD1_2_NUM_VOLT_COARSE;
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500938 } else if (i == TPS65910_REG_VDD3) {
939 if (tps65910_chip_id(tps65910) == TPS65910)
940 pmic->desc[i].ops = &tps65910_ops_vdd3;
941 else
942 pmic->desc[i].ops = &tps65910_ops_dcdc;
943 } else {
944 if (tps65910_chip_id(tps65910) == TPS65910)
945 pmic->desc[i].ops = &tps65910_ops;
946 else
947 pmic->desc[i].ops = &tps65911_ops;
948 }
Graeme Gregory518fb722011-05-02 16:20:08 -0500949
950 pmic->desc[i].type = REGULATOR_VOLTAGE;
951 pmic->desc[i].owner = THIS_MODULE;
952
953 rdev = regulator_register(&pmic->desc[i],
Rajendra Nayak2c043bc2011-11-18 16:47:19 +0530954 tps65910->dev, reg_data, pmic, NULL);
Graeme Gregory518fb722011-05-02 16:20:08 -0500955 if (IS_ERR(rdev)) {
956 dev_err(tps65910->dev,
957 "failed to register %s regulator\n",
958 pdev->name);
959 err = PTR_ERR(rdev);
Axel Lin39aa9b62011-07-11 09:57:43 +0800960 goto err_unregister_regulator;
Graeme Gregory518fb722011-05-02 16:20:08 -0500961 }
962
963 /* Save regulator for cleanup */
964 pmic->rdev[i] = rdev;
965 }
966 return 0;
967
Axel Lin39aa9b62011-07-11 09:57:43 +0800968err_unregister_regulator:
Graeme Gregory518fb722011-05-02 16:20:08 -0500969 while (--i >= 0)
970 regulator_unregister(pmic->rdev[i]);
Axel Lin39aa9b62011-07-11 09:57:43 +0800971 kfree(pmic->rdev);
972err_free_info:
973 kfree(pmic->info);
974err_free_desc:
975 kfree(pmic->desc);
976err_free_pmic:
Graeme Gregory518fb722011-05-02 16:20:08 -0500977 kfree(pmic);
978 return err;
979}
980
981static int __devexit tps65910_remove(struct platform_device *pdev)
982{
Axel Lin39aa9b62011-07-11 09:57:43 +0800983 struct tps65910_reg *pmic = platform_get_drvdata(pdev);
Graeme Gregory518fb722011-05-02 16:20:08 -0500984 int i;
985
Axel Lin39aa9b62011-07-11 09:57:43 +0800986 for (i = 0; i < pmic->num_regulators; i++)
987 regulator_unregister(pmic->rdev[i]);
Graeme Gregory518fb722011-05-02 16:20:08 -0500988
Axel Lin39aa9b62011-07-11 09:57:43 +0800989 kfree(pmic->rdev);
990 kfree(pmic->info);
991 kfree(pmic->desc);
992 kfree(pmic);
Graeme Gregory518fb722011-05-02 16:20:08 -0500993 return 0;
994}
995
996static struct platform_driver tps65910_driver = {
997 .driver = {
998 .name = "tps65910-pmic",
999 .owner = THIS_MODULE,
1000 },
1001 .probe = tps65910_probe,
1002 .remove = __devexit_p(tps65910_remove),
1003};
1004
1005static int __init tps65910_init(void)
1006{
1007 return platform_driver_register(&tps65910_driver);
1008}
1009subsys_initcall(tps65910_init);
1010
1011static void __exit tps65910_cleanup(void)
1012{
1013 platform_driver_unregister(&tps65910_driver);
1014}
1015module_exit(tps65910_cleanup);
1016
1017MODULE_AUTHOR("Graeme Gregory <gg@slimlogic.co.uk>");
1018MODULE_DESCRIPTION("TPS6507x voltage regulator driver");
1019MODULE_LICENSE("GPL v2");
1020MODULE_ALIAS("platform:tps65910-pmic");