blob: 72b16b5f3db6fca2f7a2ded2ce55344256ba327f [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>
Paul Gortmaker65602c32011-07-17 16:28:23 -040019#include <linux/module.h>
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +020020#include <linux/regulator/driver.h>
21#include <linux/regulator/lp3971.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090022#include <linux/slab.h>
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +020023
24struct lp3971 {
25 struct device *dev;
26 struct mutex io_lock;
27 struct i2c_client *i2c;
28 int num_regulators;
29 struct regulator_dev **rdev;
30};
31
32static u8 lp3971_reg_read(struct lp3971 *lp3971, u8 reg);
33static int lp3971_set_bits(struct lp3971 *lp3971, u8 reg, u16 mask, u16 val);
34
35#define LP3971_SYS_CONTROL1_REG 0x07
36
37/* System control register 1 initial value,
38 bits 4 and 5 are EPROM programmable */
39#define SYS_CONTROL1_INIT_VAL 0x40
40#define SYS_CONTROL1_INIT_MASK 0xCF
41
42#define LP3971_BUCK_VOL_ENABLE_REG 0x10
43#define LP3971_BUCK_VOL_CHANGE_REG 0x20
44
45/* Voltage control registers shift:
46 LP3971_BUCK1 -> 0
47 LP3971_BUCK2 -> 4
48 LP3971_BUCK3 -> 6
49*/
Axel Lin451a73c2010-03-11 09:50:07 +080050#define BUCK_VOL_CHANGE_SHIFT(x) (((!!x) << 2) | (x & ~0x01))
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +020051#define BUCK_VOL_CHANGE_FLAG_GO 0x01
52#define BUCK_VOL_CHANGE_FLAG_TARGET 0x02
53#define BUCK_VOL_CHANGE_FLAG_MASK 0x03
54
55#define LP3971_BUCK1_BASE 0x23
56#define LP3971_BUCK2_BASE 0x29
57#define LP3971_BUCK3_BASE 0x32
58
Tobias Klauser6faa7e02009-12-23 14:13:17 +010059static const int buck_base_addr[] = {
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +020060 LP3971_BUCK1_BASE,
61 LP3971_BUCK2_BASE,
62 LP3971_BUCK3_BASE,
63};
64
65#define LP3971_BUCK_TARGET_VOL1_REG(x) (buck_base_addr[x])
66#define LP3971_BUCK_TARGET_VOL2_REG(x) (buck_base_addr[x]+1)
67
Tobias Klauser6faa7e02009-12-23 14:13:17 +010068static const int buck_voltage_map[] = {
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +020069 0, 800, 850, 900, 950, 1000, 1050, 1100,
70 1150, 1200, 1250, 1300, 1350, 1400, 1450, 1500,
71 1550, 1600, 1650, 1700, 1800, 1900, 2500, 2800,
72 3000, 3300,
73};
74
75#define BUCK_TARGET_VOL_MASK 0x3f
76#define BUCK_TARGET_VOL_MIN_IDX 0x01
77#define BUCK_TARGET_VOL_MAX_IDX 0x19
78
79#define LP3971_BUCK_RAMP_REG(x) (buck_base_addr[x]+2)
80
81#define LP3971_LDO_ENABLE_REG 0x12
82#define LP3971_LDO_VOL_CONTR_BASE 0x39
83
84/* Voltage control registers:
85 LP3971_LDO1 -> LP3971_LDO_VOL_CONTR_BASE + 0
86 LP3971_LDO2 -> LP3971_LDO_VOL_CONTR_BASE + 0
87 LP3971_LDO3 -> LP3971_LDO_VOL_CONTR_BASE + 1
88 LP3971_LDO4 -> LP3971_LDO_VOL_CONTR_BASE + 1
89 LP3971_LDO5 -> LP3971_LDO_VOL_CONTR_BASE + 2
90*/
91#define LP3971_LDO_VOL_CONTR_REG(x) (LP3971_LDO_VOL_CONTR_BASE + (x >> 1))
92
93/* Voltage control registers shift:
94 LP3971_LDO1 -> 0, LP3971_LDO2 -> 4
95 LP3971_LDO3 -> 0, LP3971_LDO4 -> 4
96 LP3971_LDO5 -> 0
97*/
98#define LDO_VOL_CONTR_SHIFT(x) ((x & 1) << 2)
99#define LDO_VOL_CONTR_MASK 0x0f
100
Tobias Klauser6faa7e02009-12-23 14:13:17 +0100101static const int ldo45_voltage_map[] = {
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200102 1000, 1050, 1100, 1150, 1200, 1250, 1300, 1350,
103 1400, 1500, 1800, 1900, 2500, 2800, 3000, 3300,
104};
105
Tobias Klauser6faa7e02009-12-23 14:13:17 +0100106static const int ldo123_voltage_map[] = {
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200107 1800, 1900, 2000, 2100, 2200, 2300, 2400, 2500,
108 2600, 2700, 2800, 2900, 3000, 3100, 3200, 3300,
109};
110
Tobias Klauser6faa7e02009-12-23 14:13:17 +0100111static const int *ldo_voltage_map[] = {
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200112 ldo123_voltage_map, /* LDO1 */
113 ldo123_voltage_map, /* LDO2 */
114 ldo123_voltage_map, /* LDO3 */
115 ldo45_voltage_map, /* LDO4 */
116 ldo45_voltage_map, /* LDO5 */
117};
118
119#define LDO_VOL_VALUE_MAP(x) (ldo_voltage_map[(x - LP3971_LDO1)])
120
121#define LDO_VOL_MIN_IDX 0x00
122#define LDO_VOL_MAX_IDX 0x0f
123
124static int lp3971_ldo_list_voltage(struct regulator_dev *dev, unsigned index)
125{
126 int ldo = rdev_get_id(dev) - LP3971_LDO1;
127 return 1000 * LDO_VOL_VALUE_MAP(ldo)[index];
128}
129
130static int lp3971_ldo_is_enabled(struct regulator_dev *dev)
131{
132 struct lp3971 *lp3971 = rdev_get_drvdata(dev);
133 int ldo = rdev_get_id(dev) - LP3971_LDO1;
134 u16 mask = 1 << (1 + ldo);
135 u16 val;
136
137 val = lp3971_reg_read(lp3971, LP3971_LDO_ENABLE_REG);
138 return (val & mask) != 0;
139}
140
141static int lp3971_ldo_enable(struct regulator_dev *dev)
142{
143 struct lp3971 *lp3971 = rdev_get_drvdata(dev);
144 int ldo = rdev_get_id(dev) - LP3971_LDO1;
145 u16 mask = 1 << (1 + ldo);
146
147 return lp3971_set_bits(lp3971, LP3971_LDO_ENABLE_REG, mask, mask);
148}
149
150static int lp3971_ldo_disable(struct regulator_dev *dev)
151{
152 struct lp3971 *lp3971 = rdev_get_drvdata(dev);
153 int ldo = rdev_get_id(dev) - LP3971_LDO1;
154 u16 mask = 1 << (1 + ldo);
155
156 return lp3971_set_bits(lp3971, LP3971_LDO_ENABLE_REG, mask, 0);
157}
158
159static int lp3971_ldo_get_voltage(struct regulator_dev *dev)
160{
161 struct lp3971 *lp3971 = rdev_get_drvdata(dev);
162 int ldo = rdev_get_id(dev) - LP3971_LDO1;
163 u16 val, reg;
164
165 reg = lp3971_reg_read(lp3971, LP3971_LDO_VOL_CONTR_REG(ldo));
166 val = (reg >> LDO_VOL_CONTR_SHIFT(ldo)) & LDO_VOL_CONTR_MASK;
167
168 return 1000 * LDO_VOL_VALUE_MAP(ldo)[val];
169}
170
171static int lp3971_ldo_set_voltage(struct regulator_dev *dev,
Mark Brown3a93f2a2010-11-10 14:38:29 +0000172 int min_uV, int max_uV,
173 unsigned int *selector)
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200174{
175 struct lp3971 *lp3971 = rdev_get_drvdata(dev);
176 int ldo = rdev_get_id(dev) - LP3971_LDO1;
177 int min_vol = min_uV / 1000, max_vol = max_uV / 1000;
178 const int *vol_map = LDO_VOL_VALUE_MAP(ldo);
179 u16 val;
180
181 if (min_vol < vol_map[LDO_VOL_MIN_IDX] ||
182 min_vol > vol_map[LDO_VOL_MAX_IDX])
183 return -EINVAL;
184
185 for (val = LDO_VOL_MIN_IDX; val <= LDO_VOL_MAX_IDX; val++)
186 if (vol_map[val] >= min_vol)
187 break;
188
Roel Kluin62737d42010-02-12 12:30:21 +0100189 if (val > LDO_VOL_MAX_IDX || vol_map[val] > max_vol)
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200190 return -EINVAL;
191
Mark Brown3a93f2a2010-11-10 14:38:29 +0000192 *selector = val;
193
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200194 return lp3971_set_bits(lp3971, LP3971_LDO_VOL_CONTR_REG(ldo),
Axel Lincdb868f2010-03-09 16:53:59 +0800195 LDO_VOL_CONTR_MASK << LDO_VOL_CONTR_SHIFT(ldo),
196 val << LDO_VOL_CONTR_SHIFT(ldo));
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200197}
198
199static struct regulator_ops lp3971_ldo_ops = {
200 .list_voltage = lp3971_ldo_list_voltage,
201 .is_enabled = lp3971_ldo_is_enabled,
202 .enable = lp3971_ldo_enable,
203 .disable = lp3971_ldo_disable,
204 .get_voltage = lp3971_ldo_get_voltage,
205 .set_voltage = lp3971_ldo_set_voltage,
206};
207
208static int lp3971_dcdc_list_voltage(struct regulator_dev *dev, unsigned index)
209{
210 return 1000 * buck_voltage_map[index];
211}
212
213static int lp3971_dcdc_is_enabled(struct regulator_dev *dev)
214{
215 struct lp3971 *lp3971 = rdev_get_drvdata(dev);
216 int buck = rdev_get_id(dev) - LP3971_DCDC1;
217 u16 mask = 1 << (buck * 2);
218 u16 val;
219
220 val = lp3971_reg_read(lp3971, LP3971_BUCK_VOL_ENABLE_REG);
221 return (val & mask) != 0;
222}
223
224static int lp3971_dcdc_enable(struct regulator_dev *dev)
225{
226 struct lp3971 *lp3971 = rdev_get_drvdata(dev);
227 int buck = rdev_get_id(dev) - LP3971_DCDC1;
228 u16 mask = 1 << (buck * 2);
229
230 return lp3971_set_bits(lp3971, LP3971_BUCK_VOL_ENABLE_REG, mask, mask);
231}
232
233static int lp3971_dcdc_disable(struct regulator_dev *dev)
234{
235 struct lp3971 *lp3971 = rdev_get_drvdata(dev);
236 int buck = rdev_get_id(dev) - LP3971_DCDC1;
237 u16 mask = 1 << (buck * 2);
238
239 return lp3971_set_bits(lp3971, LP3971_BUCK_VOL_ENABLE_REG, mask, 0);
240}
241
242static int lp3971_dcdc_get_voltage(struct regulator_dev *dev)
243{
244 struct lp3971 *lp3971 = rdev_get_drvdata(dev);
245 int buck = rdev_get_id(dev) - LP3971_DCDC1;
246 u16 reg;
247 int val;
248
249 reg = lp3971_reg_read(lp3971, LP3971_BUCK_TARGET_VOL1_REG(buck));
250 reg &= BUCK_TARGET_VOL_MASK;
251
252 if (reg <= BUCK_TARGET_VOL_MAX_IDX)
253 val = 1000 * buck_voltage_map[reg];
254 else {
255 val = 0;
256 dev_warn(&dev->dev, "chip reported incorrect voltage value.\n");
257 }
258
259 return val;
260}
261
262static int lp3971_dcdc_set_voltage(struct regulator_dev *dev,
Mark Brown3a93f2a2010-11-10 14:38:29 +0000263 int min_uV, int max_uV,
264 unsigned int *selector)
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200265{
266 struct lp3971 *lp3971 = rdev_get_drvdata(dev);
267 int buck = rdev_get_id(dev) - LP3971_DCDC1;
268 int min_vol = min_uV / 1000, max_vol = max_uV / 1000;
269 const int *vol_map = buck_voltage_map;
270 u16 val;
271 int ret;
272
273 if (min_vol < vol_map[BUCK_TARGET_VOL_MIN_IDX] ||
274 min_vol > vol_map[BUCK_TARGET_VOL_MAX_IDX])
275 return -EINVAL;
276
277 for (val = BUCK_TARGET_VOL_MIN_IDX; val <= BUCK_TARGET_VOL_MAX_IDX;
278 val++)
279 if (vol_map[val] >= min_vol)
280 break;
281
Roel Kluin62737d42010-02-12 12:30:21 +0100282 if (val > BUCK_TARGET_VOL_MAX_IDX || vol_map[val] > max_vol)
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200283 return -EINVAL;
284
Mark Brown3a93f2a2010-11-10 14:38:29 +0000285 *selector = val;
286
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200287 ret = lp3971_set_bits(lp3971, LP3971_BUCK_TARGET_VOL1_REG(buck),
288 BUCK_TARGET_VOL_MASK, val);
289 if (ret)
290 return ret;
291
292 ret = lp3971_set_bits(lp3971, LP3971_BUCK_VOL_CHANGE_REG,
293 BUCK_VOL_CHANGE_FLAG_MASK << BUCK_VOL_CHANGE_SHIFT(buck),
294 BUCK_VOL_CHANGE_FLAG_GO << BUCK_VOL_CHANGE_SHIFT(buck));
295 if (ret)
296 return ret;
297
298 return lp3971_set_bits(lp3971, LP3971_BUCK_VOL_CHANGE_REG,
299 BUCK_VOL_CHANGE_FLAG_MASK << BUCK_VOL_CHANGE_SHIFT(buck),
300 0 << BUCK_VOL_CHANGE_SHIFT(buck));
301}
302
303static struct regulator_ops lp3971_dcdc_ops = {
304 .list_voltage = lp3971_dcdc_list_voltage,
305 .is_enabled = lp3971_dcdc_is_enabled,
306 .enable = lp3971_dcdc_enable,
307 .disable = lp3971_dcdc_disable,
308 .get_voltage = lp3971_dcdc_get_voltage,
309 .set_voltage = lp3971_dcdc_set_voltage,
310};
311
312static struct regulator_desc regulators[] = {
313 {
314 .name = "LDO1",
315 .id = LP3971_LDO1,
316 .ops = &lp3971_ldo_ops,
317 .n_voltages = ARRAY_SIZE(ldo123_voltage_map),
318 .type = REGULATOR_VOLTAGE,
319 .owner = THIS_MODULE,
320 },
321 {
322 .name = "LDO2",
323 .id = LP3971_LDO2,
324 .ops = &lp3971_ldo_ops,
325 .n_voltages = ARRAY_SIZE(ldo123_voltage_map),
326 .type = REGULATOR_VOLTAGE,
327 .owner = THIS_MODULE,
328 },
329 {
330 .name = "LDO3",
331 .id = LP3971_LDO3,
332 .ops = &lp3971_ldo_ops,
333 .n_voltages = ARRAY_SIZE(ldo123_voltage_map),
334 .type = REGULATOR_VOLTAGE,
335 .owner = THIS_MODULE,
336 },
337 {
338 .name = "LDO4",
339 .id = LP3971_LDO4,
340 .ops = &lp3971_ldo_ops,
341 .n_voltages = ARRAY_SIZE(ldo45_voltage_map),
342 .type = REGULATOR_VOLTAGE,
343 .owner = THIS_MODULE,
344 },
345 {
346 .name = "LDO5",
347 .id = LP3971_LDO5,
348 .ops = &lp3971_ldo_ops,
349 .n_voltages = ARRAY_SIZE(ldo45_voltage_map),
350 .type = REGULATOR_VOLTAGE,
351 .owner = THIS_MODULE,
352 },
353 {
354 .name = "DCDC1",
355 .id = LP3971_DCDC1,
356 .ops = &lp3971_dcdc_ops,
357 .n_voltages = ARRAY_SIZE(buck_voltage_map),
358 .type = REGULATOR_VOLTAGE,
359 .owner = THIS_MODULE,
360 },
361 {
362 .name = "DCDC2",
363 .id = LP3971_DCDC2,
364 .ops = &lp3971_dcdc_ops,
365 .n_voltages = ARRAY_SIZE(buck_voltage_map),
366 .type = REGULATOR_VOLTAGE,
367 .owner = THIS_MODULE,
368 },
369 {
370 .name = "DCDC3",
371 .id = LP3971_DCDC3,
372 .ops = &lp3971_dcdc_ops,
373 .n_voltages = ARRAY_SIZE(buck_voltage_map),
374 .type = REGULATOR_VOLTAGE,
375 .owner = THIS_MODULE,
376 },
377};
378
379static int lp3971_i2c_read(struct i2c_client *i2c, char reg, int count,
380 u16 *dest)
381{
382 int ret;
383
384 if (count != 1)
385 return -EIO;
386 ret = i2c_smbus_read_byte_data(i2c, reg);
Axel Lin27ef7f02010-08-06 08:09:14 +0800387 if (ret < 0)
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200388 return -EIO;
389
390 *dest = ret;
391 return 0;
392}
393
394static int lp3971_i2c_write(struct i2c_client *i2c, char reg, int count,
395 const u16 *src)
396{
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200397 if (count != 1)
398 return -EIO;
Axel Lin1bddc2f2010-08-09 17:01:21 +0800399 return i2c_smbus_write_byte_data(i2c, reg, *src);
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200400}
401
402static u8 lp3971_reg_read(struct lp3971 *lp3971, u8 reg)
403{
404 u16 val = 0;
405
406 mutex_lock(&lp3971->io_lock);
407
408 lp3971_i2c_read(lp3971->i2c, reg, 1, &val);
409
410 dev_dbg(lp3971->dev, "reg read 0x%02x -> 0x%02x\n", (int)reg,
411 (unsigned)val&0xff);
412
413 mutex_unlock(&lp3971->io_lock);
414
415 return val & 0xff;
416}
417
418static int lp3971_set_bits(struct lp3971 *lp3971, u8 reg, u16 mask, u16 val)
419{
420 u16 tmp;
421 int ret;
422
423 mutex_lock(&lp3971->io_lock);
424
425 ret = lp3971_i2c_read(lp3971->i2c, reg, 1, &tmp);
426 tmp = (tmp & ~mask) | val;
427 if (ret == 0) {
428 ret = lp3971_i2c_write(lp3971->i2c, reg, 1, &tmp);
429 dev_dbg(lp3971->dev, "reg write 0x%02x -> 0x%02x\n", (int)reg,
430 (unsigned)val&0xff);
431 }
432 mutex_unlock(&lp3971->io_lock);
433
434 return ret;
435}
436
Dmitry Torokhovebbed042010-02-23 23:38:17 -0800437static int __devinit setup_regulators(struct lp3971 *lp3971,
438 struct lp3971_platform_data *pdata)
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200439{
440 int i, err;
Dmitry Torokhovebbed042010-02-23 23:38:17 -0800441
442 lp3971->num_regulators = pdata->num_regulators;
443 lp3971->rdev = kcalloc(pdata->num_regulators,
444 sizeof(struct regulator_dev *), GFP_KERNEL);
Dan Carpenter67e46f32010-03-07 15:36:45 +0300445 if (!lp3971->rdev) {
446 err = -ENOMEM;
447 goto err_nomem;
448 }
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200449
450 /* Instantiate the regulators */
Dmitry Torokhovebbed042010-02-23 23:38:17 -0800451 for (i = 0; i < pdata->num_regulators; i++) {
452 struct lp3971_regulator_subdev *reg = &pdata->regulators[i];
453 lp3971->rdev[i] = regulator_register(&regulators[reg->id],
454 lp3971->dev, reg->initdata, lp3971);
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200455
Julia Lawalld662fc82009-11-21 22:18:44 +0100456 if (IS_ERR(lp3971->rdev[i])) {
457 err = PTR_ERR(lp3971->rdev[i]);
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200458 dev_err(lp3971->dev, "regulator init failed: %d\n",
459 err);
460 goto error;
461 }
462 }
463
464 return 0;
Dmitry Torokhovebbed042010-02-23 23:38:17 -0800465
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200466error:
Dmitry Torokhovebbed042010-02-23 23:38:17 -0800467 while (--i >= 0)
468 regulator_unregister(lp3971->rdev[i]);
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200469 kfree(lp3971->rdev);
470 lp3971->rdev = NULL;
Dan Carpenter67e46f32010-03-07 15:36:45 +0300471err_nomem:
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200472 return err;
473}
474
475static int __devinit lp3971_i2c_probe(struct i2c_client *i2c,
476 const struct i2c_device_id *id)
477{
478 struct lp3971 *lp3971;
479 struct lp3971_platform_data *pdata = i2c->dev.platform_data;
480 int ret;
481 u16 val;
482
Dmitry Torokhovebbed042010-02-23 23:38:17 -0800483 if (!pdata) {
484 dev_dbg(&i2c->dev, "No platform init data supplied\n");
485 return -ENODEV;
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200486 }
487
Dmitry Torokhovebbed042010-02-23 23:38:17 -0800488 lp3971 = kzalloc(sizeof(struct lp3971), GFP_KERNEL);
489 if (lp3971 == NULL)
490 return -ENOMEM;
491
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200492 lp3971->i2c = i2c;
493 lp3971->dev = &i2c->dev;
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200494
495 mutex_init(&lp3971->io_lock);
496
497 /* Detect LP3971 */
498 ret = lp3971_i2c_read(i2c, LP3971_SYS_CONTROL1_REG, 1, &val);
499 if (ret == 0 && (val & SYS_CONTROL1_INIT_MASK) != SYS_CONTROL1_INIT_VAL)
500 ret = -ENODEV;
501 if (ret < 0) {
502 dev_err(&i2c->dev, "failed to detect device\n");
503 goto err_detect;
504 }
505
Dmitry Torokhovebbed042010-02-23 23:38:17 -0800506 ret = setup_regulators(lp3971, pdata);
507 if (ret < 0)
508 goto err_detect;
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200509
Dmitry Torokhovebbed042010-02-23 23:38:17 -0800510 i2c_set_clientdata(i2c, lp3971);
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200511 return 0;
512
513err_detect:
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200514 kfree(lp3971);
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200515 return ret;
516}
517
518static int __devexit lp3971_i2c_remove(struct i2c_client *i2c)
519{
520 struct lp3971 *lp3971 = i2c_get_clientdata(i2c);
521 int i;
Dmitry Torokhovebbed042010-02-23 23:38:17 -0800522
Dmitry Torokhovebbed042010-02-23 23:38:17 -0800523 for (i = 0; i < lp3971->num_regulators; i++)
524 regulator_unregister(lp3971->rdev[i]);
525
526 kfree(lp3971->rdev);
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200527 kfree(lp3971);
528
529 return 0;
530}
531
532static const struct i2c_device_id lp3971_i2c_id[] = {
533 { "lp3971", 0 },
534 { }
535};
536MODULE_DEVICE_TABLE(i2c, lp3971_i2c_id);
537
538static struct i2c_driver lp3971_i2c_driver = {
539 .driver = {
540 .name = "LP3971",
541 .owner = THIS_MODULE,
542 },
543 .probe = lp3971_i2c_probe,
Liam Girdwood6113c3a2009-05-19 11:44:37 +0100544 .remove = __devexit_p(lp3971_i2c_remove),
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200545 .id_table = lp3971_i2c_id,
546};
547
548static int __init lp3971_module_init(void)
549{
Wolfram Sang12a1d932009-09-18 22:44:45 +0200550 int ret;
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200551
552 ret = i2c_add_driver(&lp3971_i2c_driver);
553 if (ret != 0)
554 pr_err("Failed to register I2C driver: %d\n", ret);
555
556 return ret;
557}
558module_init(lp3971_module_init);
559
560static void __exit lp3971_module_exit(void)
561{
562 i2c_del_driver(&lp3971_i2c_driver);
563}
564module_exit(lp3971_module_exit);
565
566MODULE_LICENSE("GPL");
567MODULE_AUTHOR("Marek Szyprowski <m.szyprowski@samsung.com>");
568MODULE_DESCRIPTION("LP3971 PMIC driver");