blob: deb855c41e16f5d123aae465cefad28450cbbaba [file] [log] [blame]
Mike Rapoport49610232010-07-27 14:03:01 +03001/*
2 * Regulator driver for TI TPS6586x
3 *
4 * Copyright (C) 2010 Compulab Ltd.
5 * Author: Mike Rapoport <mike@compulab.co.il>
6 *
7 * Based on da903x
8 * Copyright (C) 2006-2008 Marvell International Ltd.
9 * Copyright (C) 2008 Compulab Ltd.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 */
15
Mike Rapoport49610232010-07-27 14:03:01 +030016#include <linux/kernel.h>
Paul Gortmaker65602c32011-07-17 16:28:23 -040017#include <linux/module.h>
Mike Rapoport49610232010-07-27 14:03:01 +030018#include <linux/init.h>
19#include <linux/err.h>
20#include <linux/slab.h>
21#include <linux/platform_device.h>
22#include <linux/regulator/driver.h>
23#include <linux/regulator/machine.h>
24#include <linux/mfd/tps6586x.h>
25
26/* supply control and voltage setting */
27#define TPS6586X_SUPPLYENA 0x10
28#define TPS6586X_SUPPLYENB 0x11
29#define TPS6586X_SUPPLYENC 0x12
30#define TPS6586X_SUPPLYEND 0x13
31#define TPS6586X_SUPPLYENE 0x14
32#define TPS6586X_VCC1 0x20
33#define TPS6586X_VCC2 0x21
34#define TPS6586X_SM1V1 0x23
35#define TPS6586X_SM1V2 0x24
36#define TPS6586X_SM1SL 0x25
37#define TPS6586X_SM0V1 0x26
38#define TPS6586X_SM0V2 0x27
39#define TPS6586X_SM0SL 0x28
40#define TPS6586X_LDO2AV1 0x29
41#define TPS6586X_LDO2AV2 0x2A
42#define TPS6586X_LDO2BV1 0x2F
43#define TPS6586X_LDO2BV2 0x30
44#define TPS6586X_LDO4V1 0x32
45#define TPS6586X_LDO4V2 0x33
46
47/* converter settings */
48#define TPS6586X_SUPPLYV1 0x41
49#define TPS6586X_SUPPLYV2 0x42
50#define TPS6586X_SUPPLYV3 0x43
51#define TPS6586X_SUPPLYV4 0x44
52#define TPS6586X_SUPPLYV5 0x45
53#define TPS6586X_SUPPLYV6 0x46
54#define TPS6586X_SMODE1 0x47
55#define TPS6586X_SMODE2 0x48
56
57struct tps6586x_regulator {
58 struct regulator_desc desc;
59
60 int volt_reg;
61 int volt_shift;
62 int volt_nbits;
63 int enable_bit[2];
64 int enable_reg[2];
65
66 int *voltages;
67
68 /* for DVM regulators */
69 int go_reg;
70 int go_bit;
71};
72
73static inline struct device *to_tps6586x_dev(struct regulator_dev *rdev)
74{
75 return rdev_get_dev(rdev)->parent->parent;
76}
77
Axel Line1816232012-03-24 09:44:42 +080078static int tps6586x_list_voltage(struct regulator_dev *rdev, unsigned selector)
Mike Rapoport49610232010-07-27 14:03:01 +030079{
80 struct tps6586x_regulator *info = rdev_get_drvdata(rdev);
81
Gary King4cc2e392010-07-30 22:58:58 +030082 return info->voltages[selector] * 1000;
Mike Rapoport49610232010-07-27 14:03:01 +030083}
84
85
Axel Lineed06512012-03-24 09:42:26 +080086static int tps6586x_set_voltage_sel(struct regulator_dev *rdev,
87 unsigned selector)
Mike Rapoport49610232010-07-27 14:03:01 +030088{
89 struct tps6586x_regulator *ri = rdev_get_drvdata(rdev);
90 struct device *parent = to_tps6586x_dev(rdev);
Axel Lineed06512012-03-24 09:42:26 +080091 int ret, val, rid = rdev_get_id(rdev);
92 uint8_t mask;
Mike Rapoport49610232010-07-27 14:03:01 +030093
Axel Lineed06512012-03-24 09:42:26 +080094 val = selector << ri->volt_shift;
95 mask = ((1 << ri->volt_nbits) - 1) << ri->volt_shift;
96
97 ret = tps6586x_update(parent, ri->volt_reg, val, mask);
98 if (ret)
99 return ret;
100
101 /* Update go bit for DVM regulators */
102 switch (rid) {
103 case TPS6586X_ID_LDO_2:
104 case TPS6586X_ID_LDO_4:
105 case TPS6586X_ID_SM_0:
106 case TPS6586X_ID_SM_1:
107 ret = tps6586x_set_bits(parent, ri->go_reg, 1 << ri->go_bit);
108 break;
109 }
110 return ret;
Mike Rapoport49610232010-07-27 14:03:01 +0300111}
112
Axel Lin44a7cda2012-03-24 09:38:30 +0800113static int tps6586x_get_voltage_sel(struct regulator_dev *rdev)
Mike Rapoport49610232010-07-27 14:03:01 +0300114{
115 struct tps6586x_regulator *ri = rdev_get_drvdata(rdev);
116 struct device *parent = to_tps6586x_dev(rdev);
117 uint8_t val, mask;
118 int ret;
119
120 ret = tps6586x_read(parent, ri->volt_reg, &val);
121 if (ret)
122 return ret;
123
124 mask = ((1 << ri->volt_nbits) - 1) << ri->volt_shift;
125 val = (val & mask) >> ri->volt_shift;
126
Axel Lin327531b2010-08-22 22:38:15 +0800127 if (val >= ri->desc.n_voltages)
Mike Rapoport49610232010-07-27 14:03:01 +0300128 BUG();
129
Axel Lin44a7cda2012-03-24 09:38:30 +0800130 return val;
Mike Rapoport49610232010-07-27 14:03:01 +0300131}
132
Mike Rapoport49610232010-07-27 14:03:01 +0300133static int tps6586x_regulator_enable(struct regulator_dev *rdev)
134{
135 struct tps6586x_regulator *ri = rdev_get_drvdata(rdev);
136 struct device *parent = to_tps6586x_dev(rdev);
137
138 return tps6586x_set_bits(parent, ri->enable_reg[0],
139 1 << ri->enable_bit[0]);
140}
141
142static int tps6586x_regulator_disable(struct regulator_dev *rdev)
143{
144 struct tps6586x_regulator *ri = rdev_get_drvdata(rdev);
145 struct device *parent = to_tps6586x_dev(rdev);
146
147 return tps6586x_clr_bits(parent, ri->enable_reg[0],
148 1 << ri->enable_bit[0]);
149}
150
151static int tps6586x_regulator_is_enabled(struct regulator_dev *rdev)
152{
153 struct tps6586x_regulator *ri = rdev_get_drvdata(rdev);
154 struct device *parent = to_tps6586x_dev(rdev);
155 uint8_t reg_val;
156 int ret;
157
158 ret = tps6586x_read(parent, ri->enable_reg[0], &reg_val);
159 if (ret)
160 return ret;
161
162 return !!(reg_val & (1 << ri->enable_bit[0]));
163}
164
Axel Line1816232012-03-24 09:44:42 +0800165static struct regulator_ops tps6586x_regulator_ops = {
166 .list_voltage = tps6586x_list_voltage,
Axel Lin44a7cda2012-03-24 09:38:30 +0800167 .get_voltage_sel = tps6586x_get_voltage_sel,
Axel Lineed06512012-03-24 09:42:26 +0800168 .set_voltage_sel = tps6586x_set_voltage_sel,
Mike Rapoport49610232010-07-27 14:03:01 +0300169
170 .is_enabled = tps6586x_regulator_is_enabled,
171 .enable = tps6586x_regulator_enable,
172 .disable = tps6586x_regulator_disable,
173};
174
175static int tps6586x_ldo_voltages[] = {
176 1250, 1500, 1800, 2500, 2700, 2850, 3100, 3300,
177};
178
179static int tps6586x_ldo4_voltages[] = {
180 1700, 1725, 1750, 1775, 1800, 1825, 1850, 1875,
181 1900, 1925, 1950, 1975, 2000, 2025, 2050, 2075,
182 2100, 2125, 2150, 2175, 2200, 2225, 2250, 2275,
183 2300, 2325, 2350, 2375, 2400, 2425, 2450, 2475,
184};
185
Gary King4cc2e392010-07-30 22:58:58 +0300186static int tps6586x_sm2_voltages[] = {
187 3000, 3050, 3100, 3150, 3200, 3250, 3300, 3350,
188 3400, 3450, 3500, 3550, 3600, 3650, 3700, 3750,
189 3800, 3850, 3900, 3950, 4000, 4050, 4100, 4150,
190 4200, 4250, 4300, 4350, 4400, 4450, 4500, 4550,
191};
192
Mike Rapoport49610232010-07-27 14:03:01 +0300193static int tps6586x_dvm_voltages[] = {
194 725, 750, 775, 800, 825, 850, 875, 900,
195 925, 950, 975, 1000, 1025, 1050, 1075, 1100,
196 1125, 1150, 1175, 1200, 1225, 1250, 1275, 1300,
197 1325, 1350, 1375, 1400, 1425, 1450, 1475, 1500,
198};
199
Axel Line1816232012-03-24 09:44:42 +0800200#define TPS6586X_REGULATOR(_id, vdata, vreg, shift, nbits, \
Danny Huang64db6572010-12-01 13:37:29 -0700201 ereg0, ebit0, ereg1, ebit1) \
Mike Rapoport49610232010-07-27 14:03:01 +0300202 .desc = { \
203 .name = "REG-" #_id, \
Axel Line1816232012-03-24 09:44:42 +0800204 .ops = &tps6586x_regulator_ops, \
Mike Rapoport49610232010-07-27 14:03:01 +0300205 .type = REGULATOR_VOLTAGE, \
206 .id = TPS6586X_ID_##_id, \
207 .n_voltages = ARRAY_SIZE(tps6586x_##vdata##_voltages), \
208 .owner = THIS_MODULE, \
209 }, \
210 .volt_reg = TPS6586X_##vreg, \
211 .volt_shift = (shift), \
212 .volt_nbits = (nbits), \
213 .enable_reg[0] = TPS6586X_SUPPLY##ereg0, \
214 .enable_bit[0] = (ebit0), \
215 .enable_reg[1] = TPS6586X_SUPPLY##ereg1, \
216 .enable_bit[1] = (ebit1), \
Danny Huang64db6572010-12-01 13:37:29 -0700217 .voltages = tps6586x_##vdata##_voltages,
218
219#define TPS6586X_REGULATOR_DVM_GOREG(goreg, gobit) \
220 .go_reg = TPS6586X_##goreg, \
221 .go_bit = (gobit),
Mike Rapoport49610232010-07-27 14:03:01 +0300222
223#define TPS6586X_LDO(_id, vdata, vreg, shift, nbits, \
224 ereg0, ebit0, ereg1, ebit1) \
Danny Huang64db6572010-12-01 13:37:29 -0700225{ \
Axel Line1816232012-03-24 09:44:42 +0800226 TPS6586X_REGULATOR(_id, vdata, vreg, shift, nbits, \
Danny Huang64db6572010-12-01 13:37:29 -0700227 ereg0, ebit0, ereg1, ebit1) \
228}
Mike Rapoport49610232010-07-27 14:03:01 +0300229
230#define TPS6586X_DVM(_id, vdata, vreg, shift, nbits, \
231 ereg0, ebit0, ereg1, ebit1, goreg, gobit) \
Danny Huang64db6572010-12-01 13:37:29 -0700232{ \
Axel Line1816232012-03-24 09:44:42 +0800233 TPS6586X_REGULATOR(_id, vdata, vreg, shift, nbits, \
Danny Huang64db6572010-12-01 13:37:29 -0700234 ereg0, ebit0, ereg1, ebit1) \
235 TPS6586X_REGULATOR_DVM_GOREG(goreg, gobit) \
236}
Mike Rapoport49610232010-07-27 14:03:01 +0300237
238static struct tps6586x_regulator tps6586x_regulator[] = {
239 TPS6586X_LDO(LDO_0, ldo, SUPPLYV1, 5, 3, ENC, 0, END, 0),
240 TPS6586X_LDO(LDO_3, ldo, SUPPLYV4, 0, 3, ENC, 2, END, 2),
241 TPS6586X_LDO(LDO_5, ldo, SUPPLYV6, 0, 3, ENE, 6, ENE, 6),
242 TPS6586X_LDO(LDO_6, ldo, SUPPLYV3, 0, 3, ENC, 4, END, 4),
243 TPS6586X_LDO(LDO_7, ldo, SUPPLYV3, 3, 3, ENC, 5, END, 5),
Danny Huang1b39ed02010-12-01 13:37:31 -0700244 TPS6586X_LDO(LDO_8, ldo, SUPPLYV2, 5, 3, ENC, 6, END, 6),
Mike Rapoport49610232010-07-27 14:03:01 +0300245 TPS6586X_LDO(LDO_9, ldo, SUPPLYV6, 3, 3, ENE, 7, ENE, 7),
Danny Huang1b39ed02010-12-01 13:37:31 -0700246 TPS6586X_LDO(LDO_RTC, ldo, SUPPLYV4, 3, 3, V4, 7, V4, 7),
Mike Rapoport49610232010-07-27 14:03:01 +0300247 TPS6586X_LDO(LDO_1, dvm, SUPPLYV1, 0, 5, ENC, 1, END, 1),
Danny Huang1b39ed02010-12-01 13:37:31 -0700248 TPS6586X_LDO(SM_2, sm2, SUPPLYV2, 0, 5, ENC, 7, END, 7),
Mike Rapoport49610232010-07-27 14:03:01 +0300249
250 TPS6586X_DVM(LDO_2, dvm, LDO2BV1, 0, 5, ENA, 3, ENB, 3, VCC2, 6),
251 TPS6586X_DVM(LDO_4, ldo4, LDO4V1, 0, 5, ENC, 3, END, 3, VCC1, 6),
252 TPS6586X_DVM(SM_0, dvm, SM0V1, 0, 5, ENA, 1, ENB, 1, VCC1, 2),
253 TPS6586X_DVM(SM_1, dvm, SM1V1, 0, 5, ENA, 0, ENB, 0, VCC1, 0),
254};
255
256/*
257 * TPS6586X has 2 enable bits that are OR'ed to determine the actual
258 * regulator state. Clearing one of this bits allows switching
259 * regulator on and of with single register write.
260 */
261static inline int tps6586x_regulator_preinit(struct device *parent,
262 struct tps6586x_regulator *ri)
263{
264 uint8_t val1, val2;
265 int ret;
266
Danny Huang1dbcf352010-12-01 13:37:30 -0700267 if (ri->enable_reg[0] == ri->enable_reg[1] &&
268 ri->enable_bit[0] == ri->enable_bit[1])
269 return 0;
270
Mike Rapoport49610232010-07-27 14:03:01 +0300271 ret = tps6586x_read(parent, ri->enable_reg[0], &val1);
272 if (ret)
273 return ret;
274
275 ret = tps6586x_read(parent, ri->enable_reg[1], &val2);
276 if (ret)
277 return ret;
278
Danny Huang4f5867072010-12-01 13:37:28 -0700279 if (!(val2 & (1 << ri->enable_bit[1])))
Mike Rapoport49610232010-07-27 14:03:01 +0300280 return 0;
281
282 /*
283 * The regulator is on, but it's enabled with the bit we don't
284 * want to use, so we switch the enable bits
285 */
Danny Huang4f5867072010-12-01 13:37:28 -0700286 if (!(val1 & (1 << ri->enable_bit[0]))) {
Mike Rapoport49610232010-07-27 14:03:01 +0300287 ret = tps6586x_set_bits(parent, ri->enable_reg[0],
288 1 << ri->enable_bit[0]);
289 if (ret)
290 return ret;
291 }
292
293 return tps6586x_clr_bits(parent, ri->enable_reg[1],
294 1 << ri->enable_bit[1]);
295}
296
Xin Xie500c5242011-08-09 18:47:50 +0800297static int tps6586x_regulator_set_slew_rate(struct platform_device *pdev)
298{
299 struct device *parent = pdev->dev.parent;
300 struct regulator_init_data *p = pdev->dev.platform_data;
301 struct tps6586x_settings *setting = p->driver_data;
302 uint8_t reg;
303
304 if (setting == NULL)
305 return 0;
306
307 if (!(setting->slew_rate & TPS6586X_SLEW_RATE_SET))
308 return 0;
309
310 /* only SM0 and SM1 can have the slew rate settings */
311 switch (pdev->id) {
312 case TPS6586X_ID_SM_0:
313 reg = TPS6586X_SM0SL;
314 break;
315 case TPS6586X_ID_SM_1:
316 reg = TPS6586X_SM1SL;
317 break;
318 default:
319 dev_warn(&pdev->dev, "Only SM0/SM1 can set slew rate\n");
320 return -EINVAL;
321 }
322
323 return tps6586x_write(parent, reg,
324 setting->slew_rate & TPS6586X_SLEW_RATE_MASK);
325}
326
Mike Rapoport49610232010-07-27 14:03:01 +0300327static inline struct tps6586x_regulator *find_regulator_info(int id)
328{
329 struct tps6586x_regulator *ri;
330 int i;
331
332 for (i = 0; i < ARRAY_SIZE(tps6586x_regulator); i++) {
333 ri = &tps6586x_regulator[i];
334 if (ri->desc.id == id)
335 return ri;
336 }
337 return NULL;
338}
339
340static int __devinit tps6586x_regulator_probe(struct platform_device *pdev)
341{
342 struct tps6586x_regulator *ri = NULL;
Mark Brownc172708d2012-04-04 00:50:22 +0100343 struct regulator_config config = { };
Mike Rapoport49610232010-07-27 14:03:01 +0300344 struct regulator_dev *rdev;
345 int id = pdev->id;
346 int err;
347
Thierry Reding394ee3d2012-03-08 15:51:24 +0100348 dev_dbg(&pdev->dev, "Probing regulator %d\n", id);
Mike Rapoport49610232010-07-27 14:03:01 +0300349
350 ri = find_regulator_info(id);
351 if (ri == NULL) {
352 dev_err(&pdev->dev, "invalid regulator ID specified\n");
353 return -EINVAL;
354 }
355
356 err = tps6586x_regulator_preinit(pdev->dev.parent, ri);
357 if (err)
358 return err;
359
Mark Brownc172708d2012-04-04 00:50:22 +0100360 config.dev = &pdev->dev;
361 config.init_data = pdev->dev.platform_data;
362 config.driver_data = ri;
363
364 rdev = regulator_register(&ri->desc, &config);
Mike Rapoport49610232010-07-27 14:03:01 +0300365 if (IS_ERR(rdev)) {
366 dev_err(&pdev->dev, "failed to register regulator %s\n",
367 ri->desc.name);
368 return PTR_ERR(rdev);
369 }
370
Axel Line7973c32010-08-09 15:58:06 +0800371 platform_set_drvdata(pdev, rdev);
Mike Rapoport49610232010-07-27 14:03:01 +0300372
Xin Xie500c5242011-08-09 18:47:50 +0800373 return tps6586x_regulator_set_slew_rate(pdev);
Mike Rapoport49610232010-07-27 14:03:01 +0300374}
375
376static int __devexit tps6586x_regulator_remove(struct platform_device *pdev)
377{
Axel Line7973c32010-08-09 15:58:06 +0800378 struct regulator_dev *rdev = platform_get_drvdata(pdev);
379
380 regulator_unregister(rdev);
Mike Rapoport49610232010-07-27 14:03:01 +0300381 return 0;
382}
383
384static struct platform_driver tps6586x_regulator_driver = {
385 .driver = {
386 .name = "tps6586x-regulator",
387 .owner = THIS_MODULE,
388 },
389 .probe = tps6586x_regulator_probe,
390 .remove = __devexit_p(tps6586x_regulator_remove),
391};
392
393static int __init tps6586x_regulator_init(void)
394{
395 return platform_driver_register(&tps6586x_regulator_driver);
396}
397subsys_initcall(tps6586x_regulator_init);
398
399static void __exit tps6586x_regulator_exit(void)
400{
401 platform_driver_unregister(&tps6586x_regulator_driver);
402}
403module_exit(tps6586x_regulator_exit);
404
405MODULE_LICENSE("GPL");
406MODULE_AUTHOR("Mike Rapoport <mike@compulab.co.il>");
407MODULE_DESCRIPTION("Regulator Driver for TI TPS6586X PMIC");
408MODULE_ALIAS("platform:tps6586x-regulator");