aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/regulator
diff options
context:
space:
mode:
authorGraeme Gregory <gg@slimlogic.co.uk>2012-05-18 11:53:57 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2012-05-19 07:45:18 -0400
commite5ce4208f111e5b6ae22df334750324711c28320 (patch)
treebb36d773d999f36e4fa50f860e16957066a60d57 /drivers/regulator
parent1bdd670a32a5728502887a5f7e49aae081abdb4b (diff)
regulator: regulator driver for Palmas series chips
Palmas has both Switched Mode (SMPS) and Linear (LDO) regulators in it. This regulator driver allows software control of these regulators. The regulators available on Palmas series chips vary depending on the muxing. This is handled automatically in the driver by reading the mux info from OTP. Signed-off-by: Graeme Gregory <gg@slimlogic.co.uk> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'drivers/regulator')
-rw-r--r--drivers/regulator/palmas-regulator.c822
1 files changed, 822 insertions, 0 deletions
diff --git a/drivers/regulator/palmas-regulator.c b/drivers/regulator/palmas-regulator.c
new file mode 100644
index 000000000000..c4435f608df7
--- /dev/null
+++ b/drivers/regulator/palmas-regulator.c
@@ -0,0 +1,822 @@
1/*
2 * Driver for Regulator part of Palmas PMIC Chips
3 *
4 * Copyright 2011-2012 Texas Instruments Inc.
5 *
6 * Author: Graeme Gregory <gg@slimlogic.co.uk>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 *
13 */
14
15#include <linux/kernel.h>
16#include <linux/module.h>
17#include <linux/init.h>
18#include <linux/err.h>
19#include <linux/platform_device.h>
20#include <linux/regulator/driver.h>
21#include <linux/regulator/machine.h>
22#include <linux/slab.h>
23#include <linux/regmap.h>
24#include <linux/mfd/palmas.h>
25
26struct regs_info {
27 char *name;
28 u8 vsel_addr;
29 u8 ctrl_addr;
30 u8 tstep_addr;
31};
32
33static const struct regs_info palmas_regs_info[] = {
34 {
35 .name = "SMPS12",
36 .vsel_addr = PALMAS_SMPS12_VOLTAGE,
37 .ctrl_addr = PALMAS_SMPS12_CTRL,
38 .tstep_addr = PALMAS_SMPS12_TSTEP,
39 },
40 {
41 .name = "SMPS123",
42 .vsel_addr = PALMAS_SMPS12_VOLTAGE,
43 .ctrl_addr = PALMAS_SMPS12_CTRL,
44 .tstep_addr = PALMAS_SMPS12_TSTEP,
45 },
46 {
47 .name = "SMPS3",
48 .vsel_addr = PALMAS_SMPS3_VOLTAGE,
49 .ctrl_addr = PALMAS_SMPS3_CTRL,
50 },
51 {
52 .name = "SMPS45",
53 .vsel_addr = PALMAS_SMPS45_VOLTAGE,
54 .ctrl_addr = PALMAS_SMPS45_CTRL,
55 .tstep_addr = PALMAS_SMPS45_TSTEP,
56 },
57 {
58 .name = "SMPS457",
59 .vsel_addr = PALMAS_SMPS45_VOLTAGE,
60 .ctrl_addr = PALMAS_SMPS45_CTRL,
61 .tstep_addr = PALMAS_SMPS45_TSTEP,
62 },
63 {
64 .name = "SMPS6",
65 .vsel_addr = PALMAS_SMPS6_VOLTAGE,
66 .ctrl_addr = PALMAS_SMPS6_CTRL,
67 .tstep_addr = PALMAS_SMPS6_TSTEP,
68 },
69 {
70 .name = "SMPS7",
71 .vsel_addr = PALMAS_SMPS7_VOLTAGE,
72 .ctrl_addr = PALMAS_SMPS7_CTRL,
73 },
74 {
75 .name = "SMPS8",
76 .vsel_addr = PALMAS_SMPS8_VOLTAGE,
77 .ctrl_addr = PALMAS_SMPS8_CTRL,
78 .tstep_addr = PALMAS_SMPS8_TSTEP,
79 },
80 {
81 .name = "SMPS9",
82 .vsel_addr = PALMAS_SMPS9_VOLTAGE,
83 .ctrl_addr = PALMAS_SMPS9_CTRL,
84 },
85 {
86 .name = "SMPS10",
87 },
88 {
89 .name = "LDO1",
90 .vsel_addr = PALMAS_LDO1_VOLTAGE,
91 .ctrl_addr = PALMAS_LDO1_CTRL,
92 },
93 {
94 .name = "LDO2",
95 .vsel_addr = PALMAS_LDO2_VOLTAGE,
96 .ctrl_addr = PALMAS_LDO2_CTRL,
97 },
98 {
99 .name = "LDO3",
100 .vsel_addr = PALMAS_LDO3_VOLTAGE,
101 .ctrl_addr = PALMAS_LDO3_CTRL,
102 },
103 {
104 .name = "LDO4",
105 .vsel_addr = PALMAS_LDO4_VOLTAGE,
106 .ctrl_addr = PALMAS_LDO4_CTRL,
107 },
108 {
109 .name = "LDO5",
110 .vsel_addr = PALMAS_LDO5_VOLTAGE,
111 .ctrl_addr = PALMAS_LDO5_CTRL,
112 },
113 {
114 .name = "LDO6",
115 .vsel_addr = PALMAS_LDO6_VOLTAGE,
116 .ctrl_addr = PALMAS_LDO6_CTRL,
117 },
118 {
119 .name = "LDO7",
120 .vsel_addr = PALMAS_LDO7_VOLTAGE,
121 .ctrl_addr = PALMAS_LDO7_CTRL,
122 },
123 {
124 .name = "LDO8",
125 .vsel_addr = PALMAS_LDO8_VOLTAGE,
126 .ctrl_addr = PALMAS_LDO8_CTRL,
127 },
128 {
129 .name = "LDO9",
130 .vsel_addr = PALMAS_LDO9_VOLTAGE,
131 .ctrl_addr = PALMAS_LDO9_CTRL,
132 },
133 {
134 .name = "LDOLN",
135 .vsel_addr = PALMAS_LDOLN_VOLTAGE,
136 .ctrl_addr = PALMAS_LDOLN_CTRL,
137 },
138 {
139 .name = "LDOUSB",
140 .vsel_addr = PALMAS_LDOUSB_VOLTAGE,
141 .ctrl_addr = PALMAS_LDOUSB_CTRL,
142 },
143};
144
145#define SMPS_CTRL_MODE_OFF 0x00
146#define SMPS_CTRL_MODE_ON 0x01
147#define SMPS_CTRL_MODE_ECO 0x02
148#define SMPS_CTRL_MODE_PWM 0x03
149
150/* These values are derived from the data sheet. And are the number of steps
151 * where there is a voltage change, the ranges at beginning and end of register
152 * max/min values where there are no change are ommitted.
153 *
154 * So they are basically (maxV-minV)/stepV
155 */
156#define PALMAS_SMPS_NUM_VOLTAGES 116
157#define PALMAS_SMPS10_NUM_VOLTAGES 2
158#define PALMAS_LDO_NUM_VOLTAGES 50
159
160#define SMPS10_VSEL (1<<3)
161#define SMPS10_BOOST_EN (1<<2)
162#define SMPS10_BYPASS_EN (1<<1)
163#define SMPS10_SWITCH_EN (1<<0)
164
165#define REGULATOR_SLAVE 0
166
167static int palmas_smps_read(struct palmas *palmas, unsigned int reg,
168 unsigned int *dest)
169{
170 unsigned int addr;
171
172 addr = PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE, reg);
173
174 return regmap_read(palmas->regmap[REGULATOR_SLAVE], addr, dest);
175}
176
177static int palmas_smps_write(struct palmas *palmas, unsigned int reg,
178 unsigned int value)
179{
180 unsigned int addr;
181
182 addr = PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE, reg);
183
184 return regmap_write(palmas->regmap[REGULATOR_SLAVE], addr, value);
185}
186
187static int palmas_ldo_read(struct palmas *palmas, unsigned int reg,
188 unsigned int *dest)
189{
190 unsigned int addr;
191
192 addr = PALMAS_BASE_TO_REG(PALMAS_LDO_BASE, reg);
193
194 return regmap_read(palmas->regmap[REGULATOR_SLAVE], addr, dest);
195}
196
197static int palmas_ldo_write(struct palmas *palmas, unsigned int reg,
198 unsigned int value)
199{
200 unsigned int addr;
201
202 addr = PALMAS_BASE_TO_REG(PALMAS_LDO_BASE, reg);
203
204 return regmap_write(palmas->regmap[REGULATOR_SLAVE], addr, value);
205}
206
207static int palmas_is_enabled_smps(struct regulator_dev *dev)
208{
209 struct palmas_pmic *pmic = rdev_get_drvdata(dev);
210 int id = rdev_get_id(dev);
211 unsigned int reg;
212
213 palmas_smps_read(pmic->palmas, palmas_regs_info[id].ctrl_addr, &reg);
214
215 reg &= PALMAS_SMPS12_CTRL_STATUS_MASK;
216 reg >>= PALMAS_SMPS12_CTRL_STATUS_SHIFT;
217
218 return !!(reg);
219}
220
221static int palmas_enable_smps(struct regulator_dev *dev)
222{
223 struct palmas_pmic *pmic = rdev_get_drvdata(dev);
224 int id = rdev_get_id(dev);
225 unsigned int reg;
226
227 palmas_smps_read(pmic->palmas, palmas_regs_info[id].ctrl_addr, &reg);
228
229 reg &= ~PALMAS_SMPS12_CTRL_MODE_ACTIVE_MASK;
230 reg |= SMPS_CTRL_MODE_ON;
231
232 palmas_smps_write(pmic->palmas, palmas_regs_info[id].ctrl_addr, reg);
233
234 return 0;
235}
236
237static int palmas_disable_smps(struct regulator_dev *dev)
238{
239 struct palmas_pmic *pmic = rdev_get_drvdata(dev);
240 int id = rdev_get_id(dev);
241 unsigned int reg;
242
243 palmas_smps_read(pmic->palmas, palmas_regs_info[id].ctrl_addr, &reg);
244
245 reg &= ~PALMAS_SMPS12_CTRL_MODE_ACTIVE_MASK;
246
247 palmas_smps_write(pmic->palmas, palmas_regs_info[id].ctrl_addr, reg);
248
249 return 0;
250}
251
252
253static int palmas_set_mode_smps(struct regulator_dev *dev, unsigned int mode)
254{
255 struct palmas_pmic *pmic = rdev_get_drvdata(dev);
256 int id = rdev_get_id(dev);
257 unsigned int reg;
258
259 palmas_smps_read(pmic->palmas, palmas_regs_info[id].ctrl_addr, &reg);
260 reg &= ~PALMAS_SMPS12_CTRL_STATUS_MASK;
261 reg >>= PALMAS_SMPS12_CTRL_STATUS_SHIFT;
262
263 switch (mode) {
264 case REGULATOR_MODE_NORMAL:
265 reg |= SMPS_CTRL_MODE_ON;
266 break;
267 case REGULATOR_MODE_IDLE:
268 reg |= SMPS_CTRL_MODE_ECO;
269 break;
270 case REGULATOR_MODE_FAST:
271 reg |= SMPS_CTRL_MODE_PWM;
272 break;
273 default:
274 return -EINVAL;
275 }
276 palmas_smps_write(pmic->palmas, palmas_regs_info[id].ctrl_addr, reg);
277
278 return 0;
279}
280
281static unsigned int palmas_get_mode_smps(struct regulator_dev *dev)
282{
283 struct palmas_pmic *pmic = rdev_get_drvdata(dev);
284 int id = rdev_get_id(dev);
285 unsigned int reg;
286
287 palmas_smps_read(pmic->palmas, palmas_regs_info[id].ctrl_addr, &reg);
288 reg &= PALMAS_SMPS12_CTRL_STATUS_MASK;
289 reg >>= PALMAS_SMPS12_CTRL_STATUS_SHIFT;
290
291 switch (reg) {
292 case SMPS_CTRL_MODE_ON:
293 return REGULATOR_MODE_NORMAL;
294 case SMPS_CTRL_MODE_ECO:
295 return REGULATOR_MODE_IDLE;
296 case SMPS_CTRL_MODE_PWM:
297 return REGULATOR_MODE_FAST;
298 }
299
300 return 0;
301}
302
303static int palmas_list_voltage_smps(struct regulator_dev *dev,
304 unsigned selector)
305{
306 struct palmas_pmic *pmic = rdev_get_drvdata(dev);
307 int id = rdev_get_id(dev);
308 int mult = 1;
309
310 if (!selector)
311 return 0;
312
313 /* Read the multiplier set in VSEL register to return
314 * the correct voltage.
315 */
316 if (pmic->range[id])
317 mult = 2;
318
319 /* Voltage is (0.49V + (selector * 0.01V)) * RANGE
320 * as defined in data sheet. RANGE is either x1 or x2
321 */
322 return (490000 + (selector * 10000)) * mult;
323}
324
325static int palmas_get_voltage_smps_sel(struct regulator_dev *dev)
326{
327 struct palmas_pmic *pmic = rdev_get_drvdata(dev);
328 int id = rdev_get_id(dev);
329 int selector;
330 unsigned int reg;
331 unsigned int addr;
332
333 addr = palmas_regs_info[id].vsel_addr;
334
335 palmas_smps_read(pmic->palmas, addr, &reg);
336
337 selector = reg & PALMAS_SMPS12_VOLTAGE_VSEL_MASK;
338
339 /* Adjust selector to match list_voltage ranges */
340 if ((selector > 0) && (selector < 6))
341 selector = 6;
342 if (!selector)
343 selector = 5;
344 if (selector > 121)
345 selector = 121;
346 selector -= 5;
347
348 return selector;
349}
350
351static int palmas_set_voltage_smps_sel(struct regulator_dev *dev,
352 unsigned selector)
353{
354 struct palmas_pmic *pmic = rdev_get_drvdata(dev);
355 int id = rdev_get_id(dev);
356 unsigned int reg = 0;
357 unsigned int addr;
358
359 addr = palmas_regs_info[id].vsel_addr;
360
361 /* Make sure we don't change the value of RANGE */
362 if (pmic->range[id])
363 reg |= PALMAS_SMPS12_VOLTAGE_RANGE;
364
365 /* Adjust the linux selector into range used in VSEL register */
366 if (selector)
367 reg |= selector + 5;
368
369 palmas_smps_write(pmic->palmas, addr, reg);
370
371 return 0;
372}
373
374static int palmas_map_voltage_smps(struct regulator_dev *rdev,
375 int min_uV, int max_uV)
376{
377 int ret, voltage;
378
379 ret = ((min_uV - 500000) / 10000) + 1;
380 if (ret < 0)
381 return ret;
382
383 /* Map back into a voltage to verify we're still in bounds */
384 voltage = palmas_list_voltage_smps(rdev, ret);
385 if (voltage < min_uV || voltage > max_uV)
386 return -EINVAL;
387
388 return ret;
389}
390
391static struct regulator_ops palmas_ops_smps = {
392 .is_enabled = palmas_is_enabled_smps,
393 .enable = palmas_enable_smps,
394 .disable = palmas_disable_smps,
395 .set_mode = palmas_set_mode_smps,
396 .get_mode = palmas_get_mode_smps,
397 .get_voltage_sel = palmas_get_voltage_smps_sel,
398 .set_voltage_sel = palmas_set_voltage_smps_sel,
399 .list_voltage = palmas_list_voltage_smps,
400 .map_voltage = palmas_map_voltage_smps,
401};
402
403static int palmas_list_voltage_smps10(struct regulator_dev *dev,
404 unsigned selector)
405{
406 return 3750000 + (selector * 1250000);
407}
408
409static struct regulator_ops palmas_ops_smps10 = {
410 .is_enabled = regulator_is_enabled_regmap,
411 .enable = regulator_enable_regmap,
412 .disable = regulator_disable_regmap,
413 .get_voltage_sel = regulator_get_voltage_sel_regmap,
414 .set_voltage_sel = regulator_set_voltage_sel_regmap,
415 .list_voltage = palmas_list_voltage_smps10,
416};
417
418static int palmas_is_enabled_ldo(struct regulator_dev *dev)
419{
420 struct palmas_pmic *pmic = rdev_get_drvdata(dev);
421 int id = rdev_get_id(dev);
422 unsigned int reg;
423
424 palmas_ldo_read(pmic->palmas, palmas_regs_info[id].ctrl_addr, &reg);
425
426 reg &= PALMAS_LDO1_CTRL_STATUS;
427
428 return !!(reg);
429}
430
431static int palmas_list_voltage_ldo(struct regulator_dev *dev,
432 unsigned selector)
433{
434 if (!selector)
435 return 0;
436
437 /* voltage is 0.85V + (selector * 0.05v) */
438 return 850000 + (selector * 50000);
439}
440
441static int palmas_get_voltage_ldo_sel(struct regulator_dev *dev)
442{
443 struct palmas_pmic *pmic = rdev_get_drvdata(dev);
444 int id = rdev_get_id(dev);
445 int selector;
446 unsigned int reg;
447 unsigned int addr;
448
449 addr = palmas_regs_info[id].vsel_addr;
450
451 palmas_ldo_read(pmic->palmas, addr, &reg);
452
453 selector = reg & PALMAS_LDO1_VOLTAGE_VSEL_MASK;
454
455 /* Adjust selector to match list_voltage ranges */
456 if (selector > 49)
457 selector = 49;
458
459 return selector;
460}
461
462static int palmas_set_voltage_ldo_sel(struct regulator_dev *dev,
463 unsigned selector)
464{
465 struct palmas_pmic *pmic = rdev_get_drvdata(dev);
466 int id = rdev_get_id(dev);
467 unsigned int reg = 0;
468 unsigned int addr;
469
470 addr = palmas_regs_info[id].vsel_addr;
471
472 reg = selector;
473
474 palmas_ldo_write(pmic->palmas, addr, reg);
475
476 return 0;
477}
478
479static int palmas_map_voltage_ldo(struct regulator_dev *rdev,
480 int min_uV, int max_uV)
481{
482 int ret, voltage;
483
484 ret = ((min_uV - 900000) / 50000) + 1;
485 if (ret < 0)
486 return ret;
487
488 /* Map back into a voltage to verify we're still in bounds */
489 voltage = palmas_list_voltage_ldo(rdev, ret);
490 if (voltage < min_uV || voltage > max_uV)
491 return -EINVAL;
492
493 return ret;
494}
495
496static struct regulator_ops palmas_ops_ldo = {
497 .is_enabled = palmas_is_enabled_ldo,
498 .enable = regulator_enable_regmap,
499 .disable = regulator_disable_regmap,
500 .get_voltage_sel = palmas_get_voltage_ldo_sel,
501 .set_voltage_sel = palmas_set_voltage_ldo_sel,
502 .list_voltage = palmas_list_voltage_ldo,
503 .map_voltage = palmas_map_voltage_ldo,
504};
505
506/*
507 * setup the hardware based sleep configuration of the SMPS/LDO regulators
508 * from the platform data. This is different to the software based control
509 * supported by the regulator framework as it is controlled by toggling
510 * pins on the PMIC such as PREQ, SYSEN, ...
511 */
512static int palmas_smps_init(struct palmas *palmas, int id,
513 struct palmas_reg_init *reg_init)
514{
515 unsigned int reg;
516 unsigned int addr;
517 int ret;
518
519 addr = palmas_regs_info[id].ctrl_addr;
520
521 ret = palmas_smps_read(palmas, addr, &reg);
522 if (ret)
523 return ret;
524
525 if (id != PALMAS_REG_SMPS10) {
526 if (reg_init->warm_reset)
527 reg |= PALMAS_SMPS12_CTRL_WR_S;
528
529 if (reg_init->roof_floor)
530 reg |= PALMAS_SMPS12_CTRL_ROOF_FLOOR_EN;
531
532 if (reg_init->mode_sleep) {
533 reg &= ~PALMAS_SMPS12_CTRL_MODE_SLEEP_MASK;
534 reg |= reg_init->mode_sleep <<
535 PALMAS_SMPS12_CTRL_MODE_SLEEP_SHIFT;
536 }
537 } else {
538 if (reg_init->mode_sleep) {
539 reg &= ~PALMAS_SMPS10_CTRL_MODE_SLEEP_MASK;
540 reg |= reg_init->mode_sleep <<
541 PALMAS_SMPS10_CTRL_MODE_SLEEP_SHIFT;
542 }
543
544 }
545 ret = palmas_smps_write(palmas, addr, reg);
546 if (ret)
547 return ret;
548
549 if (palmas_regs_info[id].tstep_addr && reg_init->tstep) {
550 addr = palmas_regs_info[id].tstep_addr;
551
552 reg = reg_init->tstep & PALMAS_SMPS12_TSTEP_TSTEP_MASK;
553
554 ret = palmas_smps_write(palmas, addr, reg);
555 if (ret)
556 return ret;
557 }
558
559 if (palmas_regs_info[id].vsel_addr && reg_init->vsel) {
560 addr = palmas_regs_info[id].vsel_addr;
561
562 reg = reg_init->vsel;
563
564 ret = palmas_smps_write(palmas, addr, reg);
565 if (ret)
566 return ret;
567 }
568
569
570 return 0;
571}
572
573static int palmas_ldo_init(struct palmas *palmas, int id,
574 struct palmas_reg_init *reg_init)
575{
576 unsigned int reg;
577 unsigned int addr;
578 int ret;
579
580 addr = palmas_regs_info[id].ctrl_addr;
581
582 ret = palmas_smps_read(palmas, addr, &reg);
583 if (ret)
584 return ret;
585
586 if (reg_init->warm_reset)
587 reg |= PALMAS_LDO1_CTRL_WR_S;
588
589 if (reg_init->mode_sleep)
590 reg |= PALMAS_LDO1_CTRL_MODE_SLEEP;
591
592 ret = palmas_smps_write(palmas, addr, reg);
593 if (ret)
594 return ret;
595
596 return 0;
597}
598
599static __devinit int palmas_probe(struct platform_device *pdev)
600{
601 struct palmas *palmas = dev_get_drvdata(pdev->dev.parent);
602 struct palmas_pmic_platform_data *pdata = pdev->dev.platform_data;
603 struct regulator_dev *rdev;
604 struct regulator_config config = { };
605 struct palmas_pmic *pmic;
606 struct palmas_reg_init *reg_init;
607 int id = 0, ret;
608 unsigned int addr, reg;
609
610 if (!pdata)
611 return -EINVAL;
612 if (!pdata->reg_data)
613 return -EINVAL;
614
615 pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL);
616 if (!pmic)
617 return -ENOMEM;
618
619 pmic->dev = &pdev->dev;
620 pmic->palmas = palmas;
621 palmas->pmic = pmic;
622 platform_set_drvdata(pdev, pmic);
623
624 ret = palmas_smps_read(palmas, PALMAS_SMPS_CTRL, &reg);
625 if (ret)
626 goto err_unregister_regulator;
627
628 if (reg & PALMAS_SMPS_CTRL_SMPS12_SMPS123_EN)
629 pmic->smps123 = 1;
630
631 if (reg & PALMAS_SMPS_CTRL_SMPS45_SMPS457_EN)
632 pmic->smps457 = 1;
633
634 config.regmap = palmas->regmap[REGULATOR_SLAVE];
635 config.dev = &pdev->dev;
636 config.driver_data = pmic;
637
638 for (id = 0; id < PALMAS_REG_LDO1; id++) {
639
640 /*
641 * Miss out regulators which are not available due
642 * to slaving configurations.
643 */
644 switch (id) {
645 case PALMAS_REG_SMPS12:
646 case PALMAS_REG_SMPS3:
647 if (pmic->smps123)
648 continue;
649 break;
650 case PALMAS_REG_SMPS123:
651 if (!pmic->smps123)
652 continue;
653 break;
654 case PALMAS_REG_SMPS45:
655 case PALMAS_REG_SMPS7:
656 if (pmic->smps457)
657 continue;
658 break;
659 case PALMAS_REG_SMPS457:
660 if (!pmic->smps457)
661 continue;
662 }
663
664 /* Register the regulators */
665 pmic->desc[id].name = palmas_regs_info[id].name;
666 pmic->desc[id].id = id;
667
668 if (id != PALMAS_REG_SMPS10) {
669 pmic->desc[id].ops = &palmas_ops_smps;
670 pmic->desc[id].n_voltages = PALMAS_SMPS_NUM_VOLTAGES;
671 } else {
672 pmic->desc[id].n_voltages = PALMAS_SMPS10_NUM_VOLTAGES;
673 pmic->desc[id].ops = &palmas_ops_smps10;
674 pmic->desc[id].vsel_reg = PALMAS_SMPS10_CTRL;
675 pmic->desc[id].vsel_mask = SMPS10_VSEL;
676 pmic->desc[id].enable_reg = PALMAS_SMPS10_STATUS;
677 pmic->desc[id].enable_mask = SMPS10_BOOST_EN;
678 }
679
680 pmic->desc[id].type = REGULATOR_VOLTAGE;
681 pmic->desc[id].owner = THIS_MODULE;
682
683 /* Initialise sleep/init values from platform data */
684 if (pdata && pdata->reg_init) {
685 reg_init = pdata->reg_init[id];
686 if (reg_init) {
687 ret = palmas_smps_init(palmas, id, reg_init);
688 if (ret)
689 goto err_unregister_regulator;
690 }
691 }
692
693 /*
694 * read and store the RANGE bit for later use
695 * This must be done before regulator is probed otherwise
696 * we error in probe with unsuportable ranges.
697 */
698 if (id != PALMAS_REG_SMPS10) {
699 addr = palmas_regs_info[id].vsel_addr;
700
701 ret = palmas_smps_read(pmic->palmas, addr, &reg);
702 if (ret)
703 goto err_unregister_regulator;
704 if (reg & PALMAS_SMPS12_VOLTAGE_RANGE)
705 pmic->range[id] = 1;
706 }
707
708 if (pdata && pdata->reg_data)
709 config.init_data = pdata->reg_data[id];
710 else
711 config.init_data = NULL;
712
713 rdev = regulator_register(&pmic->desc[id], &config);
714 if (IS_ERR(rdev)) {
715 dev_err(&pdev->dev,
716 "failed to register %s regulator\n",
717 pdev->name);
718 ret = PTR_ERR(rdev);
719 goto err_unregister_regulator;
720 }
721
722 /* Save regulator for cleanup */
723 pmic->rdev[id] = rdev;
724 }
725
726 /* Start this loop from the id left from previous loop */
727 for (; id < PALMAS_NUM_REGS; id++) {
728
729 /* Miss out regulators which are not available due
730 * to alternate functions.
731 */
732
733 /* Register the regulators */
734 pmic->desc[id].name = palmas_regs_info[id].name;
735 pmic->desc[id].id = id;
736 pmic->desc[id].n_voltages = PALMAS_LDO_NUM_VOLTAGES;
737
738 pmic->desc[id].ops = &palmas_ops_ldo;
739
740 pmic->desc[id].type = REGULATOR_VOLTAGE;
741 pmic->desc[id].owner = THIS_MODULE;
742 pmic->desc[id].enable_reg = palmas_regs_info[id].ctrl_addr;
743 pmic->desc[id].enable_mask = PALMAS_LDO1_CTRL_MODE_ACTIVE;
744
745 if (pdata && pdata->reg_data)
746 config.init_data = pdata->reg_data[id];
747 else
748 config.init_data = NULL;
749
750 rdev = regulator_register(&pmic->desc[id], &config);
751 if (IS_ERR(rdev)) {
752 dev_err(&pdev->dev,
753 "failed to register %s regulator\n",
754 pdev->name);
755 ret = PTR_ERR(rdev);
756 goto err_unregister_regulator;
757 }
758
759 /* Save regulator for cleanup */
760 pmic->rdev[id] = rdev;
761
762 /* Initialise sleep/init values from platform data */
763 if (pdata->reg_init) {
764 reg_init = pdata->reg_init[id];
765 if (reg_init) {
766 ret = palmas_ldo_init(palmas, id, reg_init);
767 if (ret)
768 goto err_unregister_regulator;
769 }
770 }
771 }
772
773 return 0;
774
775err_unregister_regulator:
776 while (--id >= 0)
777 regulator_unregister(pmic->rdev[id]);
778 kfree(pmic->rdev);
779 kfree(pmic->desc);
780 kfree(pmic);
781 return ret;
782}
783
784static int __devexit palmas_remove(struct platform_device *pdev)
785{
786 struct palmas_pmic *pmic = platform_get_drvdata(pdev);
787 int id;
788
789 for (id = 0; id < PALMAS_NUM_REGS; id++)
790 regulator_unregister(pmic->rdev[id]);
791
792 kfree(pmic->rdev);
793 kfree(pmic->desc);
794 kfree(pmic);
795 return 0;
796}
797
798static struct platform_driver palmas_driver = {
799 .driver = {
800 .name = "palmas-pmic",
801 .owner = THIS_MODULE,
802 },
803 .probe = palmas_probe,
804 .remove = __devexit_p(palmas_remove),
805};
806
807static int __init palmas_init(void)
808{
809 return platform_driver_register(&palmas_driver);
810}
811subsys_initcall(palmas_init);
812
813static void __exit palmas_exit(void)
814{
815 platform_driver_unregister(&palmas_driver);
816}
817module_exit(palmas_exit);
818
819MODULE_AUTHOR("Graeme Gregory <gg@slimlogic.co.uk>");
820MODULE_DESCRIPTION("Palmas voltage regulator driver");
821MODULE_LICENSE("GPL");
822MODULE_ALIAS("platform:palmas-pmic");