aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/regulator/Kconfig8
-rw-r--r--drivers/regulator/Makefile1
-rw-r--r--drivers/regulator/da903x.c513
3 files changed, 522 insertions, 0 deletions
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index a620023169bc..4dada6ee1119 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -72,4 +72,12 @@ config REGULATOR_WM8400
72 This driver provides support for the voltage regulators of the 72 This driver provides support for the voltage regulators of the
73 WM8400 AudioPlus PMIC. 73 WM8400 AudioPlus PMIC.
74 74
75config REGULATOR_DA903X
76 tristate "Support regulators on Dialog Semiconductor DA9030/DA9034 PMIC"
77 depends on PMIC_DA903X
78 select REGULATOR
79 help
80 Say y here to support the BUCKs and LDOs regulators found on
81 Dialog Semiconductor DA9030/DA9034 PMIC.
82
75endmenu 83endmenu
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 0de39fe2eaea..254d40c02ee8 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -10,5 +10,6 @@ obj-$(CONFIG_REGULATOR_VIRTUAL_CONSUMER) += virtual.o
10obj-$(CONFIG_REGULATOR_BQ24022) += bq24022.o 10obj-$(CONFIG_REGULATOR_BQ24022) += bq24022.o
11obj-$(CONFIG_REGULATOR_WM8350) += wm8350-regulator.o 11obj-$(CONFIG_REGULATOR_WM8350) += wm8350-regulator.o
12obj-$(CONFIG_REGULATOR_WM8400) += wm8400-regulator.o 12obj-$(CONFIG_REGULATOR_WM8400) += wm8400-regulator.o
13obj-$(CONFIG_REGULATOR_DA903X) += da903x.o
13 14
14ccflags-$(CONFIG_REGULATOR_DEBUG) += -DDEBUG 15ccflags-$(CONFIG_REGULATOR_DEBUG) += -DDEBUG
diff --git a/drivers/regulator/da903x.c b/drivers/regulator/da903x.c
new file mode 100644
index 000000000000..3688e339db87
--- /dev/null
+++ b/drivers/regulator/da903x.c
@@ -0,0 +1,513 @@
1/*
2 * Regulators driver for Dialog Semiconductor DA903x
3 *
4 * Copyright (C) 2006-2008 Marvell International Ltd.
5 * Copyright (C) 2008 Compulab Ltd.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/kernel.h>
13#include <linux/init.h>
14#include <linux/err.h>
15#include <linux/platform_device.h>
16#include <linux/regulator/driver.h>
17#include <linux/regulator/machine.h>
18#include <linux/mfd/da903x.h>
19
20/* DA9030 Registers */
21#define DA9030_INVAL (-1)
22#define DA9030_LDO1011 (0x10)
23#define DA9030_LDO15 (0x11)
24#define DA9030_LDO1416 (0x12)
25#define DA9030_LDO1819 (0x13)
26#define DA9030_LDO17 (0x14)
27#define DA9030_BUCK2DVM1 (0x15)
28#define DA9030_BUCK2DVM2 (0x16)
29#define DA9030_RCTL11 (0x17)
30#define DA9030_RCTL21 (0x18)
31#define DA9030_LDO1 (0x90)
32#define DA9030_LDO23 (0x91)
33#define DA9030_LDO45 (0x92)
34#define DA9030_LDO6 (0x93)
35#define DA9030_LDO78 (0x94)
36#define DA9030_LDO912 (0x95)
37#define DA9030_BUCK (0x96)
38#define DA9030_RCTL12 (0x97)
39#define DA9030_RCTL22 (0x98)
40#define DA9030_LDO_UNLOCK (0xa0)
41#define DA9030_LDO_UNLOCK_MASK (0xe0)
42#define DA9034_OVER1 (0x10)
43
44/* DA9034 Registers */
45#define DA9034_INVAL (-1)
46#define DA9034_OVER2 (0x11)
47#define DA9034_OVER3 (0x12)
48#define DA9034_LDO643 (0x13)
49#define DA9034_LDO987 (0x14)
50#define DA9034_LDO1110 (0x15)
51#define DA9034_LDO1312 (0x16)
52#define DA9034_LDO1514 (0x17)
53#define DA9034_VCC1 (0x20)
54#define DA9034_ADTV1 (0x23)
55#define DA9034_ADTV2 (0x24)
56#define DA9034_AVRC (0x25)
57#define DA9034_CDTV1 (0x26)
58#define DA9034_CDTV2 (0x27)
59#define DA9034_CVRC (0x28)
60#define DA9034_SDTV1 (0x29)
61#define DA9034_SDTV2 (0x2a)
62#define DA9034_SVRC (0x2b)
63#define DA9034_MDTV1 (0x32)
64#define DA9034_MDTV2 (0x33)
65#define DA9034_MVRC (0x34)
66
67struct da903x_regulator_info {
68 struct regulator_desc desc;
69
70 int min_uV;
71 int max_uV;
72 int step_uV;
73 int vol_reg;
74 int vol_shift;
75 int vol_nbits;
76 int update_reg;
77 int update_bit;
78 int enable_reg;
79 int enable_bit;
80};
81
82static inline int check_range(struct da903x_regulator_info *info,
83 int min_uV, int max_uV)
84{
85 if (min_uV < info->min_uV || min_uV > info->max_uV)
86 return -EINVAL;
87
88 return 0;
89}
90
91/* DA9030/DA9034 common operations */
92static int da903x_set_ldo_voltage(struct regulator_dev *rdev,
93 int min_uV, int max_uV)
94{
95 struct da903x_regulator_info *info = rdev_get_drvdata(rdev);
96 struct device *da9034_dev = rdev_get_dev(rdev)->parent;
97 uint8_t val, mask;
98
99 if (check_range(info, min_uV, max_uV)) {
100 pr_err("invalid voltage range (%d, %d) uV", min_uV, max_uV);
101 return -EINVAL;
102 }
103
104 val = (min_uV - info->min_uV + info->step_uV - 1) / info->step_uV;
105 val <<= info->vol_shift;
106 mask = ((1 << info->vol_nbits) - 1) << info->vol_shift;
107
108 return da903x_update(da9034_dev, info->vol_reg, val, mask);
109}
110
111static int da903x_get_voltage(struct regulator_dev *rdev)
112{
113 struct da903x_regulator_info *info = rdev_get_drvdata(rdev);
114 struct device *da9034_dev = rdev_get_dev(rdev)->parent;
115 uint8_t val, mask;
116 int ret;
117
118 ret = da903x_read(da9034_dev, info->vol_reg, &val);
119 if (ret)
120 return ret;
121
122 mask = ((1 << info->vol_nbits) - 1) << info->vol_shift;
123 val = (val & mask) >> info->vol_shift;
124
125 return info->min_uV + info->step_uV * val;
126}
127
128static int da903x_enable(struct regulator_dev *rdev)
129{
130 struct da903x_regulator_info *info = rdev_get_drvdata(rdev);
131 struct device *da9034_dev = rdev_get_dev(rdev)->parent;
132
133 return da903x_set_bits(da9034_dev, info->enable_reg,
134 1 << info->enable_bit);
135}
136
137static int da903x_disable(struct regulator_dev *rdev)
138{
139 struct da903x_regulator_info *info = rdev_get_drvdata(rdev);
140 struct device *da9034_dev = rdev_get_dev(rdev)->parent;
141
142 return da903x_clr_bits(da9034_dev, info->enable_reg,
143 1 << info->enable_bit);
144}
145
146static int da903x_is_enabled(struct regulator_dev *rdev)
147{
148 struct da903x_regulator_info *info = rdev_get_drvdata(rdev);
149 struct device *da9034_dev = rdev_get_dev(rdev)->parent;
150 uint8_t reg_val;
151 int ret;
152
153 ret = da903x_read(da9034_dev, info->enable_reg, &reg_val);
154 if (ret)
155 return ret;
156
157 return reg_val & (1 << info->enable_bit);
158}
159
160/* DA9030 specific operations */
161static int da9030_set_ldo1_15_voltage(struct regulator_dev *rdev,
162 int min_uV, int max_uV)
163{
164 struct da903x_regulator_info *info = rdev_get_drvdata(rdev);
165 struct device *da903x_dev = rdev_get_dev(rdev)->parent;
166 uint8_t val, mask;
167 int ret;
168
169 if (check_range(info, min_uV, max_uV)) {
170 pr_err("invalid voltage range (%d, %d) uV", min_uV, max_uV);
171 return -EINVAL;
172 }
173
174 val = (min_uV - info->min_uV + info->step_uV - 1) / info->step_uV;
175 val <<= info->vol_shift;
176 mask = ((1 << info->vol_nbits) - 1) << info->vol_shift;
177 val |= DA9030_LDO_UNLOCK; /* have to set UNLOCK bits */
178 mask |= DA9030_LDO_UNLOCK_MASK;
179
180 /* write twice */
181 ret = da903x_update(da903x_dev, info->vol_reg, val, mask);
182 if (ret)
183 return ret;
184
185 return da903x_update(da903x_dev, info->vol_reg, val, mask);
186}
187
188static int da9030_set_ldo14_voltage(struct regulator_dev *rdev,
189 int min_uV, int max_uV)
190{
191 struct da903x_regulator_info *info = rdev_get_drvdata(rdev);
192 struct device *da903x_dev = rdev_get_dev(rdev)->parent;
193 uint8_t val, mask;
194 int thresh;
195
196 if (check_range(info, min_uV, max_uV)) {
197 pr_err("invalid voltage range (%d, %d) uV", min_uV, max_uV);
198 return -EINVAL;
199 }
200
201 thresh = (info->max_uV + info->min_uV) / 2;
202 if (min_uV < thresh) {
203 val = (thresh - min_uV + info->step_uV - 1) / info->step_uV;
204 val |= 0x4;
205 } else {
206 val = (min_uV - thresh + info->step_uV - 1) / info->step_uV;
207 }
208
209 val <<= info->vol_shift;
210 mask = ((1 << info->vol_nbits) - 1) << info->vol_shift;
211
212 return da903x_update(da903x_dev, info->vol_reg, val, mask);
213}
214
215static int da9030_get_ldo14_voltage(struct regulator_dev *rdev)
216{
217 struct da903x_regulator_info *info = rdev_get_drvdata(rdev);
218 struct device *da903x_dev = rdev_get_dev(rdev)->parent;
219 uint8_t val, mask;
220 int ret;
221
222 ret = da903x_read(da903x_dev, info->vol_reg, &val);
223 if (ret)
224 return ret;
225
226 mask = ((1 << info->vol_nbits) - 1) << info->vol_shift;
227 val = (val & mask) >> info->vol_shift;
228
229 if (val & 0x4)
230 return info->min_uV + info->step_uV * (3 - (val & ~0x4));
231 else
232 return (info->max_uV + info->min_uV) / 2 +
233 info->step_uV * (val & ~0x4);
234}
235
236/* DA9034 specific operations */
237static int da9034_set_dvc_voltage(struct regulator_dev *rdev,
238 int min_uV, int max_uV)
239{
240 struct da903x_regulator_info *info = rdev_get_drvdata(rdev);
241 struct device *da9034_dev = rdev_get_dev(rdev)->parent;
242 uint8_t val, mask;
243 int ret;
244
245 if (check_range(info, min_uV, max_uV)) {
246 pr_err("invalid voltage range (%d, %d) uV", min_uV, max_uV);
247 return -EINVAL;
248 }
249
250 val = (min_uV - info->min_uV + info->step_uV - 1) / info->step_uV;
251 val <<= info->vol_shift;
252 mask = ((1 << info->vol_nbits) - 1) << info->vol_shift;
253
254 ret = da903x_update(da9034_dev, info->vol_reg, val, mask);
255 if (ret)
256 return ret;
257
258 ret = da903x_set_bits(da9034_dev, info->update_reg,
259 1 << info->update_bit);
260 return ret;
261}
262
263static int da9034_set_ldo12_voltage(struct regulator_dev *rdev,
264 int min_uV, int max_uV)
265{
266 struct da903x_regulator_info *info = rdev_get_drvdata(rdev);
267 struct device *da9034_dev = rdev_get_dev(rdev)->parent;
268 uint8_t val, mask;
269
270 if (check_range(info, min_uV, max_uV)) {
271 pr_err("invalid voltage range (%d, %d) uV", min_uV, max_uV);
272 return -EINVAL;
273 }
274
275 val = (min_uV - info->min_uV + info->step_uV - 1) / info->step_uV;
276 val = (val > 7 || val < 20) ? 8 : val - 12;
277 val <<= info->vol_shift;
278 mask = ((1 << info->vol_nbits) - 1) << info->vol_shift;
279
280 return da903x_update(da9034_dev, info->vol_reg, val, mask);
281}
282
283static int da9034_get_ldo12_voltage(struct regulator_dev *rdev)
284{
285 struct da903x_regulator_info *info = rdev_get_drvdata(rdev);
286 struct device *da9034_dev = rdev_get_dev(rdev)->parent;
287 uint8_t val, mask;
288 int ret;
289
290 ret = da903x_read(da9034_dev, info->vol_reg, &val);
291 if (ret)
292 return ret;
293
294 mask = ((1 << info->vol_nbits) - 1) << info->vol_shift;
295 val = (val & mask) >> info->vol_shift;
296
297 if (val >= 8)
298 return 2700000 + info->step_uV * (val - 8);
299
300 return info->min_uV + info->step_uV * val;
301}
302
303static struct regulator_ops da903x_regulator_ldo_ops = {
304 .set_voltage = da903x_set_ldo_voltage,
305 .get_voltage = da903x_get_voltage,
306 .enable = da903x_enable,
307 .disable = da903x_disable,
308 .is_enabled = da903x_is_enabled,
309};
310
311/* NOTE: this is dedicated for the insane DA9030 LDO14 */
312static struct regulator_ops da9030_regulator_ldo14_ops = {
313 .set_voltage = da9030_set_ldo14_voltage,
314 .get_voltage = da9030_get_ldo14_voltage,
315 .enable = da903x_enable,
316 .disable = da903x_disable,
317 .is_enabled = da903x_is_enabled,
318};
319
320/* NOTE: this is dedicated for the DA9030 LDO1 and LDO15 that have locks */
321static struct regulator_ops da9030_regulator_ldo1_15_ops = {
322 .set_voltage = da9030_set_ldo1_15_voltage,
323 .get_voltage = da903x_get_voltage,
324 .enable = da903x_enable,
325 .disable = da903x_disable,
326 .is_enabled = da903x_is_enabled,
327};
328
329static struct regulator_ops da9034_regulator_dvc_ops = {
330 .set_voltage = da9034_set_dvc_voltage,
331 .get_voltage = da903x_get_voltage,
332 .enable = da903x_enable,
333 .disable = da903x_disable,
334 .is_enabled = da903x_is_enabled,
335};
336
337/* NOTE: this is dedicated for the insane LDO12 */
338static struct regulator_ops da9034_regulator_ldo12_ops = {
339 .set_voltage = da9034_set_ldo12_voltage,
340 .get_voltage = da9034_get_ldo12_voltage,
341 .enable = da903x_enable,
342 .disable = da903x_disable,
343 .is_enabled = da903x_is_enabled,
344};
345
346#define DA903x_LDO(_pmic, _id, min, max, step, vreg, shift, nbits, ereg, ebit) \
347{ \
348 .desc = { \
349 .name = "LDO" #_id, \
350 .ops = &da903x_regulator_ldo_ops, \
351 .type = REGULATOR_VOLTAGE, \
352 .id = _pmic##_ID_LDO##_id, \
353 .owner = THIS_MODULE, \
354 }, \
355 .min_uV = (min) * 1000, \
356 .max_uV = (max) * 1000, \
357 .step_uV = (step) * 1000, \
358 .vol_reg = _pmic##_##vreg, \
359 .vol_shift = (shift), \
360 .vol_nbits = (nbits), \
361 .enable_reg = _pmic##_##ereg, \
362 .enable_bit = (ebit), \
363}
364
365#define DA9034_DVC(_id, min, max, step, vreg, nbits, ureg, ubit, ereg, ebit) \
366{ \
367 .desc = { \
368 .name = #_id, \
369 .ops = &da9034_regulator_dvc_ops, \
370 .type = REGULATOR_VOLTAGE, \
371 .id = DA9034_ID_##_id, \
372 .owner = THIS_MODULE, \
373 }, \
374 .min_uV = (min) * 1000, \
375 .max_uV = (max) * 1000, \
376 .step_uV = (step) * 1000, \
377 .vol_reg = DA9034_##vreg, \
378 .vol_shift = (0), \
379 .vol_nbits = (nbits), \
380 .update_reg = DA9034_##ureg, \
381 .update_bit = (ubit), \
382 .enable_reg = DA9034_##ereg, \
383 .enable_bit = (ebit), \
384}
385
386#define DA9034_LDO(_id, min, max, step, vreg, shift, nbits, ereg, ebit) \
387 DA903x_LDO(DA9034, _id, min, max, step, vreg, shift, nbits, ereg, ebit)
388
389#define DA9030_LDO(_id, min, max, step, vreg, shift, nbits, ereg, ebit) \
390 DA903x_LDO(DA9030, _id, min, max, step, vreg, shift, nbits, ereg, ebit)
391
392static struct da903x_regulator_info da903x_regulator_info[] = {
393 /* DA9030 */
394 DA9030_LDO( 1, 1200, 3200, 100, LDO1, 0, 5, RCTL12, 1),
395 DA9030_LDO( 2, 1800, 3200, 100, LDO23, 0, 4, RCTL12, 2),
396 DA9030_LDO( 3, 1800, 3200, 100, LDO23, 4, 4, RCTL12, 3),
397 DA9030_LDO( 4, 1800, 3200, 100, LDO45, 0, 4, RCTL12, 4),
398 DA9030_LDO( 5, 1800, 3200, 100, LDO45, 4, 4, RCTL12, 5),
399 DA9030_LDO( 6, 1800, 3200, 100, LDO6, 0, 4, RCTL12, 6),
400 DA9030_LDO( 7, 1800, 3200, 100, LDO78, 0, 4, RCTL12, 7),
401 DA9030_LDO( 8, 1800, 3200, 100, LDO78, 4, 4, RCTL22, 0),
402 DA9030_LDO( 9, 1800, 3200, 100, LDO912, 0, 4, RCTL22, 1),
403 DA9030_LDO(10, 1800, 3200, 100, LDO1011, 0, 4, RCTL22, 2),
404 DA9030_LDO(11, 1800, 3200, 100, LDO1011, 4, 4, RCTL22, 3),
405 DA9030_LDO(12, 1800, 3200, 100, LDO912, 4, 4, RCTL22, 4),
406 DA9030_LDO(14, 2760, 2940, 30, LDO1416, 0, 3, RCTL11, 4),
407 DA9030_LDO(15, 1100, 2650, 50, LDO15, 0, 5, RCTL11, 5),
408 DA9030_LDO(16, 1100, 2650, 50, LDO1416, 3, 5, RCTL11, 6),
409 DA9030_LDO(17, 1800, 3200, 100, LDO17, 0, 4, RCTL11, 7),
410 DA9030_LDO(18, 1800, 3200, 100, LDO1819, 0, 4, RCTL21, 2),
411 DA9030_LDO(19, 1800, 3200, 100, LDO1819, 4, 4, RCTL21, 1),
412 DA9030_LDO(13, 2100, 2100, 0, INVAL, 0, 0, RCTL11, 3), /* fixed @2.1V */
413
414 /* DA9034 */
415 DA9034_DVC(BUCK1, 725, 1500, 25, ADTV1, 5, VCC1, 0, OVER1, 0),
416 DA9034_DVC(BUCK2, 725, 1500, 25, CDTV1, 5, VCC1, 2, OVER1, 1),
417 DA9034_DVC(LDO2, 725, 1500, 25, SDTV1, 5, VCC1, 4, OVER1, 2),
418 DA9034_DVC(LDO1, 1700, 2075, 25, MDTV1, 4, VCC1, 6, OVER3, 4),
419
420 DA9034_LDO( 3, 1800, 3300, 100, LDO643, 0, 4, OVER3, 5),
421 DA9034_LDO( 4, 1800, 2900,1100, LDO643, 4, 1, OVER3, 6),
422 DA9034_LDO( 6, 2500, 2850, 50, LDO643, 5, 3, OVER2, 0),
423 DA9034_LDO( 7, 2700, 3050, 50, LDO987, 0, 3, OVER2, 1),
424 DA9034_LDO( 8, 2700, 2850, 50, LDO987, 3, 2, OVER2, 2),
425 DA9034_LDO( 9, 2700, 3050, 50, LDO987, 5, 3, OVER2, 3),
426 DA9034_LDO(10, 2700, 3050, 50, LDO1110, 0, 3, OVER2, 4),
427 DA9034_LDO(11, 1800, 3300, 100, LDO1110, 4, 4, OVER2, 5),
428 DA9034_LDO(12, 1700, 3050, 50, LDO1312, 0, 4, OVER3, 6),
429 DA9034_LDO(13, 1800, 3300, 100, LDO1312, 4, 4, OVER2, 7),
430 DA9034_LDO(14, 1800, 3300, 100, LDO1514, 0, 4, OVER3, 0),
431 DA9034_LDO(15, 1800, 3300, 100, LDO1514, 4, 4, OVER3, 1),
432 DA9034_LDO(5, 3100, 3100, 0, INVAL, 0, 0, OVER3, 7), /* fixed @3.1V */
433};
434
435static inline struct da903x_regulator_info *find_regulator_info(int id)
436{
437 struct da903x_regulator_info *ri;
438 int i;
439
440 for (i = 0; i < ARRAY_SIZE(da903x_regulator_info); i++) {
441 ri = &da903x_regulator_info[i];
442 if (ri->desc.id == id)
443 return ri;
444 }
445 return NULL;
446}
447
448static int __devinit da903x_regulator_probe(struct platform_device *pdev)
449{
450 struct da903x_regulator_info *ri = NULL;
451 struct regulator_dev *rdev;
452
453 ri = find_regulator_info(pdev->id);
454 if (ri == NULL) {
455 dev_err(&pdev->dev, "invalid regulator ID specified\n");
456 return -EINVAL;
457 }
458
459 /* Workaround for the weird LDO12 voltage setting */
460 if (ri->desc.id == DA9034_ID_LDO12)
461 ri->desc.ops = &da9034_regulator_ldo12_ops;
462
463 if (ri->desc.id == DA9030_ID_LDO14)
464 ri->desc.ops = &da9030_regulator_ldo14_ops;
465
466 if (ri->desc.id == DA9030_ID_LDO1 || ri->desc.id == DA9030_ID_LDO15)
467 ri->desc.ops = &da9030_regulator_ldo1_15_ops;
468
469 rdev = regulator_register(&ri->desc, pdev->dev.parent, ri);
470 if (IS_ERR(rdev)) {
471 dev_err(&pdev->dev, "failed to register regulator %s\n",
472 ri->desc.name);
473 return PTR_ERR(rdev);
474 }
475
476 platform_set_drvdata(pdev, rdev);
477 return 0;
478}
479
480static int __devexit da903x_regulator_remove(struct platform_device *pdev)
481{
482 struct regulator_dev *rdev = platform_get_drvdata(pdev);
483
484 regulator_unregister(rdev);
485 return 0;
486}
487
488static struct platform_driver da903x_regulator_driver = {
489 .driver = {
490 .name = "da903x-regulator",
491 .owner = THIS_MODULE,
492 },
493 .probe = da903x_regulator_probe,
494 .remove = da903x_regulator_remove,
495};
496
497static int __init da903x_regulator_init(void)
498{
499 return platform_driver_register(&da903x_regulator_driver);
500}
501module_init(da903x_regulator_init);
502
503static void __exit da903x_regulator_exit(void)
504{
505 platform_driver_unregister(&da903x_regulator_driver);
506}
507module_exit(da903x_regulator_exit);
508
509MODULE_LICENSE("GPL");
510MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>"
511 "Mike Rapoport <mike@compulab.co.il>");
512MODULE_DESCRIPTION("Regulator Driver for Dialog Semiconductor DA903X PMIC");
513MODULE_ALIAS("platform:da903x-regulator");