Fixed pohmelfs_write_page_init() to match callback
[pohmelfs.git] / drivers / regulator / da9052-regulator.c
blob09915e89705dfd45f3f0b9f8102ac8946defa9b2
1 /*
2 * da9052-regulator.c: Regulator driver for DA9052
4 * Copyright(c) 2011 Dialog Semiconductor Ltd.
6 * Author: David Dajun Chen <dchen@diasemi.com>
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.
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>
23 #include <linux/mfd/da9052/da9052.h>
24 #include <linux/mfd/da9052/reg.h>
25 #include <linux/mfd/da9052/pdata.h>
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
32 #define DA9052_MIN_UA 0
33 #define DA9052_MAX_UA 3
34 #define DA9052_CURRENT_RANGE 4
36 /* Bit masks */
37 #define DA9052_BUCK_ILIM_MASK_EVEN 0x0c
38 #define DA9052_BUCK_ILIM_MASK_ODD 0xc0
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
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;
58 struct da9052_regulator {
59 struct da9052 *da9052;
60 struct da9052_regulator_info *info;
61 struct regulator_dev *rdev;
64 static int verify_range(struct da9052_regulator_info *info,
65 int min_uV, int max_uV)
67 if (min_uV > info->max_uV || max_uV < info->min_uV)
68 return -EINVAL;
70 return 0;
73 static int da9052_regulator_enable(struct regulator_dev *rdev)
75 struct da9052_regulator *regulator = rdev_get_drvdata(rdev);
76 struct da9052_regulator_info *info = regulator->info;
77 int offset = rdev_get_id(rdev);
79 return da9052_reg_update(regulator->da9052,
80 DA9052_BUCKCORE_REG + offset,
81 1 << info->en_bit, 1 << info->en_bit);
84 static int da9052_regulator_disable(struct regulator_dev *rdev)
86 struct da9052_regulator *regulator = rdev_get_drvdata(rdev);
87 struct da9052_regulator_info *info = regulator->info;
88 int offset = rdev_get_id(rdev);
90 return da9052_reg_update(regulator->da9052,
91 DA9052_BUCKCORE_REG + offset,
92 1 << info->en_bit, 0);
95 static int da9052_regulator_is_enabled(struct regulator_dev *rdev)
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;
102 ret = da9052_reg_read(regulator->da9052, DA9052_BUCKCORE_REG + offset);
103 if (ret < 0)
104 return ret;
106 return ret & (1 << info->en_bit);
109 static int da9052_dcdc_get_current_limit(struct regulator_dev *rdev)
111 struct da9052_regulator *regulator = rdev_get_drvdata(rdev);
112 int offset = rdev_get_id(rdev);
113 int ret, row = 2;
115 ret = da9052_reg_read(regulator->da9052, DA9052_BUCKA_REG + offset/2);
116 if (ret < 0)
117 return ret;
119 /* Determine the even or odd position of the buck current limit
120 * register field
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;
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;
133 return da9052_current_limits[row][ret];
136 static int da9052_dcdc_set_current_limit(struct regulator_dev *rdev, int min_uA,
137 int max_uA)
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;
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;
150 if (min_uA > da9052_current_limits[row][DA9052_MAX_UA] ||
151 max_uA < da9052_current_limits[row][DA9052_MIN_UA])
152 return -EINVAL;
154 for (i = 0; i < DA9052_CURRENT_RANGE; i++) {
155 if (min_uA <= da9052_current_limits[row][i]) {
156 reg_val = i;
157 break;
161 /* Determine the even or odd position of the buck current limit
162 * register field
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);
176 static int da9052_list_buckperi_voltage(struct regulator_dev *rdev,
177 unsigned int selector)
179 struct da9052_regulator *regulator = rdev_get_drvdata(rdev);
180 struct da9052_regulator_info *info = regulator->info;
181 int volt_uV;
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;
192 if (volt_uV > info->max_uV)
193 return -EINVAL;
195 return volt_uV;
198 static int da9052_list_voltage(struct regulator_dev *rdev,
199 unsigned int selector)
201 struct da9052_regulator *regulator = rdev_get_drvdata(rdev);
202 struct da9052_regulator_info *info = regulator->info;
203 int volt_uV;
205 volt_uV = info->min_uV + info->step_uV * selector;
207 if (volt_uV > info->max_uV)
208 return -EINVAL;
210 return volt_uV;
213 static int da9052_regulator_set_voltage_int(struct regulator_dev *rdev,
214 int min_uV, int max_uV,
215 unsigned int *selector)
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;
222 ret = verify_range(info, min_uV, max_uV);
223 if (ret < 0)
224 return ret;
226 if (min_uV < info->min_uV)
227 min_uV = info->min_uV;
229 *selector = DIV_ROUND_UP(min_uV - info->min_uV, info->step_uV);
231 ret = da9052_list_voltage(rdev, *selector);
232 if (ret < 0)
233 return ret;
235 return da9052_reg_update(regulator->da9052,
236 DA9052_BUCKCORE_REG + offset,
237 (1 << info->volt_shift) - 1, *selector);
240 static int da9052_set_ldo_voltage(struct regulator_dev *rdev,
241 int min_uV, int max_uV,
242 unsigned int *selector)
244 return da9052_regulator_set_voltage_int(rdev, min_uV, max_uV, selector);
247 static int da9052_set_ldo5_6_voltage(struct regulator_dev *rdev,
248 int min_uV, int max_uV,
249 unsigned int *selector)
251 struct da9052_regulator *regulator = rdev_get_drvdata(rdev);
252 struct da9052_regulator_info *info = regulator->info;
253 int ret;
255 ret = da9052_regulator_set_voltage_int(rdev, min_uV, max_uV, selector);
256 if (ret < 0)
257 return ret;
259 /* Some LDOs are DVC controlled which requires enabling of
260 * the LDO activate bit to implment the changes on the
261 * LDO output.
263 return da9052_reg_update(regulator->da9052, DA9052_SUPPLY_REG,
264 info->activate_bit, info->activate_bit);
267 static int da9052_set_dcdc_voltage(struct regulator_dev *rdev,
268 int min_uV, int max_uV,
269 unsigned int *selector)
271 struct da9052_regulator *regulator = rdev_get_drvdata(rdev);
272 struct da9052_regulator_info *info = regulator->info;
273 int ret;
275 ret = da9052_regulator_set_voltage_int(rdev, min_uV, max_uV, selector);
276 if (ret < 0)
277 return ret;
279 /* Some DCDCs are DVC controlled which requires enabling of
280 * the DCDC activate bit to implment the changes on the
281 * DCDC output.
283 return da9052_reg_update(regulator->da9052, DA9052_SUPPLY_REG,
284 info->activate_bit, info->activate_bit);
287 static int da9052_get_regulator_voltage_sel(struct regulator_dev *rdev)
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;
294 ret = da9052_reg_read(regulator->da9052, DA9052_BUCKCORE_REG + offset);
295 if (ret < 0)
296 return ret;
298 ret &= ((1 << info->volt_shift) - 1);
300 return ret;
303 static int da9052_set_buckperi_voltage(struct regulator_dev *rdev, int min_uV,
304 int max_uV, unsigned int *selector)
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;
311 ret = verify_range(info, min_uV, max_uV);
312 if (ret < 0)
313 return ret;
315 if (min_uV < info->min_uV)
316 min_uV = info->min_uV;
318 if ((regulator->da9052->chip_id == DA9052) &&
319 (min_uV >= DA9052_CONST_3uV))
320 *selector = DA9052_BUCK_PERI_REG_MAP_UPTO_3uV +
321 DIV_ROUND_UP(min_uV - DA9052_CONST_3uV,
322 DA9052_BUCK_PERI_3uV_STEP);
323 else
324 *selector = DIV_ROUND_UP(min_uV - info->min_uV, info->step_uV);
326 ret = da9052_list_buckperi_voltage(rdev, *selector);
327 if (ret < 0)
328 return ret;
330 return da9052_reg_update(regulator->da9052,
331 DA9052_BUCKCORE_REG + offset,
332 (1 << info->volt_shift) - 1, *selector);
335 static int da9052_get_buckperi_voltage_sel(struct regulator_dev *rdev)
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;
342 ret = da9052_reg_read(regulator->da9052, DA9052_BUCKCORE_REG + offset);
343 if (ret < 0)
344 return ret;
346 ret &= ((1 << info->volt_shift) - 1);
348 return ret;
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,
356 .get_current_limit = da9052_dcdc_get_current_limit,
357 .set_current_limit = da9052_dcdc_set_current_limit,
359 .is_enabled = da9052_regulator_is_enabled,
360 .enable = da9052_regulator_enable,
361 .disable = da9052_regulator_disable,
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,
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,
376 static struct regulator_ops da9052_ldo5_6_ops = {
377 .set_voltage = da9052_set_ldo5_6_voltage,
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,
386 static struct regulator_ops da9052_ldo_ops = {
387 .set_voltage = da9052_set_ldo_voltage,
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,
396 #define DA9052_LDO5_6(_id, step, min, max, sbits, ebits, abits) \
398 .reg_desc = {\
399 .name = "LDO" #_id,\
400 .ops = &da9052_ldo5_6_ops,\
401 .type = REGULATOR_VOLTAGE,\
402 .id = _id,\
403 .n_voltages = (max - min) / step + 1, \
404 .owner = THIS_MODULE,\
406 .min_uV = (min) * 1000,\
407 .max_uV = (max) * 1000,\
408 .step_uV = (step) * 1000,\
409 .volt_shift = (sbits),\
410 .en_bit = (ebits),\
411 .activate_bit = (abits),\
414 #define DA9052_LDO(_id, step, min, max, sbits, ebits, abits) \
416 .reg_desc = {\
417 .name = "LDO" #_id,\
418 .ops = &da9052_ldo_ops,\
419 .type = REGULATOR_VOLTAGE,\
420 .id = _id,\
421 .n_voltages = (max - min) / step + 1, \
422 .owner = THIS_MODULE,\
424 .min_uV = (min) * 1000,\
425 .max_uV = (max) * 1000,\
426 .step_uV = (step) * 1000,\
427 .volt_shift = (sbits),\
428 .en_bit = (ebits),\
429 .activate_bit = (abits),\
432 #define DA9052_DCDC(_id, step, min, max, sbits, ebits, abits) \
434 .reg_desc = {\
435 .name = "BUCK" #_id,\
436 .ops = &da9052_dcdc_ops,\
437 .type = REGULATOR_VOLTAGE,\
438 .id = _id,\
439 .n_voltages = (max - min) / step + 1, \
440 .owner = THIS_MODULE,\
442 .min_uV = (min) * 1000,\
443 .max_uV = (max) * 1000,\
444 .step_uV = (step) * 1000,\
445 .volt_shift = (sbits),\
446 .en_bit = (ebits),\
447 .activate_bit = (abits),\
450 #define DA9052_BUCKPERI(_id, step, min, max, sbits, ebits, abits) \
452 .reg_desc = {\
453 .name = "BUCK" #_id,\
454 .ops = &da9052_buckperi_ops,\
455 .type = REGULATOR_VOLTAGE,\
456 .id = _id,\
457 .n_voltages = (max - min) / step + 1, \
458 .owner = THIS_MODULE,\
460 .min_uV = (min) * 1000,\
461 .max_uV = (max) * 1000,\
462 .step_uV = (step) * 1000,\
463 .volt_shift = (sbits),\
464 .en_bit = (ebits),\
465 .activate_bit = (abits),\
468 static struct da9052_regulator_info da9052_regulator_info[] = {
469 /* Buck1 - 4 */
470 DA9052_DCDC(0, 25, 500, 2075, 6, 6, DA9052_SUPPLY_VBCOREGO),
471 DA9052_DCDC(1, 25, 500, 2075, 6, 6, DA9052_SUPPLY_VBPROGO),
472 DA9052_DCDC(2, 25, 925, 2500, 6, 6, DA9052_SUPPLY_VBMEMGO),
473 DA9052_BUCKPERI(3, 50, 1800, 3600, 5, 6, 0),
474 /* LD01 - LDO10 */
475 DA9052_LDO(4, 50, 600, 1800, 5, 6, 0),
476 DA9052_LDO5_6(5, 25, 600, 1800, 6, 6, DA9052_SUPPLY_VLDO2GO),
477 DA9052_LDO5_6(6, 25, 1725, 3300, 6, 6, DA9052_SUPPLY_VLDO3GO),
478 DA9052_LDO(7, 25, 1725, 3300, 6, 6, 0),
479 DA9052_LDO(8, 50, 1200, 3600, 6, 6, 0),
480 DA9052_LDO(9, 50, 1200, 3600, 6, 6, 0),
481 DA9052_LDO(10, 50, 1200, 3600, 6, 6, 0),
482 DA9052_LDO(11, 50, 1200, 3600, 6, 6, 0),
483 DA9052_LDO(12, 50, 1250, 3650, 6, 6, 0),
484 DA9052_LDO(13, 50, 1200, 3600, 6, 6, 0),
487 static struct da9052_regulator_info da9053_regulator_info[] = {
488 /* Buck1 - 4 */
489 DA9052_DCDC(0, 25, 500, 2075, 6, 6, DA9052_SUPPLY_VBCOREGO),
490 DA9052_DCDC(1, 25, 500, 2075, 6, 6, DA9052_SUPPLY_VBPROGO),
491 DA9052_DCDC(2, 25, 925, 2500, 6, 6, DA9052_SUPPLY_VBMEMGO),
492 DA9052_BUCKPERI(3, 25, 925, 2500, 6, 6, 0),
493 /* LD01 - LDO10 */
494 DA9052_LDO(4, 50, 600, 1800, 5, 6, 0),
495 DA9052_LDO5_6(5, 25, 600, 1800, 6, 6, DA9052_SUPPLY_VLDO2GO),
496 DA9052_LDO5_6(6, 25, 1725, 3300, 6, 6, DA9052_SUPPLY_VLDO3GO),
497 DA9052_LDO(7, 25, 1725, 3300, 6, 6, 0),
498 DA9052_LDO(8, 50, 1200, 3600, 6, 6, 0),
499 DA9052_LDO(9, 50, 1200, 3600, 6, 6, 0),
500 DA9052_LDO(10, 50, 1200, 3600, 6, 6, 0),
501 DA9052_LDO(11, 50, 1200, 3600, 6, 6, 0),
502 DA9052_LDO(12, 50, 1250, 3650, 6, 6, 0),
503 DA9052_LDO(13, 50, 1200, 3600, 6, 6, 0),
506 static inline struct da9052_regulator_info *find_regulator_info(u8 chip_id,
507 int id)
509 struct da9052_regulator_info *info;
510 int i;
512 switch (chip_id) {
513 case DA9052:
514 for (i = 0; i < ARRAY_SIZE(da9052_regulator_info); i++) {
515 info = &da9052_regulator_info[i];
516 if (info->reg_desc.id == id)
517 return info;
519 break;
520 case DA9053_AA:
521 case DA9053_BA:
522 case DA9053_BB:
523 for (i = 0; i < ARRAY_SIZE(da9053_regulator_info); i++) {
524 info = &da9053_regulator_info[i];
525 if (info->reg_desc.id == id)
526 return info;
528 break;
531 return NULL;
534 static int __devinit da9052_regulator_probe(struct platform_device *pdev)
536 struct da9052_regulator *regulator;
537 struct da9052 *da9052;
538 struct da9052_pdata *pdata;
539 int ret;
541 regulator = devm_kzalloc(&pdev->dev, sizeof(struct da9052_regulator),
542 GFP_KERNEL);
543 if (!regulator)
544 return -ENOMEM;
546 da9052 = dev_get_drvdata(pdev->dev.parent);
547 pdata = da9052->dev->platform_data;
548 regulator->da9052 = da9052;
550 regulator->info = find_regulator_info(regulator->da9052->chip_id,
551 pdev->id);
552 if (regulator->info == NULL) {
553 dev_err(&pdev->dev, "invalid regulator ID specified\n");
554 ret = -EINVAL;
555 goto err;
557 regulator->rdev = regulator_register(&regulator->info->reg_desc,
558 &pdev->dev,
559 pdata->regulators[pdev->id],
560 regulator, NULL);
561 if (IS_ERR(regulator->rdev)) {
562 dev_err(&pdev->dev, "failed to register regulator %s\n",
563 regulator->info->reg_desc.name);
564 ret = PTR_ERR(regulator->rdev);
565 goto err;
568 platform_set_drvdata(pdev, regulator);
570 return 0;
571 err:
572 devm_kfree(&pdev->dev, regulator);
573 return ret;
576 static int __devexit da9052_regulator_remove(struct platform_device *pdev)
578 struct da9052_regulator *regulator = platform_get_drvdata(pdev);
580 regulator_unregister(regulator->rdev);
581 devm_kfree(&pdev->dev, regulator);
583 return 0;
586 static struct platform_driver da9052_regulator_driver = {
587 .probe = da9052_regulator_probe,
588 .remove = __devexit_p(da9052_regulator_remove),
589 .driver = {
590 .name = "da9052-regulator",
591 .owner = THIS_MODULE,
595 static int __init da9052_regulator_init(void)
597 return platform_driver_register(&da9052_regulator_driver);
599 subsys_initcall(da9052_regulator_init);
601 static void __exit da9052_regulator_exit(void)
603 platform_driver_unregister(&da9052_regulator_driver);
605 module_exit(da9052_regulator_exit);
607 MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>");
608 MODULE_DESCRIPTION("Power Regulator driver for Dialog DA9052 PMIC");
609 MODULE_LICENSE("GPL");
610 MODULE_ALIAS("platform:da9052-regulator");