blob: 48e37bd95a27331e3c40878c965e0a4afd39f74d [file] [log] [blame]
Cyril Chemparathy1394fd22010-12-07 12:04:11 -05001/*
2 * Regulator driver for TPS6524x PMIC
3 *
4 * Copyright (C) 2010 Texas Instruments
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation version 2.
9 *
10 * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind,
11 * whether express or implied; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 */
15
16#include <linux/kernel.h>
17#include <linux/module.h>
18#include <linux/err.h>
19#include <linux/errno.h>
20#include <linux/slab.h>
21#include <linux/spi/spi.h>
22#include <linux/regulator/driver.h>
23#include <linux/regulator/machine.h>
24
25#define REG_LDO_SET 0x0
26#define LDO_ILIM_MASK 1 /* 0 = 400-800, 1 = 900-1500 */
27#define LDO_VSEL_MASK 0x0f
28#define LDO2_ILIM_SHIFT 12
29#define LDO2_VSEL_SHIFT 4
30#define LDO1_ILIM_SHIFT 8
31#define LDO1_VSEL_SHIFT 0
32
33#define REG_BLOCK_EN 0x1
34#define BLOCK_MASK 1
35#define BLOCK_LDO1_SHIFT 0
36#define BLOCK_LDO2_SHIFT 1
37#define BLOCK_LCD_SHIFT 2
38#define BLOCK_USB_SHIFT 3
39
40#define REG_DCDC_SET 0x2
41#define DCDC_VDCDC_MASK 0x1f
42#define DCDC_VDCDC1_SHIFT 0
43#define DCDC_VDCDC2_SHIFT 5
44#define DCDC_VDCDC3_SHIFT 10
45
46#define REG_DCDC_EN 0x3
47#define DCDCDCDC_EN_MASK 0x1
48#define DCDCDCDC1_EN_SHIFT 0
49#define DCDCDCDC1_PG_MSK BIT(1)
50#define DCDCDCDC2_EN_SHIFT 2
51#define DCDCDCDC2_PG_MSK BIT(3)
52#define DCDCDCDC3_EN_SHIFT 4
53#define DCDCDCDC3_PG_MSK BIT(5)
54
55#define REG_USB 0x4
56#define USB_ILIM_SHIFT 0
57#define USB_ILIM_MASK 0x3
58#define USB_TSD_SHIFT 2
59#define USB_TSD_MASK 0x3
60#define USB_TWARN_SHIFT 4
61#define USB_TWARN_MASK 0x3
62#define USB_IWARN_SD BIT(6)
63#define USB_FAST_LOOP BIT(7)
64
65#define REG_ALARM 0x5
66#define ALARM_LDO1 BIT(0)
67#define ALARM_DCDC1 BIT(1)
68#define ALARM_DCDC2 BIT(2)
69#define ALARM_DCDC3 BIT(3)
70#define ALARM_LDO2 BIT(4)
71#define ALARM_USB_WARN BIT(5)
72#define ALARM_USB_ALARM BIT(6)
73#define ALARM_LCD BIT(9)
74#define ALARM_TEMP_WARM BIT(10)
75#define ALARM_TEMP_HOT BIT(11)
76#define ALARM_NRST BIT(14)
77#define ALARM_POWERUP BIT(15)
78
79#define REG_INT_ENABLE 0x6
80#define INT_LDO1 BIT(0)
81#define INT_DCDC1 BIT(1)
82#define INT_DCDC2 BIT(2)
83#define INT_DCDC3 BIT(3)
84#define INT_LDO2 BIT(4)
85#define INT_USB_WARN BIT(5)
86#define INT_USB_ALARM BIT(6)
87#define INT_LCD BIT(9)
88#define INT_TEMP_WARM BIT(10)
89#define INT_TEMP_HOT BIT(11)
90#define INT_GLOBAL_EN BIT(15)
91
92#define REG_INT_STATUS 0x7
93#define STATUS_LDO1 BIT(0)
94#define STATUS_DCDC1 BIT(1)
95#define STATUS_DCDC2 BIT(2)
96#define STATUS_DCDC3 BIT(3)
97#define STATUS_LDO2 BIT(4)
98#define STATUS_USB_WARN BIT(5)
99#define STATUS_USB_ALARM BIT(6)
100#define STATUS_LCD BIT(9)
101#define STATUS_TEMP_WARM BIT(10)
102#define STATUS_TEMP_HOT BIT(11)
103
104#define REG_SOFTWARE_RESET 0xb
105#define REG_WRITE_ENABLE 0xd
106#define REG_REV_ID 0xf
107
108#define N_DCDC 3
109#define N_LDO 2
110#define N_SWITCH 2
Axel Lin4d984d12012-03-09 11:37:30 +0800111#define N_REGULATORS (N_DCDC + N_LDO + N_SWITCH)
Cyril Chemparathy1394fd22010-12-07 12:04:11 -0500112
113#define FIXED_ILIMSEL BIT(0)
Cyril Chemparathy1394fd22010-12-07 12:04:11 -0500114
115#define CMD_READ(reg) ((reg) << 6)
116#define CMD_WRITE(reg) (BIT(5) | (reg) << 6)
117#define STAT_CLK BIT(3)
118#define STAT_WRITE BIT(2)
119#define STAT_INVALID BIT(1)
120#define STAT_WP BIT(0)
121
122struct field {
123 int reg;
124 int shift;
125 int mask;
126};
127
128struct supply_info {
129 const char *name;
130 int n_voltages;
Axel Lincac87fd2012-06-20 22:30:15 +0800131 const unsigned int *voltages;
Cyril Chemparathy1394fd22010-12-07 12:04:11 -0500132 int n_ilimsels;
133 const int *ilimsels;
134 int fixed_ilimsel;
135 int flags;
136 struct field enable, voltage, ilimsel;
137};
138
139struct tps6524x {
140 struct device *dev;
141 struct spi_device *spi;
142 struct mutex lock;
143 struct regulator_desc desc[N_REGULATORS];
144 struct regulator_dev *rdev[N_REGULATORS];
145};
146
147static int __read_reg(struct tps6524x *hw, int reg)
148{
149 int error = 0;
150 u16 cmd = CMD_READ(reg), in;
151 u8 status;
152 struct spi_message m;
153 struct spi_transfer t[3];
154
155 spi_message_init(&m);
156 memset(t, 0, sizeof(t));
157
158 t[0].tx_buf = &cmd;
159 t[0].len = 2;
160 t[0].bits_per_word = 12;
161 spi_message_add_tail(&t[0], &m);
162
163 t[1].rx_buf = &in;
164 t[1].len = 2;
165 t[1].bits_per_word = 16;
166 spi_message_add_tail(&t[1], &m);
167
168 t[2].rx_buf = &status;
169 t[2].len = 1;
170 t[2].bits_per_word = 4;
171 spi_message_add_tail(&t[2], &m);
172
173 error = spi_sync(hw->spi, &m);
174 if (error < 0)
175 return error;
176
177 dev_dbg(hw->dev, "read reg %d, data %x, status %x\n",
178 reg, in, status);
179
180 if (!(status & STAT_CLK) || (status & STAT_WRITE))
181 return -EIO;
182
183 if (status & STAT_INVALID)
184 return -EINVAL;
185
186 return in;
187}
188
189static int read_reg(struct tps6524x *hw, int reg)
190{
191 int ret;
192
193 mutex_lock(&hw->lock);
194 ret = __read_reg(hw, reg);
195 mutex_unlock(&hw->lock);
196
197 return ret;
198}
199
200static int __write_reg(struct tps6524x *hw, int reg, int val)
201{
202 int error = 0;
203 u16 cmd = CMD_WRITE(reg), out = val;
204 u8 status;
205 struct spi_message m;
206 struct spi_transfer t[3];
207
208 spi_message_init(&m);
209 memset(t, 0, sizeof(t));
210
211 t[0].tx_buf = &cmd;
212 t[0].len = 2;
213 t[0].bits_per_word = 12;
214 spi_message_add_tail(&t[0], &m);
215
216 t[1].tx_buf = &out;
217 t[1].len = 2;
218 t[1].bits_per_word = 16;
219 spi_message_add_tail(&t[1], &m);
220
221 t[2].rx_buf = &status;
222 t[2].len = 1;
223 t[2].bits_per_word = 4;
224 spi_message_add_tail(&t[2], &m);
225
226 error = spi_sync(hw->spi, &m);
227 if (error < 0)
228 return error;
229
230 dev_dbg(hw->dev, "wrote reg %d, data %x, status %x\n",
231 reg, out, status);
232
233 if (!(status & STAT_CLK) || !(status & STAT_WRITE))
234 return -EIO;
235
236 if (status & (STAT_INVALID | STAT_WP))
237 return -EINVAL;
238
239 return error;
240}
241
242static int __rmw_reg(struct tps6524x *hw, int reg, int mask, int val)
243{
244 int ret;
245
246 ret = __read_reg(hw, reg);
247 if (ret < 0)
248 return ret;
249
250 ret &= ~mask;
251 ret |= val;
252
253 ret = __write_reg(hw, reg, ret);
254
255 return (ret < 0) ? ret : 0;
256}
257
258static int rmw_protect(struct tps6524x *hw, int reg, int mask, int val)
259{
260 int ret;
261
262 mutex_lock(&hw->lock);
263
264 ret = __write_reg(hw, REG_WRITE_ENABLE, 1);
265 if (ret) {
266 dev_err(hw->dev, "failed to set write enable\n");
267 goto error;
268 }
269
270 ret = __rmw_reg(hw, reg, mask, val);
271 if (ret)
272 dev_err(hw->dev, "failed to rmw register %d\n", reg);
273
274 ret = __write_reg(hw, REG_WRITE_ENABLE, 0);
275 if (ret) {
276 dev_err(hw->dev, "failed to clear write enable\n");
277 goto error;
278 }
279
280error:
281 mutex_unlock(&hw->lock);
282
283 return ret;
284}
285
286static int read_field(struct tps6524x *hw, const struct field *field)
287{
288 int tmp;
289
290 tmp = read_reg(hw, field->reg);
291 if (tmp < 0)
292 return tmp;
293
294 return (tmp >> field->shift) & field->mask;
295}
296
297static int write_field(struct tps6524x *hw, const struct field *field,
298 int val)
299{
300 if (val & ~field->mask)
301 return -EOVERFLOW;
302
303 return rmw_protect(hw, field->reg,
304 field->mask << field->shift,
305 val << field->shift);
306}
307
Axel Lincac87fd2012-06-20 22:30:15 +0800308static const unsigned int dcdc1_voltages[] = {
Cyril Chemparathy1394fd22010-12-07 12:04:11 -0500309 800000, 825000, 850000, 875000,
310 900000, 925000, 950000, 975000,
311 1000000, 1025000, 1050000, 1075000,
312 1100000, 1125000, 1150000, 1175000,
313 1200000, 1225000, 1250000, 1275000,
314 1300000, 1325000, 1350000, 1375000,
315 1400000, 1425000, 1450000, 1475000,
316 1500000, 1525000, 1550000, 1575000,
317};
318
Axel Lincac87fd2012-06-20 22:30:15 +0800319static const unsigned int dcdc2_voltages[] = {
Cyril Chemparathy1394fd22010-12-07 12:04:11 -0500320 1400000, 1450000, 1500000, 1550000,
321 1600000, 1650000, 1700000, 1750000,
322 1800000, 1850000, 1900000, 1950000,
323 2000000, 2050000, 2100000, 2150000,
324 2200000, 2250000, 2300000, 2350000,
325 2400000, 2450000, 2500000, 2550000,
326 2600000, 2650000, 2700000, 2750000,
327 2800000, 2850000, 2900000, 2950000,
328};
329
Axel Lincac87fd2012-06-20 22:30:15 +0800330static const unsigned int dcdc3_voltages[] = {
Cyril Chemparathy1394fd22010-12-07 12:04:11 -0500331 2400000, 2450000, 2500000, 2550000, 2600000,
332 2650000, 2700000, 2750000, 2800000, 2850000,
333 2900000, 2950000, 3000000, 3050000, 3100000,
334 3150000, 3200000, 3250000, 3300000, 3350000,
335 3400000, 3450000, 3500000, 3550000, 3600000,
336};
337
Axel Lincac87fd2012-06-20 22:30:15 +0800338static const unsigned int ldo1_voltages[] = {
Cyril Chemparathy1394fd22010-12-07 12:04:11 -0500339 4300000, 4350000, 4400000, 4450000,
340 4500000, 4550000, 4600000, 4650000,
341 4700000, 4750000, 4800000, 4850000,
342 4900000, 4950000, 5000000, 5050000,
343};
344
Axel Lincac87fd2012-06-20 22:30:15 +0800345static const unsigned int ldo2_voltages[] = {
Cyril Chemparathy1394fd22010-12-07 12:04:11 -0500346 1100000, 1150000, 1200000, 1250000,
347 1300000, 1700000, 1750000, 1800000,
348 1850000, 1900000, 3150000, 3200000,
349 3250000, 3300000, 3350000, 3400000,
350};
351
Axel Lincac87fd2012-06-20 22:30:15 +0800352static const unsigned int fixed_5000000_voltage[] = {
353 5000000
354};
355
Cyril Chemparathy1394fd22010-12-07 12:04:11 -0500356static const int ldo_ilimsel[] = {
357 400000, 1500000
358};
359
360static const int usb_ilimsel[] = {
361 200000, 400000, 800000, 1000000
362};
363
364#define __MK_FIELD(_reg, _mask, _shift) \
365 { .reg = (_reg), .mask = (_mask), .shift = (_shift), }
366
367static const struct supply_info supply_info[N_REGULATORS] = {
368 {
369 .name = "DCDC1",
370 .flags = FIXED_ILIMSEL,
371 .n_voltages = ARRAY_SIZE(dcdc1_voltages),
372 .voltages = dcdc1_voltages,
373 .fixed_ilimsel = 2400000,
374 .enable = __MK_FIELD(REG_DCDC_EN, DCDCDCDC_EN_MASK,
375 DCDCDCDC1_EN_SHIFT),
376 .voltage = __MK_FIELD(REG_DCDC_SET, DCDC_VDCDC_MASK,
377 DCDC_VDCDC1_SHIFT),
378 },
379 {
380 .name = "DCDC2",
381 .flags = FIXED_ILIMSEL,
382 .n_voltages = ARRAY_SIZE(dcdc2_voltages),
383 .voltages = dcdc2_voltages,
384 .fixed_ilimsel = 1200000,
385 .enable = __MK_FIELD(REG_DCDC_EN, DCDCDCDC_EN_MASK,
386 DCDCDCDC2_EN_SHIFT),
387 .voltage = __MK_FIELD(REG_DCDC_SET, DCDC_VDCDC_MASK,
388 DCDC_VDCDC2_SHIFT),
389 },
390 {
391 .name = "DCDC3",
392 .flags = FIXED_ILIMSEL,
393 .n_voltages = ARRAY_SIZE(dcdc3_voltages),
394 .voltages = dcdc3_voltages,
395 .fixed_ilimsel = 1200000,
396 .enable = __MK_FIELD(REG_DCDC_EN, DCDCDCDC_EN_MASK,
397 DCDCDCDC3_EN_SHIFT),
398 .voltage = __MK_FIELD(REG_DCDC_SET, DCDC_VDCDC_MASK,
399 DCDC_VDCDC3_SHIFT),
400 },
401 {
402 .name = "LDO1",
403 .n_voltages = ARRAY_SIZE(ldo1_voltages),
404 .voltages = ldo1_voltages,
405 .n_ilimsels = ARRAY_SIZE(ldo_ilimsel),
406 .ilimsels = ldo_ilimsel,
407 .enable = __MK_FIELD(REG_BLOCK_EN, BLOCK_MASK,
408 BLOCK_LDO1_SHIFT),
409 .voltage = __MK_FIELD(REG_LDO_SET, LDO_VSEL_MASK,
410 LDO1_VSEL_SHIFT),
411 .ilimsel = __MK_FIELD(REG_LDO_SET, LDO_ILIM_MASK,
412 LDO1_ILIM_SHIFT),
413 },
414 {
415 .name = "LDO2",
416 .n_voltages = ARRAY_SIZE(ldo2_voltages),
417 .voltages = ldo2_voltages,
418 .n_ilimsels = ARRAY_SIZE(ldo_ilimsel),
419 .ilimsels = ldo_ilimsel,
420 .enable = __MK_FIELD(REG_BLOCK_EN, BLOCK_MASK,
421 BLOCK_LDO2_SHIFT),
422 .voltage = __MK_FIELD(REG_LDO_SET, LDO_VSEL_MASK,
423 LDO2_VSEL_SHIFT),
424 .ilimsel = __MK_FIELD(REG_LDO_SET, LDO_ILIM_MASK,
425 LDO2_ILIM_SHIFT),
426 },
427 {
428 .name = "USB",
Axel Lincac87fd2012-06-20 22:30:15 +0800429 .n_voltages = ARRAY_SIZE(fixed_5000000_voltage),
430 .voltages = fixed_5000000_voltage,
Cyril Chemparathy1394fd22010-12-07 12:04:11 -0500431 .n_ilimsels = ARRAY_SIZE(usb_ilimsel),
432 .ilimsels = usb_ilimsel,
433 .enable = __MK_FIELD(REG_BLOCK_EN, BLOCK_MASK,
434 BLOCK_USB_SHIFT),
435 .ilimsel = __MK_FIELD(REG_USB, USB_ILIM_MASK,
436 USB_ILIM_SHIFT),
437 },
438 {
439 .name = "LCD",
Axel Lincac87fd2012-06-20 22:30:15 +0800440 .n_voltages = ARRAY_SIZE(fixed_5000000_voltage),
441 .voltages = fixed_5000000_voltage,
442 .flags = FIXED_ILIMSEL,
Cyril Chemparathy1394fd22010-12-07 12:04:11 -0500443 .fixed_ilimsel = 400000,
444 .enable = __MK_FIELD(REG_BLOCK_EN, BLOCK_MASK,
445 BLOCK_LCD_SHIFT),
446 },
447};
448
Axel Linf8ee3392012-03-28 19:45:43 +0800449static int set_voltage_sel(struct regulator_dev *rdev, unsigned selector)
Cyril Chemparathy1394fd22010-12-07 12:04:11 -0500450{
451 const struct supply_info *info;
452 struct tps6524x *hw;
Cyril Chemparathy1394fd22010-12-07 12:04:11 -0500453
454 hw = rdev_get_drvdata(rdev);
455 info = &supply_info[rdev_get_id(rdev)];
456
Axel Lincac87fd2012-06-20 22:30:15 +0800457 if (rdev->desc->n_voltages == 1)
Cyril Chemparathy1394fd22010-12-07 12:04:11 -0500458 return -EINVAL;
459
Axel Linf8ee3392012-03-28 19:45:43 +0800460 return write_field(hw, &info->voltage, selector);
Cyril Chemparathy1394fd22010-12-07 12:04:11 -0500461}
462
Axel Lin4af7c1d2012-03-28 19:46:39 +0800463static int get_voltage_sel(struct regulator_dev *rdev)
Cyril Chemparathy1394fd22010-12-07 12:04:11 -0500464{
465 const struct supply_info *info;
466 struct tps6524x *hw;
467 int ret;
468
469 hw = rdev_get_drvdata(rdev);
470 info = &supply_info[rdev_get_id(rdev)];
471
Axel Lincac87fd2012-06-20 22:30:15 +0800472 if (rdev->desc->n_voltages == 1)
Axel Lin8386a002012-06-14 16:00:53 +0800473 return 0;
Cyril Chemparathy1394fd22010-12-07 12:04:11 -0500474
475 ret = read_field(hw, &info->voltage);
476 if (ret < 0)
477 return ret;
478 if (WARN_ON(ret >= info->n_voltages))
479 return -EIO;
480
Axel Lin4af7c1d2012-03-28 19:46:39 +0800481 return ret;
Cyril Chemparathy1394fd22010-12-07 12:04:11 -0500482}
483
484static int set_current_limit(struct regulator_dev *rdev, int min_uA,
485 int max_uA)
486{
487 const struct supply_info *info;
488 struct tps6524x *hw;
489 int i;
490
491 hw = rdev_get_drvdata(rdev);
492 info = &supply_info[rdev_get_id(rdev)];
493
494 if (info->flags & FIXED_ILIMSEL)
495 return -EINVAL;
496
497 for (i = 0; i < info->n_ilimsels; i++)
498 if (min_uA <= info->ilimsels[i] &&
499 max_uA >= info->ilimsels[i])
500 break;
501
502 if (i >= info->n_ilimsels)
503 return -EINVAL;
504
505 return write_field(hw, &info->ilimsel, i);
506}
507
508static int get_current_limit(struct regulator_dev *rdev)
509{
510 const struct supply_info *info;
511 struct tps6524x *hw;
512 int ret;
513
514 hw = rdev_get_drvdata(rdev);
515 info = &supply_info[rdev_get_id(rdev)];
516
517 if (info->flags & FIXED_ILIMSEL)
518 return info->fixed_ilimsel;
519
520 ret = read_field(hw, &info->ilimsel);
521 if (ret < 0)
522 return ret;
523 if (WARN_ON(ret >= info->n_ilimsels))
524 return -EIO;
525
526 return info->ilimsels[ret];
527}
528
529static int enable_supply(struct regulator_dev *rdev)
530{
531 const struct supply_info *info;
532 struct tps6524x *hw;
533
534 hw = rdev_get_drvdata(rdev);
535 info = &supply_info[rdev_get_id(rdev)];
536
537 return write_field(hw, &info->enable, 1);
538}
539
540static int disable_supply(struct regulator_dev *rdev)
541{
542 const struct supply_info *info;
543 struct tps6524x *hw;
544
545 hw = rdev_get_drvdata(rdev);
546 info = &supply_info[rdev_get_id(rdev)];
547
548 return write_field(hw, &info->enable, 0);
549}
550
551static int is_supply_enabled(struct regulator_dev *rdev)
552{
553 const struct supply_info *info;
554 struct tps6524x *hw;
555
556 hw = rdev_get_drvdata(rdev);
557 info = &supply_info[rdev_get_id(rdev)];
558
559 return read_field(hw, &info->enable);
560}
561
562static struct regulator_ops regulator_ops = {
563 .is_enabled = is_supply_enabled,
564 .enable = enable_supply,
565 .disable = disable_supply,
Axel Lin4af7c1d2012-03-28 19:46:39 +0800566 .get_voltage_sel = get_voltage_sel,
Axel Linf8ee3392012-03-28 19:45:43 +0800567 .set_voltage_sel = set_voltage_sel,
Axel Lincac87fd2012-06-20 22:30:15 +0800568 .list_voltage = regulator_list_voltage_table,
Cyril Chemparathy1394fd22010-12-07 12:04:11 -0500569 .set_current_limit = set_current_limit,
570 .get_current_limit = get_current_limit,
571};
572
Randy Dunlap5362b092011-03-24 13:30:59 -0700573static int pmic_remove(struct spi_device *spi)
Cyril Chemparathy1394fd22010-12-07 12:04:11 -0500574{
575 struct tps6524x *hw = spi_get_drvdata(spi);
576 int i;
577
578 if (!hw)
579 return 0;
580 for (i = 0; i < N_REGULATORS; i++) {
581 if (hw->rdev[i])
582 regulator_unregister(hw->rdev[i]);
583 hw->rdev[i] = NULL;
584 }
585 spi_set_drvdata(spi, NULL);
Cyril Chemparathy1394fd22010-12-07 12:04:11 -0500586 return 0;
587}
588
589static int __devinit pmic_probe(struct spi_device *spi)
590{
591 struct tps6524x *hw;
592 struct device *dev = &spi->dev;
593 const struct supply_info *info = supply_info;
594 struct regulator_init_data *init_data;
Mark Brownc1727082012-04-04 00:50:22 +0100595 struct regulator_config config = { };
Cyril Chemparathy1394fd22010-12-07 12:04:11 -0500596 int ret = 0, i;
597
598 init_data = dev->platform_data;
599 if (!init_data) {
600 dev_err(dev, "could not find regulator platform data\n");
601 return -EINVAL;
602 }
603
Axel Lin9eb0c422012-04-11 14:40:18 +0800604 hw = devm_kzalloc(&spi->dev, sizeof(struct tps6524x), GFP_KERNEL);
Cyril Chemparathy1394fd22010-12-07 12:04:11 -0500605 if (!hw) {
606 dev_err(dev, "cannot allocate regulator private data\n");
607 return -ENOMEM;
608 }
609 spi_set_drvdata(spi, hw);
610
611 memset(hw, 0, sizeof(struct tps6524x));
612 hw->dev = dev;
613 hw->spi = spi_dev_get(spi);
614 mutex_init(&hw->lock);
615
616 for (i = 0; i < N_REGULATORS; i++, info++, init_data++) {
617 hw->desc[i].name = info->name;
618 hw->desc[i].id = i;
619 hw->desc[i].n_voltages = info->n_voltages;
Axel Lincac87fd2012-06-20 22:30:15 +0800620 hw->desc[i].volt_table = info->voltages;
Cyril Chemparathy1394fd22010-12-07 12:04:11 -0500621 hw->desc[i].ops = &regulator_ops;
622 hw->desc[i].type = REGULATOR_VOLTAGE;
623 hw->desc[i].owner = THIS_MODULE;
624
Mark Brownc1727082012-04-04 00:50:22 +0100625 config.dev = dev;
626 config.init_data = init_data;
627 config.driver_data = hw;
628
629 hw->rdev[i] = regulator_register(&hw->desc[i], &config);
Cyril Chemparathy1394fd22010-12-07 12:04:11 -0500630 if (IS_ERR(hw->rdev[i])) {
631 ret = PTR_ERR(hw->rdev[i]);
632 hw->rdev[i] = NULL;
633 goto fail;
634 }
635 }
636
637 return 0;
638
639fail:
640 pmic_remove(spi);
641 return ret;
642}
643
644static struct spi_driver pmic_driver = {
645 .probe = pmic_probe,
646 .remove = __devexit_p(pmic_remove),
647 .driver = {
648 .name = "tps6524x",
649 .owner = THIS_MODULE,
650 },
651};
652
Mark Brown173f24d2012-04-04 00:34:23 +0100653module_spi_driver(pmic_driver);
Cyril Chemparathy1394fd22010-12-07 12:04:11 -0500654
655MODULE_DESCRIPTION("TPS6524X PMIC Driver");
656MODULE_AUTHOR("Cyril Chemparathy");
657MODULE_LICENSE("GPL");
658MODULE_ALIAS("spi:tps6524x");