Merge branch 'modsplit-Oct31_2011' of git://git.kernel.org/pub/scm/linux/kernel/git...
[pandora-kernel.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
22 /*
23  * power state reference count
24  */
25 static int power_state_active_cnt; /* will initialize to zero */
26 static DEFINE_SPINLOCK(power_state_active_lock);
27
28 static void power_state_active_enable(void)
29 {
30         unsigned long flags;
31
32         spin_lock_irqsave(&power_state_active_lock, flags);
33         power_state_active_cnt++;
34         spin_unlock_irqrestore(&power_state_active_lock, flags);
35 }
36
37 static int power_state_active_disable(void)
38 {
39         int ret = 0;
40         unsigned long flags;
41
42         spin_lock_irqsave(&power_state_active_lock, flags);
43         if (power_state_active_cnt <= 0) {
44                 pr_err("power state: unbalanced enable/disable calls\n");
45                 ret = -EINVAL;
46                 goto out;
47         }
48
49         power_state_active_cnt--;
50 out:
51         spin_unlock_irqrestore(&power_state_active_lock, flags);
52         return ret;
53 }
54
55 /*
56  * Exported interface for CPUIdle only. This function is called when interrupts
57  * are turned off. Hence, no locking.
58  */
59 int power_state_active_is_enabled(void)
60 {
61         return (power_state_active_cnt > 0);
62 }
63
64 /**
65  * struct db8500_regulator_info - db8500 regulator information
66  * @dev: device pointer
67  * @desc: regulator description
68  * @rdev: regulator device pointer
69  * @is_enabled: status of the regulator
70  * @epod_id: id for EPOD (power domain)
71  * @is_ramret: RAM retention switch for EPOD (power domain)
72  * @operating_point: operating point (only for vape, to be removed)
73  *
74  */
75 struct db8500_regulator_info {
76         struct device *dev;
77         struct regulator_desc desc;
78         struct regulator_dev *rdev;
79         bool is_enabled;
80         u16 epod_id;
81         bool is_ramret;
82         bool exclude_from_power_state;
83         unsigned int operating_point;
84 };
85
86 static int db8500_regulator_enable(struct regulator_dev *rdev)
87 {
88         struct db8500_regulator_info *info = rdev_get_drvdata(rdev);
89
90         if (info == NULL)
91                 return -EINVAL;
92
93         dev_vdbg(rdev_get_dev(rdev), "regulator-%s-enable\n",
94                 info->desc.name);
95
96         info->is_enabled = true;
97         if (!info->exclude_from_power_state)
98                 power_state_active_enable();
99
100         return 0;
101 }
102
103 static int db8500_regulator_disable(struct regulator_dev *rdev)
104 {
105         struct db8500_regulator_info *info = rdev_get_drvdata(rdev);
106         int ret = 0;
107
108         if (info == NULL)
109                 return -EINVAL;
110
111         dev_vdbg(rdev_get_dev(rdev), "regulator-%s-disable\n",
112                 info->desc.name);
113
114         info->is_enabled = false;
115         if (!info->exclude_from_power_state)
116                 ret = power_state_active_disable();
117
118         return ret;
119 }
120
121 static int db8500_regulator_is_enabled(struct regulator_dev *rdev)
122 {
123         struct db8500_regulator_info *info = rdev_get_drvdata(rdev);
124
125         if (info == NULL)
126                 return -EINVAL;
127
128         dev_vdbg(rdev_get_dev(rdev), "regulator-%s-is_enabled (is_enabled):"
129                 " %i\n", info->desc.name, info->is_enabled);
130
131         return info->is_enabled;
132 }
133
134 /* db8500 regulator operations */
135 static struct regulator_ops db8500_regulator_ops = {
136         .enable                 = db8500_regulator_enable,
137         .disable                = db8500_regulator_disable,
138         .is_enabled             = db8500_regulator_is_enabled,
139 };
140
141 /*
142  * EPOD control
143  */
144 static bool epod_on[NUM_EPOD_ID];
145 static bool epod_ramret[NUM_EPOD_ID];
146
147 static int enable_epod(u16 epod_id, bool ramret)
148 {
149         int ret;
150
151         if (ramret) {
152                 if (!epod_on[epod_id]) {
153                         ret = prcmu_set_epod(epod_id, EPOD_STATE_RAMRET);
154                         if (ret < 0)
155                                 return ret;
156                 }
157                 epod_ramret[epod_id] = true;
158         } else {
159                 ret = prcmu_set_epod(epod_id, EPOD_STATE_ON);
160                 if (ret < 0)
161                         return ret;
162                 epod_on[epod_id] = true;
163         }
164
165         return 0;
166 }
167
168 static int disable_epod(u16 epod_id, bool ramret)
169 {
170         int ret;
171
172         if (ramret) {
173                 if (!epod_on[epod_id]) {
174                         ret = prcmu_set_epod(epod_id, EPOD_STATE_OFF);
175                         if (ret < 0)
176                                 return ret;
177                 }
178                 epod_ramret[epod_id] = false;
179         } else {
180                 if (epod_ramret[epod_id]) {
181                         ret = prcmu_set_epod(epod_id, EPOD_STATE_RAMRET);
182                         if (ret < 0)
183                                 return ret;
184                 } else {
185                         ret = prcmu_set_epod(epod_id, EPOD_STATE_OFF);
186                         if (ret < 0)
187                                 return ret;
188                 }
189                 epod_on[epod_id] = false;
190         }
191
192         return 0;
193 }
194
195 /*
196  * Regulator switch
197  */
198 static int db8500_regulator_switch_enable(struct regulator_dev *rdev)
199 {
200         struct db8500_regulator_info *info = rdev_get_drvdata(rdev);
201         int ret;
202
203         if (info == NULL)
204                 return -EINVAL;
205
206         dev_vdbg(rdev_get_dev(rdev), "regulator-switch-%s-enable\n",
207                 info->desc.name);
208
209         ret = enable_epod(info->epod_id, info->is_ramret);
210         if (ret < 0) {
211                 dev_err(rdev_get_dev(rdev),
212                         "regulator-switch-%s-enable: prcmu call failed\n",
213                         info->desc.name);
214                 goto out;
215         }
216
217         info->is_enabled = true;
218 out:
219         return ret;
220 }
221
222 static int db8500_regulator_switch_disable(struct regulator_dev *rdev)
223 {
224         struct db8500_regulator_info *info = rdev_get_drvdata(rdev);
225         int ret;
226
227         if (info == NULL)
228                 return -EINVAL;
229
230         dev_vdbg(rdev_get_dev(rdev), "regulator-switch-%s-disable\n",
231                 info->desc.name);
232
233         ret = disable_epod(info->epod_id, info->is_ramret);
234         if (ret < 0) {
235                 dev_err(rdev_get_dev(rdev),
236                         "regulator_switch-%s-disable: prcmu call failed\n",
237                         info->desc.name);
238                 goto out;
239         }
240
241         info->is_enabled = 0;
242 out:
243         return ret;
244 }
245
246 static int db8500_regulator_switch_is_enabled(struct regulator_dev *rdev)
247 {
248         struct db8500_regulator_info *info = rdev_get_drvdata(rdev);
249
250         if (info == NULL)
251                 return -EINVAL;
252
253         dev_vdbg(rdev_get_dev(rdev),
254                 "regulator-switch-%s-is_enabled (is_enabled): %i\n",
255                 info->desc.name, info->is_enabled);
256
257         return info->is_enabled;
258 }
259
260 static struct regulator_ops db8500_regulator_switch_ops = {
261         .enable                 = db8500_regulator_switch_enable,
262         .disable                = db8500_regulator_switch_disable,
263         .is_enabled             = db8500_regulator_switch_is_enabled,
264 };
265
266 /*
267  * Regulator information
268  */
269 static struct db8500_regulator_info
270 db8500_regulator_info[DB8500_NUM_REGULATORS] = {
271         [DB8500_REGULATOR_VAPE] = {
272                 .desc = {
273                         .name   = "db8500-vape",
274                         .id     = DB8500_REGULATOR_VAPE,
275                         .ops    = &db8500_regulator_ops,
276                         .type   = REGULATOR_VOLTAGE,
277                         .owner  = THIS_MODULE,
278                 },
279         },
280         [DB8500_REGULATOR_VARM] = {
281                 .desc = {
282                         .name   = "db8500-varm",
283                         .id     = DB8500_REGULATOR_VARM,
284                         .ops    = &db8500_regulator_ops,
285                         .type   = REGULATOR_VOLTAGE,
286                         .owner  = THIS_MODULE,
287                 },
288         },
289         [DB8500_REGULATOR_VMODEM] = {
290                 .desc = {
291                         .name   = "db8500-vmodem",
292                         .id     = DB8500_REGULATOR_VMODEM,
293                         .ops    = &db8500_regulator_ops,
294                         .type   = REGULATOR_VOLTAGE,
295                         .owner  = THIS_MODULE,
296                 },
297         },
298         [DB8500_REGULATOR_VPLL] = {
299                 .desc = {
300                         .name   = "db8500-vpll",
301                         .id     = DB8500_REGULATOR_VPLL,
302                         .ops    = &db8500_regulator_ops,
303                         .type   = REGULATOR_VOLTAGE,
304                         .owner  = THIS_MODULE,
305                 },
306         },
307         [DB8500_REGULATOR_VSMPS1] = {
308                 .desc = {
309                         .name   = "db8500-vsmps1",
310                         .id     = DB8500_REGULATOR_VSMPS1,
311                         .ops    = &db8500_regulator_ops,
312                         .type   = REGULATOR_VOLTAGE,
313                         .owner  = THIS_MODULE,
314                 },
315         },
316         [DB8500_REGULATOR_VSMPS2] = {
317                 .desc = {
318                         .name   = "db8500-vsmps2",
319                         .id     = DB8500_REGULATOR_VSMPS2,
320                         .ops    = &db8500_regulator_ops,
321                         .type   = REGULATOR_VOLTAGE,
322                         .owner  = THIS_MODULE,
323                 },
324                 .exclude_from_power_state = true,
325         },
326         [DB8500_REGULATOR_VSMPS3] = {
327                 .desc = {
328                         .name   = "db8500-vsmps3",
329                         .id     = DB8500_REGULATOR_VSMPS3,
330                         .ops    = &db8500_regulator_ops,
331                         .type   = REGULATOR_VOLTAGE,
332                         .owner  = THIS_MODULE,
333                 },
334         },
335         [DB8500_REGULATOR_VRF1] = {
336                 .desc = {
337                         .name   = "db8500-vrf1",
338                         .id     = DB8500_REGULATOR_VRF1,
339                         .ops    = &db8500_regulator_ops,
340                         .type   = REGULATOR_VOLTAGE,
341                         .owner  = THIS_MODULE,
342                 },
343         },
344         [DB8500_REGULATOR_SWITCH_SVAMMDSP] = {
345                 .desc = {
346                         .name   = "db8500-sva-mmdsp",
347                         .id     = DB8500_REGULATOR_SWITCH_SVAMMDSP,
348                         .ops    = &db8500_regulator_switch_ops,
349                         .type   = REGULATOR_VOLTAGE,
350                         .owner  = THIS_MODULE,
351                 },
352                 .epod_id = EPOD_ID_SVAMMDSP,
353         },
354         [DB8500_REGULATOR_SWITCH_SVAMMDSPRET] = {
355                 .desc = {
356                         .name   = "db8500-sva-mmdsp-ret",
357                         .id     = DB8500_REGULATOR_SWITCH_SVAMMDSPRET,
358                         .ops    = &db8500_regulator_switch_ops,
359                         .type   = REGULATOR_VOLTAGE,
360                         .owner  = THIS_MODULE,
361                 },
362                 .epod_id = EPOD_ID_SVAMMDSP,
363                 .is_ramret = true,
364         },
365         [DB8500_REGULATOR_SWITCH_SVAPIPE] = {
366                 .desc = {
367                         .name   = "db8500-sva-pipe",
368                         .id     = DB8500_REGULATOR_SWITCH_SVAPIPE,
369                         .ops    = &db8500_regulator_switch_ops,
370                         .type   = REGULATOR_VOLTAGE,
371                         .owner  = THIS_MODULE,
372                 },
373                 .epod_id = EPOD_ID_SVAPIPE,
374         },
375         [DB8500_REGULATOR_SWITCH_SIAMMDSP] = {
376                 .desc = {
377                         .name   = "db8500-sia-mmdsp",
378                         .id     = DB8500_REGULATOR_SWITCH_SIAMMDSP,
379                         .ops    = &db8500_regulator_switch_ops,
380                         .type   = REGULATOR_VOLTAGE,
381                         .owner  = THIS_MODULE,
382                 },
383                 .epod_id = EPOD_ID_SIAMMDSP,
384         },
385         [DB8500_REGULATOR_SWITCH_SIAMMDSPRET] = {
386                 .desc = {
387                         .name   = "db8500-sia-mmdsp-ret",
388                         .id     = DB8500_REGULATOR_SWITCH_SIAMMDSPRET,
389                         .ops    = &db8500_regulator_switch_ops,
390                         .type   = REGULATOR_VOLTAGE,
391                         .owner  = THIS_MODULE,
392                 },
393                 .epod_id = EPOD_ID_SIAMMDSP,
394                 .is_ramret = true,
395         },
396         [DB8500_REGULATOR_SWITCH_SIAPIPE] = {
397                 .desc = {
398                         .name   = "db8500-sia-pipe",
399                         .id     = DB8500_REGULATOR_SWITCH_SIAPIPE,
400                         .ops    = &db8500_regulator_switch_ops,
401                         .type   = REGULATOR_VOLTAGE,
402                         .owner  = THIS_MODULE,
403                 },
404                 .epod_id = EPOD_ID_SIAPIPE,
405         },
406         [DB8500_REGULATOR_SWITCH_SGA] = {
407                 .desc = {
408                         .name   = "db8500-sga",
409                         .id     = DB8500_REGULATOR_SWITCH_SGA,
410                         .ops    = &db8500_regulator_switch_ops,
411                         .type   = REGULATOR_VOLTAGE,
412                         .owner  = THIS_MODULE,
413                 },
414                 .epod_id = EPOD_ID_SGA,
415         },
416         [DB8500_REGULATOR_SWITCH_B2R2_MCDE] = {
417                 .desc = {
418                         .name   = "db8500-b2r2-mcde",
419                         .id     = DB8500_REGULATOR_SWITCH_B2R2_MCDE,
420                         .ops    = &db8500_regulator_switch_ops,
421                         .type   = REGULATOR_VOLTAGE,
422                         .owner  = THIS_MODULE,
423                 },
424                 .epod_id = EPOD_ID_B2R2_MCDE,
425         },
426         [DB8500_REGULATOR_SWITCH_ESRAM12] = {
427                 .desc = {
428                         .name   = "db8500-esram12",
429                         .id     = DB8500_REGULATOR_SWITCH_ESRAM12,
430                         .ops    = &db8500_regulator_switch_ops,
431                         .type   = REGULATOR_VOLTAGE,
432                         .owner  = THIS_MODULE,
433                 },
434                 .epod_id        = EPOD_ID_ESRAM12,
435                 .is_enabled     = true,
436         },
437         [DB8500_REGULATOR_SWITCH_ESRAM12RET] = {
438                 .desc = {
439                         .name   = "db8500-esram12-ret",
440                         .id     = DB8500_REGULATOR_SWITCH_ESRAM12RET,
441                         .ops    = &db8500_regulator_switch_ops,
442                         .type   = REGULATOR_VOLTAGE,
443                         .owner  = THIS_MODULE,
444                 },
445                 .epod_id = EPOD_ID_ESRAM12,
446                 .is_ramret = true,
447         },
448         [DB8500_REGULATOR_SWITCH_ESRAM34] = {
449                 .desc = {
450                         .name   = "db8500-esram34",
451                         .id     = DB8500_REGULATOR_SWITCH_ESRAM34,
452                         .ops    = &db8500_regulator_switch_ops,
453                         .type   = REGULATOR_VOLTAGE,
454                         .owner  = THIS_MODULE,
455                 },
456                 .epod_id        = EPOD_ID_ESRAM34,
457                 .is_enabled     = true,
458         },
459         [DB8500_REGULATOR_SWITCH_ESRAM34RET] = {
460                 .desc = {
461                         .name   = "db8500-esram34-ret",
462                         .id     = DB8500_REGULATOR_SWITCH_ESRAM34RET,
463                         .ops    = &db8500_regulator_switch_ops,
464                         .type   = REGULATOR_VOLTAGE,
465                         .owner  = THIS_MODULE,
466                 },
467                 .epod_id = EPOD_ID_ESRAM34,
468                 .is_ramret = true,
469         },
470 };
471
472 static int __devinit db8500_regulator_probe(struct platform_device *pdev)
473 {
474         struct regulator_init_data *db8500_init_data =
475                                         dev_get_platdata(&pdev->dev);
476         int i, err;
477
478         /* register all regulators */
479         for (i = 0; i < ARRAY_SIZE(db8500_regulator_info); i++) {
480                 struct db8500_regulator_info *info;
481                 struct regulator_init_data *init_data = &db8500_init_data[i];
482
483                 /* assign per-regulator data */
484                 info = &db8500_regulator_info[i];
485                 info->dev = &pdev->dev;
486
487                 /* register with the regulator framework */
488                 info->rdev = regulator_register(&info->desc, &pdev->dev,
489                                 init_data, info);
490                 if (IS_ERR(info->rdev)) {
491                         err = PTR_ERR(info->rdev);
492                         dev_err(&pdev->dev, "failed to register %s: err %i\n",
493                                 info->desc.name, err);
494
495                         /* if failing, unregister all earlier regulators */
496                         while (--i >= 0) {
497                                 info = &db8500_regulator_info[i];
498                                 regulator_unregister(info->rdev);
499                         }
500                         return err;
501                 }
502
503                 dev_dbg(rdev_get_dev(info->rdev),
504                         "regulator-%s-probed\n", info->desc.name);
505         }
506
507         return 0;
508 }
509
510 static int __exit db8500_regulator_remove(struct platform_device *pdev)
511 {
512         int i;
513
514         for (i = 0; i < ARRAY_SIZE(db8500_regulator_info); i++) {
515                 struct db8500_regulator_info *info;
516                 info = &db8500_regulator_info[i];
517
518                 dev_vdbg(rdev_get_dev(info->rdev),
519                         "regulator-%s-remove\n", info->desc.name);
520
521                 regulator_unregister(info->rdev);
522         }
523
524         return 0;
525 }
526
527 static struct platform_driver db8500_regulator_driver = {
528         .driver = {
529                 .name = "db8500-prcmu-regulators",
530                 .owner = THIS_MODULE,
531         },
532         .probe = db8500_regulator_probe,
533         .remove = __exit_p(db8500_regulator_remove),
534 };
535
536 static int __init db8500_regulator_init(void)
537 {
538         return platform_driver_register(&db8500_regulator_driver);
539 }
540
541 static void __exit db8500_regulator_exit(void)
542 {
543         platform_driver_unregister(&db8500_regulator_driver);
544 }
545
546 arch_initcall(db8500_regulator_init);
547 module_exit(db8500_regulator_exit);
548
549 MODULE_AUTHOR("STMicroelectronics/ST-Ericsson");
550 MODULE_DESCRIPTION("DB8500 regulator driver");
551 MODULE_LICENSE("GPL v2");