regulator: core: support of supply name through desc
[linux-2.6.git] / drivers / regulator / db8500-prcmu.c
1 /*
2  * Copyright (C) ST-Ericsson SA 2010
3  *
4  * License Terms: GNU General Public License v2
5  * Authors: Sundar Iyer <sundar.iyer@stericsson.com> for ST-Ericsson
6  *          Bengt Jonsson <bengt.g.jonsson@stericsson.com> for ST-Ericsson
7  *
8  * Power domain regulators on DB8500
9  */
10
11 #include <linux/kernel.h>
12 #include <linux/init.h>
13 #include <linux/err.h>
14 #include <linux/spinlock.h>
15 #include <linux/platform_device.h>
16 #include <linux/mfd/dbx500-prcmu.h>
17 #include <linux/regulator/driver.h>
18 #include <linux/regulator/machine.h>
19 #include <linux/regulator/db8500-prcmu.h>
20 #include <linux/module.h>
21 #include "dbx500-prcmu.h"
22
23 static int db8500_regulator_enable(struct regulator_dev *rdev)
24 {
25         struct dbx500_regulator_info *info = rdev_get_drvdata(rdev);
26
27         if (info == NULL)
28                 return -EINVAL;
29
30         dev_vdbg(rdev_get_dev(rdev), "regulator-%s-enable\n",
31                 info->desc.name);
32
33         if (!info->is_enabled) {
34                 info->is_enabled = true;
35                 if (!info->exclude_from_power_state)
36                         power_state_active_enable();
37         }
38
39         return 0;
40 }
41
42 static int db8500_regulator_disable(struct regulator_dev *rdev)
43 {
44         struct dbx500_regulator_info *info = rdev_get_drvdata(rdev);
45         int ret = 0;
46
47         if (info == NULL)
48                 return -EINVAL;
49
50         dev_vdbg(rdev_get_dev(rdev), "regulator-%s-disable\n",
51                 info->desc.name);
52
53         if (info->is_enabled) {
54                 info->is_enabled = false;
55                 if (!info->exclude_from_power_state)
56                         ret = power_state_active_disable();
57         }
58
59         return ret;
60 }
61
62 static int db8500_regulator_is_enabled(struct regulator_dev *rdev)
63 {
64         struct dbx500_regulator_info *info = rdev_get_drvdata(rdev);
65
66         if (info == NULL)
67                 return -EINVAL;
68
69         dev_vdbg(rdev_get_dev(rdev), "regulator-%s-is_enabled (is_enabled):"
70                 " %i\n", info->desc.name, info->is_enabled);
71
72         return info->is_enabled;
73 }
74
75 /* db8500 regulator operations */
76 static struct regulator_ops db8500_regulator_ops = {
77         .enable                 = db8500_regulator_enable,
78         .disable                = db8500_regulator_disable,
79         .is_enabled             = db8500_regulator_is_enabled,
80 };
81
82 /*
83  * EPOD control
84  */
85 static bool epod_on[NUM_EPOD_ID];
86 static bool epod_ramret[NUM_EPOD_ID];
87
88 static int enable_epod(u16 epod_id, bool ramret)
89 {
90         int ret;
91
92         if (ramret) {
93                 if (!epod_on[epod_id]) {
94                         ret = prcmu_set_epod(epod_id, EPOD_STATE_RAMRET);
95                         if (ret < 0)
96                                 return ret;
97                 }
98                 epod_ramret[epod_id] = true;
99         } else {
100                 ret = prcmu_set_epod(epod_id, EPOD_STATE_ON);
101                 if (ret < 0)
102                         return ret;
103                 epod_on[epod_id] = true;
104         }
105
106         return 0;
107 }
108
109 static int disable_epod(u16 epod_id, bool ramret)
110 {
111         int ret;
112
113         if (ramret) {
114                 if (!epod_on[epod_id]) {
115                         ret = prcmu_set_epod(epod_id, EPOD_STATE_OFF);
116                         if (ret < 0)
117                                 return ret;
118                 }
119                 epod_ramret[epod_id] = false;
120         } else {
121                 if (epod_ramret[epod_id]) {
122                         ret = prcmu_set_epod(epod_id, EPOD_STATE_RAMRET);
123                         if (ret < 0)
124                                 return ret;
125                 } else {
126                         ret = prcmu_set_epod(epod_id, EPOD_STATE_OFF);
127                         if (ret < 0)
128                                 return ret;
129                 }
130                 epod_on[epod_id] = false;
131         }
132
133         return 0;
134 }
135
136 /*
137  * Regulator switch
138  */
139 static int db8500_regulator_switch_enable(struct regulator_dev *rdev)
140 {
141         struct dbx500_regulator_info *info = rdev_get_drvdata(rdev);
142         int ret;
143
144         if (info == NULL)
145                 return -EINVAL;
146
147         dev_vdbg(rdev_get_dev(rdev), "regulator-switch-%s-enable\n",
148                 info->desc.name);
149
150         ret = enable_epod(info->epod_id, info->is_ramret);
151         if (ret < 0) {
152                 dev_err(rdev_get_dev(rdev),
153                         "regulator-switch-%s-enable: prcmu call failed\n",
154                         info->desc.name);
155                 goto out;
156         }
157
158         info->is_enabled = true;
159 out:
160         return ret;
161 }
162
163 static int db8500_regulator_switch_disable(struct regulator_dev *rdev)
164 {
165         struct dbx500_regulator_info *info = rdev_get_drvdata(rdev);
166         int ret;
167
168         if (info == NULL)
169                 return -EINVAL;
170
171         dev_vdbg(rdev_get_dev(rdev), "regulator-switch-%s-disable\n",
172                 info->desc.name);
173
174         ret = disable_epod(info->epod_id, info->is_ramret);
175         if (ret < 0) {
176                 dev_err(rdev_get_dev(rdev),
177                         "regulator_switch-%s-disable: prcmu call failed\n",
178                         info->desc.name);
179                 goto out;
180         }
181
182         info->is_enabled = 0;
183 out:
184         return ret;
185 }
186
187 static int db8500_regulator_switch_is_enabled(struct regulator_dev *rdev)
188 {
189         struct dbx500_regulator_info *info = rdev_get_drvdata(rdev);
190
191         if (info == NULL)
192                 return -EINVAL;
193
194         dev_vdbg(rdev_get_dev(rdev),
195                 "regulator-switch-%s-is_enabled (is_enabled): %i\n",
196                 info->desc.name, info->is_enabled);
197
198         return info->is_enabled;
199 }
200
201 static struct regulator_ops db8500_regulator_switch_ops = {
202         .enable                 = db8500_regulator_switch_enable,
203         .disable                = db8500_regulator_switch_disable,
204         .is_enabled             = db8500_regulator_switch_is_enabled,
205 };
206
207 /*
208  * Regulator information
209  */
210 static struct dbx500_regulator_info
211 dbx500_regulator_info[DB8500_NUM_REGULATORS] = {
212         [DB8500_REGULATOR_VAPE] = {
213                 .desc = {
214                         .name   = "db8500-vape",
215                         .id     = DB8500_REGULATOR_VAPE,
216                         .ops    = &db8500_regulator_ops,
217                         .type   = REGULATOR_VOLTAGE,
218                         .owner  = THIS_MODULE,
219                 },
220         },
221         [DB8500_REGULATOR_VARM] = {
222                 .desc = {
223                         .name   = "db8500-varm",
224                         .id     = DB8500_REGULATOR_VARM,
225                         .ops    = &db8500_regulator_ops,
226                         .type   = REGULATOR_VOLTAGE,
227                         .owner  = THIS_MODULE,
228                 },
229         },
230         [DB8500_REGULATOR_VMODEM] = {
231                 .desc = {
232                         .name   = "db8500-vmodem",
233                         .id     = DB8500_REGULATOR_VMODEM,
234                         .ops    = &db8500_regulator_ops,
235                         .type   = REGULATOR_VOLTAGE,
236                         .owner  = THIS_MODULE,
237                 },
238         },
239         [DB8500_REGULATOR_VPLL] = {
240                 .desc = {
241                         .name   = "db8500-vpll",
242                         .id     = DB8500_REGULATOR_VPLL,
243                         .ops    = &db8500_regulator_ops,
244                         .type   = REGULATOR_VOLTAGE,
245                         .owner  = THIS_MODULE,
246                 },
247         },
248         [DB8500_REGULATOR_VSMPS1] = {
249                 .desc = {
250                         .name   = "db8500-vsmps1",
251                         .id     = DB8500_REGULATOR_VSMPS1,
252                         .ops    = &db8500_regulator_ops,
253                         .type   = REGULATOR_VOLTAGE,
254                         .owner  = THIS_MODULE,
255                 },
256         },
257         [DB8500_REGULATOR_VSMPS2] = {
258                 .desc = {
259                         .name   = "db8500-vsmps2",
260                         .id     = DB8500_REGULATOR_VSMPS2,
261                         .ops    = &db8500_regulator_ops,
262                         .type   = REGULATOR_VOLTAGE,
263                         .owner  = THIS_MODULE,
264                 },
265                 .exclude_from_power_state = true,
266         },
267         [DB8500_REGULATOR_VSMPS3] = {
268                 .desc = {
269                         .name   = "db8500-vsmps3",
270                         .id     = DB8500_REGULATOR_VSMPS3,
271                         .ops    = &db8500_regulator_ops,
272                         .type   = REGULATOR_VOLTAGE,
273                         .owner  = THIS_MODULE,
274                 },
275         },
276         [DB8500_REGULATOR_VRF1] = {
277                 .desc = {
278                         .name   = "db8500-vrf1",
279                         .id     = DB8500_REGULATOR_VRF1,
280                         .ops    = &db8500_regulator_ops,
281                         .type   = REGULATOR_VOLTAGE,
282                         .owner  = THIS_MODULE,
283                 },
284         },
285         [DB8500_REGULATOR_SWITCH_SVAMMDSP] = {
286                 .desc = {
287                         .name   = "db8500-sva-mmdsp",
288                         .id     = DB8500_REGULATOR_SWITCH_SVAMMDSP,
289                         .ops    = &db8500_regulator_switch_ops,
290                         .type   = REGULATOR_VOLTAGE,
291                         .owner  = THIS_MODULE,
292                 },
293                 .epod_id = EPOD_ID_SVAMMDSP,
294         },
295         [DB8500_REGULATOR_SWITCH_SVAMMDSPRET] = {
296                 .desc = {
297                         .name   = "db8500-sva-mmdsp-ret",
298                         .id     = DB8500_REGULATOR_SWITCH_SVAMMDSPRET,
299                         .ops    = &db8500_regulator_switch_ops,
300                         .type   = REGULATOR_VOLTAGE,
301                         .owner  = THIS_MODULE,
302                 },
303                 .epod_id = EPOD_ID_SVAMMDSP,
304                 .is_ramret = true,
305         },
306         [DB8500_REGULATOR_SWITCH_SVAPIPE] = {
307                 .desc = {
308                         .name   = "db8500-sva-pipe",
309                         .id     = DB8500_REGULATOR_SWITCH_SVAPIPE,
310                         .ops    = &db8500_regulator_switch_ops,
311                         .type   = REGULATOR_VOLTAGE,
312                         .owner  = THIS_MODULE,
313                 },
314                 .epod_id = EPOD_ID_SVAPIPE,
315         },
316         [DB8500_REGULATOR_SWITCH_SIAMMDSP] = {
317                 .desc = {
318                         .name   = "db8500-sia-mmdsp",
319                         .id     = DB8500_REGULATOR_SWITCH_SIAMMDSP,
320                         .ops    = &db8500_regulator_switch_ops,
321                         .type   = REGULATOR_VOLTAGE,
322                         .owner  = THIS_MODULE,
323                 },
324                 .epod_id = EPOD_ID_SIAMMDSP,
325         },
326         [DB8500_REGULATOR_SWITCH_SIAMMDSPRET] = {
327                 .desc = {
328                         .name   = "db8500-sia-mmdsp-ret",
329                         .id     = DB8500_REGULATOR_SWITCH_SIAMMDSPRET,
330                         .ops    = &db8500_regulator_switch_ops,
331                         .type   = REGULATOR_VOLTAGE,
332                         .owner  = THIS_MODULE,
333                 },
334                 .epod_id = EPOD_ID_SIAMMDSP,
335                 .is_ramret = true,
336         },
337         [DB8500_REGULATOR_SWITCH_SIAPIPE] = {
338                 .desc = {
339                         .name   = "db8500-sia-pipe",
340                         .id     = DB8500_REGULATOR_SWITCH_SIAPIPE,
341                         .ops    = &db8500_regulator_switch_ops,
342                         .type   = REGULATOR_VOLTAGE,
343                         .owner  = THIS_MODULE,
344                 },
345                 .epod_id = EPOD_ID_SIAPIPE,
346         },
347         [DB8500_REGULATOR_SWITCH_SGA] = {
348                 .desc = {
349                         .name   = "db8500-sga",
350                         .id     = DB8500_REGULATOR_SWITCH_SGA,
351                         .ops    = &db8500_regulator_switch_ops,
352                         .type   = REGULATOR_VOLTAGE,
353                         .owner  = THIS_MODULE,
354                 },
355                 .epod_id = EPOD_ID_SGA,
356         },
357         [DB8500_REGULATOR_SWITCH_B2R2_MCDE] = {
358                 .desc = {
359                         .name   = "db8500-b2r2-mcde",
360                         .id     = DB8500_REGULATOR_SWITCH_B2R2_MCDE,
361                         .ops    = &db8500_regulator_switch_ops,
362                         .type   = REGULATOR_VOLTAGE,
363                         .owner  = THIS_MODULE,
364                 },
365                 .epod_id = EPOD_ID_B2R2_MCDE,
366         },
367         [DB8500_REGULATOR_SWITCH_ESRAM12] = {
368                 .desc = {
369                         .name   = "db8500-esram12",
370                         .id     = DB8500_REGULATOR_SWITCH_ESRAM12,
371                         .ops    = &db8500_regulator_switch_ops,
372                         .type   = REGULATOR_VOLTAGE,
373                         .owner  = THIS_MODULE,
374                 },
375                 .epod_id        = EPOD_ID_ESRAM12,
376                 .is_enabled     = true,
377         },
378         [DB8500_REGULATOR_SWITCH_ESRAM12RET] = {
379                 .desc = {
380                         .name   = "db8500-esram12-ret",
381                         .id     = DB8500_REGULATOR_SWITCH_ESRAM12RET,
382                         .ops    = &db8500_regulator_switch_ops,
383                         .type   = REGULATOR_VOLTAGE,
384                         .owner  = THIS_MODULE,
385                 },
386                 .epod_id = EPOD_ID_ESRAM12,
387                 .is_ramret = true,
388         },
389         [DB8500_REGULATOR_SWITCH_ESRAM34] = {
390                 .desc = {
391                         .name   = "db8500-esram34",
392                         .id     = DB8500_REGULATOR_SWITCH_ESRAM34,
393                         .ops    = &db8500_regulator_switch_ops,
394                         .type   = REGULATOR_VOLTAGE,
395                         .owner  = THIS_MODULE,
396                 },
397                 .epod_id        = EPOD_ID_ESRAM34,
398                 .is_enabled     = true,
399         },
400         [DB8500_REGULATOR_SWITCH_ESRAM34RET] = {
401                 .desc = {
402                         .name   = "db8500-esram34-ret",
403                         .id     = DB8500_REGULATOR_SWITCH_ESRAM34RET,
404                         .ops    = &db8500_regulator_switch_ops,
405                         .type   = REGULATOR_VOLTAGE,
406                         .owner  = THIS_MODULE,
407                 },
408                 .epod_id = EPOD_ID_ESRAM34,
409                 .is_ramret = true,
410         },
411 };
412
413 static int __devinit db8500_regulator_probe(struct platform_device *pdev)
414 {
415         struct regulator_init_data *db8500_init_data =
416                                         dev_get_platdata(&pdev->dev);
417         int i, err;
418
419         /* register all regulators */
420         for (i = 0; i < ARRAY_SIZE(dbx500_regulator_info); i++) {
421                 struct dbx500_regulator_info *info;
422                 struct regulator_init_data *init_data = &db8500_init_data[i];
423
424                 /* assign per-regulator data */
425                 info = &dbx500_regulator_info[i];
426                 info->dev = &pdev->dev;
427
428                 /* register with the regulator framework */
429                 info->rdev = regulator_register(&info->desc, &pdev->dev,
430                                 init_data, info, NULL);
431                 if (IS_ERR(info->rdev)) {
432                         err = PTR_ERR(info->rdev);
433                         dev_err(&pdev->dev, "failed to register %s: err %i\n",
434                                 info->desc.name, err);
435
436                         /* if failing, unregister all earlier regulators */
437                         while (--i >= 0) {
438                                 info = &dbx500_regulator_info[i];
439                                 regulator_unregister(info->rdev);
440                         }
441                         return err;
442                 }
443
444                 dev_dbg(rdev_get_dev(info->rdev),
445                         "regulator-%s-probed\n", info->desc.name);
446         }
447         err = ux500_regulator_debug_init(pdev,
448                                          dbx500_regulator_info,
449                                          ARRAY_SIZE(dbx500_regulator_info));
450
451         return err;
452 }
453
454 static int __exit db8500_regulator_remove(struct platform_device *pdev)
455 {
456         int i;
457
458         ux500_regulator_debug_exit();
459
460         for (i = 0; i < ARRAY_SIZE(dbx500_regulator_info); i++) {
461                 struct dbx500_regulator_info *info;
462                 info = &dbx500_regulator_info[i];
463
464                 dev_vdbg(rdev_get_dev(info->rdev),
465                         "regulator-%s-remove\n", info->desc.name);
466
467                 regulator_unregister(info->rdev);
468         }
469
470         return 0;
471 }
472
473 static struct platform_driver db8500_regulator_driver = {
474         .driver = {
475                 .name = "db8500-prcmu-regulators",
476                 .owner = THIS_MODULE,
477         },
478         .probe = db8500_regulator_probe,
479         .remove = __exit_p(db8500_regulator_remove),
480 };
481
482 static int __init db8500_regulator_init(void)
483 {
484         return platform_driver_register(&db8500_regulator_driver);
485 }
486
487 static void __exit db8500_regulator_exit(void)
488 {
489         platform_driver_unregister(&db8500_regulator_driver);
490 }
491
492 arch_initcall(db8500_regulator_init);
493 module_exit(db8500_regulator_exit);
494
495 MODULE_AUTHOR("STMicroelectronics/ST-Ericsson");
496 MODULE_DESCRIPTION("DB8500 regulator driver");
497 MODULE_LICENSE("GPL v2");