blob: 0f22ef12601c2204170edb3d00eb38c0319e0976 [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>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090021#include <linux/slab.h>
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +020022
23struct lp3971 {
24 struct device *dev;
25 struct mutex io_lock;
26 struct i2c_client *i2c;
27 int num_regulators;
28 struct regulator_dev **rdev;
29};
30
31static u8 lp3971_reg_read(struct lp3971 *lp3971, u8 reg);
32static int lp3971_set_bits(struct lp3971 *lp3971, u8 reg, u16 mask, u16 val);
33
34#define LP3971_SYS_CONTROL1_REG 0x07
35
36/* System control register 1 initial value,
37 bits 4 and 5 are EPROM programmable */
38#define SYS_CONTROL1_INIT_VAL 0x40
39#define SYS_CONTROL1_INIT_MASK 0xCF
40
41#define LP3971_BUCK_VOL_ENABLE_REG 0x10
42#define LP3971_BUCK_VOL_CHANGE_REG 0x20
43
44/* Voltage control registers shift:
45 LP3971_BUCK1 -> 0
46 LP3971_BUCK2 -> 4
47 LP3971_BUCK3 -> 6
48*/
Axel Lin451a73c2010-03-11 09:50:07 +080049#define BUCK_VOL_CHANGE_SHIFT(x) (((!!x) << 2) | (x & ~0x01))
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +020050#define BUCK_VOL_CHANGE_FLAG_GO 0x01
51#define BUCK_VOL_CHANGE_FLAG_TARGET 0x02
52#define BUCK_VOL_CHANGE_FLAG_MASK 0x03
53
54#define LP3971_BUCK1_BASE 0x23
55#define LP3971_BUCK2_BASE 0x29
56#define LP3971_BUCK3_BASE 0x32
57
Tobias Klauser6faa7e02009-12-23 14:13:17 +010058static const int buck_base_addr[] = {
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +020059 LP3971_BUCK1_BASE,
60 LP3971_BUCK2_BASE,
61 LP3971_BUCK3_BASE,
62};
63
64#define LP3971_BUCK_TARGET_VOL1_REG(x) (buck_base_addr[x])
65#define LP3971_BUCK_TARGET_VOL2_REG(x) (buck_base_addr[x]+1)
66
Tobias Klauser6faa7e02009-12-23 14:13:17 +010067static const int buck_voltage_map[] = {
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +020068 0, 800, 850, 900, 950, 1000, 1050, 1100,
69 1150, 1200, 1250, 1300, 1350, 1400, 1450, 1500,
70 1550, 1600, 1650, 1700, 1800, 1900, 2500, 2800,
71 3000, 3300,
72};
73
74#define BUCK_TARGET_VOL_MASK 0x3f
75#define BUCK_TARGET_VOL_MIN_IDX 0x01
76#define BUCK_TARGET_VOL_MAX_IDX 0x19
77
78#define LP3971_BUCK_RAMP_REG(x) (buck_base_addr[x]+2)
79
80#define LP3971_LDO_ENABLE_REG 0x12
81#define LP3971_LDO_VOL_CONTR_BASE 0x39
82
83/* Voltage control registers:
84 LP3971_LDO1 -> LP3971_LDO_VOL_CONTR_BASE + 0
85 LP3971_LDO2 -> LP3971_LDO_VOL_CONTR_BASE + 0
86 LP3971_LDO3 -> LP3971_LDO_VOL_CONTR_BASE + 1
87 LP3971_LDO4 -> LP3971_LDO_VOL_CONTR_BASE + 1
88 LP3971_LDO5 -> LP3971_LDO_VOL_CONTR_BASE + 2
89*/
90#define LP3971_LDO_VOL_CONTR_REG(x) (LP3971_LDO_VOL_CONTR_BASE + (x >> 1))
91
92/* Voltage control registers shift:
93 LP3971_LDO1 -> 0, LP3971_LDO2 -> 4
94 LP3971_LDO3 -> 0, LP3971_LDO4 -> 4
95 LP3971_LDO5 -> 0
96*/
97#define LDO_VOL_CONTR_SHIFT(x) ((x & 1) << 2)
98#define LDO_VOL_CONTR_MASK 0x0f
99
Tobias Klauser6faa7e02009-12-23 14:13:17 +0100100static const int ldo45_voltage_map[] = {
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200101 1000, 1050, 1100, 1150, 1200, 1250, 1300, 1350,
102 1400, 1500, 1800, 1900, 2500, 2800, 3000, 3300,
103};
104
Tobias Klauser6faa7e02009-12-23 14:13:17 +0100105static const int ldo123_voltage_map[] = {
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200106 1800, 1900, 2000, 2100, 2200, 2300, 2400, 2500,
107 2600, 2700, 2800, 2900, 3000, 3100, 3200, 3300,
108};
109
Tobias Klauser6faa7e02009-12-23 14:13:17 +0100110static const int *ldo_voltage_map[] = {
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200111 ldo123_voltage_map, /* LDO1 */
112 ldo123_voltage_map, /* LDO2 */
113 ldo123_voltage_map, /* LDO3 */
114 ldo45_voltage_map, /* LDO4 */
115 ldo45_voltage_map, /* LDO5 */
116};
117
118#define LDO_VOL_VALUE_MAP(x) (ldo_voltage_map[(x - LP3971_LDO1)])
119
120#define LDO_VOL_MIN_IDX 0x00
121#define LDO_VOL_MAX_IDX 0x0f
122
123static int lp3971_ldo_list_voltage(struct regulator_dev *dev, unsigned index)
124{
125 int ldo = rdev_get_id(dev) - LP3971_LDO1;
126 return 1000 * LDO_VOL_VALUE_MAP(ldo)[index];
127}
128
129static int lp3971_ldo_is_enabled(struct regulator_dev *dev)
130{
131 struct lp3971 *lp3971 = rdev_get_drvdata(dev);
132 int ldo = rdev_get_id(dev) - LP3971_LDO1;
133 u16 mask = 1 << (1 + ldo);
134 u16 val;
135
136 val = lp3971_reg_read(lp3971, LP3971_LDO_ENABLE_REG);
137 return (val & mask) != 0;
138}
139
140static int lp3971_ldo_enable(struct regulator_dev *dev)
141{
142 struct lp3971 *lp3971 = rdev_get_drvdata(dev);
143 int ldo = rdev_get_id(dev) - LP3971_LDO1;
144 u16 mask = 1 << (1 + ldo);
145
146 return lp3971_set_bits(lp3971, LP3971_LDO_ENABLE_REG, mask, mask);
147}
148
149static int lp3971_ldo_disable(struct regulator_dev *dev)
150{
151 struct lp3971 *lp3971 = rdev_get_drvdata(dev);
152 int ldo = rdev_get_id(dev) - LP3971_LDO1;
153 u16 mask = 1 << (1 + ldo);
154
155 return lp3971_set_bits(lp3971, LP3971_LDO_ENABLE_REG, mask, 0);
156}
157
158static int lp3971_ldo_get_voltage(struct regulator_dev *dev)
159{
160 struct lp3971 *lp3971 = rdev_get_drvdata(dev);
161 int ldo = rdev_get_id(dev) - LP3971_LDO1;
162 u16 val, reg;
163
164 reg = lp3971_reg_read(lp3971, LP3971_LDO_VOL_CONTR_REG(ldo));
165 val = (reg >> LDO_VOL_CONTR_SHIFT(ldo)) & LDO_VOL_CONTR_MASK;
166
167 return 1000 * LDO_VOL_VALUE_MAP(ldo)[val];
168}
169
170static int lp3971_ldo_set_voltage(struct regulator_dev *dev,
Mark Brown3a93f2a2010-11-10 14:38:29 +0000171 int min_uV, int max_uV,
172 unsigned int *selector)
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200173{
174 struct lp3971 *lp3971 = rdev_get_drvdata(dev);
175 int ldo = rdev_get_id(dev) - LP3971_LDO1;
176 int min_vol = min_uV / 1000, max_vol = max_uV / 1000;
177 const int *vol_map = LDO_VOL_VALUE_MAP(ldo);
178 u16 val;
179
180 if (min_vol < vol_map[LDO_VOL_MIN_IDX] ||
181 min_vol > vol_map[LDO_VOL_MAX_IDX])
182 return -EINVAL;
183
184 for (val = LDO_VOL_MIN_IDX; val <= LDO_VOL_MAX_IDX; val++)
185 if (vol_map[val] >= min_vol)
186 break;
187
Roel Kluin62737d42010-02-12 12:30:21 +0100188 if (val > LDO_VOL_MAX_IDX || vol_map[val] > max_vol)
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200189 return -EINVAL;
190
Mark Brown3a93f2a2010-11-10 14:38:29 +0000191 *selector = val;
192
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200193 return lp3971_set_bits(lp3971, LP3971_LDO_VOL_CONTR_REG(ldo),
Axel Lincdb868f2010-03-09 16:53:59 +0800194 LDO_VOL_CONTR_MASK << LDO_VOL_CONTR_SHIFT(ldo),
195 val << LDO_VOL_CONTR_SHIFT(ldo));
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200196}
197
198static struct regulator_ops lp3971_ldo_ops = {
199 .list_voltage = lp3971_ldo_list_voltage,
200 .is_enabled = lp3971_ldo_is_enabled,
201 .enable = lp3971_ldo_enable,
202 .disable = lp3971_ldo_disable,
203 .get_voltage = lp3971_ldo_get_voltage,
204 .set_voltage = lp3971_ldo_set_voltage,
205};
206
207static int lp3971_dcdc_list_voltage(struct regulator_dev *dev, unsigned index)
208{
209 return 1000 * buck_voltage_map[index];
210}
211
212static int lp3971_dcdc_is_enabled(struct regulator_dev *dev)
213{
214 struct lp3971 *lp3971 = rdev_get_drvdata(dev);
215 int buck = rdev_get_id(dev) - LP3971_DCDC1;
216 u16 mask = 1 << (buck * 2);
217 u16 val;
218
219 val = lp3971_reg_read(lp3971, LP3971_BUCK_VOL_ENABLE_REG);
220 return (val & mask) != 0;
221}
222
223static int lp3971_dcdc_enable(struct regulator_dev *dev)
224{
225 struct lp3971 *lp3971 = rdev_get_drvdata(dev);
226 int buck = rdev_get_id(dev) - LP3971_DCDC1;
227 u16 mask = 1 << (buck * 2);
228
229 return lp3971_set_bits(lp3971, LP3971_BUCK_VOL_ENABLE_REG, mask, mask);
230}
231
232static int lp3971_dcdc_disable(struct regulator_dev *dev)
233{
234 struct lp3971 *lp3971 = rdev_get_drvdata(dev);
235 int buck = rdev_get_id(dev) - LP3971_DCDC1;
236 u16 mask = 1 << (buck * 2);
237
238 return lp3971_set_bits(lp3971, LP3971_BUCK_VOL_ENABLE_REG, mask, 0);
239}
240
241static int lp3971_dcdc_get_voltage(struct regulator_dev *dev)
242{
243 struct lp3971 *lp3971 = rdev_get_drvdata(dev);
244 int buck = rdev_get_id(dev) - LP3971_DCDC1;
245 u16 reg;
246 int val;
247
248 reg = lp3971_reg_read(lp3971, LP3971_BUCK_TARGET_VOL1_REG(buck));
249 reg &= BUCK_TARGET_VOL_MASK;
250
251 if (reg <= BUCK_TARGET_VOL_MAX_IDX)
252 val = 1000 * buck_voltage_map[reg];
253 else {
254 val = 0;
255 dev_warn(&dev->dev, "chip reported incorrect voltage value.\n");
256 }
257
258 return val;
259}
260
261static int lp3971_dcdc_set_voltage(struct regulator_dev *dev,
Mark Brown3a93f2a2010-11-10 14:38:29 +0000262 int min_uV, int max_uV,
263 unsigned int *selector)
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200264{
265 struct lp3971 *lp3971 = rdev_get_drvdata(dev);
266 int buck = rdev_get_id(dev) - LP3971_DCDC1;
267 int min_vol = min_uV / 1000, max_vol = max_uV / 1000;
268 const int *vol_map = buck_voltage_map;
269 u16 val;
270 int ret;
271
272 if (min_vol < vol_map[BUCK_TARGET_VOL_MIN_IDX] ||
273 min_vol > vol_map[BUCK_TARGET_VOL_MAX_IDX])
274 return -EINVAL;
275
276 for (val = BUCK_TARGET_VOL_MIN_IDX; val <= BUCK_TARGET_VOL_MAX_IDX;
277 val++)
278 if (vol_map[val] >= min_vol)
279 break;
280
Roel Kluin62737d42010-02-12 12:30:21 +0100281 if (val > BUCK_TARGET_VOL_MAX_IDX || vol_map[val] > max_vol)
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200282 return -EINVAL;
283
Mark Brown3a93f2a2010-11-10 14:38:29 +0000284 *selector = val;
285
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200286 ret = lp3971_set_bits(lp3971, LP3971_BUCK_TARGET_VOL1_REG(buck),
287 BUCK_TARGET_VOL_MASK, val);
288 if (ret)
289 return ret;
290
291 ret = lp3971_set_bits(lp3971, LP3971_BUCK_VOL_CHANGE_REG,
292 BUCK_VOL_CHANGE_FLAG_MASK << BUCK_VOL_CHANGE_SHIFT(buck),
293 BUCK_VOL_CHANGE_FLAG_GO << BUCK_VOL_CHANGE_SHIFT(buck));
294 if (ret)
295 return ret;
296
297 return lp3971_set_bits(lp3971, LP3971_BUCK_VOL_CHANGE_REG,
298 BUCK_VOL_CHANGE_FLAG_MASK << BUCK_VOL_CHANGE_SHIFT(buck),
299 0 << BUCK_VOL_CHANGE_SHIFT(buck));
300}
301
302static struct regulator_ops lp3971_dcdc_ops = {
303 .list_voltage = lp3971_dcdc_list_voltage,
304 .is_enabled = lp3971_dcdc_is_enabled,
305 .enable = lp3971_dcdc_enable,
306 .disable = lp3971_dcdc_disable,
307 .get_voltage = lp3971_dcdc_get_voltage,
308 .set_voltage = lp3971_dcdc_set_voltage,
309};
310
311static struct regulator_desc regulators[] = {
312 {
313 .name = "LDO1",
314 .id = LP3971_LDO1,
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 = "LDO2",
322 .id = LP3971_LDO2,
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 = "LDO3",
330 .id = LP3971_LDO3,
331 .ops = &lp3971_ldo_ops,
332 .n_voltages = ARRAY_SIZE(ldo123_voltage_map),
333 .type = REGULATOR_VOLTAGE,
334 .owner = THIS_MODULE,
335 },
336 {
337 .name = "LDO4",
338 .id = LP3971_LDO4,
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 = "LDO5",
346 .id = LP3971_LDO5,
347 .ops = &lp3971_ldo_ops,
348 .n_voltages = ARRAY_SIZE(ldo45_voltage_map),
349 .type = REGULATOR_VOLTAGE,
350 .owner = THIS_MODULE,
351 },
352 {
353 .name = "DCDC1",
354 .id = LP3971_DCDC1,
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 = "DCDC2",
362 .id = LP3971_DCDC2,
363 .ops = &lp3971_dcdc_ops,
364 .n_voltages = ARRAY_SIZE(buck_voltage_map),
365 .type = REGULATOR_VOLTAGE,
366 .owner = THIS_MODULE,
367 },
368 {
369 .name = "DCDC3",
370 .id = LP3971_DCDC3,
371 .ops = &lp3971_dcdc_ops,
372 .n_voltages = ARRAY_SIZE(buck_voltage_map),
373 .type = REGULATOR_VOLTAGE,
374 .owner = THIS_MODULE,
375 },
376};
377
378static int lp3971_i2c_read(struct i2c_client *i2c, char reg, int count,
379 u16 *dest)
380{
381 int ret;
382
383 if (count != 1)
384 return -EIO;
385 ret = i2c_smbus_read_byte_data(i2c, reg);
Axel Lin27ef7f02010-08-06 08:09:14 +0800386 if (ret < 0)
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200387 return -EIO;
388
389 *dest = ret;
390 return 0;
391}
392
393static int lp3971_i2c_write(struct i2c_client *i2c, char reg, int count,
394 const u16 *src)
395{
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200396 if (count != 1)
397 return -EIO;
Axel Lin1bddc2f2010-08-09 17:01:21 +0800398 return i2c_smbus_write_byte_data(i2c, reg, *src);
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200399}
400
401static u8 lp3971_reg_read(struct lp3971 *lp3971, u8 reg)
402{
403 u16 val = 0;
404
405 mutex_lock(&lp3971->io_lock);
406
407 lp3971_i2c_read(lp3971->i2c, reg, 1, &val);
408
409 dev_dbg(lp3971->dev, "reg read 0x%02x -> 0x%02x\n", (int)reg,
410 (unsigned)val&0xff);
411
412 mutex_unlock(&lp3971->io_lock);
413
414 return val & 0xff;
415}
416
417static int lp3971_set_bits(struct lp3971 *lp3971, u8 reg, u16 mask, u16 val)
418{
419 u16 tmp;
420 int ret;
421
422 mutex_lock(&lp3971->io_lock);
423
424 ret = lp3971_i2c_read(lp3971->i2c, reg, 1, &tmp);
425 tmp = (tmp & ~mask) | val;
426 if (ret == 0) {
427 ret = lp3971_i2c_write(lp3971->i2c, reg, 1, &tmp);
428 dev_dbg(lp3971->dev, "reg write 0x%02x -> 0x%02x\n", (int)reg,
429 (unsigned)val&0xff);
430 }
431 mutex_unlock(&lp3971->io_lock);
432
433 return ret;
434}
435
Dmitry Torokhovebbed042010-02-23 23:38:17 -0800436static int __devinit setup_regulators(struct lp3971 *lp3971,
437 struct lp3971_platform_data *pdata)
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200438{
439 int i, err;
Dmitry Torokhovebbed042010-02-23 23:38:17 -0800440
441 lp3971->num_regulators = pdata->num_regulators;
442 lp3971->rdev = kcalloc(pdata->num_regulators,
443 sizeof(struct regulator_dev *), GFP_KERNEL);
Dan Carpenter67e46f32010-03-07 15:36:45 +0300444 if (!lp3971->rdev) {
445 err = -ENOMEM;
446 goto err_nomem;
447 }
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200448
449 /* Instantiate the regulators */
Dmitry Torokhovebbed042010-02-23 23:38:17 -0800450 for (i = 0; i < pdata->num_regulators; i++) {
451 struct lp3971_regulator_subdev *reg = &pdata->regulators[i];
452 lp3971->rdev[i] = regulator_register(&regulators[reg->id],
453 lp3971->dev, reg->initdata, lp3971);
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200454
Julia Lawalld662fc82009-11-21 22:18:44 +0100455 if (IS_ERR(lp3971->rdev[i])) {
456 err = PTR_ERR(lp3971->rdev[i]);
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200457 dev_err(lp3971->dev, "regulator init failed: %d\n",
458 err);
459 goto error;
460 }
461 }
462
463 return 0;
Dmitry Torokhovebbed042010-02-23 23:38:17 -0800464
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200465error:
Dmitry Torokhovebbed042010-02-23 23:38:17 -0800466 while (--i >= 0)
467 regulator_unregister(lp3971->rdev[i]);
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200468 kfree(lp3971->rdev);
469 lp3971->rdev = NULL;
Dan Carpenter67e46f32010-03-07 15:36:45 +0300470err_nomem:
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200471 return err;
472}
473
474static int __devinit lp3971_i2c_probe(struct i2c_client *i2c,
475 const struct i2c_device_id *id)
476{
477 struct lp3971 *lp3971;
478 struct lp3971_platform_data *pdata = i2c->dev.platform_data;
479 int ret;
480 u16 val;
481
Dmitry Torokhovebbed042010-02-23 23:38:17 -0800482 if (!pdata) {
483 dev_dbg(&i2c->dev, "No platform init data supplied\n");
484 return -ENODEV;
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200485 }
486
Dmitry Torokhovebbed042010-02-23 23:38:17 -0800487 lp3971 = kzalloc(sizeof(struct lp3971), GFP_KERNEL);
488 if (lp3971 == NULL)
489 return -ENOMEM;
490
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200491 lp3971->i2c = i2c;
492 lp3971->dev = &i2c->dev;
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200493
494 mutex_init(&lp3971->io_lock);
495
496 /* Detect LP3971 */
497 ret = lp3971_i2c_read(i2c, LP3971_SYS_CONTROL1_REG, 1, &val);
498 if (ret == 0 && (val & SYS_CONTROL1_INIT_MASK) != SYS_CONTROL1_INIT_VAL)
499 ret = -ENODEV;
500 if (ret < 0) {
501 dev_err(&i2c->dev, "failed to detect device\n");
502 goto err_detect;
503 }
504
Dmitry Torokhovebbed042010-02-23 23:38:17 -0800505 ret = setup_regulators(lp3971, pdata);
506 if (ret < 0)
507 goto err_detect;
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200508
Dmitry Torokhovebbed042010-02-23 23:38:17 -0800509 i2c_set_clientdata(i2c, lp3971);
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200510 return 0;
511
512err_detect:
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200513 kfree(lp3971);
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200514 return ret;
515}
516
517static int __devexit lp3971_i2c_remove(struct i2c_client *i2c)
518{
519 struct lp3971 *lp3971 = i2c_get_clientdata(i2c);
520 int i;
Dmitry Torokhovebbed042010-02-23 23:38:17 -0800521
Dmitry Torokhovebbed042010-02-23 23:38:17 -0800522 for (i = 0; i < lp3971->num_regulators; i++)
523 regulator_unregister(lp3971->rdev[i]);
524
525 kfree(lp3971->rdev);
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200526 kfree(lp3971);
527
528 return 0;
529}
530
531static const struct i2c_device_id lp3971_i2c_id[] = {
532 { "lp3971", 0 },
533 { }
534};
535MODULE_DEVICE_TABLE(i2c, lp3971_i2c_id);
536
537static struct i2c_driver lp3971_i2c_driver = {
538 .driver = {
539 .name = "LP3971",
540 .owner = THIS_MODULE,
541 },
542 .probe = lp3971_i2c_probe,
Liam Girdwood6113c3a2009-05-19 11:44:37 +0100543 .remove = __devexit_p(lp3971_i2c_remove),
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200544 .id_table = lp3971_i2c_id,
545};
546
547static int __init lp3971_module_init(void)
548{
Wolfram Sang12a1d932009-09-18 22:44:45 +0200549 int ret;
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200550
551 ret = i2c_add_driver(&lp3971_i2c_driver);
552 if (ret != 0)
553 pr_err("Failed to register I2C driver: %d\n", ret);
554
555 return ret;
556}
557module_init(lp3971_module_init);
558
559static void __exit lp3971_module_exit(void)
560{
561 i2c_del_driver(&lp3971_i2c_driver);
562}
563module_exit(lp3971_module_exit);
564
565MODULE_LICENSE("GPL");
566MODULE_AUTHOR("Marek Szyprowski <m.szyprowski@samsung.com>");
567MODULE_DESCRIPTION("LP3971 PMIC driver");