regulator: DA9052/53 Regulator support
[linux-2.6.git] / drivers / regulator / da9052-regulator.c
1 /*
2 * da9052-regulator.c: Regulator driver for DA9052
3 *
4 * Copyright(c) 2011 Dialog Semiconductor Ltd.
5 *
6 * Author: David Dajun Chen <dchen@diasemi.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 */
14
15 #include <linux/module.h>
16 #include <linux/moduleparam.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
23 #include <linux/mfd/da9052/da9052.h>
24 #include <linux/mfd/da9052/reg.h>
25 #include <linux/mfd/da9052/pdata.h>
26
27 /* Buck step size */
28 #define DA9052_BUCK_PERI_3uV_STEP               100000
29 #define DA9052_BUCK_PERI_REG_MAP_UPTO_3uV       24
30 #define DA9052_CONST_3uV                        3000000
31
32 #define DA9052_MIN_UA           0
33 #define DA9052_MAX_UA           3
34 #define DA9052_CURRENT_RANGE    4
35
36 /* Bit masks */
37 #define DA9052_BUCK_ILIM_MASK_EVEN      0x0c
38 #define DA9052_BUCK_ILIM_MASK_ODD       0xc0
39
40 static const u32 da9052_current_limits[3][4] = {
41         {700000, 800000, 1000000, 1200000},     /* DA9052-BC BUCKs */
42         {1600000, 2000000, 2400000, 3000000},   /* DA9053-AA/Bx BUCK-CORE */
43         {800000, 1000000, 1200000, 1500000},    /* DA9053-AA/Bx BUCK-PRO,
44                                                  * BUCK-MEM and BUCK-PERI
45                                                 */
46 };
47
48 struct da9052_regulator_info {
49         struct regulator_desc reg_desc;
50         int step_uV;
51         int min_uV;
52         int max_uV;
53         unsigned char volt_shift;
54         unsigned char en_bit;
55         unsigned char activate_bit;
56 };
57
58 struct da9052_regulator {
59         struct da9052 *da9052;
60         struct da9052_regulator_info *info;
61         struct regulator_dev *rdev;
62 };
63
64 static int verify_range(struct da9052_regulator_info *info,
65                          int min_uV, int max_uV)
66 {
67         if (min_uV > info->max_uV || max_uV < info->min_uV)
68                 return -EINVAL;
69
70         return 0;
71 }
72
73 static int da9052_regulator_enable(struct regulator_dev *rdev)
74 {
75         struct da9052_regulator *regulator = rdev_get_drvdata(rdev);
76         struct da9052_regulator_info *info = regulator->info;
77         int offset = rdev_get_id(rdev);
78
79         return da9052_reg_update(regulator->da9052,
80                                  DA9052_BUCKCORE_REG + offset,
81                                  1 << info->en_bit, 1 << info->en_bit);
82 }
83
84 static int da9052_regulator_disable(struct regulator_dev *rdev)
85 {
86         struct da9052_regulator *regulator = rdev_get_drvdata(rdev);
87         struct da9052_regulator_info *info = regulator->info;
88         int offset = rdev_get_id(rdev);
89
90         return da9052_reg_update(regulator->da9052,
91                                  DA9052_BUCKCORE_REG + offset,
92                                  1 << info->en_bit, 0);
93 }
94
95 static int da9052_regulator_is_enabled(struct regulator_dev *rdev)
96 {
97         struct da9052_regulator *regulator = rdev_get_drvdata(rdev);
98         struct da9052_regulator_info *info = regulator->info;
99         int offset = rdev_get_id(rdev);
100         int ret;
101
102         ret = da9052_reg_read(regulator->da9052, DA9052_BUCKCORE_REG + offset);
103         if (ret < 0)
104                 return ret;
105
106         return ret & (1 << info->en_bit);
107 }
108
109 static int da9052_dcdc_get_current_limit(struct regulator_dev *rdev)
110 {
111         struct da9052_regulator *regulator = rdev_get_drvdata(rdev);
112         int offset = rdev_get_id(rdev);
113         int ret, row = 2;
114
115         ret = da9052_reg_read(regulator->da9052, DA9052_BUCKA_REG + offset/2);
116         if (ret < 0)
117                 return ret;
118
119         /* Determine the even or odd position of the buck current limit
120          * register field
121         */
122         if (offset % 2 == 0)
123                 ret = (ret & DA9052_BUCK_ILIM_MASK_EVEN) >> 2;
124         else
125                 ret = (ret & DA9052_BUCK_ILIM_MASK_ODD) >> 6;
126
127         /* Select the appropriate current limit range */
128         if (regulator->da9052->chip_id == DA9052)
129                 row = 0;
130         else if (offset == 0)
131                 row = 1;
132
133         return da9052_current_limits[row][ret];
134 }
135
136 static int da9052_dcdc_set_current_limit(struct regulator_dev *rdev, int min_uA,
137                                           int max_uA)
138 {
139         struct da9052_regulator *regulator = rdev_get_drvdata(rdev);
140         int offset = rdev_get_id(rdev);
141         int reg_val = 0;
142         int i, row = 2;
143
144         /* Select the appropriate current limit range */
145         if (regulator->da9052->chip_id == DA9052)
146                 row = 0;
147         else if (offset == 0)
148                 row = 1;
149
150         if (min_uA > da9052_current_limits[row][DA9052_MAX_UA] ||
151             max_uA < da9052_current_limits[row][DA9052_MIN_UA])
152                 return -EINVAL;
153
154         for (i = 0; i < DA9052_CURRENT_RANGE; i++) {
155                 if (min_uA <= da9052_current_limits[row][i]) {
156                         reg_val = i;
157                         break;
158                 }
159         }
160
161         /* Determine the even or odd position of the buck current limit
162          * register field
163         */
164         if (offset % 2 == 0)
165                 return da9052_reg_update(regulator->da9052,
166                                          DA9052_BUCKA_REG + offset/2,
167                                          DA9052_BUCK_ILIM_MASK_EVEN,
168                                          reg_val << 2);
169         else
170                 return da9052_reg_update(regulator->da9052,
171                                          DA9052_BUCKA_REG + offset/2,
172                                          DA9052_BUCK_ILIM_MASK_ODD,
173                                          reg_val << 6);
174 }
175
176 static int da9052_list_buckperi_voltage(struct regulator_dev *rdev,
177                                          unsigned int selector)
178 {
179         struct da9052_regulator *regulator = rdev_get_drvdata(rdev);
180         struct da9052_regulator_info *info = regulator->info;
181         int volt_uV;
182
183         if ((regulator->da9052->chip_id == DA9052) &&
184             (selector >= DA9052_BUCK_PERI_REG_MAP_UPTO_3uV)) {
185                 volt_uV = ((DA9052_BUCK_PERI_REG_MAP_UPTO_3uV * info->step_uV)
186                             + info->min_uV);
187                 volt_uV += (selector - DA9052_BUCK_PERI_REG_MAP_UPTO_3uV)
188                             * (DA9052_BUCK_PERI_3uV_STEP);
189         } else
190                         volt_uV = (selector * info->step_uV) + info->min_uV;
191
192         if (volt_uV > info->max_uV)
193                 return -EINVAL;
194
195         return volt_uV;
196 }
197
198 static int da9052_list_voltage(struct regulator_dev *rdev,
199                                 unsigned int selector)
200 {
201         struct da9052_regulator *regulator = rdev_get_drvdata(rdev);
202         struct da9052_regulator_info *info = regulator->info;
203         int volt_uV;
204
205         volt_uV = info->min_uV + info->step_uV * selector;
206
207         if (volt_uV > info->max_uV)
208                 return -EINVAL;
209
210         return volt_uV;
211 }
212
213 static int da9052_regulator_set_voltage_int(struct regulator_dev *rdev,
214                                              int min_uV, int max_uV,
215                                              unsigned int *selector)
216 {
217         struct da9052_regulator *regulator = rdev_get_drvdata(rdev);
218         struct da9052_regulator_info *info = regulator->info;
219         int offset = rdev_get_id(rdev);
220         int ret;
221
222         ret = verify_range(info, min_uV, max_uV);
223         if (ret < 0)
224                 return ret;
225
226         if (min_uV < info->min_uV)
227                 min_uV = info->min_uV;
228
229         *selector = (min_uV - info->min_uV) / info->step_uV;
230
231         ret = da9052_list_voltage(rdev, *selector);
232         if (ret < 0)
233                 return ret;
234
235         return da9052_reg_update(regulator->da9052,
236                                  DA9052_BUCKCORE_REG + offset,
237                                  (1 << info->volt_shift) - 1, *selector);
238 }
239
240 static int da9052_set_ldo_voltage(struct regulator_dev *rdev,
241                                    int min_uV, int max_uV,
242                                    unsigned int *selector)
243 {
244         return da9052_regulator_set_voltage_int(rdev, min_uV, max_uV, selector);
245 }
246
247 static int da9052_set_ldo5_6_voltage(struct regulator_dev *rdev,
248                                       int min_uV, int max_uV,
249                                       unsigned int *selector)
250 {
251         struct da9052_regulator *regulator = rdev_get_drvdata(rdev);
252         struct da9052_regulator_info *info = regulator->info;
253         int ret;
254
255         ret = da9052_regulator_set_voltage_int(rdev, min_uV, max_uV, selector);
256         if (ret < 0)
257                 return ret;
258
259         /* Some LDOs are DVC controlled which requires enabling of
260          * the LDO activate bit to implment the changes on the
261          * LDO output.
262         */
263         return da9052_reg_update(regulator->da9052, DA9052_SUPPLY_REG, 0,
264                                  info->activate_bit);
265 }
266
267 static int da9052_set_dcdc_voltage(struct regulator_dev *rdev,
268                                     int min_uV, int max_uV,
269                                     unsigned int *selector)
270 {
271         struct da9052_regulator *regulator = rdev_get_drvdata(rdev);
272         struct da9052_regulator_info *info = regulator->info;
273         int ret;
274
275         ret = da9052_regulator_set_voltage_int(rdev, min_uV, max_uV, selector);
276         if (ret < 0)
277                 return ret;
278
279         /* Some DCDCs are DVC controlled which requires enabling of
280          * the DCDC activate bit to implment the changes on the
281          * DCDC output.
282         */
283         return da9052_reg_update(regulator->da9052, DA9052_SUPPLY_REG, 0,
284                                  info->activate_bit);
285 }
286
287 static int da9052_get_regulator_voltage_sel(struct regulator_dev *rdev)
288 {
289         struct da9052_regulator *regulator = rdev_get_drvdata(rdev);
290         struct da9052_regulator_info *info = regulator->info;
291         int offset = rdev_get_id(rdev);
292         int ret;
293
294         ret = da9052_reg_read(regulator->da9052, DA9052_BUCKCORE_REG + offset);
295         if (ret < 0)
296                 return ret;
297
298         ret &= ((1 << info->volt_shift) - 1);
299
300         return ret;
301 }
302
303 static int da9052_set_buckperi_voltage(struct regulator_dev *rdev, int min_uV,
304                                         int max_uV, unsigned int *selector)
305 {
306         struct da9052_regulator *regulator = rdev_get_drvdata(rdev);
307         struct da9052_regulator_info *info = regulator->info;
308         int offset = rdev_get_id(rdev);
309         int ret;
310
311         ret = verify_range(info, min_uV, max_uV);
312         if (ret < 0)
313                 return ret;
314
315         if (min_uV < info->min_uV)
316                 min_uV = info->min_uV;
317
318         if ((regulator->da9052->chip_id == DA9052) &&
319             (min_uV >= DA9052_CONST_3uV))
320                 *selector = DA9052_BUCK_PERI_REG_MAP_UPTO_3uV +
321                             ((min_uV - DA9052_CONST_3uV) /
322                             (DA9052_BUCK_PERI_3uV_STEP));
323         else
324                 *selector = (min_uV - info->min_uV) / info->step_uV;
325
326         ret = da9052_list_buckperi_voltage(rdev, *selector);
327         if (ret < 0)
328                 return ret;
329
330         return da9052_reg_update(regulator->da9052,
331                                  DA9052_BUCKCORE_REG + offset,
332                                  (1 << info->volt_shift) - 1, *selector);
333 }
334
335 static int da9052_get_buckperi_voltage_sel(struct regulator_dev *rdev)
336 {
337         struct da9052_regulator *regulator = rdev_get_drvdata(rdev);
338         struct da9052_regulator_info *info = regulator->info;
339         int offset = rdev_get_id(rdev);
340         int ret;
341
342         ret = da9052_reg_read(regulator->da9052, DA9052_BUCKCORE_REG + offset);
343         if (ret < 0)
344                 return ret;
345
346         ret &= ((1 << info->volt_shift) - 1);
347
348         return ret;
349 }
350
351 static struct regulator_ops da9052_buckperi_ops = {
352         .list_voltage = da9052_list_buckperi_voltage,
353         .get_voltage_sel = da9052_get_buckperi_voltage_sel,
354         .set_voltage = da9052_set_buckperi_voltage,
355
356         .get_current_limit = da9052_dcdc_get_current_limit,
357         .set_current_limit = da9052_dcdc_set_current_limit,
358
359         .is_enabled = da9052_regulator_is_enabled,
360         .enable = da9052_regulator_enable,
361         .disable = da9052_regulator_disable,
362 };
363
364 static struct regulator_ops da9052_dcdc_ops = {
365         .set_voltage = da9052_set_dcdc_voltage,
366         .get_current_limit = da9052_dcdc_get_current_limit,
367         .set_current_limit = da9052_dcdc_set_current_limit,
368
369         .list_voltage = da9052_list_voltage,
370         .get_voltage_sel = da9052_get_regulator_voltage_sel,
371         .is_enabled = da9052_regulator_is_enabled,
372         .enable = da9052_regulator_enable,
373         .disable = da9052_regulator_disable,
374 };
375
376 static struct regulator_ops da9052_ldo5_6_ops = {
377         .set_voltage = da9052_set_ldo5_6_voltage,
378
379         .list_voltage = da9052_list_voltage,
380         .get_voltage_sel = da9052_get_regulator_voltage_sel,
381         .is_enabled = da9052_regulator_is_enabled,
382         .enable = da9052_regulator_enable,
383         .disable = da9052_regulator_disable,
384 };
385
386 static struct regulator_ops da9052_ldo_ops = {
387         .set_voltage = da9052_set_ldo_voltage,
388
389         .list_voltage = da9052_list_voltage,
390         .get_voltage_sel = da9052_get_regulator_voltage_sel,
391         .is_enabled = da9052_regulator_is_enabled,
392         .enable = da9052_regulator_enable,
393         .disable = da9052_regulator_disable,
394 };
395
396 #define DA9052_LDO5_6(_id, step, min, max, sbits, ebits, abits) \
397 {\
398         .reg_desc = {\
399                 .name = "LDO" #_id,\
400                 .ops = &da9052_ldo5_6_ops,\
401                 .type = REGULATOR_VOLTAGE,\
402                 .id = _id,\
403                 .owner = THIS_MODULE,\
404         },\
405         .min_uV = (min) * 1000,\
406         .max_uV = (max) * 1000,\
407         .step_uV = (step) * 1000,\
408         .volt_shift = (sbits),\
409         .en_bit = (ebits),\
410         .activate_bit = (abits),\
411 }
412
413 #define DA9052_LDO(_id, step, min, max, sbits, ebits, abits) \
414 {\
415         .reg_desc = {\
416                 .name = "LDO" #_id,\
417                 .ops = &da9052_ldo_ops,\
418                 .type = REGULATOR_VOLTAGE,\
419                 .id = _id,\
420                 .owner = THIS_MODULE,\
421         },\
422         .min_uV = (min) * 1000,\
423         .max_uV = (max) * 1000,\
424         .step_uV = (step) * 1000,\
425         .volt_shift = (sbits),\
426         .en_bit = (ebits),\
427         .activate_bit = (abits),\
428 }
429
430 #define DA9052_DCDC(_id, step, min, max, sbits, ebits, abits) \
431 {\
432         .reg_desc = {\
433                 .name = "BUCK" #_id,\
434                 .ops = &da9052_dcdc_ops,\
435                 .type = REGULATOR_VOLTAGE,\
436                 .id = _id,\
437                 .owner = THIS_MODULE,\
438         },\
439         .min_uV = (min) * 1000,\
440         .max_uV = (max) * 1000,\
441         .step_uV = (step) * 1000,\
442         .volt_shift = (sbits),\
443         .en_bit = (ebits),\
444         .activate_bit = (abits),\
445 }
446
447 #define DA9052_BUCKPERI(_id, step, min, max, sbits, ebits, abits) \
448 {\
449         .reg_desc = {\
450                 .name = "BUCK" #_id,\
451                 .ops = &da9052_buckperi_ops,\
452                 .type = REGULATOR_VOLTAGE,\
453                 .id = _id,\
454                 .owner = THIS_MODULE,\
455         },\
456         .min_uV = (min) * 1000,\
457         .max_uV = (max) * 1000,\
458         .step_uV = (step) * 1000,\
459         .volt_shift = (sbits),\
460         .en_bit = (ebits),\
461         .activate_bit = (abits),\
462 }
463
464 struct da9052_regulator_info da9052_regulator_info[] = {
465         /* Buck1 - 4 */
466         DA9052_DCDC(0, 25, 500, 2075, 6, 6, DA9052_SUPPLY_VBCOREGO),
467         DA9052_DCDC(1, 25, 500, 2075, 6, 6, DA9052_SUPPLY_VBPROGO),
468         DA9052_DCDC(2, 25, 925, 2500, 6, 6, DA9052_SUPPLY_VBMEMGO),
469         DA9052_BUCKPERI(3, 50, 1800, 3600, 5, 6, 0),
470         /* LD01 - LDO10 */
471         DA9052_LDO(4, 50, 600, 1800, 5, 6, 0),
472         DA9052_LDO5_6(5, 25, 600, 1800, 6, 6, DA9052_SUPPLY_VLDO2GO),
473         DA9052_LDO5_6(6, 25, 1725, 3300, 6, 6, DA9052_SUPPLY_VLDO3GO),
474         DA9052_LDO(7, 25, 1725, 3300, 6, 6, 0),
475         DA9052_LDO(8, 50, 1200, 3600, 6, 6, 0),
476         DA9052_LDO(9, 50, 1200, 3600, 6, 6, 0),
477         DA9052_LDO(10, 50, 1200, 3600, 6, 6, 0),
478         DA9052_LDO(11, 50, 1200, 3600, 6, 6, 0),
479         DA9052_LDO(12, 50, 1250, 3650, 6, 6, 0),
480         DA9052_LDO(13, 50, 1200, 3600, 6, 6, 0),
481 };
482
483 struct da9052_regulator_info da9053_regulator_info[] = {
484         /* Buck1 - 4 */
485         DA9052_DCDC(0, 25, 500, 2075, 6, 6, DA9052_SUPPLY_VBCOREGO),
486         DA9052_DCDC(1, 25, 500, 2075, 6, 6, DA9052_SUPPLY_VBPROGO),
487         DA9052_DCDC(2, 25, 925, 2500, 6, 6, DA9052_SUPPLY_VBMEMGO),
488         DA9052_BUCKPERI(3, 25, 925, 2500, 6, 6, 0),
489         /* LD01 - LDO10 */
490         DA9052_LDO(4, 50, 600, 1800, 5, 6, 0),
491         DA9052_LDO5_6(5, 25, 600, 1800, 6, 6, DA9052_SUPPLY_VLDO2GO),
492         DA9052_LDO5_6(6, 25, 1725, 3300, 6, 6, DA9052_SUPPLY_VLDO3GO),
493         DA9052_LDO(7, 25, 1725, 3300, 6, 6, 0),
494         DA9052_LDO(8, 50, 1200, 3600, 6, 6, 0),
495         DA9052_LDO(9, 50, 1200, 3600, 6, 6, 0),
496         DA9052_LDO(10, 50, 1200, 3600, 6, 6, 0),
497         DA9052_LDO(11, 50, 1200, 3600, 6, 6, 0),
498         DA9052_LDO(12, 50, 1250, 3650, 6, 6, 0),
499         DA9052_LDO(13, 50, 1200, 3600, 6, 6, 0),
500 };
501
502 static inline struct da9052_regulator_info *find_regulator_info(u8 chip_id,
503                                                                  int id)
504 {
505         struct da9052_regulator_info *info;
506         int i;
507
508         if (chip_id == DA9052) {
509                 for (i = 0; i < ARRAY_SIZE(da9052_regulator_info); i++) {
510                         info = &da9052_regulator_info[i];
511                         if (info->reg_desc.id == id)
512                                 return info;
513                 }
514         } else {
515                 for (i = 0; i < ARRAY_SIZE(da9053_regulator_info); i++) {
516                         info = &da9053_regulator_info[i];
517                         if (info->reg_desc.id == id)
518                                 return info;
519                 }
520         }
521
522         return NULL;
523 }
524
525 static int __devinit da9052_regulator_probe(struct platform_device *pdev)
526 {
527         struct da9052_regulator *regulator;
528         struct da9052 *da9052;
529         struct da9052_pdata *pdata;
530         int ret;
531
532         regulator = kzalloc(sizeof(struct da9052_regulator), GFP_KERNEL);
533         if (!regulator)
534                 return -ENOMEM;
535
536         da9052 = dev_get_drvdata(pdev->dev.parent);
537         pdata = da9052->dev->platform_data;
538         regulator->da9052 = da9052;
539
540         regulator->info = find_regulator_info(regulator->da9052->chip_id,
541                                               pdev->id);
542         if (regulator->info == NULL) {
543                 dev_err(&pdev->dev, "invalid regulator ID specified\n");
544                 ret = -EINVAL;
545                 goto err;
546         }
547         regulator->rdev = regulator_register(&regulator->info->reg_desc,
548                                              &pdev->dev,
549                                              pdata->regulators[pdev->id],
550                                              regulator);
551         if (IS_ERR(regulator->rdev)) {
552                 dev_err(&pdev->dev, "failed to register regulator %s\n",
553                         regulator->info->reg_desc.name);
554                 ret = PTR_ERR(regulator->rdev);
555                 goto err;
556         }
557
558         platform_set_drvdata(pdev, regulator);
559
560         return 0;
561 err:
562         kfree(regulator);
563         return ret;
564 }
565
566 static int __devexit da9052_regulator_remove(struct platform_device *pdev)
567 {
568         struct da9052_regulator *regulator = platform_get_drvdata(pdev);
569
570         regulator_unregister(regulator->rdev);
571         kfree(regulator);
572
573         return 0;
574 }
575
576 static struct platform_driver da9052_regulator_driver = {
577         .probe = da9052_regulator_probe,
578         .remove = __devexit_p(da9052_regulator_remove),
579         .driver = {
580                 .name = "da9052-regulator",
581                 .owner = THIS_MODULE,
582         },
583 };
584
585 static int __init da9052_regulator_init(void)
586 {
587         return platform_driver_register(&da9052_regulator_driver);
588 }
589 subsys_initcall(da9052_regulator_init);
590
591 static void __exit da9052_regulator_exit(void)
592 {
593         platform_driver_unregister(&da9052_regulator_driver);
594 }
595 module_exit(da9052_regulator_exit);
596
597 MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>");
598 MODULE_DESCRIPTION("Power Regulator driver for Dialog DA9052 PMIC");
599 MODULE_LICENSE("GPL");
600 MODULE_ALIAS("platform:da9052-regulator");