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");
498