blob: 4ac0058dbf828d90407eeceb8a4a85cf6ae458c6 [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
Laxman Dewangan1e0c66f2012-01-28 15:07:57 +053029#define EXT_SLEEP_CONTROL (TPS65910_SLEEP_CONTROL_EXT_INPUT_EN1 | \
30 TPS65910_SLEEP_CONTROL_EXT_INPUT_EN2 | \
Laxman Dewanganf30b0712012-03-07 18:21:49 +053031 TPS65910_SLEEP_CONTROL_EXT_INPUT_EN3 | \
32 TPS65911_SLEEP_CONTROL_EXT_INPUT_SLEEP)
Graeme Gregory518fb722011-05-02 16:20:08 -050033
34/* supported VIO voltages in milivolts */
35static const u16 VIO_VSEL_table[] = {
36 1500, 1800, 2500, 3300,
37};
38
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -050039/* VSEL tables for TPS65910 specific LDOs and dcdc's */
40
41/* supported VDD3 voltages in milivolts */
Graeme Gregory518fb722011-05-02 16:20:08 -050042static const u16 VDD3_VSEL_table[] = {
43 5000,
44};
45
46/* supported VDIG1 voltages in milivolts */
47static const u16 VDIG1_VSEL_table[] = {
48 1200, 1500, 1800, 2700,
49};
50
51/* supported VDIG2 voltages in milivolts */
52static const u16 VDIG2_VSEL_table[] = {
53 1000, 1100, 1200, 1800,
54};
55
56/* supported VPLL voltages in milivolts */
57static const u16 VPLL_VSEL_table[] = {
58 1000, 1100, 1800, 2500,
59};
60
61/* supported VDAC voltages in milivolts */
62static const u16 VDAC_VSEL_table[] = {
63 1800, 2600, 2800, 2850,
64};
65
66/* supported VAUX1 voltages in milivolts */
67static const u16 VAUX1_VSEL_table[] = {
68 1800, 2500, 2800, 2850,
69};
70
71/* supported VAUX2 voltages in milivolts */
72static const u16 VAUX2_VSEL_table[] = {
73 1800, 2800, 2900, 3300,
74};
75
76/* supported VAUX33 voltages in milivolts */
77static const u16 VAUX33_VSEL_table[] = {
78 1800, 2000, 2800, 3300,
79};
80
81/* supported VMMC voltages in milivolts */
82static const u16 VMMC_VSEL_table[] = {
83 1800, 2800, 3000, 3300,
84};
85
86struct tps_info {
87 const char *name;
88 unsigned min_uV;
89 unsigned max_uV;
Laxman Dewangan7d38a3c2012-01-20 16:36:22 +053090 u8 n_voltages;
91 const u16 *voltage_table;
Graeme Gregory518fb722011-05-02 16:20:08 -050092};
93
94static struct tps_info tps65910_regs[] = {
95 {
96 .name = "VRTC",
97 },
98 {
99 .name = "VIO",
100 .min_uV = 1500000,
101 .max_uV = 3300000,
Laxman Dewangan7d38a3c2012-01-20 16:36:22 +0530102 .n_voltages = ARRAY_SIZE(VIO_VSEL_table),
103 .voltage_table = VIO_VSEL_table,
Graeme Gregory518fb722011-05-02 16:20:08 -0500104 },
105 {
106 .name = "VDD1",
107 .min_uV = 600000,
108 .max_uV = 4500000,
109 },
110 {
111 .name = "VDD2",
112 .min_uV = 600000,
113 .max_uV = 4500000,
114 },
115 {
116 .name = "VDD3",
117 .min_uV = 5000000,
118 .max_uV = 5000000,
Laxman Dewangan7d38a3c2012-01-20 16:36:22 +0530119 .n_voltages = ARRAY_SIZE(VDD3_VSEL_table),
120 .voltage_table = VDD3_VSEL_table,
Graeme Gregory518fb722011-05-02 16:20:08 -0500121 },
122 {
123 .name = "VDIG1",
124 .min_uV = 1200000,
125 .max_uV = 2700000,
Laxman Dewangan7d38a3c2012-01-20 16:36:22 +0530126 .n_voltages = ARRAY_SIZE(VDIG1_VSEL_table),
127 .voltage_table = VDIG1_VSEL_table,
Graeme Gregory518fb722011-05-02 16:20:08 -0500128 },
129 {
130 .name = "VDIG2",
131 .min_uV = 1000000,
132 .max_uV = 1800000,
Laxman Dewangan7d38a3c2012-01-20 16:36:22 +0530133 .n_voltages = ARRAY_SIZE(VDIG2_VSEL_table),
134 .voltage_table = VDIG2_VSEL_table,
Graeme Gregory518fb722011-05-02 16:20:08 -0500135 },
136 {
137 .name = "VPLL",
138 .min_uV = 1000000,
139 .max_uV = 2500000,
Laxman Dewangan7d38a3c2012-01-20 16:36:22 +0530140 .n_voltages = ARRAY_SIZE(VPLL_VSEL_table),
141 .voltage_table = VPLL_VSEL_table,
Graeme Gregory518fb722011-05-02 16:20:08 -0500142 },
143 {
144 .name = "VDAC",
145 .min_uV = 1800000,
146 .max_uV = 2850000,
Laxman Dewangan7d38a3c2012-01-20 16:36:22 +0530147 .n_voltages = ARRAY_SIZE(VDAC_VSEL_table),
148 .voltage_table = VDAC_VSEL_table,
Graeme Gregory518fb722011-05-02 16:20:08 -0500149 },
150 {
151 .name = "VAUX1",
152 .min_uV = 1800000,
153 .max_uV = 2850000,
Laxman Dewangan7d38a3c2012-01-20 16:36:22 +0530154 .n_voltages = ARRAY_SIZE(VAUX1_VSEL_table),
155 .voltage_table = VAUX1_VSEL_table,
Graeme Gregory518fb722011-05-02 16:20:08 -0500156 },
157 {
158 .name = "VAUX2",
159 .min_uV = 1800000,
160 .max_uV = 3300000,
Laxman Dewangan7d38a3c2012-01-20 16:36:22 +0530161 .n_voltages = ARRAY_SIZE(VAUX2_VSEL_table),
162 .voltage_table = VAUX2_VSEL_table,
Graeme Gregory518fb722011-05-02 16:20:08 -0500163 },
164 {
165 .name = "VAUX33",
166 .min_uV = 1800000,
167 .max_uV = 3300000,
Laxman Dewangan7d38a3c2012-01-20 16:36:22 +0530168 .n_voltages = ARRAY_SIZE(VAUX33_VSEL_table),
169 .voltage_table = VAUX33_VSEL_table,
Graeme Gregory518fb722011-05-02 16:20:08 -0500170 },
171 {
172 .name = "VMMC",
173 .min_uV = 1800000,
174 .max_uV = 3300000,
Laxman Dewangan7d38a3c2012-01-20 16:36:22 +0530175 .n_voltages = ARRAY_SIZE(VMMC_VSEL_table),
176 .voltage_table = VMMC_VSEL_table,
Graeme Gregory518fb722011-05-02 16:20:08 -0500177 },
178};
179
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500180static struct tps_info tps65911_regs[] = {
181 {
Laxman Dewanganc2f8efd2012-01-18 20:46:56 +0530182 .name = "VRTC",
183 },
184 {
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500185 .name = "VIO",
186 .min_uV = 1500000,
187 .max_uV = 3300000,
Laxman Dewangan7d38a3c2012-01-20 16:36:22 +0530188 .n_voltages = ARRAY_SIZE(VIO_VSEL_table),
189 .voltage_table = VIO_VSEL_table,
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500190 },
191 {
192 .name = "VDD1",
193 .min_uV = 600000,
194 .max_uV = 4500000,
Laxman Dewangan7d38a3c2012-01-20 16:36:22 +0530195 .n_voltages = 73,
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500196 },
197 {
198 .name = "VDD2",
199 .min_uV = 600000,
200 .max_uV = 4500000,
Laxman Dewangan7d38a3c2012-01-20 16:36:22 +0530201 .n_voltages = 73,
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500202 },
203 {
204 .name = "VDDCTRL",
205 .min_uV = 600000,
206 .max_uV = 1400000,
Laxman Dewangan7d38a3c2012-01-20 16:36:22 +0530207 .n_voltages = 65,
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500208 },
209 {
210 .name = "LDO1",
211 .min_uV = 1000000,
212 .max_uV = 3300000,
Laxman Dewangan7d38a3c2012-01-20 16:36:22 +0530213 .n_voltages = 47,
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500214 },
215 {
216 .name = "LDO2",
217 .min_uV = 1000000,
218 .max_uV = 3300000,
Laxman Dewangan7d38a3c2012-01-20 16:36:22 +0530219 .n_voltages = 47,
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500220 },
221 {
222 .name = "LDO3",
223 .min_uV = 1000000,
224 .max_uV = 3300000,
Laxman Dewangan7d38a3c2012-01-20 16:36:22 +0530225 .n_voltages = 24,
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500226 },
227 {
228 .name = "LDO4",
229 .min_uV = 1000000,
230 .max_uV = 3300000,
Laxman Dewangan7d38a3c2012-01-20 16:36:22 +0530231 .n_voltages = 47,
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500232 },
233 {
234 .name = "LDO5",
235 .min_uV = 1000000,
236 .max_uV = 3300000,
Laxman Dewangan7d38a3c2012-01-20 16:36:22 +0530237 .n_voltages = 24,
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500238 },
239 {
240 .name = "LDO6",
241 .min_uV = 1000000,
242 .max_uV = 3300000,
Laxman Dewangan7d38a3c2012-01-20 16:36:22 +0530243 .n_voltages = 24,
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500244 },
245 {
246 .name = "LDO7",
247 .min_uV = 1000000,
248 .max_uV = 3300000,
Laxman Dewangan7d38a3c2012-01-20 16:36:22 +0530249 .n_voltages = 24,
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500250 },
251 {
252 .name = "LDO8",
253 .min_uV = 1000000,
254 .max_uV = 3300000,
Laxman Dewangan7d38a3c2012-01-20 16:36:22 +0530255 .n_voltages = 24,
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500256 },
257};
258
Laxman Dewangan1e0c66f2012-01-28 15:07:57 +0530259#define EXT_CONTROL_REG_BITS(id, regs_offs, bits) (((regs_offs) << 8) | (bits))
260static unsigned int tps65910_ext_sleep_control[] = {
261 0,
262 EXT_CONTROL_REG_BITS(VIO, 1, 0),
263 EXT_CONTROL_REG_BITS(VDD1, 1, 1),
264 EXT_CONTROL_REG_BITS(VDD2, 1, 2),
265 EXT_CONTROL_REG_BITS(VDD3, 1, 3),
266 EXT_CONTROL_REG_BITS(VDIG1, 0, 1),
267 EXT_CONTROL_REG_BITS(VDIG2, 0, 2),
268 EXT_CONTROL_REG_BITS(VPLL, 0, 6),
269 EXT_CONTROL_REG_BITS(VDAC, 0, 7),
270 EXT_CONTROL_REG_BITS(VAUX1, 0, 3),
271 EXT_CONTROL_REG_BITS(VAUX2, 0, 4),
272 EXT_CONTROL_REG_BITS(VAUX33, 0, 5),
273 EXT_CONTROL_REG_BITS(VMMC, 0, 0),
274};
275
276static unsigned int tps65911_ext_sleep_control[] = {
277 0,
278 EXT_CONTROL_REG_BITS(VIO, 1, 0),
279 EXT_CONTROL_REG_BITS(VDD1, 1, 1),
280 EXT_CONTROL_REG_BITS(VDD2, 1, 2),
281 EXT_CONTROL_REG_BITS(VDDCTRL, 1, 3),
282 EXT_CONTROL_REG_BITS(LDO1, 0, 1),
283 EXT_CONTROL_REG_BITS(LDO2, 0, 2),
284 EXT_CONTROL_REG_BITS(LDO3, 0, 7),
285 EXT_CONTROL_REG_BITS(LDO4, 0, 6),
286 EXT_CONTROL_REG_BITS(LDO5, 0, 3),
287 EXT_CONTROL_REG_BITS(LDO6, 0, 0),
288 EXT_CONTROL_REG_BITS(LDO7, 0, 5),
289 EXT_CONTROL_REG_BITS(LDO8, 0, 4),
290};
291
Graeme Gregory518fb722011-05-02 16:20:08 -0500292struct tps65910_reg {
Axel Lin39aa9b62011-07-11 09:57:43 +0800293 struct regulator_desc *desc;
Graeme Gregory518fb722011-05-02 16:20:08 -0500294 struct tps65910 *mfd;
Axel Lin39aa9b62011-07-11 09:57:43 +0800295 struct regulator_dev **rdev;
296 struct tps_info **info;
Graeme Gregory518fb722011-05-02 16:20:08 -0500297 struct mutex mutex;
Axel Lin39aa9b62011-07-11 09:57:43 +0800298 int num_regulators;
Graeme Gregory518fb722011-05-02 16:20:08 -0500299 int mode;
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500300 int (*get_ctrl_reg)(int);
Laxman Dewangan1e0c66f2012-01-28 15:07:57 +0530301 unsigned int *ext_sleep_control;
302 unsigned int board_ext_control[TPS65910_NUM_REGS];
Graeme Gregory518fb722011-05-02 16:20:08 -0500303};
304
305static inline int tps65910_read(struct tps65910_reg *pmic, u8 reg)
306{
307 u8 val;
308 int err;
309
310 err = pmic->mfd->read(pmic->mfd, reg, 1, &val);
311 if (err)
312 return err;
313
314 return val;
315}
316
317static inline int tps65910_write(struct tps65910_reg *pmic, u8 reg, u8 val)
318{
319 return pmic->mfd->write(pmic->mfd, reg, 1, &val);
320}
321
322static int tps65910_modify_bits(struct tps65910_reg *pmic, u8 reg,
323 u8 set_mask, u8 clear_mask)
324{
325 int err, data;
326
327 mutex_lock(&pmic->mutex);
328
329 data = tps65910_read(pmic, reg);
330 if (data < 0) {
331 dev_err(pmic->mfd->dev, "Read from reg 0x%x failed\n", reg);
332 err = data;
333 goto out;
334 }
335
336 data &= ~clear_mask;
337 data |= set_mask;
338 err = tps65910_write(pmic, reg, data);
339 if (err)
340 dev_err(pmic->mfd->dev, "Write for reg 0x%x failed\n", reg);
341
342out:
343 mutex_unlock(&pmic->mutex);
344 return err;
345}
346
347static int tps65910_reg_read(struct tps65910_reg *pmic, u8 reg)
348{
349 int data;
350
351 mutex_lock(&pmic->mutex);
352
353 data = tps65910_read(pmic, reg);
354 if (data < 0)
355 dev_err(pmic->mfd->dev, "Read from reg 0x%x failed\n", reg);
356
357 mutex_unlock(&pmic->mutex);
358 return data;
359}
360
361static int tps65910_reg_write(struct tps65910_reg *pmic, u8 reg, u8 val)
362{
363 int err;
364
365 mutex_lock(&pmic->mutex);
366
367 err = tps65910_write(pmic, reg, val);
368 if (err < 0)
369 dev_err(pmic->mfd->dev, "Write for reg 0x%x failed\n", reg);
370
371 mutex_unlock(&pmic->mutex);
372 return err;
373}
374
375static int tps65910_get_ctrl_register(int id)
376{
377 switch (id) {
378 case TPS65910_REG_VRTC:
379 return TPS65910_VRTC;
380 case TPS65910_REG_VIO:
381 return TPS65910_VIO;
382 case TPS65910_REG_VDD1:
383 return TPS65910_VDD1;
384 case TPS65910_REG_VDD2:
385 return TPS65910_VDD2;
386 case TPS65910_REG_VDD3:
387 return TPS65910_VDD3;
388 case TPS65910_REG_VDIG1:
389 return TPS65910_VDIG1;
390 case TPS65910_REG_VDIG2:
391 return TPS65910_VDIG2;
392 case TPS65910_REG_VPLL:
393 return TPS65910_VPLL;
394 case TPS65910_REG_VDAC:
395 return TPS65910_VDAC;
396 case TPS65910_REG_VAUX1:
397 return TPS65910_VAUX1;
398 case TPS65910_REG_VAUX2:
399 return TPS65910_VAUX2;
400 case TPS65910_REG_VAUX33:
401 return TPS65910_VAUX33;
402 case TPS65910_REG_VMMC:
403 return TPS65910_VMMC;
404 default:
405 return -EINVAL;
406 }
407}
408
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500409static int tps65911_get_ctrl_register(int id)
410{
411 switch (id) {
412 case TPS65910_REG_VRTC:
413 return TPS65910_VRTC;
414 case TPS65910_REG_VIO:
415 return TPS65910_VIO;
416 case TPS65910_REG_VDD1:
417 return TPS65910_VDD1;
418 case TPS65910_REG_VDD2:
419 return TPS65910_VDD2;
420 case TPS65911_REG_VDDCTRL:
421 return TPS65911_VDDCTRL;
422 case TPS65911_REG_LDO1:
423 return TPS65911_LDO1;
424 case TPS65911_REG_LDO2:
425 return TPS65911_LDO2;
426 case TPS65911_REG_LDO3:
427 return TPS65911_LDO3;
428 case TPS65911_REG_LDO4:
429 return TPS65911_LDO4;
430 case TPS65911_REG_LDO5:
431 return TPS65911_LDO5;
432 case TPS65911_REG_LDO6:
433 return TPS65911_LDO6;
434 case TPS65911_REG_LDO7:
435 return TPS65911_LDO7;
436 case TPS65911_REG_LDO8:
437 return TPS65911_LDO8;
438 default:
439 return -EINVAL;
440 }
441}
442
Graeme Gregory518fb722011-05-02 16:20:08 -0500443static int tps65910_is_enabled(struct regulator_dev *dev)
444{
445 struct tps65910_reg *pmic = rdev_get_drvdata(dev);
446 int reg, value, id = rdev_get_id(dev);
447
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500448 reg = pmic->get_ctrl_reg(id);
Graeme Gregory518fb722011-05-02 16:20:08 -0500449 if (reg < 0)
450 return reg;
451
452 value = tps65910_reg_read(pmic, reg);
453 if (value < 0)
454 return value;
455
456 return value & TPS65910_SUPPLY_STATE_ENABLED;
457}
458
459static int tps65910_enable(struct regulator_dev *dev)
460{
461 struct tps65910_reg *pmic = rdev_get_drvdata(dev);
462 struct tps65910 *mfd = pmic->mfd;
463 int reg, 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 return tps65910_set_bits(mfd, reg, TPS65910_SUPPLY_STATE_ENABLED);
470}
471
472static int tps65910_disable(struct regulator_dev *dev)
473{
474 struct tps65910_reg *pmic = rdev_get_drvdata(dev);
475 struct tps65910 *mfd = pmic->mfd;
476 int reg, id = rdev_get_id(dev);
477
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500478 reg = pmic->get_ctrl_reg(id);
Graeme Gregory518fb722011-05-02 16:20:08 -0500479 if (reg < 0)
480 return reg;
481
482 return tps65910_clear_bits(mfd, reg, TPS65910_SUPPLY_STATE_ENABLED);
483}
484
485
486static int tps65910_set_mode(struct regulator_dev *dev, unsigned int mode)
487{
488 struct tps65910_reg *pmic = rdev_get_drvdata(dev);
489 struct tps65910 *mfd = pmic->mfd;
490 int reg, value, id = rdev_get_id(dev);
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500491
492 reg = pmic->get_ctrl_reg(id);
Graeme Gregory518fb722011-05-02 16:20:08 -0500493 if (reg < 0)
494 return reg;
495
496 switch (mode) {
497 case REGULATOR_MODE_NORMAL:
498 return tps65910_modify_bits(pmic, reg, LDO_ST_ON_BIT,
499 LDO_ST_MODE_BIT);
500 case REGULATOR_MODE_IDLE:
501 value = LDO_ST_ON_BIT | LDO_ST_MODE_BIT;
502 return tps65910_set_bits(mfd, reg, value);
503 case REGULATOR_MODE_STANDBY:
504 return tps65910_clear_bits(mfd, reg, LDO_ST_ON_BIT);
505 }
506
507 return -EINVAL;
508}
509
510static unsigned int tps65910_get_mode(struct regulator_dev *dev)
511{
512 struct tps65910_reg *pmic = rdev_get_drvdata(dev);
513 int reg, value, id = rdev_get_id(dev);
514
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500515 reg = pmic->get_ctrl_reg(id);
Graeme Gregory518fb722011-05-02 16:20:08 -0500516 if (reg < 0)
517 return reg;
518
519 value = tps65910_reg_read(pmic, reg);
520 if (value < 0)
521 return value;
522
523 if (value & LDO_ST_ON_BIT)
524 return REGULATOR_MODE_STANDBY;
525 else if (value & LDO_ST_MODE_BIT)
526 return REGULATOR_MODE_IDLE;
527 else
528 return REGULATOR_MODE_NORMAL;
529}
530
531static int tps65910_get_voltage_dcdc(struct regulator_dev *dev)
532{
533 struct tps65910_reg *pmic = rdev_get_drvdata(dev);
534 int id = rdev_get_id(dev), voltage = 0;
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500535 int opvsel = 0, srvsel = 0, vselmax = 0, mult = 0, sr = 0;
Graeme Gregory518fb722011-05-02 16:20:08 -0500536
537 switch (id) {
538 case TPS65910_REG_VDD1:
539 opvsel = tps65910_reg_read(pmic, TPS65910_VDD1_OP);
540 mult = tps65910_reg_read(pmic, TPS65910_VDD1);
541 mult = (mult & VDD1_VGAIN_SEL_MASK) >> VDD1_VGAIN_SEL_SHIFT;
542 srvsel = tps65910_reg_read(pmic, TPS65910_VDD1_SR);
543 sr = opvsel & VDD1_OP_CMD_MASK;
544 opvsel &= VDD1_OP_SEL_MASK;
545 srvsel &= VDD1_SR_SEL_MASK;
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500546 vselmax = 75;
Graeme Gregory518fb722011-05-02 16:20:08 -0500547 break;
548 case TPS65910_REG_VDD2:
549 opvsel = tps65910_reg_read(pmic, TPS65910_VDD2_OP);
550 mult = tps65910_reg_read(pmic, TPS65910_VDD2);
551 mult = (mult & VDD2_VGAIN_SEL_MASK) >> VDD2_VGAIN_SEL_SHIFT;
552 srvsel = tps65910_reg_read(pmic, TPS65910_VDD2_SR);
553 sr = opvsel & VDD2_OP_CMD_MASK;
554 opvsel &= VDD2_OP_SEL_MASK;
555 srvsel &= VDD2_SR_SEL_MASK;
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500556 vselmax = 75;
557 break;
558 case TPS65911_REG_VDDCTRL:
559 opvsel = tps65910_reg_read(pmic, TPS65911_VDDCTRL_OP);
560 srvsel = tps65910_reg_read(pmic, TPS65911_VDDCTRL_SR);
561 sr = opvsel & VDDCTRL_OP_CMD_MASK;
562 opvsel &= VDDCTRL_OP_SEL_MASK;
563 srvsel &= VDDCTRL_SR_SEL_MASK;
564 vselmax = 64;
Graeme Gregory518fb722011-05-02 16:20:08 -0500565 break;
566 }
567
568 /* multiplier 0 == 1 but 2,3 normal */
569 if (!mult)
570 mult=1;
571
572 if (sr) {
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500573 /* normalise to valid range */
574 if (srvsel < 3)
575 srvsel = 3;
576 if (srvsel > vselmax)
577 srvsel = vselmax;
Graeme Gregory518fb722011-05-02 16:20:08 -0500578 srvsel -= 3;
579
580 voltage = (srvsel * VDD1_2_OFFSET + VDD1_2_MIN_VOLT) * 100;
581 } else {
582
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500583 /* normalise to valid range*/
584 if (opvsel < 3)
585 opvsel = 3;
586 if (opvsel > vselmax)
587 opvsel = vselmax;
Graeme Gregory518fb722011-05-02 16:20:08 -0500588 opvsel -= 3;
589
590 voltage = (opvsel * VDD1_2_OFFSET + VDD1_2_MIN_VOLT) * 100;
591 }
592
593 voltage *= mult;
594
595 return voltage;
596}
597
598static int tps65910_get_voltage(struct regulator_dev *dev)
599{
600 struct tps65910_reg *pmic = rdev_get_drvdata(dev);
601 int reg, value, id = rdev_get_id(dev), voltage = 0;
602
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500603 reg = pmic->get_ctrl_reg(id);
Graeme Gregory518fb722011-05-02 16:20:08 -0500604 if (reg < 0)
605 return reg;
606
607 value = tps65910_reg_read(pmic, reg);
608 if (value < 0)
609 return value;
610
611 switch (id) {
612 case TPS65910_REG_VIO:
613 case TPS65910_REG_VDIG1:
614 case TPS65910_REG_VDIG2:
615 case TPS65910_REG_VPLL:
616 case TPS65910_REG_VDAC:
617 case TPS65910_REG_VAUX1:
618 case TPS65910_REG_VAUX2:
619 case TPS65910_REG_VAUX33:
620 case TPS65910_REG_VMMC:
621 value &= LDO_SEL_MASK;
622 value >>= LDO_SEL_SHIFT;
623 break;
624 default:
625 return -EINVAL;
626 }
627
Laxman Dewangan7d38a3c2012-01-20 16:36:22 +0530628 voltage = pmic->info[id]->voltage_table[value] * 1000;
Graeme Gregory518fb722011-05-02 16:20:08 -0500629
630 return voltage;
631}
632
633static int tps65910_get_voltage_vdd3(struct regulator_dev *dev)
634{
635 return 5 * 1000 * 1000;
636}
637
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500638static int tps65911_get_voltage(struct regulator_dev *dev)
639{
640 struct tps65910_reg *pmic = rdev_get_drvdata(dev);
641 int step_mv, id = rdev_get_id(dev);
642 u8 value, reg;
643
644 reg = pmic->get_ctrl_reg(id);
645
646 value = tps65910_reg_read(pmic, reg);
647
648 switch (id) {
649 case TPS65911_REG_LDO1:
650 case TPS65911_REG_LDO2:
651 case TPS65911_REG_LDO4:
652 value &= LDO1_SEL_MASK;
653 value >>= LDO_SEL_SHIFT;
654 /* The first 5 values of the selector correspond to 1V */
655 if (value < 5)
656 value = 0;
657 else
658 value -= 4;
659
660 step_mv = 50;
661 break;
662 case TPS65911_REG_LDO3:
663 case TPS65911_REG_LDO5:
664 case TPS65911_REG_LDO6:
665 case TPS65911_REG_LDO7:
666 case TPS65911_REG_LDO8:
667 value &= LDO3_SEL_MASK;
668 value >>= LDO_SEL_SHIFT;
669 /* The first 3 values of the selector correspond to 1V */
670 if (value < 3)
671 value = 0;
672 else
673 value -= 2;
674
675 step_mv = 100;
676 break;
677 case TPS65910_REG_VIO:
Laxman Dewangane882eae2012-02-17 18:56:11 +0530678 value &= LDO_SEL_MASK;
679 value >>= LDO_SEL_SHIFT;
Laxman Dewangan7d38a3c2012-01-20 16:36:22 +0530680 return pmic->info[id]->voltage_table[value] * 1000;
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500681 default:
682 return -EINVAL;
683 }
684
685 return (LDO_MIN_VOLT + value * step_mv) * 1000;
686}
687
Axel Lin94732b92012-03-09 10:22:20 +0800688static int tps65910_set_voltage_dcdc_sel(struct regulator_dev *dev,
689 unsigned selector)
Graeme Gregory518fb722011-05-02 16:20:08 -0500690{
691 struct tps65910_reg *pmic = rdev_get_drvdata(dev);
692 int id = rdev_get_id(dev), vsel;
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500693 int dcdc_mult = 0;
Graeme Gregory518fb722011-05-02 16:20:08 -0500694
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500695 switch (id) {
696 case TPS65910_REG_VDD1:
Afzal Mohammed780dc9b2011-11-08 18:54:10 +0530697 dcdc_mult = (selector / VDD1_2_NUM_VOLT_FINE) + 1;
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500698 if (dcdc_mult == 1)
699 dcdc_mult--;
Afzal Mohammed780dc9b2011-11-08 18:54:10 +0530700 vsel = (selector % VDD1_2_NUM_VOLT_FINE) + 3;
Graeme Gregory518fb722011-05-02 16:20:08 -0500701
Graeme Gregory518fb722011-05-02 16:20:08 -0500702 tps65910_modify_bits(pmic, TPS65910_VDD1,
703 (dcdc_mult << VDD1_VGAIN_SEL_SHIFT),
704 VDD1_VGAIN_SEL_MASK);
705 tps65910_reg_write(pmic, TPS65910_VDD1_OP, vsel);
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500706 break;
707 case TPS65910_REG_VDD2:
Afzal Mohammed780dc9b2011-11-08 18:54:10 +0530708 dcdc_mult = (selector / VDD1_2_NUM_VOLT_FINE) + 1;
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500709 if (dcdc_mult == 1)
710 dcdc_mult--;
Afzal Mohammed780dc9b2011-11-08 18:54:10 +0530711 vsel = (selector % VDD1_2_NUM_VOLT_FINE) + 3;
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500712
Graeme Gregory518fb722011-05-02 16:20:08 -0500713 tps65910_modify_bits(pmic, TPS65910_VDD2,
714 (dcdc_mult << VDD2_VGAIN_SEL_SHIFT),
715 VDD1_VGAIN_SEL_MASK);
716 tps65910_reg_write(pmic, TPS65910_VDD2_OP, vsel);
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500717 break;
718 case TPS65911_REG_VDDCTRL:
719 vsel = selector;
720 tps65910_reg_write(pmic, TPS65911_VDDCTRL_OP, vsel);
Graeme Gregory518fb722011-05-02 16:20:08 -0500721 }
722
723 return 0;
724}
725
Axel Lin94732b92012-03-09 10:22:20 +0800726static int tps65910_set_voltage_sel(struct regulator_dev *dev,
727 unsigned selector)
Graeme Gregory518fb722011-05-02 16:20:08 -0500728{
729 struct tps65910_reg *pmic = rdev_get_drvdata(dev);
730 int reg, id = rdev_get_id(dev);
731
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500732 reg = pmic->get_ctrl_reg(id);
Graeme Gregory518fb722011-05-02 16:20:08 -0500733 if (reg < 0)
734 return reg;
735
736 switch (id) {
737 case TPS65910_REG_VIO:
738 case TPS65910_REG_VDIG1:
739 case TPS65910_REG_VDIG2:
740 case TPS65910_REG_VPLL:
741 case TPS65910_REG_VDAC:
742 case TPS65910_REG_VAUX1:
743 case TPS65910_REG_VAUX2:
744 case TPS65910_REG_VAUX33:
745 case TPS65910_REG_VMMC:
746 return tps65910_modify_bits(pmic, reg,
747 (selector << LDO_SEL_SHIFT), LDO_SEL_MASK);
748 }
749
750 return -EINVAL;
751}
752
Axel Lin94732b92012-03-09 10:22:20 +0800753static int tps65911_set_voltage_sel(struct regulator_dev *dev,
754 unsigned selector)
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500755{
756 struct tps65910_reg *pmic = rdev_get_drvdata(dev);
757 int reg, id = rdev_get_id(dev);
758
759 reg = pmic->get_ctrl_reg(id);
760 if (reg < 0)
761 return reg;
762
763 switch (id) {
764 case TPS65911_REG_LDO1:
765 case TPS65911_REG_LDO2:
766 case TPS65911_REG_LDO4:
767 return tps65910_modify_bits(pmic, reg,
768 (selector << LDO_SEL_SHIFT), LDO1_SEL_MASK);
769 case TPS65911_REG_LDO3:
770 case TPS65911_REG_LDO5:
771 case TPS65911_REG_LDO6:
772 case TPS65911_REG_LDO7:
773 case TPS65911_REG_LDO8:
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500774 return tps65910_modify_bits(pmic, reg,
775 (selector << LDO_SEL_SHIFT), LDO3_SEL_MASK);
Laxman Dewangane882eae2012-02-17 18:56:11 +0530776 case TPS65910_REG_VIO:
777 return tps65910_modify_bits(pmic, reg,
778 (selector << LDO_SEL_SHIFT), LDO_SEL_MASK);
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500779 }
780
781 return -EINVAL;
782}
783
784
Graeme Gregory518fb722011-05-02 16:20:08 -0500785static int tps65910_list_voltage_dcdc(struct regulator_dev *dev,
786 unsigned selector)
787{
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500788 int volt, mult = 1, id = rdev_get_id(dev);
Graeme Gregory518fb722011-05-02 16:20:08 -0500789
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500790 switch (id) {
791 case TPS65910_REG_VDD1:
792 case TPS65910_REG_VDD2:
Afzal Mohammed780dc9b2011-11-08 18:54:10 +0530793 mult = (selector / VDD1_2_NUM_VOLT_FINE) + 1;
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500794 volt = VDD1_2_MIN_VOLT +
Afzal Mohammed780dc9b2011-11-08 18:54:10 +0530795 (selector % VDD1_2_NUM_VOLT_FINE) * VDD1_2_OFFSET;
Axel Lind04156b2011-07-10 21:44:09 +0800796 break;
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500797 case TPS65911_REG_VDDCTRL:
798 volt = VDDCTRL_MIN_VOLT + (selector * VDDCTRL_OFFSET);
Axel Lind04156b2011-07-10 21:44:09 +0800799 break;
800 default:
801 BUG();
802 return -EINVAL;
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500803 }
Graeme Gregory518fb722011-05-02 16:20:08 -0500804
805 return volt * 100 * mult;
806}
807
808static int tps65910_list_voltage(struct regulator_dev *dev,
809 unsigned selector)
810{
811 struct tps65910_reg *pmic = rdev_get_drvdata(dev);
812 int id = rdev_get_id(dev), voltage;
813
814 if (id < TPS65910_REG_VIO || id > TPS65910_REG_VMMC)
815 return -EINVAL;
816
Laxman Dewangan7d38a3c2012-01-20 16:36:22 +0530817 if (selector >= pmic->info[id]->n_voltages)
Graeme Gregory518fb722011-05-02 16:20:08 -0500818 return -EINVAL;
819 else
Laxman Dewangan7d38a3c2012-01-20 16:36:22 +0530820 voltage = pmic->info[id]->voltage_table[selector] * 1000;
Graeme Gregory518fb722011-05-02 16:20:08 -0500821
822 return voltage;
823}
824
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500825static int tps65911_list_voltage(struct regulator_dev *dev, unsigned selector)
826{
827 struct tps65910_reg *pmic = rdev_get_drvdata(dev);
828 int step_mv = 0, id = rdev_get_id(dev);
829
830 switch(id) {
831 case TPS65911_REG_LDO1:
832 case TPS65911_REG_LDO2:
833 case TPS65911_REG_LDO4:
834 /* The first 5 values of the selector correspond to 1V */
835 if (selector < 5)
836 selector = 0;
837 else
838 selector -= 4;
839
840 step_mv = 50;
841 break;
842 case TPS65911_REG_LDO3:
843 case TPS65911_REG_LDO5:
844 case TPS65911_REG_LDO6:
845 case TPS65911_REG_LDO7:
846 case TPS65911_REG_LDO8:
847 /* The first 3 values of the selector correspond to 1V */
848 if (selector < 3)
849 selector = 0;
850 else
851 selector -= 2;
852
853 step_mv = 100;
854 break;
855 case TPS65910_REG_VIO:
Laxman Dewangan7d38a3c2012-01-20 16:36:22 +0530856 return pmic->info[id]->voltage_table[selector] * 1000;
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500857 default:
858 return -EINVAL;
859 }
860
861 return (LDO_MIN_VOLT + selector * step_mv) * 1000;
862}
863
Graeme Gregory518fb722011-05-02 16:20:08 -0500864/* Regulator ops (except VRTC) */
865static struct regulator_ops tps65910_ops_dcdc = {
866 .is_enabled = tps65910_is_enabled,
867 .enable = tps65910_enable,
868 .disable = tps65910_disable,
869 .set_mode = tps65910_set_mode,
870 .get_mode = tps65910_get_mode,
871 .get_voltage = tps65910_get_voltage_dcdc,
Axel Lin94732b92012-03-09 10:22:20 +0800872 .set_voltage_sel = tps65910_set_voltage_dcdc_sel,
Graeme Gregory518fb722011-05-02 16:20:08 -0500873 .list_voltage = tps65910_list_voltage_dcdc,
874};
875
876static struct regulator_ops tps65910_ops_vdd3 = {
877 .is_enabled = tps65910_is_enabled,
878 .enable = tps65910_enable,
879 .disable = tps65910_disable,
880 .set_mode = tps65910_set_mode,
881 .get_mode = tps65910_get_mode,
882 .get_voltage = tps65910_get_voltage_vdd3,
883 .list_voltage = tps65910_list_voltage,
884};
885
886static struct regulator_ops tps65910_ops = {
887 .is_enabled = tps65910_is_enabled,
888 .enable = tps65910_enable,
889 .disable = tps65910_disable,
890 .set_mode = tps65910_set_mode,
891 .get_mode = tps65910_get_mode,
892 .get_voltage = tps65910_get_voltage,
Axel Lin94732b92012-03-09 10:22:20 +0800893 .set_voltage_sel = tps65910_set_voltage_sel,
Graeme Gregory518fb722011-05-02 16:20:08 -0500894 .list_voltage = tps65910_list_voltage,
895};
896
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500897static struct regulator_ops tps65911_ops = {
898 .is_enabled = tps65910_is_enabled,
899 .enable = tps65910_enable,
900 .disable = tps65910_disable,
901 .set_mode = tps65910_set_mode,
902 .get_mode = tps65910_get_mode,
903 .get_voltage = tps65911_get_voltage,
Axel Lin94732b92012-03-09 10:22:20 +0800904 .set_voltage_sel = tps65911_set_voltage_sel,
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -0500905 .list_voltage = tps65911_list_voltage,
906};
907
Laxman Dewangan1e0c66f2012-01-28 15:07:57 +0530908static int tps65910_set_ext_sleep_config(struct tps65910_reg *pmic,
909 int id, int ext_sleep_config)
910{
911 struct tps65910 *mfd = pmic->mfd;
912 u8 regoffs = (pmic->ext_sleep_control[id] >> 8) & 0xFF;
913 u8 bit_pos = (1 << pmic->ext_sleep_control[id] & 0xFF);
914 int ret;
915
916 /*
917 * Regulator can not be control from multiple external input EN1, EN2
918 * and EN3 together.
919 */
920 if (ext_sleep_config & EXT_SLEEP_CONTROL) {
921 int en_count;
922 en_count = ((ext_sleep_config &
923 TPS65910_SLEEP_CONTROL_EXT_INPUT_EN1) != 0);
924 en_count += ((ext_sleep_config &
925 TPS65910_SLEEP_CONTROL_EXT_INPUT_EN2) != 0);
926 en_count += ((ext_sleep_config &
927 TPS65910_SLEEP_CONTROL_EXT_INPUT_EN3) != 0);
Laxman Dewanganf30b0712012-03-07 18:21:49 +0530928 en_count += ((ext_sleep_config &
929 TPS65911_SLEEP_CONTROL_EXT_INPUT_SLEEP) != 0);
Laxman Dewangan1e0c66f2012-01-28 15:07:57 +0530930 if (en_count > 1) {
931 dev_err(mfd->dev,
932 "External sleep control flag is not proper\n");
933 return -EINVAL;
934 }
935 }
936
937 pmic->board_ext_control[id] = ext_sleep_config;
938
939 /* External EN1 control */
940 if (ext_sleep_config & TPS65910_SLEEP_CONTROL_EXT_INPUT_EN1)
941 ret = tps65910_set_bits(mfd,
942 TPS65910_EN1_LDO_ASS + regoffs, bit_pos);
943 else
944 ret = tps65910_clear_bits(mfd,
945 TPS65910_EN1_LDO_ASS + regoffs, bit_pos);
946 if (ret < 0) {
947 dev_err(mfd->dev,
948 "Error in configuring external control EN1\n");
949 return ret;
950 }
951
952 /* External EN2 control */
953 if (ext_sleep_config & TPS65910_SLEEP_CONTROL_EXT_INPUT_EN2)
954 ret = tps65910_set_bits(mfd,
955 TPS65910_EN2_LDO_ASS + regoffs, bit_pos);
956 else
957 ret = tps65910_clear_bits(mfd,
958 TPS65910_EN2_LDO_ASS + regoffs, bit_pos);
959 if (ret < 0) {
960 dev_err(mfd->dev,
961 "Error in configuring external control EN2\n");
962 return ret;
963 }
964
965 /* External EN3 control for TPS65910 LDO only */
966 if ((tps65910_chip_id(mfd) == TPS65910) &&
967 (id >= TPS65910_REG_VDIG1)) {
968 if (ext_sleep_config & TPS65910_SLEEP_CONTROL_EXT_INPUT_EN3)
969 ret = tps65910_set_bits(mfd,
970 TPS65910_EN3_LDO_ASS + regoffs, bit_pos);
971 else
972 ret = tps65910_clear_bits(mfd,
973 TPS65910_EN3_LDO_ASS + regoffs, bit_pos);
974 if (ret < 0) {
975 dev_err(mfd->dev,
976 "Error in configuring external control EN3\n");
977 return ret;
978 }
979 }
980
981 /* Return if no external control is selected */
982 if (!(ext_sleep_config & EXT_SLEEP_CONTROL)) {
983 /* Clear all sleep controls */
984 ret = tps65910_clear_bits(mfd,
985 TPS65910_SLEEP_KEEP_LDO_ON + regoffs, bit_pos);
986 if (!ret)
987 ret = tps65910_clear_bits(mfd,
988 TPS65910_SLEEP_SET_LDO_OFF + regoffs, bit_pos);
989 if (ret < 0)
990 dev_err(mfd->dev,
991 "Error in configuring SLEEP register\n");
992 return ret;
993 }
994
995 /*
996 * For regulator that has separate operational and sleep register make
997 * sure that operational is used and clear sleep register to turn
998 * regulator off when external control is inactive
999 */
1000 if ((id == TPS65910_REG_VDD1) ||
1001 (id == TPS65910_REG_VDD2) ||
1002 ((id == TPS65911_REG_VDDCTRL) &&
1003 (tps65910_chip_id(mfd) == TPS65911))) {
1004 int op_reg_add = pmic->get_ctrl_reg(id) + 1;
1005 int sr_reg_add = pmic->get_ctrl_reg(id) + 2;
1006 int opvsel = tps65910_reg_read(pmic, op_reg_add);
1007 int srvsel = tps65910_reg_read(pmic, sr_reg_add);
1008 if (opvsel & VDD1_OP_CMD_MASK) {
1009 u8 reg_val = srvsel & VDD1_OP_SEL_MASK;
1010 ret = tps65910_reg_write(pmic, op_reg_add, reg_val);
1011 if (ret < 0) {
1012 dev_err(mfd->dev,
1013 "Error in configuring op register\n");
1014 return ret;
1015 }
1016 }
1017 ret = tps65910_reg_write(pmic, sr_reg_add, 0);
1018 if (ret < 0) {
1019 dev_err(mfd->dev, "Error in settting sr register\n");
1020 return ret;
1021 }
1022 }
1023
1024 ret = tps65910_clear_bits(mfd,
1025 TPS65910_SLEEP_KEEP_LDO_ON + regoffs, bit_pos);
Laxman Dewanganf30b0712012-03-07 18:21:49 +05301026 if (!ret) {
1027 if (ext_sleep_config & TPS65911_SLEEP_CONTROL_EXT_INPUT_SLEEP)
1028 ret = tps65910_set_bits(mfd,
1029 TPS65910_SLEEP_SET_LDO_OFF + regoffs, bit_pos);
1030 else
1031 ret = tps65910_clear_bits(mfd,
1032 TPS65910_SLEEP_SET_LDO_OFF + regoffs, bit_pos);
1033 }
Laxman Dewangan1e0c66f2012-01-28 15:07:57 +05301034 if (ret < 0)
1035 dev_err(mfd->dev,
1036 "Error in configuring SLEEP register\n");
Laxman Dewanganf30b0712012-03-07 18:21:49 +05301037
Laxman Dewangan1e0c66f2012-01-28 15:07:57 +05301038 return ret;
1039}
1040
Graeme Gregory518fb722011-05-02 16:20:08 -05001041static __devinit int tps65910_probe(struct platform_device *pdev)
1042{
1043 struct tps65910 *tps65910 = dev_get_drvdata(pdev->dev.parent);
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -05001044 struct tps_info *info;
Graeme Gregory518fb722011-05-02 16:20:08 -05001045 struct regulator_init_data *reg_data;
1046 struct regulator_dev *rdev;
1047 struct tps65910_reg *pmic;
1048 struct tps65910_board *pmic_plat_data;
Graeme Gregory518fb722011-05-02 16:20:08 -05001049 int i, err;
1050
1051 pmic_plat_data = dev_get_platdata(tps65910->dev);
1052 if (!pmic_plat_data)
1053 return -EINVAL;
1054
Graeme Gregory518fb722011-05-02 16:20:08 -05001055 pmic = kzalloc(sizeof(*pmic), GFP_KERNEL);
1056 if (!pmic)
1057 return -ENOMEM;
1058
1059 mutex_init(&pmic->mutex);
1060 pmic->mfd = tps65910;
1061 platform_set_drvdata(pdev, pmic);
1062
1063 /* Give control of all register to control port */
1064 tps65910_set_bits(pmic->mfd, TPS65910_DEVCTRL,
1065 DEVCTRL_SR_CTL_I2C_SEL_MASK);
1066
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -05001067 switch(tps65910_chip_id(tps65910)) {
1068 case TPS65910:
1069 pmic->get_ctrl_reg = &tps65910_get_ctrl_register;
Axel Lin39aa9b62011-07-11 09:57:43 +08001070 pmic->num_regulators = ARRAY_SIZE(tps65910_regs);
Laxman Dewangan1e0c66f2012-01-28 15:07:57 +05301071 pmic->ext_sleep_control = tps65910_ext_sleep_control;
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -05001072 info = tps65910_regs;
Axel Lind04156b2011-07-10 21:44:09 +08001073 break;
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -05001074 case TPS65911:
1075 pmic->get_ctrl_reg = &tps65911_get_ctrl_register;
Axel Lin39aa9b62011-07-11 09:57:43 +08001076 pmic->num_regulators = ARRAY_SIZE(tps65911_regs);
Laxman Dewangan1e0c66f2012-01-28 15:07:57 +05301077 pmic->ext_sleep_control = tps65911_ext_sleep_control;
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -05001078 info = tps65911_regs;
Axel Lind04156b2011-07-10 21:44:09 +08001079 break;
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -05001080 default:
1081 pr_err("Invalid tps chip version\n");
Axel Lina3ee13e2011-07-10 18:52:07 +08001082 kfree(pmic);
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -05001083 return -ENODEV;
1084 }
1085
Axel Lin39aa9b62011-07-11 09:57:43 +08001086 pmic->desc = kcalloc(pmic->num_regulators,
1087 sizeof(struct regulator_desc), GFP_KERNEL);
1088 if (!pmic->desc) {
1089 err = -ENOMEM;
1090 goto err_free_pmic;
1091 }
1092
1093 pmic->info = kcalloc(pmic->num_regulators,
1094 sizeof(struct tps_info *), GFP_KERNEL);
1095 if (!pmic->info) {
1096 err = -ENOMEM;
1097 goto err_free_desc;
1098 }
1099
1100 pmic->rdev = kcalloc(pmic->num_regulators,
1101 sizeof(struct regulator_dev *), GFP_KERNEL);
1102 if (!pmic->rdev) {
1103 err = -ENOMEM;
1104 goto err_free_info;
1105 }
1106
Kyle Mannac1fc1482011-11-03 12:08:06 -05001107 for (i = 0; i < pmic->num_regulators && i < TPS65910_NUM_REGS;
1108 i++, info++) {
1109
1110 reg_data = pmic_plat_data->tps65910_pmic_init_data[i];
1111
1112 /* Regulator API handles empty constraints but not NULL
1113 * constraints */
1114 if (!reg_data)
1115 continue;
1116
Graeme Gregory518fb722011-05-02 16:20:08 -05001117 /* Register the regulators */
1118 pmic->info[i] = info;
1119
1120 pmic->desc[i].name = info->name;
Axel Lin77fa44d2011-05-12 13:47:50 +08001121 pmic->desc[i].id = i;
Laxman Dewangan7d38a3c2012-01-20 16:36:22 +05301122 pmic->desc[i].n_voltages = info->n_voltages;
Graeme Gregory518fb722011-05-02 16:20:08 -05001123
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -05001124 if (i == TPS65910_REG_VDD1 || i == TPS65910_REG_VDD2) {
Graeme Gregory518fb722011-05-02 16:20:08 -05001125 pmic->desc[i].ops = &tps65910_ops_dcdc;
Afzal Mohammed780dc9b2011-11-08 18:54:10 +05301126 pmic->desc[i].n_voltages = VDD1_2_NUM_VOLT_FINE *
1127 VDD1_2_NUM_VOLT_COARSE;
Jorge Eduardo Candelariaa320e3c2011-05-16 18:35:03 -05001128 } else if (i == TPS65910_REG_VDD3) {
1129 if (tps65910_chip_id(tps65910) == TPS65910)
1130 pmic->desc[i].ops = &tps65910_ops_vdd3;
1131 else
1132 pmic->desc[i].ops = &tps65910_ops_dcdc;
1133 } else {
1134 if (tps65910_chip_id(tps65910) == TPS65910)
1135 pmic->desc[i].ops = &tps65910_ops;
1136 else
1137 pmic->desc[i].ops = &tps65911_ops;
1138 }
Graeme Gregory518fb722011-05-02 16:20:08 -05001139
Laxman Dewangan1e0c66f2012-01-28 15:07:57 +05301140 err = tps65910_set_ext_sleep_config(pmic, i,
1141 pmic_plat_data->regulator_ext_sleep_control[i]);
1142 /*
1143 * Failing on regulator for configuring externally control
1144 * is not a serious issue, just throw warning.
1145 */
1146 if (err < 0)
1147 dev_warn(tps65910->dev,
1148 "Failed to initialise ext control config\n");
1149
Graeme Gregory518fb722011-05-02 16:20:08 -05001150 pmic->desc[i].type = REGULATOR_VOLTAGE;
1151 pmic->desc[i].owner = THIS_MODULE;
1152
1153 rdev = regulator_register(&pmic->desc[i],
Rajendra Nayak2c043bc2011-11-18 16:47:19 +05301154 tps65910->dev, reg_data, pmic, NULL);
Graeme Gregory518fb722011-05-02 16:20:08 -05001155 if (IS_ERR(rdev)) {
1156 dev_err(tps65910->dev,
1157 "failed to register %s regulator\n",
1158 pdev->name);
1159 err = PTR_ERR(rdev);
Axel Lin39aa9b62011-07-11 09:57:43 +08001160 goto err_unregister_regulator;
Graeme Gregory518fb722011-05-02 16:20:08 -05001161 }
1162
1163 /* Save regulator for cleanup */
1164 pmic->rdev[i] = rdev;
1165 }
1166 return 0;
1167
Axel Lin39aa9b62011-07-11 09:57:43 +08001168err_unregister_regulator:
Graeme Gregory518fb722011-05-02 16:20:08 -05001169 while (--i >= 0)
1170 regulator_unregister(pmic->rdev[i]);
Axel Lin39aa9b62011-07-11 09:57:43 +08001171 kfree(pmic->rdev);
1172err_free_info:
1173 kfree(pmic->info);
1174err_free_desc:
1175 kfree(pmic->desc);
1176err_free_pmic:
Graeme Gregory518fb722011-05-02 16:20:08 -05001177 kfree(pmic);
1178 return err;
1179}
1180
1181static int __devexit tps65910_remove(struct platform_device *pdev)
1182{
Axel Lin39aa9b62011-07-11 09:57:43 +08001183 struct tps65910_reg *pmic = platform_get_drvdata(pdev);
Graeme Gregory518fb722011-05-02 16:20:08 -05001184 int i;
1185
Axel Lin39aa9b62011-07-11 09:57:43 +08001186 for (i = 0; i < pmic->num_regulators; i++)
1187 regulator_unregister(pmic->rdev[i]);
Graeme Gregory518fb722011-05-02 16:20:08 -05001188
Axel Lin39aa9b62011-07-11 09:57:43 +08001189 kfree(pmic->rdev);
1190 kfree(pmic->info);
1191 kfree(pmic->desc);
1192 kfree(pmic);
Graeme Gregory518fb722011-05-02 16:20:08 -05001193 return 0;
1194}
1195
Laxman Dewangan1e0c66f2012-01-28 15:07:57 +05301196static void tps65910_shutdown(struct platform_device *pdev)
1197{
1198 struct tps65910_reg *pmic = platform_get_drvdata(pdev);
1199 int i;
1200
1201 /*
1202 * Before bootloader jumps to kernel, it makes sure that required
1203 * external control signals are in desired state so that given rails
1204 * can be configure accordingly.
1205 * If rails are configured to be controlled from external control
1206 * then before shutting down/rebooting the system, the external
1207 * control configuration need to be remove from the rails so that
1208 * its output will be available as per register programming even
1209 * if external controls are removed. This is require when the POR
1210 * value of the control signals are not in active state and before
1211 * bootloader initializes it, the system requires the rail output
1212 * to be active for booting.
1213 */
1214 for (i = 0; i < pmic->num_regulators; i++) {
1215 int err;
1216 if (!pmic->rdev[i])
1217 continue;
1218
1219 err = tps65910_set_ext_sleep_config(pmic, i, 0);
1220 if (err < 0)
1221 dev_err(&pdev->dev,
1222 "Error in clearing external control\n");
1223 }
1224}
1225
Graeme Gregory518fb722011-05-02 16:20:08 -05001226static struct platform_driver tps65910_driver = {
1227 .driver = {
1228 .name = "tps65910-pmic",
1229 .owner = THIS_MODULE,
1230 },
1231 .probe = tps65910_probe,
1232 .remove = __devexit_p(tps65910_remove),
Laxman Dewangan1e0c66f2012-01-28 15:07:57 +05301233 .shutdown = tps65910_shutdown,
Graeme Gregory518fb722011-05-02 16:20:08 -05001234};
1235
1236static int __init tps65910_init(void)
1237{
1238 return platform_driver_register(&tps65910_driver);
1239}
1240subsys_initcall(tps65910_init);
1241
1242static void __exit tps65910_cleanup(void)
1243{
1244 platform_driver_unregister(&tps65910_driver);
1245}
1246module_exit(tps65910_cleanup);
1247
1248MODULE_AUTHOR("Graeme Gregory <gg@slimlogic.co.uk>");
Axel Linae0e6542012-02-21 10:14:55 +08001249MODULE_DESCRIPTION("TPS65910/TPS65911 voltage regulator driver");
Graeme Gregory518fb722011-05-02 16:20:08 -05001250MODULE_LICENSE("GPL v2");
1251MODULE_ALIAS("platform:tps65910-pmic");