xref: /linux/drivers/regulator/db8500-prcmu.c (revision f2ee442115c9b6219083c019939a9cc0c9abb2f8)
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");
552