blob: 3ea639f29e95a2d8abbf9e37fa44d0672c3e8fc3 [file] [log] [blame]
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +02001/*
2 * Regulator driver for National Semiconductors LP3971 PMIC chip
3 *
4 * Copyright (C) 2009 Samsung Electronics
5 * Author: Marek Szyprowski <m.szyprowski@samsung.com>
6 *
7 * Based on wm8350.c
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 *
13 */
14
15#include <linux/bug.h>
16#include <linux/err.h>
17#include <linux/i2c.h>
18#include <linux/kernel.h>
19#include <linux/regulator/driver.h>
20#include <linux/regulator/lp3971.h>
21
22struct lp3971 {
23 struct device *dev;
24 struct mutex io_lock;
25 struct i2c_client *i2c;
26 int num_regulators;
27 struct regulator_dev **rdev;
28};
29
30static u8 lp3971_reg_read(struct lp3971 *lp3971, u8 reg);
31static int lp3971_set_bits(struct lp3971 *lp3971, u8 reg, u16 mask, u16 val);
32
33#define LP3971_SYS_CONTROL1_REG 0x07
34
35/* System control register 1 initial value,
36 bits 4 and 5 are EPROM programmable */
37#define SYS_CONTROL1_INIT_VAL 0x40
38#define SYS_CONTROL1_INIT_MASK 0xCF
39
40#define LP3971_BUCK_VOL_ENABLE_REG 0x10
41#define LP3971_BUCK_VOL_CHANGE_REG 0x20
42
43/* Voltage control registers shift:
44 LP3971_BUCK1 -> 0
45 LP3971_BUCK2 -> 4
46 LP3971_BUCK3 -> 6
47*/
48#define BUCK_VOL_CHANGE_SHIFT(x) (((1 << x) & ~0x01) << 1)
49#define BUCK_VOL_CHANGE_FLAG_GO 0x01
50#define BUCK_VOL_CHANGE_FLAG_TARGET 0x02
51#define BUCK_VOL_CHANGE_FLAG_MASK 0x03
52
53#define LP3971_BUCK1_BASE 0x23
54#define LP3971_BUCK2_BASE 0x29
55#define LP3971_BUCK3_BASE 0x32
56
Tobias Klauser6faa7e02009-12-23 14:13:17 +010057static const int buck_base_addr[] = {
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +020058 LP3971_BUCK1_BASE,
59 LP3971_BUCK2_BASE,
60 LP3971_BUCK3_BASE,
61};
62
63#define LP3971_BUCK_TARGET_VOL1_REG(x) (buck_base_addr[x])
64#define LP3971_BUCK_TARGET_VOL2_REG(x) (buck_base_addr[x]+1)
65
Tobias Klauser6faa7e02009-12-23 14:13:17 +010066static const int buck_voltage_map[] = {
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +020067 0, 800, 850, 900, 950, 1000, 1050, 1100,
68 1150, 1200, 1250, 1300, 1350, 1400, 1450, 1500,
69 1550, 1600, 1650, 1700, 1800, 1900, 2500, 2800,
70 3000, 3300,
71};
72
73#define BUCK_TARGET_VOL_MASK 0x3f
74#define BUCK_TARGET_VOL_MIN_IDX 0x01
75#define BUCK_TARGET_VOL_MAX_IDX 0x19
76
77#define LP3971_BUCK_RAMP_REG(x) (buck_base_addr[x]+2)
78
79#define LP3971_LDO_ENABLE_REG 0x12
80#define LP3971_LDO_VOL_CONTR_BASE 0x39
81
82/* Voltage control registers:
83 LP3971_LDO1 -> LP3971_LDO_VOL_CONTR_BASE + 0
84 LP3971_LDO2 -> LP3971_LDO_VOL_CONTR_BASE + 0
85 LP3971_LDO3 -> LP3971_LDO_VOL_CONTR_BASE + 1
86 LP3971_LDO4 -> LP3971_LDO_VOL_CONTR_BASE + 1
87 LP3971_LDO5 -> LP3971_LDO_VOL_CONTR_BASE + 2
88*/
89#define LP3971_LDO_VOL_CONTR_REG(x) (LP3971_LDO_VOL_CONTR_BASE + (x >> 1))
90
91/* Voltage control registers shift:
92 LP3971_LDO1 -> 0, LP3971_LDO2 -> 4
93 LP3971_LDO3 -> 0, LP3971_LDO4 -> 4
94 LP3971_LDO5 -> 0
95*/
96#define LDO_VOL_CONTR_SHIFT(x) ((x & 1) << 2)
97#define LDO_VOL_CONTR_MASK 0x0f
98
Tobias Klauser6faa7e02009-12-23 14:13:17 +010099static const int ldo45_voltage_map[] = {
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200100 1000, 1050, 1100, 1150, 1200, 1250, 1300, 1350,
101 1400, 1500, 1800, 1900, 2500, 2800, 3000, 3300,
102};
103
Tobias Klauser6faa7e02009-12-23 14:13:17 +0100104static const int ldo123_voltage_map[] = {
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200105 1800, 1900, 2000, 2100, 2200, 2300, 2400, 2500,
106 2600, 2700, 2800, 2900, 3000, 3100, 3200, 3300,
107};
108
Tobias Klauser6faa7e02009-12-23 14:13:17 +0100109static const int *ldo_voltage_map[] = {
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200110 ldo123_voltage_map, /* LDO1 */
111 ldo123_voltage_map, /* LDO2 */
112 ldo123_voltage_map, /* LDO3 */
113 ldo45_voltage_map, /* LDO4 */
114 ldo45_voltage_map, /* LDO5 */
115};
116
117#define LDO_VOL_VALUE_MAP(x) (ldo_voltage_map[(x - LP3971_LDO1)])
118
119#define LDO_VOL_MIN_IDX 0x00
120#define LDO_VOL_MAX_IDX 0x0f
121
122static int lp3971_ldo_list_voltage(struct regulator_dev *dev, unsigned index)
123{
124 int ldo = rdev_get_id(dev) - LP3971_LDO1;
125 return 1000 * LDO_VOL_VALUE_MAP(ldo)[index];
126}
127
128static int lp3971_ldo_is_enabled(struct regulator_dev *dev)
129{
130 struct lp3971 *lp3971 = rdev_get_drvdata(dev);
131 int ldo = rdev_get_id(dev) - LP3971_LDO1;
132 u16 mask = 1 << (1 + ldo);
133 u16 val;
134
135 val = lp3971_reg_read(lp3971, LP3971_LDO_ENABLE_REG);
136 return (val & mask) != 0;
137}
138
139static int lp3971_ldo_enable(struct regulator_dev *dev)
140{
141 struct lp3971 *lp3971 = rdev_get_drvdata(dev);
142 int ldo = rdev_get_id(dev) - LP3971_LDO1;
143 u16 mask = 1 << (1 + ldo);
144
145 return lp3971_set_bits(lp3971, LP3971_LDO_ENABLE_REG, mask, mask);
146}
147
148static int lp3971_ldo_disable(struct regulator_dev *dev)
149{
150 struct lp3971 *lp3971 = rdev_get_drvdata(dev);
151 int ldo = rdev_get_id(dev) - LP3971_LDO1;
152 u16 mask = 1 << (1 + ldo);
153
154 return lp3971_set_bits(lp3971, LP3971_LDO_ENABLE_REG, mask, 0);
155}
156
157static int lp3971_ldo_get_voltage(struct regulator_dev *dev)
158{
159 struct lp3971 *lp3971 = rdev_get_drvdata(dev);
160 int ldo = rdev_get_id(dev) - LP3971_LDO1;
161 u16 val, reg;
162
163 reg = lp3971_reg_read(lp3971, LP3971_LDO_VOL_CONTR_REG(ldo));
164 val = (reg >> LDO_VOL_CONTR_SHIFT(ldo)) & LDO_VOL_CONTR_MASK;
165
166 return 1000 * LDO_VOL_VALUE_MAP(ldo)[val];
167}
168
169static int lp3971_ldo_set_voltage(struct regulator_dev *dev,
170 int min_uV, int max_uV)
171{
172 struct lp3971 *lp3971 = rdev_get_drvdata(dev);
173 int ldo = rdev_get_id(dev) - LP3971_LDO1;
174 int min_vol = min_uV / 1000, max_vol = max_uV / 1000;
175 const int *vol_map = LDO_VOL_VALUE_MAP(ldo);
176 u16 val;
177
178 if (min_vol < vol_map[LDO_VOL_MIN_IDX] ||
179 min_vol > vol_map[LDO_VOL_MAX_IDX])
180 return -EINVAL;
181
182 for (val = LDO_VOL_MIN_IDX; val <= LDO_VOL_MAX_IDX; val++)
183 if (vol_map[val] >= min_vol)
184 break;
185
Roel Kluin62737d42010-02-12 12:30:21 +0100186 if (val > LDO_VOL_MAX_IDX || vol_map[val] > max_vol)
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200187 return -EINVAL;
188
189 return lp3971_set_bits(lp3971, LP3971_LDO_VOL_CONTR_REG(ldo),
190 LDO_VOL_CONTR_MASK << LDO_VOL_CONTR_SHIFT(ldo), val);
191}
192
193static struct regulator_ops lp3971_ldo_ops = {
194 .list_voltage = lp3971_ldo_list_voltage,
195 .is_enabled = lp3971_ldo_is_enabled,
196 .enable = lp3971_ldo_enable,
197 .disable = lp3971_ldo_disable,
198 .get_voltage = lp3971_ldo_get_voltage,
199 .set_voltage = lp3971_ldo_set_voltage,
200};
201
202static int lp3971_dcdc_list_voltage(struct regulator_dev *dev, unsigned index)
203{
204 return 1000 * buck_voltage_map[index];
205}
206
207static int lp3971_dcdc_is_enabled(struct regulator_dev *dev)
208{
209 struct lp3971 *lp3971 = rdev_get_drvdata(dev);
210 int buck = rdev_get_id(dev) - LP3971_DCDC1;
211 u16 mask = 1 << (buck * 2);
212 u16 val;
213
214 val = lp3971_reg_read(lp3971, LP3971_BUCK_VOL_ENABLE_REG);
215 return (val & mask) != 0;
216}
217
218static int lp3971_dcdc_enable(struct regulator_dev *dev)
219{
220 struct lp3971 *lp3971 = rdev_get_drvdata(dev);
221 int buck = rdev_get_id(dev) - LP3971_DCDC1;
222 u16 mask = 1 << (buck * 2);
223
224 return lp3971_set_bits(lp3971, LP3971_BUCK_VOL_ENABLE_REG, mask, mask);
225}
226
227static int lp3971_dcdc_disable(struct regulator_dev *dev)
228{
229 struct lp3971 *lp3971 = rdev_get_drvdata(dev);
230 int buck = rdev_get_id(dev) - LP3971_DCDC1;
231 u16 mask = 1 << (buck * 2);
232
233 return lp3971_set_bits(lp3971, LP3971_BUCK_VOL_ENABLE_REG, mask, 0);
234}
235
236static int lp3971_dcdc_get_voltage(struct regulator_dev *dev)
237{
238 struct lp3971 *lp3971 = rdev_get_drvdata(dev);
239 int buck = rdev_get_id(dev) - LP3971_DCDC1;
240 u16 reg;
241 int val;
242
243 reg = lp3971_reg_read(lp3971, LP3971_BUCK_TARGET_VOL1_REG(buck));
244 reg &= BUCK_TARGET_VOL_MASK;
245
246 if (reg <= BUCK_TARGET_VOL_MAX_IDX)
247 val = 1000 * buck_voltage_map[reg];
248 else {
249 val = 0;
250 dev_warn(&dev->dev, "chip reported incorrect voltage value.\n");
251 }
252
253 return val;
254}
255
256static int lp3971_dcdc_set_voltage(struct regulator_dev *dev,
257 int min_uV, int max_uV)
258{
259 struct lp3971 *lp3971 = rdev_get_drvdata(dev);
260 int buck = rdev_get_id(dev) - LP3971_DCDC1;
261 int min_vol = min_uV / 1000, max_vol = max_uV / 1000;
262 const int *vol_map = buck_voltage_map;
263 u16 val;
264 int ret;
265
266 if (min_vol < vol_map[BUCK_TARGET_VOL_MIN_IDX] ||
267 min_vol > vol_map[BUCK_TARGET_VOL_MAX_IDX])
268 return -EINVAL;
269
270 for (val = BUCK_TARGET_VOL_MIN_IDX; val <= BUCK_TARGET_VOL_MAX_IDX;
271 val++)
272 if (vol_map[val] >= min_vol)
273 break;
274
Roel Kluin62737d42010-02-12 12:30:21 +0100275 if (val > BUCK_TARGET_VOL_MAX_IDX || vol_map[val] > max_vol)
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200276 return -EINVAL;
277
278 ret = lp3971_set_bits(lp3971, LP3971_BUCK_TARGET_VOL1_REG(buck),
279 BUCK_TARGET_VOL_MASK, val);
280 if (ret)
281 return ret;
282
283 ret = lp3971_set_bits(lp3971, LP3971_BUCK_VOL_CHANGE_REG,
284 BUCK_VOL_CHANGE_FLAG_MASK << BUCK_VOL_CHANGE_SHIFT(buck),
285 BUCK_VOL_CHANGE_FLAG_GO << BUCK_VOL_CHANGE_SHIFT(buck));
286 if (ret)
287 return ret;
288
289 return lp3971_set_bits(lp3971, LP3971_BUCK_VOL_CHANGE_REG,
290 BUCK_VOL_CHANGE_FLAG_MASK << BUCK_VOL_CHANGE_SHIFT(buck),
291 0 << BUCK_VOL_CHANGE_SHIFT(buck));
292}
293
294static struct regulator_ops lp3971_dcdc_ops = {
295 .list_voltage = lp3971_dcdc_list_voltage,
296 .is_enabled = lp3971_dcdc_is_enabled,
297 .enable = lp3971_dcdc_enable,
298 .disable = lp3971_dcdc_disable,
299 .get_voltage = lp3971_dcdc_get_voltage,
300 .set_voltage = lp3971_dcdc_set_voltage,
301};
302
303static struct regulator_desc regulators[] = {
304 {
305 .name = "LDO1",
306 .id = LP3971_LDO1,
307 .ops = &lp3971_ldo_ops,
308 .n_voltages = ARRAY_SIZE(ldo123_voltage_map),
309 .type = REGULATOR_VOLTAGE,
310 .owner = THIS_MODULE,
311 },
312 {
313 .name = "LDO2",
314 .id = LP3971_LDO2,
315 .ops = &lp3971_ldo_ops,
316 .n_voltages = ARRAY_SIZE(ldo123_voltage_map),
317 .type = REGULATOR_VOLTAGE,
318 .owner = THIS_MODULE,
319 },
320 {
321 .name = "LDO3",
322 .id = LP3971_LDO3,
323 .ops = &lp3971_ldo_ops,
324 .n_voltages = ARRAY_SIZE(ldo123_voltage_map),
325 .type = REGULATOR_VOLTAGE,
326 .owner = THIS_MODULE,
327 },
328 {
329 .name = "LDO4",
330 .id = LP3971_LDO4,
331 .ops = &lp3971_ldo_ops,
332 .n_voltages = ARRAY_SIZE(ldo45_voltage_map),
333 .type = REGULATOR_VOLTAGE,
334 .owner = THIS_MODULE,
335 },
336 {
337 .name = "LDO5",
338 .id = LP3971_LDO5,
339 .ops = &lp3971_ldo_ops,
340 .n_voltages = ARRAY_SIZE(ldo45_voltage_map),
341 .type = REGULATOR_VOLTAGE,
342 .owner = THIS_MODULE,
343 },
344 {
345 .name = "DCDC1",
346 .id = LP3971_DCDC1,
347 .ops = &lp3971_dcdc_ops,
348 .n_voltages = ARRAY_SIZE(buck_voltage_map),
349 .type = REGULATOR_VOLTAGE,
350 .owner = THIS_MODULE,
351 },
352 {
353 .name = "DCDC2",
354 .id = LP3971_DCDC2,
355 .ops = &lp3971_dcdc_ops,
356 .n_voltages = ARRAY_SIZE(buck_voltage_map),
357 .type = REGULATOR_VOLTAGE,
358 .owner = THIS_MODULE,
359 },
360 {
361 .name = "DCDC3",
362 .id = LP3971_DCDC3,
363 .ops = &lp3971_dcdc_ops,
364 .n_voltages = ARRAY_SIZE(buck_voltage_map),
365 .type = REGULATOR_VOLTAGE,
366 .owner = THIS_MODULE,
367 },
368};
369
370static int lp3971_i2c_read(struct i2c_client *i2c, char reg, int count,
371 u16 *dest)
372{
373 int ret;
374
375 if (count != 1)
376 return -EIO;
377 ret = i2c_smbus_read_byte_data(i2c, reg);
378 if (ret < 0 || count != 1)
379 return -EIO;
380
381 *dest = ret;
382 return 0;
383}
384
385static int lp3971_i2c_write(struct i2c_client *i2c, char reg, int count,
386 const u16 *src)
387{
388 int ret;
389
390 if (count != 1)
391 return -EIO;
392 ret = i2c_smbus_write_byte_data(i2c, reg, *src);
393 if (ret >= 0)
394 return 0;
395
396 return ret;
397}
398
399static u8 lp3971_reg_read(struct lp3971 *lp3971, u8 reg)
400{
401 u16 val = 0;
402
403 mutex_lock(&lp3971->io_lock);
404
405 lp3971_i2c_read(lp3971->i2c, reg, 1, &val);
406
407 dev_dbg(lp3971->dev, "reg read 0x%02x -> 0x%02x\n", (int)reg,
408 (unsigned)val&0xff);
409
410 mutex_unlock(&lp3971->io_lock);
411
412 return val & 0xff;
413}
414
415static int lp3971_set_bits(struct lp3971 *lp3971, u8 reg, u16 mask, u16 val)
416{
417 u16 tmp;
418 int ret;
419
420 mutex_lock(&lp3971->io_lock);
421
422 ret = lp3971_i2c_read(lp3971->i2c, reg, 1, &tmp);
423 tmp = (tmp & ~mask) | val;
424 if (ret == 0) {
425 ret = lp3971_i2c_write(lp3971->i2c, reg, 1, &tmp);
426 dev_dbg(lp3971->dev, "reg write 0x%02x -> 0x%02x\n", (int)reg,
427 (unsigned)val&0xff);
428 }
429 mutex_unlock(&lp3971->io_lock);
430
431 return ret;
432}
433
434static int setup_regulators(struct lp3971 *lp3971,
435 struct lp3971_platform_data *pdata)
436{
437 int i, err;
438 int num_regulators = pdata->num_regulators;
439 lp3971->num_regulators = num_regulators;
440 lp3971->rdev = kzalloc(sizeof(struct regulator_dev *) * num_regulators,
441 GFP_KERNEL);
442
443 /* Instantiate the regulators */
444 for (i = 0; i < num_regulators; i++) {
445 int id = pdata->regulators[i].id;
446 lp3971->rdev[i] = regulator_register(&regulators[id],
447 lp3971->dev, pdata->regulators[i].initdata, lp3971);
448
Julia Lawalld662fc82009-11-21 22:18:44 +0100449 if (IS_ERR(lp3971->rdev[i])) {
450 err = PTR_ERR(lp3971->rdev[i]);
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200451 dev_err(lp3971->dev, "regulator init failed: %d\n",
452 err);
453 goto error;
454 }
455 }
456
457 return 0;
458error:
459 for (i = 0; i < num_regulators; i++)
460 if (lp3971->rdev[i])
461 regulator_unregister(lp3971->rdev[i]);
462 kfree(lp3971->rdev);
463 lp3971->rdev = NULL;
464 return err;
465}
466
467static int __devinit lp3971_i2c_probe(struct i2c_client *i2c,
468 const struct i2c_device_id *id)
469{
470 struct lp3971 *lp3971;
471 struct lp3971_platform_data *pdata = i2c->dev.platform_data;
472 int ret;
473 u16 val;
474
475 lp3971 = kzalloc(sizeof(struct lp3971), GFP_KERNEL);
476 if (lp3971 == NULL) {
477 ret = -ENOMEM;
478 goto err;
479 }
480
481 lp3971->i2c = i2c;
482 lp3971->dev = &i2c->dev;
483 i2c_set_clientdata(i2c, lp3971);
484
485 mutex_init(&lp3971->io_lock);
486
487 /* Detect LP3971 */
488 ret = lp3971_i2c_read(i2c, LP3971_SYS_CONTROL1_REG, 1, &val);
489 if (ret == 0 && (val & SYS_CONTROL1_INIT_MASK) != SYS_CONTROL1_INIT_VAL)
490 ret = -ENODEV;
491 if (ret < 0) {
492 dev_err(&i2c->dev, "failed to detect device\n");
493 goto err_detect;
494 }
495
496 if (pdata) {
497 ret = setup_regulators(lp3971, pdata);
498 if (ret < 0)
499 goto err_detect;
500 } else
501 dev_warn(lp3971->dev, "No platform init data supplied\n");
502
503 return 0;
504
505err_detect:
506 i2c_set_clientdata(i2c, NULL);
507 kfree(lp3971);
508err:
509 return ret;
510}
511
512static int __devexit lp3971_i2c_remove(struct i2c_client *i2c)
513{
514 struct lp3971 *lp3971 = i2c_get_clientdata(i2c);
515 int i;
516 for (i = 0; i < lp3971->num_regulators; i++)
517 if (lp3971->rdev[i])
518 regulator_unregister(lp3971->rdev[i]);
519 kfree(lp3971->rdev);
520 i2c_set_clientdata(i2c, NULL);
521 kfree(lp3971);
522
523 return 0;
524}
525
526static const struct i2c_device_id lp3971_i2c_id[] = {
527 { "lp3971", 0 },
528 { }
529};
530MODULE_DEVICE_TABLE(i2c, lp3971_i2c_id);
531
532static struct i2c_driver lp3971_i2c_driver = {
533 .driver = {
534 .name = "LP3971",
535 .owner = THIS_MODULE,
536 },
537 .probe = lp3971_i2c_probe,
Liam Girdwood6113c3a2009-05-19 11:44:37 +0100538 .remove = __devexit_p(lp3971_i2c_remove),
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200539 .id_table = lp3971_i2c_id,
540};
541
542static int __init lp3971_module_init(void)
543{
Wolfram Sang12a1d932009-09-18 22:44:45 +0200544 int ret;
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200545
546 ret = i2c_add_driver(&lp3971_i2c_driver);
547 if (ret != 0)
548 pr_err("Failed to register I2C driver: %d\n", ret);
549
550 return ret;
551}
552module_init(lp3971_module_init);
553
554static void __exit lp3971_module_exit(void)
555{
556 i2c_del_driver(&lp3971_i2c_driver);
557}
558module_exit(lp3971_module_exit);
559
560MODULE_LICENSE("GPL");
561MODULE_AUTHOR("Marek Szyprowski <m.szyprowski@samsung.com>");
562MODULE_DESCRIPTION("LP3971 PMIC driver");