Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
db8500-prcmu.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) ST-Ericsson SA 2010
3  *
4  * License Terms: GNU General Public License v2
5  * Authors: Sundar Iyer <[email protected]> for ST-Ericsson
6  * Bengt Jonsson <[email protected]> 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>
21 #include <linux/of.h>
22 #include <linux/module.h>
23 #include "dbx500-prcmu.h"
24 
25 static int db8500_regulator_enable(struct regulator_dev *rdev)
26 {
28 
29  if (info == NULL)
30  return -EINVAL;
31 
32  dev_vdbg(rdev_get_dev(rdev), "regulator-%s-enable\n",
33  info->desc.name);
34 
35  if (!info->is_enabled) {
36  info->is_enabled = true;
37  if (!info->exclude_from_power_state)
39  }
40 
41  return 0;
42 }
43 
44 static int db8500_regulator_disable(struct regulator_dev *rdev)
45 {
46  struct dbx500_regulator_info *info = rdev_get_drvdata(rdev);
47  int ret = 0;
48 
49  if (info == NULL)
50  return -EINVAL;
51 
52  dev_vdbg(rdev_get_dev(rdev), "regulator-%s-disable\n",
53  info->desc.name);
54 
55  if (info->is_enabled) {
56  info->is_enabled = false;
57  if (!info->exclude_from_power_state)
59  }
60 
61  return ret;
62 }
63 
64 static int db8500_regulator_is_enabled(struct regulator_dev *rdev)
65 {
66  struct dbx500_regulator_info *info = rdev_get_drvdata(rdev);
67 
68  if (info == NULL)
69  return -EINVAL;
70 
71  dev_vdbg(rdev_get_dev(rdev), "regulator-%s-is_enabled (is_enabled):"
72  " %i\n", info->desc.name, info->is_enabled);
73 
74  return info->is_enabled;
75 }
76 
77 /* db8500 regulator operations */
78 static struct regulator_ops db8500_regulator_ops = {
79  .enable = db8500_regulator_enable,
80  .disable = db8500_regulator_disable,
81  .is_enabled = db8500_regulator_is_enabled,
82 };
83 
84 /*
85  * EPOD control
86  */
87 static bool epod_on[NUM_EPOD_ID];
88 static bool epod_ramret[NUM_EPOD_ID];
89 
90 static int enable_epod(u16 epod_id, bool ramret)
91 {
92  int ret;
93 
94  if (ramret) {
95  if (!epod_on[epod_id]) {
96  ret = prcmu_set_epod(epod_id, EPOD_STATE_RAMRET);
97  if (ret < 0)
98  return ret;
99  }
100  epod_ramret[epod_id] = true;
101  } else {
102  ret = prcmu_set_epod(epod_id, EPOD_STATE_ON);
103  if (ret < 0)
104  return ret;
105  epod_on[epod_id] = true;
106  }
107 
108  return 0;
109 }
110 
111 static int disable_epod(u16 epod_id, bool ramret)
112 {
113  int ret;
114 
115  if (ramret) {
116  if (!epod_on[epod_id]) {
117  ret = prcmu_set_epod(epod_id, EPOD_STATE_OFF);
118  if (ret < 0)
119  return ret;
120  }
121  epod_ramret[epod_id] = false;
122  } else {
123  if (epod_ramret[epod_id]) {
124  ret = prcmu_set_epod(epod_id, EPOD_STATE_RAMRET);
125  if (ret < 0)
126  return ret;
127  } else {
128  ret = prcmu_set_epod(epod_id, EPOD_STATE_OFF);
129  if (ret < 0)
130  return ret;
131  }
132  epod_on[epod_id] = false;
133  }
134 
135  return 0;
136 }
137 
138 /*
139  * Regulator switch
140  */
141 static int db8500_regulator_switch_enable(struct regulator_dev *rdev)
142 {
143  struct dbx500_regulator_info *info = rdev_get_drvdata(rdev);
144  int ret;
145 
146  if (info == NULL)
147  return -EINVAL;
148 
149  dev_vdbg(rdev_get_dev(rdev), "regulator-switch-%s-enable\n",
150  info->desc.name);
151 
152  ret = enable_epod(info->epod_id, info->is_ramret);
153  if (ret < 0) {
154  dev_err(rdev_get_dev(rdev),
155  "regulator-switch-%s-enable: prcmu call failed\n",
156  info->desc.name);
157  goto out;
158  }
159 
160  info->is_enabled = true;
161 out:
162  return ret;
163 }
164 
165 static int db8500_regulator_switch_disable(struct regulator_dev *rdev)
166 {
167  struct dbx500_regulator_info *info = rdev_get_drvdata(rdev);
168  int ret;
169 
170  if (info == NULL)
171  return -EINVAL;
172 
173  dev_vdbg(rdev_get_dev(rdev), "regulator-switch-%s-disable\n",
174  info->desc.name);
175 
176  ret = disable_epod(info->epod_id, info->is_ramret);
177  if (ret < 0) {
178  dev_err(rdev_get_dev(rdev),
179  "regulator_switch-%s-disable: prcmu call failed\n",
180  info->desc.name);
181  goto out;
182  }
183 
184  info->is_enabled = 0;
185 out:
186  return ret;
187 }
188 
189 static int db8500_regulator_switch_is_enabled(struct regulator_dev *rdev)
190 {
191  struct dbx500_regulator_info *info = rdev_get_drvdata(rdev);
192 
193  if (info == NULL)
194  return -EINVAL;
195 
196  dev_vdbg(rdev_get_dev(rdev),
197  "regulator-switch-%s-is_enabled (is_enabled): %i\n",
198  info->desc.name, info->is_enabled);
199 
200  return info->is_enabled;
201 }
202 
203 static struct regulator_ops db8500_regulator_switch_ops = {
204  .enable = db8500_regulator_switch_enable,
205  .disable = db8500_regulator_switch_disable,
206  .is_enabled = db8500_regulator_switch_is_enabled,
207 };
208 
209 /*
210  * Regulator information
211  */
212 static struct dbx500_regulator_info
215  .desc = {
216  .name = "db8500-vape",
217  .id = DB8500_REGULATOR_VAPE,
218  .ops = &db8500_regulator_ops,
219  .type = REGULATOR_VOLTAGE,
220  .owner = THIS_MODULE,
221  },
222  },
224  .desc = {
225  .name = "db8500-varm",
226  .id = DB8500_REGULATOR_VARM,
227  .ops = &db8500_regulator_ops,
228  .type = REGULATOR_VOLTAGE,
229  .owner = THIS_MODULE,
230  },
231  },
233  .desc = {
234  .name = "db8500-vmodem",
236  .ops = &db8500_regulator_ops,
237  .type = REGULATOR_VOLTAGE,
238  .owner = THIS_MODULE,
239  },
240  },
242  .desc = {
243  .name = "db8500-vpll",
244  .id = DB8500_REGULATOR_VPLL,
245  .ops = &db8500_regulator_ops,
246  .type = REGULATOR_VOLTAGE,
247  .owner = THIS_MODULE,
248  },
249  },
251  .desc = {
252  .name = "db8500-vsmps1",
254  .ops = &db8500_regulator_ops,
255  .type = REGULATOR_VOLTAGE,
256  .owner = THIS_MODULE,
257  },
258  },
260  .desc = {
261  .name = "db8500-vsmps2",
263  .ops = &db8500_regulator_ops,
264  .type = REGULATOR_VOLTAGE,
265  .owner = THIS_MODULE,
266  },
267  .exclude_from_power_state = true,
268  },
270  .desc = {
271  .name = "db8500-vsmps3",
273  .ops = &db8500_regulator_ops,
274  .type = REGULATOR_VOLTAGE,
275  .owner = THIS_MODULE,
276  },
277  },
279  .desc = {
280  .name = "db8500-vrf1",
281  .id = DB8500_REGULATOR_VRF1,
282  .ops = &db8500_regulator_ops,
283  .type = REGULATOR_VOLTAGE,
284  .owner = THIS_MODULE,
285  },
286  },
288  .desc = {
289  .name = "db8500-sva-mmdsp",
291  .ops = &db8500_regulator_switch_ops,
292  .type = REGULATOR_VOLTAGE,
293  .owner = THIS_MODULE,
294  },
295  .epod_id = EPOD_ID_SVAMMDSP,
296  },
298  .desc = {
299  .name = "db8500-sva-mmdsp-ret",
301  .ops = &db8500_regulator_switch_ops,
302  .type = REGULATOR_VOLTAGE,
303  .owner = THIS_MODULE,
304  },
305  .epod_id = EPOD_ID_SVAMMDSP,
306  .is_ramret = true,
307  },
309  .desc = {
310  .name = "db8500-sva-pipe",
312  .ops = &db8500_regulator_switch_ops,
313  .type = REGULATOR_VOLTAGE,
314  .owner = THIS_MODULE,
315  },
316  .epod_id = EPOD_ID_SVAPIPE,
317  },
319  .desc = {
320  .name = "db8500-sia-mmdsp",
322  .ops = &db8500_regulator_switch_ops,
323  .type = REGULATOR_VOLTAGE,
324  .owner = THIS_MODULE,
325  },
326  .epod_id = EPOD_ID_SIAMMDSP,
327  },
329  .desc = {
330  .name = "db8500-sia-mmdsp-ret",
332  .ops = &db8500_regulator_switch_ops,
333  .type = REGULATOR_VOLTAGE,
334  .owner = THIS_MODULE,
335  },
336  .epod_id = EPOD_ID_SIAMMDSP,
337  .is_ramret = true,
338  },
340  .desc = {
341  .name = "db8500-sia-pipe",
343  .ops = &db8500_regulator_switch_ops,
344  .type = REGULATOR_VOLTAGE,
345  .owner = THIS_MODULE,
346  },
347  .epod_id = EPOD_ID_SIAPIPE,
348  },
350  .desc = {
351  .name = "db8500-sga",
353  .ops = &db8500_regulator_switch_ops,
354  .type = REGULATOR_VOLTAGE,
355  .owner = THIS_MODULE,
356  },
357  .epod_id = EPOD_ID_SGA,
358  },
360  .desc = {
361  .name = "db8500-b2r2-mcde",
363  .ops = &db8500_regulator_switch_ops,
364  .type = REGULATOR_VOLTAGE,
365  .owner = THIS_MODULE,
366  },
367  .epod_id = EPOD_ID_B2R2_MCDE,
368  },
370  .desc = {
371  .name = "db8500-esram12",
373  .ops = &db8500_regulator_switch_ops,
374  .type = REGULATOR_VOLTAGE,
375  .owner = THIS_MODULE,
376  },
377  .epod_id = EPOD_ID_ESRAM12,
378  .is_enabled = true,
379  },
381  .desc = {
382  .name = "db8500-esram12-ret",
384  .ops = &db8500_regulator_switch_ops,
385  .type = REGULATOR_VOLTAGE,
386  .owner = THIS_MODULE,
387  },
388  .epod_id = EPOD_ID_ESRAM12,
389  .is_ramret = true,
390  },
392  .desc = {
393  .name = "db8500-esram34",
395  .ops = &db8500_regulator_switch_ops,
396  .type = REGULATOR_VOLTAGE,
397  .owner = THIS_MODULE,
398  },
399  .epod_id = EPOD_ID_ESRAM34,
400  .is_enabled = true,
401  },
403  .desc = {
404  .name = "db8500-esram34-ret",
406  .ops = &db8500_regulator_switch_ops,
407  .type = REGULATOR_VOLTAGE,
408  .owner = THIS_MODULE,
409  },
410  .epod_id = EPOD_ID_ESRAM34,
411  .is_ramret = true,
412  },
413 };
414 
415 static __devinit int db8500_regulator_register(struct platform_device *pdev,
416  struct regulator_init_data *init_data,
417  int id,
418  struct device_node *np)
419 {
420  struct dbx500_regulator_info *info;
421  struct regulator_config config = { };
422  int err;
423 
424  /* assign per-regulator data */
425  info = &dbx500_regulator_info[id];
426  info->dev = &pdev->dev;
427 
428  config.dev = &pdev->dev;
429  config.init_data = init_data;
430  config.driver_data = info;
431  config.of_node = np;
432 
433  /* register with the regulator framework */
434  info->rdev = regulator_register(&info->desc, &config);
435  if (IS_ERR(info->rdev)) {
436  err = PTR_ERR(info->rdev);
437  dev_err(&pdev->dev, "failed to register %s: err %i\n",
438  info->desc.name, err);
439 
440  /* if failing, unregister all earlier regulators */
441  while (--id >= 0) {
442  info = &dbx500_regulator_info[id];
443  regulator_unregister(info->rdev);
444  }
445  return err;
446  }
447 
448  dev_dbg(rdev_get_dev(info->rdev),
449  "regulator-%s-probed\n", info->desc.name);
450 
451  return 0;
452 }
453 
454 static struct of_regulator_match db8500_regulator_matches[] = {
455  { .name = "db8500_vape", .driver_data = (void *) DB8500_REGULATOR_VAPE, },
456  { .name = "db8500_varm", .driver_data = (void *) DB8500_REGULATOR_VARM, },
457  { .name = "db8500_vmodem", .driver_data = (void *) DB8500_REGULATOR_VMODEM, },
458  { .name = "db8500_vpll", .driver_data = (void *) DB8500_REGULATOR_VPLL, },
459  { .name = "db8500_vsmps1", .driver_data = (void *) DB8500_REGULATOR_VSMPS1, },
460  { .name = "db8500_vsmps2", .driver_data = (void *) DB8500_REGULATOR_VSMPS2, },
461  { .name = "db8500_vsmps3", .driver_data = (void *) DB8500_REGULATOR_VSMPS3, },
462  { .name = "db8500_vrf1", .driver_data = (void *) DB8500_REGULATOR_VRF1, },
463  { .name = "db8500_sva_mmdsp", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SVAMMDSP, },
464  { .name = "db8500_sva_mmdsp_ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SVAMMDSPRET, },
465  { .name = "db8500_sva_pipe", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SVAPIPE, },
466  { .name = "db8500_sia_mmdsp", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SIAMMDSP, },
467  { .name = "db8500_sia_mmdsp_ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SIAMMDSPRET, },
468  { .name = "db8500_sia_pipe", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SIAPIPE, },
469  { .name = "db8500_sga", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SGA, },
470  { .name = "db8500_b2r2_mcde", .driver_data = (void *) DB8500_REGULATOR_SWITCH_B2R2_MCDE, },
471  { .name = "db8500_esram12", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM12, },
472  { .name = "db8500_esram12_ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM12RET, },
473  { .name = "db8500_esram34", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM34, },
474  { .name = "db8500_esram34_ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM34RET, },
475 };
476 
477 static __devinit int
478 db8500_regulator_of_probe(struct platform_device *pdev,
479  struct device_node *np)
480 {
481  int i, err;
482 
483  for (i = 0; i < ARRAY_SIZE(dbx500_regulator_info); i++) {
484  err = db8500_regulator_register(
485  pdev, db8500_regulator_matches[i].init_data,
486  i, db8500_regulator_matches[i].of_node);
487  if (err)
488  return err;
489  }
490 
491  return 0;
492 }
493 
494 static int __devinit db8500_regulator_probe(struct platform_device *pdev)
495 {
496  struct regulator_init_data *db8500_init_data =
497  dev_get_platdata(&pdev->dev);
498  struct device_node *np = pdev->dev.of_node;
499  int i, err;
500 
501  /* register all regulators */
502  if (np) {
503  err = of_regulator_match(&pdev->dev, np,
504  db8500_regulator_matches,
505  ARRAY_SIZE(db8500_regulator_matches));
506  if (err < 0) {
507  dev_err(&pdev->dev,
508  "Error parsing regulator init data: %d\n", err);
509  return err;
510  }
511 
512  err = db8500_regulator_of_probe(pdev, np);
513  if (err)
514  return err;
515  } else {
516  for (i = 0; i < ARRAY_SIZE(dbx500_regulator_info); i++) {
517  err = db8500_regulator_register(pdev,
518  &db8500_init_data[i],
519  i, NULL);
520  if (err)
521  return err;
522  }
523  }
524 
525  err = ux500_regulator_debug_init(pdev,
526  dbx500_regulator_info,
527  ARRAY_SIZE(dbx500_regulator_info));
528  return 0;
529 }
530 
531 static int __exit db8500_regulator_remove(struct platform_device *pdev)
532 {
533  int i;
534 
535  ux500_regulator_debug_exit();
536 
537  for (i = 0; i < ARRAY_SIZE(dbx500_regulator_info); i++) {
538  struct dbx500_regulator_info *info;
539  info = &dbx500_regulator_info[i];
540 
541  dev_vdbg(rdev_get_dev(info->rdev),
542  "regulator-%s-remove\n", info->desc.name);
543 
544  regulator_unregister(info->rdev);
545  }
546 
547  return 0;
548 }
549 
550 static struct platform_driver db8500_regulator_driver = {
551  .driver = {
552  .name = "db8500-prcmu-regulators",
553  .owner = THIS_MODULE,
554  },
555  .probe = db8500_regulator_probe,
556  .remove = __exit_p(db8500_regulator_remove),
557 };
558 
559 static int __init db8500_regulator_init(void)
560 {
561  return platform_driver_register(&db8500_regulator_driver);
562 }
563 
564 static void __exit db8500_regulator_exit(void)
565 {
566  platform_driver_unregister(&db8500_regulator_driver);
567 }
568 
569 arch_initcall(db8500_regulator_init);
570 module_exit(db8500_regulator_exit);
571 
572 MODULE_AUTHOR("STMicroelectronics/ST-Ericsson");
573 MODULE_DESCRIPTION("DB8500 regulator driver");
574 MODULE_LICENSE("GPL v2");