blob: 3bb82b624e19f9cafb230a1a29ac3f0ce13514dc [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,
171 int min_uV, int max_uV)
172{
173 struct lp3971 *lp3971 = rdev_get_drvdata(dev);
174 int ldo = rdev_get_id(dev) - LP3971_LDO1;
175 int min_vol = min_uV / 1000, max_vol = max_uV / 1000;
176 const int *vol_map = LDO_VOL_VALUE_MAP(ldo);
177 u16 val;
178
179 if (min_vol < vol_map[LDO_VOL_MIN_IDX] ||
180 min_vol > vol_map[LDO_VOL_MAX_IDX])
181 return -EINVAL;
182
183 for (val = LDO_VOL_MIN_IDX; val <= LDO_VOL_MAX_IDX; val++)
184 if (vol_map[val] >= min_vol)
185 break;
186
Roel Kluin62737d42010-02-12 12:30:21 +0100187 if (val > LDO_VOL_MAX_IDX || vol_map[val] > max_vol)
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200188 return -EINVAL;
189
190 return lp3971_set_bits(lp3971, LP3971_LDO_VOL_CONTR_REG(ldo),
Axel Lincdb868f2010-03-09 16:53:59 +0800191 LDO_VOL_CONTR_MASK << LDO_VOL_CONTR_SHIFT(ldo),
192 val << LDO_VOL_CONTR_SHIFT(ldo));
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200193}
194
195static struct regulator_ops lp3971_ldo_ops = {
196 .list_voltage = lp3971_ldo_list_voltage,
197 .is_enabled = lp3971_ldo_is_enabled,
198 .enable = lp3971_ldo_enable,
199 .disable = lp3971_ldo_disable,
200 .get_voltage = lp3971_ldo_get_voltage,
201 .set_voltage = lp3971_ldo_set_voltage,
202};
203
204static int lp3971_dcdc_list_voltage(struct regulator_dev *dev, unsigned index)
205{
206 return 1000 * buck_voltage_map[index];
207}
208
209static int lp3971_dcdc_is_enabled(struct regulator_dev *dev)
210{
211 struct lp3971 *lp3971 = rdev_get_drvdata(dev);
212 int buck = rdev_get_id(dev) - LP3971_DCDC1;
213 u16 mask = 1 << (buck * 2);
214 u16 val;
215
216 val = lp3971_reg_read(lp3971, LP3971_BUCK_VOL_ENABLE_REG);
217 return (val & mask) != 0;
218}
219
220static int lp3971_dcdc_enable(struct regulator_dev *dev)
221{
222 struct lp3971 *lp3971 = rdev_get_drvdata(dev);
223 int buck = rdev_get_id(dev) - LP3971_DCDC1;
224 u16 mask = 1 << (buck * 2);
225
226 return lp3971_set_bits(lp3971, LP3971_BUCK_VOL_ENABLE_REG, mask, mask);
227}
228
229static int lp3971_dcdc_disable(struct regulator_dev *dev)
230{
231 struct lp3971 *lp3971 = rdev_get_drvdata(dev);
232 int buck = rdev_get_id(dev) - LP3971_DCDC1;
233 u16 mask = 1 << (buck * 2);
234
235 return lp3971_set_bits(lp3971, LP3971_BUCK_VOL_ENABLE_REG, mask, 0);
236}
237
238static int lp3971_dcdc_get_voltage(struct regulator_dev *dev)
239{
240 struct lp3971 *lp3971 = rdev_get_drvdata(dev);
241 int buck = rdev_get_id(dev) - LP3971_DCDC1;
242 u16 reg;
243 int val;
244
245 reg = lp3971_reg_read(lp3971, LP3971_BUCK_TARGET_VOL1_REG(buck));
246 reg &= BUCK_TARGET_VOL_MASK;
247
248 if (reg <= BUCK_TARGET_VOL_MAX_IDX)
249 val = 1000 * buck_voltage_map[reg];
250 else {
251 val = 0;
252 dev_warn(&dev->dev, "chip reported incorrect voltage value.\n");
253 }
254
255 return val;
256}
257
258static int lp3971_dcdc_set_voltage(struct regulator_dev *dev,
259 int min_uV, int max_uV)
260{
261 struct lp3971 *lp3971 = rdev_get_drvdata(dev);
262 int buck = rdev_get_id(dev) - LP3971_DCDC1;
263 int min_vol = min_uV / 1000, max_vol = max_uV / 1000;
264 const int *vol_map = buck_voltage_map;
265 u16 val;
266 int ret;
267
268 if (min_vol < vol_map[BUCK_TARGET_VOL_MIN_IDX] ||
269 min_vol > vol_map[BUCK_TARGET_VOL_MAX_IDX])
270 return -EINVAL;
271
272 for (val = BUCK_TARGET_VOL_MIN_IDX; val <= BUCK_TARGET_VOL_MAX_IDX;
273 val++)
274 if (vol_map[val] >= min_vol)
275 break;
276
Roel Kluin62737d42010-02-12 12:30:21 +0100277 if (val > BUCK_TARGET_VOL_MAX_IDX || vol_map[val] > max_vol)
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200278 return -EINVAL;
279
280 ret = lp3971_set_bits(lp3971, LP3971_BUCK_TARGET_VOL1_REG(buck),
281 BUCK_TARGET_VOL_MASK, val);
282 if (ret)
283 return ret;
284
285 ret = lp3971_set_bits(lp3971, LP3971_BUCK_VOL_CHANGE_REG,
286 BUCK_VOL_CHANGE_FLAG_MASK << BUCK_VOL_CHANGE_SHIFT(buck),
287 BUCK_VOL_CHANGE_FLAG_GO << BUCK_VOL_CHANGE_SHIFT(buck));
288 if (ret)
289 return ret;
290
291 return lp3971_set_bits(lp3971, LP3971_BUCK_VOL_CHANGE_REG,
292 BUCK_VOL_CHANGE_FLAG_MASK << BUCK_VOL_CHANGE_SHIFT(buck),
293 0 << BUCK_VOL_CHANGE_SHIFT(buck));
294}
295
296static struct regulator_ops lp3971_dcdc_ops = {
297 .list_voltage = lp3971_dcdc_list_voltage,
298 .is_enabled = lp3971_dcdc_is_enabled,
299 .enable = lp3971_dcdc_enable,
300 .disable = lp3971_dcdc_disable,
301 .get_voltage = lp3971_dcdc_get_voltage,
302 .set_voltage = lp3971_dcdc_set_voltage,
303};
304
305static struct regulator_desc regulators[] = {
306 {
307 .name = "LDO1",
308 .id = LP3971_LDO1,
309 .ops = &lp3971_ldo_ops,
310 .n_voltages = ARRAY_SIZE(ldo123_voltage_map),
311 .type = REGULATOR_VOLTAGE,
312 .owner = THIS_MODULE,
313 },
314 {
315 .name = "LDO2",
316 .id = LP3971_LDO2,
317 .ops = &lp3971_ldo_ops,
318 .n_voltages = ARRAY_SIZE(ldo123_voltage_map),
319 .type = REGULATOR_VOLTAGE,
320 .owner = THIS_MODULE,
321 },
322 {
323 .name = "LDO3",
324 .id = LP3971_LDO3,
325 .ops = &lp3971_ldo_ops,
326 .n_voltages = ARRAY_SIZE(ldo123_voltage_map),
327 .type = REGULATOR_VOLTAGE,
328 .owner = THIS_MODULE,
329 },
330 {
331 .name = "LDO4",
332 .id = LP3971_LDO4,
333 .ops = &lp3971_ldo_ops,
334 .n_voltages = ARRAY_SIZE(ldo45_voltage_map),
335 .type = REGULATOR_VOLTAGE,
336 .owner = THIS_MODULE,
337 },
338 {
339 .name = "LDO5",
340 .id = LP3971_LDO5,
341 .ops = &lp3971_ldo_ops,
342 .n_voltages = ARRAY_SIZE(ldo45_voltage_map),
343 .type = REGULATOR_VOLTAGE,
344 .owner = THIS_MODULE,
345 },
346 {
347 .name = "DCDC1",
348 .id = LP3971_DCDC1,
349 .ops = &lp3971_dcdc_ops,
350 .n_voltages = ARRAY_SIZE(buck_voltage_map),
351 .type = REGULATOR_VOLTAGE,
352 .owner = THIS_MODULE,
353 },
354 {
355 .name = "DCDC2",
356 .id = LP3971_DCDC2,
357 .ops = &lp3971_dcdc_ops,
358 .n_voltages = ARRAY_SIZE(buck_voltage_map),
359 .type = REGULATOR_VOLTAGE,
360 .owner = THIS_MODULE,
361 },
362 {
363 .name = "DCDC3",
364 .id = LP3971_DCDC3,
365 .ops = &lp3971_dcdc_ops,
366 .n_voltages = ARRAY_SIZE(buck_voltage_map),
367 .type = REGULATOR_VOLTAGE,
368 .owner = THIS_MODULE,
369 },
370};
371
372static int lp3971_i2c_read(struct i2c_client *i2c, char reg, int count,
373 u16 *dest)
374{
375 int ret;
376
377 if (count != 1)
378 return -EIO;
379 ret = i2c_smbus_read_byte_data(i2c, reg);
Axel Lin27ef7f02010-08-06 08:09:14 +0800380 if (ret < 0)
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200381 return -EIO;
382
383 *dest = ret;
384 return 0;
385}
386
387static int lp3971_i2c_write(struct i2c_client *i2c, char reg, int count,
388 const u16 *src)
389{
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200390 if (count != 1)
391 return -EIO;
Axel Lin1bddc2f2010-08-09 17:01:21 +0800392 return i2c_smbus_write_byte_data(i2c, reg, *src);
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200393}
394
395static u8 lp3971_reg_read(struct lp3971 *lp3971, u8 reg)
396{
397 u16 val = 0;
398
399 mutex_lock(&lp3971->io_lock);
400
401 lp3971_i2c_read(lp3971->i2c, reg, 1, &val);
402
403 dev_dbg(lp3971->dev, "reg read 0x%02x -> 0x%02x\n", (int)reg,
404 (unsigned)val&0xff);
405
406 mutex_unlock(&lp3971->io_lock);
407
408 return val & 0xff;
409}
410
411static int lp3971_set_bits(struct lp3971 *lp3971, u8 reg, u16 mask, u16 val)
412{
413 u16 tmp;
414 int ret;
415
416 mutex_lock(&lp3971->io_lock);
417
418 ret = lp3971_i2c_read(lp3971->i2c, reg, 1, &tmp);
419 tmp = (tmp & ~mask) | val;
420 if (ret == 0) {
421 ret = lp3971_i2c_write(lp3971->i2c, reg, 1, &tmp);
422 dev_dbg(lp3971->dev, "reg write 0x%02x -> 0x%02x\n", (int)reg,
423 (unsigned)val&0xff);
424 }
425 mutex_unlock(&lp3971->io_lock);
426
427 return ret;
428}
429
Dmitry Torokhovebbed042010-02-23 23:38:17 -0800430static int __devinit setup_regulators(struct lp3971 *lp3971,
431 struct lp3971_platform_data *pdata)
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200432{
433 int i, err;
Dmitry Torokhovebbed042010-02-23 23:38:17 -0800434
435 lp3971->num_regulators = pdata->num_regulators;
436 lp3971->rdev = kcalloc(pdata->num_regulators,
437 sizeof(struct regulator_dev *), GFP_KERNEL);
Dan Carpenter67e46f32010-03-07 15:36:45 +0300438 if (!lp3971->rdev) {
439 err = -ENOMEM;
440 goto err_nomem;
441 }
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200442
443 /* Instantiate the regulators */
Dmitry Torokhovebbed042010-02-23 23:38:17 -0800444 for (i = 0; i < pdata->num_regulators; i++) {
445 struct lp3971_regulator_subdev *reg = &pdata->regulators[i];
446 lp3971->rdev[i] = regulator_register(&regulators[reg->id],
447 lp3971->dev, reg->initdata, lp3971);
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200448
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;
Dmitry Torokhovebbed042010-02-23 23:38:17 -0800458
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200459error:
Dmitry Torokhovebbed042010-02-23 23:38:17 -0800460 while (--i >= 0)
461 regulator_unregister(lp3971->rdev[i]);
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200462 kfree(lp3971->rdev);
463 lp3971->rdev = NULL;
Dan Carpenter67e46f32010-03-07 15:36:45 +0300464err_nomem:
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200465 return err;
466}
467
468static int __devinit lp3971_i2c_probe(struct i2c_client *i2c,
469 const struct i2c_device_id *id)
470{
471 struct lp3971 *lp3971;
472 struct lp3971_platform_data *pdata = i2c->dev.platform_data;
473 int ret;
474 u16 val;
475
Dmitry Torokhovebbed042010-02-23 23:38:17 -0800476 if (!pdata) {
477 dev_dbg(&i2c->dev, "No platform init data supplied\n");
478 return -ENODEV;
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200479 }
480
Dmitry Torokhovebbed042010-02-23 23:38:17 -0800481 lp3971 = kzalloc(sizeof(struct lp3971), GFP_KERNEL);
482 if (lp3971 == NULL)
483 return -ENOMEM;
484
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200485 lp3971->i2c = i2c;
486 lp3971->dev = &i2c->dev;
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200487
488 mutex_init(&lp3971->io_lock);
489
490 /* Detect LP3971 */
491 ret = lp3971_i2c_read(i2c, LP3971_SYS_CONTROL1_REG, 1, &val);
492 if (ret == 0 && (val & SYS_CONTROL1_INIT_MASK) != SYS_CONTROL1_INIT_VAL)
493 ret = -ENODEV;
494 if (ret < 0) {
495 dev_err(&i2c->dev, "failed to detect device\n");
496 goto err_detect;
497 }
498
Dmitry Torokhovebbed042010-02-23 23:38:17 -0800499 ret = setup_regulators(lp3971, pdata);
500 if (ret < 0)
501 goto err_detect;
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200502
Dmitry Torokhovebbed042010-02-23 23:38:17 -0800503 i2c_set_clientdata(i2c, lp3971);
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200504 return 0;
505
506err_detect:
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200507 kfree(lp3971);
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200508 return ret;
509}
510
511static int __devexit lp3971_i2c_remove(struct i2c_client *i2c)
512{
513 struct lp3971 *lp3971 = i2c_get_clientdata(i2c);
514 int i;
Dmitry Torokhovebbed042010-02-23 23:38:17 -0800515
Dmitry Torokhovebbed042010-02-23 23:38:17 -0800516 for (i = 0; i < lp3971->num_regulators; i++)
517 regulator_unregister(lp3971->rdev[i]);
518
519 kfree(lp3971->rdev);
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200520 kfree(lp3971);
521
522 return 0;
523}
524
525static const struct i2c_device_id lp3971_i2c_id[] = {
526 { "lp3971", 0 },
527 { }
528};
529MODULE_DEVICE_TABLE(i2c, lp3971_i2c_id);
530
531static struct i2c_driver lp3971_i2c_driver = {
532 .driver = {
533 .name = "LP3971",
534 .owner = THIS_MODULE,
535 },
536 .probe = lp3971_i2c_probe,
Liam Girdwood6113c3a2009-05-19 11:44:37 +0100537 .remove = __devexit_p(lp3971_i2c_remove),
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200538 .id_table = lp3971_i2c_id,
539};
540
541static int __init lp3971_module_init(void)
542{
Wolfram Sang12a1d932009-09-18 22:44:45 +0200543 int ret;
Marek Szyprowski0cbdf7b2009-05-19 07:33:55 +0200544
545 ret = i2c_add_driver(&lp3971_i2c_driver);
546 if (ret != 0)
547 pr_err("Failed to register I2C driver: %d\n", ret);
548
549 return ret;
550}
551module_init(lp3971_module_init);
552
553static void __exit lp3971_module_exit(void)
554{
555 i2c_del_driver(&lp3971_i2c_driver);
556}
557module_exit(lp3971_module_exit);
558
559MODULE_LICENSE("GPL");
560MODULE_AUTHOR("Marek Szyprowski <m.szyprowski@samsung.com>");
561MODULE_DESCRIPTION("LP3971 PMIC driver");