• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/regulator/of_regulator.h>
21  #include <linux/of.h>
22  #include <linux/module.h>
23  #include "dbx500-prcmu.h"
24  
db8500_regulator_enable(struct regulator_dev * rdev)25  static int db8500_regulator_enable(struct regulator_dev *rdev)
26  {
27  	struct dbx500_regulator_info *info = rdev_get_drvdata(rdev);
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)
38  			power_state_active_enable();
39  	}
40  
41  	return 0;
42  }
43  
db8500_regulator_disable(struct regulator_dev * rdev)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)
58  			ret = power_state_active_disable();
59  	}
60  
61  	return ret;
62  }
63  
db8500_regulator_is_enabled(struct regulator_dev * rdev)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  
enable_epod(u16 epod_id,bool ramret)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  
disable_epod(u16 epod_id,bool ramret)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   */
db8500_regulator_switch_enable(struct regulator_dev * rdev)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  
db8500_regulator_switch_disable(struct regulator_dev * rdev)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  
db8500_regulator_switch_is_enabled(struct regulator_dev * rdev)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
213  dbx500_regulator_info[DB8500_NUM_REGULATORS] = {
214  	[DB8500_REGULATOR_VAPE] = {
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  	},
223  	[DB8500_REGULATOR_VARM] = {
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  	},
232  	[DB8500_REGULATOR_VMODEM] = {
233  		.desc = {
234  			.name	= "db8500-vmodem",
235  			.id	= DB8500_REGULATOR_VMODEM,
236  			.ops	= &db8500_regulator_ops,
237  			.type	= REGULATOR_VOLTAGE,
238  			.owner	= THIS_MODULE,
239  		},
240  	},
241  	[DB8500_REGULATOR_VPLL] = {
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  	},
250  	[DB8500_REGULATOR_VSMPS1] = {
251  		.desc = {
252  			.name	= "db8500-vsmps1",
253  			.id	= DB8500_REGULATOR_VSMPS1,
254  			.ops	= &db8500_regulator_ops,
255  			.type	= REGULATOR_VOLTAGE,
256  			.owner	= THIS_MODULE,
257  		},
258  	},
259  	[DB8500_REGULATOR_VSMPS2] = {
260  		.desc = {
261  			.name	= "db8500-vsmps2",
262  			.id	= DB8500_REGULATOR_VSMPS2,
263  			.ops	= &db8500_regulator_ops,
264  			.type	= REGULATOR_VOLTAGE,
265  			.owner	= THIS_MODULE,
266  			.fixed_uV = 1800000,
267  			.n_voltages = 1,
268  		},
269  		.exclude_from_power_state = true,
270  	},
271  	[DB8500_REGULATOR_VSMPS3] = {
272  		.desc = {
273  			.name	= "db8500-vsmps3",
274  			.id	= DB8500_REGULATOR_VSMPS3,
275  			.ops	= &db8500_regulator_ops,
276  			.type	= REGULATOR_VOLTAGE,
277  			.owner	= THIS_MODULE,
278  		},
279  	},
280  	[DB8500_REGULATOR_VRF1] = {
281  		.desc = {
282  			.name	= "db8500-vrf1",
283  			.id	= DB8500_REGULATOR_VRF1,
284  			.ops	= &db8500_regulator_ops,
285  			.type	= REGULATOR_VOLTAGE,
286  			.owner	= THIS_MODULE,
287  		},
288  	},
289  	[DB8500_REGULATOR_SWITCH_SVAMMDSP] = {
290  		.desc = {
291  			.name	= "db8500-sva-mmdsp",
292  			.id	= DB8500_REGULATOR_SWITCH_SVAMMDSP,
293  			.ops	= &db8500_regulator_switch_ops,
294  			.type	= REGULATOR_VOLTAGE,
295  			.owner	= THIS_MODULE,
296  		},
297  		.epod_id = EPOD_ID_SVAMMDSP,
298  	},
299  	[DB8500_REGULATOR_SWITCH_SVAMMDSPRET] = {
300  		.desc = {
301  			.name	= "db8500-sva-mmdsp-ret",
302  			.id	= DB8500_REGULATOR_SWITCH_SVAMMDSPRET,
303  			.ops	= &db8500_regulator_switch_ops,
304  			.type	= REGULATOR_VOLTAGE,
305  			.owner	= THIS_MODULE,
306  		},
307  		.epod_id = EPOD_ID_SVAMMDSP,
308  		.is_ramret = true,
309  	},
310  	[DB8500_REGULATOR_SWITCH_SVAPIPE] = {
311  		.desc = {
312  			.name	= "db8500-sva-pipe",
313  			.id	= DB8500_REGULATOR_SWITCH_SVAPIPE,
314  			.ops	= &db8500_regulator_switch_ops,
315  			.type	= REGULATOR_VOLTAGE,
316  			.owner	= THIS_MODULE,
317  		},
318  		.epod_id = EPOD_ID_SVAPIPE,
319  	},
320  	[DB8500_REGULATOR_SWITCH_SIAMMDSP] = {
321  		.desc = {
322  			.name	= "db8500-sia-mmdsp",
323  			.id	= DB8500_REGULATOR_SWITCH_SIAMMDSP,
324  			.ops	= &db8500_regulator_switch_ops,
325  			.type	= REGULATOR_VOLTAGE,
326  			.owner	= THIS_MODULE,
327  		},
328  		.epod_id = EPOD_ID_SIAMMDSP,
329  	},
330  	[DB8500_REGULATOR_SWITCH_SIAMMDSPRET] = {
331  		.desc = {
332  			.name	= "db8500-sia-mmdsp-ret",
333  			.id	= DB8500_REGULATOR_SWITCH_SIAMMDSPRET,
334  			.ops	= &db8500_regulator_switch_ops,
335  			.type	= REGULATOR_VOLTAGE,
336  			.owner	= THIS_MODULE,
337  		},
338  		.epod_id = EPOD_ID_SIAMMDSP,
339  		.is_ramret = true,
340  	},
341  	[DB8500_REGULATOR_SWITCH_SIAPIPE] = {
342  		.desc = {
343  			.name	= "db8500-sia-pipe",
344  			.id	= DB8500_REGULATOR_SWITCH_SIAPIPE,
345  			.ops	= &db8500_regulator_switch_ops,
346  			.type	= REGULATOR_VOLTAGE,
347  			.owner	= THIS_MODULE,
348  		},
349  		.epod_id = EPOD_ID_SIAPIPE,
350  	},
351  	[DB8500_REGULATOR_SWITCH_SGA] = {
352  		.desc = {
353  			.name	= "db8500-sga",
354  			.id	= DB8500_REGULATOR_SWITCH_SGA,
355  			.ops	= &db8500_regulator_switch_ops,
356  			.type	= REGULATOR_VOLTAGE,
357  			.owner	= THIS_MODULE,
358  		},
359  		.epod_id = EPOD_ID_SGA,
360  	},
361  	[DB8500_REGULATOR_SWITCH_B2R2_MCDE] = {
362  		.desc = {
363  			.name	= "db8500-b2r2-mcde",
364  			.id	= DB8500_REGULATOR_SWITCH_B2R2_MCDE,
365  			.ops	= &db8500_regulator_switch_ops,
366  			.type	= REGULATOR_VOLTAGE,
367  			.owner	= THIS_MODULE,
368  		},
369  		.epod_id = EPOD_ID_B2R2_MCDE,
370  	},
371  	[DB8500_REGULATOR_SWITCH_ESRAM12] = {
372  		.desc = {
373  			.name	= "db8500-esram12",
374  			.id	= DB8500_REGULATOR_SWITCH_ESRAM12,
375  			.ops	= &db8500_regulator_switch_ops,
376  			.type	= REGULATOR_VOLTAGE,
377  			.owner	= THIS_MODULE,
378  		},
379  		.epod_id	= EPOD_ID_ESRAM12,
380  		.is_enabled	= true,
381  	},
382  	[DB8500_REGULATOR_SWITCH_ESRAM12RET] = {
383  		.desc = {
384  			.name	= "db8500-esram12-ret",
385  			.id	= DB8500_REGULATOR_SWITCH_ESRAM12RET,
386  			.ops	= &db8500_regulator_switch_ops,
387  			.type	= REGULATOR_VOLTAGE,
388  			.owner	= THIS_MODULE,
389  		},
390  		.epod_id = EPOD_ID_ESRAM12,
391  		.is_ramret = true,
392  	},
393  	[DB8500_REGULATOR_SWITCH_ESRAM34] = {
394  		.desc = {
395  			.name	= "db8500-esram34",
396  			.id	= DB8500_REGULATOR_SWITCH_ESRAM34,
397  			.ops	= &db8500_regulator_switch_ops,
398  			.type	= REGULATOR_VOLTAGE,
399  			.owner	= THIS_MODULE,
400  		},
401  		.epod_id	= EPOD_ID_ESRAM34,
402  		.is_enabled	= true,
403  	},
404  	[DB8500_REGULATOR_SWITCH_ESRAM34RET] = {
405  		.desc = {
406  			.name	= "db8500-esram34-ret",
407  			.id	= DB8500_REGULATOR_SWITCH_ESRAM34RET,
408  			.ops	= &db8500_regulator_switch_ops,
409  			.type	= REGULATOR_VOLTAGE,
410  			.owner	= THIS_MODULE,
411  		},
412  		.epod_id = EPOD_ID_ESRAM34,
413  		.is_ramret = true,
414  	},
415  };
416  
db8500_regulator_register(struct platform_device * pdev,struct regulator_init_data * init_data,int id,struct device_node * np)417  static int db8500_regulator_register(struct platform_device *pdev,
418  					struct regulator_init_data *init_data,
419  					int id,
420  					struct device_node *np)
421  {
422  	struct dbx500_regulator_info *info;
423  	struct regulator_config config = { };
424  	int err;
425  
426  	/* assign per-regulator data */
427  	info = &dbx500_regulator_info[id];
428  	info->dev = &pdev->dev;
429  
430  	config.dev = &pdev->dev;
431  	config.init_data = init_data;
432  	config.driver_data = info;
433  	config.of_node = np;
434  
435  	/* register with the regulator framework */
436  	info->rdev = devm_regulator_register(&pdev->dev, &info->desc, &config);
437  	if (IS_ERR(info->rdev)) {
438  		err = PTR_ERR(info->rdev);
439  		dev_err(&pdev->dev, "failed to register %s: err %i\n",
440  			info->desc.name, err);
441  		return err;
442  	}
443  
444  	dev_dbg(rdev_get_dev(info->rdev),
445  		"regulator-%s-probed\n", info->desc.name);
446  
447  	return 0;
448  }
449  
450  static struct of_regulator_match db8500_regulator_matches[] = {
451  	{ .name	= "db8500_vape",          .driver_data = (void *) DB8500_REGULATOR_VAPE, },
452  	{ .name	= "db8500_varm",          .driver_data = (void *) DB8500_REGULATOR_VARM, },
453  	{ .name	= "db8500_vmodem",        .driver_data = (void *) DB8500_REGULATOR_VMODEM, },
454  	{ .name	= "db8500_vpll",          .driver_data = (void *) DB8500_REGULATOR_VPLL, },
455  	{ .name	= "db8500_vsmps1",        .driver_data = (void *) DB8500_REGULATOR_VSMPS1, },
456  	{ .name	= "db8500_vsmps2",        .driver_data = (void *) DB8500_REGULATOR_VSMPS2, },
457  	{ .name	= "db8500_vsmps3",        .driver_data = (void *) DB8500_REGULATOR_VSMPS3, },
458  	{ .name	= "db8500_vrf1",          .driver_data = (void *) DB8500_REGULATOR_VRF1, },
459  	{ .name	= "db8500_sva_mmdsp",     .driver_data = (void *) DB8500_REGULATOR_SWITCH_SVAMMDSP, },
460  	{ .name	= "db8500_sva_mmdsp_ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SVAMMDSPRET, },
461  	{ .name	= "db8500_sva_pipe",      .driver_data = (void *) DB8500_REGULATOR_SWITCH_SVAPIPE, },
462  	{ .name	= "db8500_sia_mmdsp",     .driver_data = (void *) DB8500_REGULATOR_SWITCH_SIAMMDSP, },
463  	{ .name	= "db8500_sia_mmdsp_ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SIAMMDSPRET, },
464  	{ .name	= "db8500_sia_pipe",      .driver_data = (void *) DB8500_REGULATOR_SWITCH_SIAPIPE, },
465  	{ .name	= "db8500_sga",           .driver_data = (void *) DB8500_REGULATOR_SWITCH_SGA, },
466  	{ .name	= "db8500_b2r2_mcde",     .driver_data = (void *) DB8500_REGULATOR_SWITCH_B2R2_MCDE, },
467  	{ .name	= "db8500_esram12",       .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM12, },
468  	{ .name	= "db8500_esram12_ret",   .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM12RET, },
469  	{ .name	= "db8500_esram34",       .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM34, },
470  	{ .name	= "db8500_esram34_ret",   .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM34RET, },
471  };
472  
473  static int
db8500_regulator_of_probe(struct platform_device * pdev,struct device_node * np)474  db8500_regulator_of_probe(struct platform_device *pdev,
475  			struct device_node *np)
476  {
477  	int i, err;
478  
479  	for (i = 0; i < ARRAY_SIZE(dbx500_regulator_info); i++) {
480  		err = db8500_regulator_register(
481  			pdev, db8500_regulator_matches[i].init_data,
482  			i, db8500_regulator_matches[i].of_node);
483  		if (err)
484  			return err;
485  	}
486  
487  	return 0;
488  }
489  
db8500_regulator_probe(struct platform_device * pdev)490  static int db8500_regulator_probe(struct platform_device *pdev)
491  {
492  	struct regulator_init_data *db8500_init_data =
493  					dev_get_platdata(&pdev->dev);
494  	struct device_node *np = pdev->dev.of_node;
495  	int i, err;
496  
497  	/* register all regulators */
498  	if (np) {
499  		err = of_regulator_match(&pdev->dev, np,
500  					db8500_regulator_matches,
501  					ARRAY_SIZE(db8500_regulator_matches));
502  		if (err < 0) {
503  			dev_err(&pdev->dev,
504  				"Error parsing regulator init data: %d\n", err);
505  			return err;
506  		}
507  
508  		err = db8500_regulator_of_probe(pdev, np);
509  		if (err)
510  			return err;
511  	} else {
512  		for (i = 0; i < ARRAY_SIZE(dbx500_regulator_info); i++) {
513  			err = db8500_regulator_register(pdev,
514  							&db8500_init_data[i],
515  							i, NULL);
516  			if (err)
517  				return err;
518  		}
519  	}
520  
521  	err = ux500_regulator_debug_init(pdev,
522  					 dbx500_regulator_info,
523  					 ARRAY_SIZE(dbx500_regulator_info));
524  	return 0;
525  }
526  
db8500_regulator_remove(struct platform_device * pdev)527  static int db8500_regulator_remove(struct platform_device *pdev)
528  {
529  	ux500_regulator_debug_exit();
530  
531  	return 0;
532  }
533  
534  static struct platform_driver db8500_regulator_driver = {
535  	.driver = {
536  		.name = "db8500-prcmu-regulators",
537  	},
538  	.probe = db8500_regulator_probe,
539  	.remove = db8500_regulator_remove,
540  };
541  
db8500_regulator_init(void)542  static int __init db8500_regulator_init(void)
543  {
544  	return platform_driver_register(&db8500_regulator_driver);
545  }
546  
db8500_regulator_exit(void)547  static void __exit db8500_regulator_exit(void)
548  {
549  	platform_driver_unregister(&db8500_regulator_driver);
550  }
551  
552  arch_initcall(db8500_regulator_init);
553  module_exit(db8500_regulator_exit);
554  
555  MODULE_AUTHOR("STMicroelectronics/ST-Ericsson");
556  MODULE_DESCRIPTION("DB8500 regulator driver");
557  MODULE_LICENSE("GPL v2");
558