2 * Copyright (C) ST-Ericsson SA 2010
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
8 * Power domain regulators on DB8500
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/db8500-prcmu.h>
17 #include <linux/regulator/driver.h>
18 #include <linux/regulator/machine.h>
19 #include <linux/regulator/db8500-prcmu.h>
22 * power state reference count
24 static int power_state_active_cnt
; /* will initialize to zero */
25 static DEFINE_SPINLOCK(power_state_active_lock
);
27 static void power_state_active_enable(void)
31 spin_lock_irqsave(&power_state_active_lock
, flags
);
32 power_state_active_cnt
++;
33 spin_unlock_irqrestore(&power_state_active_lock
, flags
);
36 static int power_state_active_disable(void)
41 spin_lock_irqsave(&power_state_active_lock
, flags
);
42 if (power_state_active_cnt
<= 0) {
43 pr_err("power state: unbalanced enable/disable calls\n");
48 power_state_active_cnt
--;
50 spin_unlock_irqrestore(&power_state_active_lock
, flags
);
55 * Exported interface for CPUIdle only. This function is called when interrupts
56 * are turned off. Hence, no locking.
58 int power_state_active_is_enabled(void)
60 return (power_state_active_cnt
> 0);
64 * struct db8500_regulator_info - db8500 regulator information
65 * @dev: device pointer
66 * @desc: regulator description
67 * @rdev: regulator device pointer
68 * @is_enabled: status of the regulator
69 * @epod_id: id for EPOD (power domain)
70 * @is_ramret: RAM retention switch for EPOD (power domain)
71 * @operating_point: operating point (only for vape, to be removed)
74 struct db8500_regulator_info
{
76 struct regulator_desc desc
;
77 struct regulator_dev
*rdev
;
81 bool exclude_from_power_state
;
82 unsigned int operating_point
;
85 static int db8500_regulator_enable(struct regulator_dev
*rdev
)
87 struct db8500_regulator_info
*info
= rdev_get_drvdata(rdev
);
92 dev_vdbg(rdev_get_dev(rdev
), "regulator-%s-enable\n",
95 info
->is_enabled
= true;
96 if (!info
->exclude_from_power_state
)
97 power_state_active_enable();
102 static int db8500_regulator_disable(struct regulator_dev
*rdev
)
104 struct db8500_regulator_info
*info
= rdev_get_drvdata(rdev
);
110 dev_vdbg(rdev_get_dev(rdev
), "regulator-%s-disable\n",
113 info
->is_enabled
= false;
114 if (!info
->exclude_from_power_state
)
115 ret
= power_state_active_disable();
120 static int db8500_regulator_is_enabled(struct regulator_dev
*rdev
)
122 struct db8500_regulator_info
*info
= rdev_get_drvdata(rdev
);
127 dev_vdbg(rdev_get_dev(rdev
), "regulator-%s-is_enabled (is_enabled):"
128 " %i\n", info
->desc
.name
, info
->is_enabled
);
130 return info
->is_enabled
;
133 /* db8500 regulator operations */
134 static struct regulator_ops db8500_regulator_ops
= {
135 .enable
= db8500_regulator_enable
,
136 .disable
= db8500_regulator_disable
,
137 .is_enabled
= db8500_regulator_is_enabled
,
143 static bool epod_on
[NUM_EPOD_ID
];
144 static bool epod_ramret
[NUM_EPOD_ID
];
146 static int enable_epod(u16 epod_id
, bool ramret
)
151 if (!epod_on
[epod_id
]) {
152 ret
= prcmu_set_epod(epod_id
, EPOD_STATE_RAMRET
);
156 epod_ramret
[epod_id
] = true;
158 ret
= prcmu_set_epod(epod_id
, EPOD_STATE_ON
);
161 epod_on
[epod_id
] = true;
167 static int disable_epod(u16 epod_id
, bool ramret
)
172 if (!epod_on
[epod_id
]) {
173 ret
= prcmu_set_epod(epod_id
, EPOD_STATE_OFF
);
177 epod_ramret
[epod_id
] = false;
179 if (epod_ramret
[epod_id
]) {
180 ret
= prcmu_set_epod(epod_id
, EPOD_STATE_RAMRET
);
184 ret
= prcmu_set_epod(epod_id
, EPOD_STATE_OFF
);
188 epod_on
[epod_id
] = false;
197 static int db8500_regulator_switch_enable(struct regulator_dev
*rdev
)
199 struct db8500_regulator_info
*info
= rdev_get_drvdata(rdev
);
205 dev_vdbg(rdev_get_dev(rdev
), "regulator-switch-%s-enable\n",
208 ret
= enable_epod(info
->epod_id
, info
->is_ramret
);
210 dev_err(rdev_get_dev(rdev
),
211 "regulator-switch-%s-enable: prcmu call failed\n",
216 info
->is_enabled
= true;
221 static int db8500_regulator_switch_disable(struct regulator_dev
*rdev
)
223 struct db8500_regulator_info
*info
= rdev_get_drvdata(rdev
);
229 dev_vdbg(rdev_get_dev(rdev
), "regulator-switch-%s-disable\n",
232 ret
= disable_epod(info
->epod_id
, info
->is_ramret
);
234 dev_err(rdev_get_dev(rdev
),
235 "regulator_switch-%s-disable: prcmu call failed\n",
240 info
->is_enabled
= 0;
245 static int db8500_regulator_switch_is_enabled(struct regulator_dev
*rdev
)
247 struct db8500_regulator_info
*info
= rdev_get_drvdata(rdev
);
252 dev_vdbg(rdev_get_dev(rdev
),
253 "regulator-switch-%s-is_enabled (is_enabled): %i\n",
254 info
->desc
.name
, info
->is_enabled
);
256 return info
->is_enabled
;
259 static struct regulator_ops db8500_regulator_switch_ops
= {
260 .enable
= db8500_regulator_switch_enable
,
261 .disable
= db8500_regulator_switch_disable
,
262 .is_enabled
= db8500_regulator_switch_is_enabled
,
266 * Regulator information
268 static struct db8500_regulator_info
269 db8500_regulator_info
[DB8500_NUM_REGULATORS
] = {
270 [DB8500_REGULATOR_VAPE
] = {
272 .name
= "db8500-vape",
273 .id
= DB8500_REGULATOR_VAPE
,
274 .ops
= &db8500_regulator_ops
,
275 .type
= REGULATOR_VOLTAGE
,
276 .owner
= THIS_MODULE
,
279 [DB8500_REGULATOR_VARM
] = {
281 .name
= "db8500-varm",
282 .id
= DB8500_REGULATOR_VARM
,
283 .ops
= &db8500_regulator_ops
,
284 .type
= REGULATOR_VOLTAGE
,
285 .owner
= THIS_MODULE
,
288 [DB8500_REGULATOR_VMODEM
] = {
290 .name
= "db8500-vmodem",
291 .id
= DB8500_REGULATOR_VMODEM
,
292 .ops
= &db8500_regulator_ops
,
293 .type
= REGULATOR_VOLTAGE
,
294 .owner
= THIS_MODULE
,
297 [DB8500_REGULATOR_VPLL
] = {
299 .name
= "db8500-vpll",
300 .id
= DB8500_REGULATOR_VPLL
,
301 .ops
= &db8500_regulator_ops
,
302 .type
= REGULATOR_VOLTAGE
,
303 .owner
= THIS_MODULE
,
306 [DB8500_REGULATOR_VSMPS1
] = {
308 .name
= "db8500-vsmps1",
309 .id
= DB8500_REGULATOR_VSMPS1
,
310 .ops
= &db8500_regulator_ops
,
311 .type
= REGULATOR_VOLTAGE
,
312 .owner
= THIS_MODULE
,
315 [DB8500_REGULATOR_VSMPS2
] = {
317 .name
= "db8500-vsmps2",
318 .id
= DB8500_REGULATOR_VSMPS2
,
319 .ops
= &db8500_regulator_ops
,
320 .type
= REGULATOR_VOLTAGE
,
321 .owner
= THIS_MODULE
,
323 .exclude_from_power_state
= true,
325 [DB8500_REGULATOR_VSMPS3
] = {
327 .name
= "db8500-vsmps3",
328 .id
= DB8500_REGULATOR_VSMPS3
,
329 .ops
= &db8500_regulator_ops
,
330 .type
= REGULATOR_VOLTAGE
,
331 .owner
= THIS_MODULE
,
334 [DB8500_REGULATOR_VRF1
] = {
336 .name
= "db8500-vrf1",
337 .id
= DB8500_REGULATOR_VRF1
,
338 .ops
= &db8500_regulator_ops
,
339 .type
= REGULATOR_VOLTAGE
,
340 .owner
= THIS_MODULE
,
343 [DB8500_REGULATOR_SWITCH_SVAMMDSP
] = {
345 .name
= "db8500-sva-mmdsp",
346 .id
= DB8500_REGULATOR_SWITCH_SVAMMDSP
,
347 .ops
= &db8500_regulator_switch_ops
,
348 .type
= REGULATOR_VOLTAGE
,
349 .owner
= THIS_MODULE
,
351 .epod_id
= EPOD_ID_SVAMMDSP
,
353 [DB8500_REGULATOR_SWITCH_SVAMMDSPRET
] = {
355 .name
= "db8500-sva-mmdsp-ret",
356 .id
= DB8500_REGULATOR_SWITCH_SVAMMDSPRET
,
357 .ops
= &db8500_regulator_switch_ops
,
358 .type
= REGULATOR_VOLTAGE
,
359 .owner
= THIS_MODULE
,
361 .epod_id
= EPOD_ID_SVAMMDSP
,
364 [DB8500_REGULATOR_SWITCH_SVAPIPE
] = {
366 .name
= "db8500-sva-pipe",
367 .id
= DB8500_REGULATOR_SWITCH_SVAPIPE
,
368 .ops
= &db8500_regulator_switch_ops
,
369 .type
= REGULATOR_VOLTAGE
,
370 .owner
= THIS_MODULE
,
372 .epod_id
= EPOD_ID_SVAPIPE
,
374 [DB8500_REGULATOR_SWITCH_SIAMMDSP
] = {
376 .name
= "db8500-sia-mmdsp",
377 .id
= DB8500_REGULATOR_SWITCH_SIAMMDSP
,
378 .ops
= &db8500_regulator_switch_ops
,
379 .type
= REGULATOR_VOLTAGE
,
380 .owner
= THIS_MODULE
,
382 .epod_id
= EPOD_ID_SIAMMDSP
,
384 [DB8500_REGULATOR_SWITCH_SIAMMDSPRET
] = {
386 .name
= "db8500-sia-mmdsp-ret",
387 .id
= DB8500_REGULATOR_SWITCH_SIAMMDSPRET
,
388 .ops
= &db8500_regulator_switch_ops
,
389 .type
= REGULATOR_VOLTAGE
,
390 .owner
= THIS_MODULE
,
392 .epod_id
= EPOD_ID_SIAMMDSP
,
395 [DB8500_REGULATOR_SWITCH_SIAPIPE
] = {
397 .name
= "db8500-sia-pipe",
398 .id
= DB8500_REGULATOR_SWITCH_SIAPIPE
,
399 .ops
= &db8500_regulator_switch_ops
,
400 .type
= REGULATOR_VOLTAGE
,
401 .owner
= THIS_MODULE
,
403 .epod_id
= EPOD_ID_SIAPIPE
,
405 [DB8500_REGULATOR_SWITCH_SGA
] = {
407 .name
= "db8500-sga",
408 .id
= DB8500_REGULATOR_SWITCH_SGA
,
409 .ops
= &db8500_regulator_switch_ops
,
410 .type
= REGULATOR_VOLTAGE
,
411 .owner
= THIS_MODULE
,
413 .epod_id
= EPOD_ID_SGA
,
415 [DB8500_REGULATOR_SWITCH_B2R2_MCDE
] = {
417 .name
= "db8500-b2r2-mcde",
418 .id
= DB8500_REGULATOR_SWITCH_B2R2_MCDE
,
419 .ops
= &db8500_regulator_switch_ops
,
420 .type
= REGULATOR_VOLTAGE
,
421 .owner
= THIS_MODULE
,
423 .epod_id
= EPOD_ID_B2R2_MCDE
,
425 [DB8500_REGULATOR_SWITCH_ESRAM12
] = {
427 .name
= "db8500-esram12",
428 .id
= DB8500_REGULATOR_SWITCH_ESRAM12
,
429 .ops
= &db8500_regulator_switch_ops
,
430 .type
= REGULATOR_VOLTAGE
,
431 .owner
= THIS_MODULE
,
433 .epod_id
= EPOD_ID_ESRAM12
,
436 [DB8500_REGULATOR_SWITCH_ESRAM12RET
] = {
438 .name
= "db8500-esram12-ret",
439 .id
= DB8500_REGULATOR_SWITCH_ESRAM12RET
,
440 .ops
= &db8500_regulator_switch_ops
,
441 .type
= REGULATOR_VOLTAGE
,
442 .owner
= THIS_MODULE
,
444 .epod_id
= EPOD_ID_ESRAM12
,
447 [DB8500_REGULATOR_SWITCH_ESRAM34
] = {
449 .name
= "db8500-esram34",
450 .id
= DB8500_REGULATOR_SWITCH_ESRAM34
,
451 .ops
= &db8500_regulator_switch_ops
,
452 .type
= REGULATOR_VOLTAGE
,
453 .owner
= THIS_MODULE
,
455 .epod_id
= EPOD_ID_ESRAM34
,
458 [DB8500_REGULATOR_SWITCH_ESRAM34RET
] = {
460 .name
= "db8500-esram34-ret",
461 .id
= DB8500_REGULATOR_SWITCH_ESRAM34RET
,
462 .ops
= &db8500_regulator_switch_ops
,
463 .type
= REGULATOR_VOLTAGE
,
464 .owner
= THIS_MODULE
,
466 .epod_id
= EPOD_ID_ESRAM34
,
471 static int __devinit
db8500_regulator_probe(struct platform_device
*pdev
)
473 struct regulator_init_data
*db8500_init_data
=
474 dev_get_platdata(&pdev
->dev
);
477 /* register all regulators */
478 for (i
= 0; i
< ARRAY_SIZE(db8500_regulator_info
); i
++) {
479 struct db8500_regulator_info
*info
;
480 struct regulator_init_data
*init_data
= &db8500_init_data
[i
];
482 /* assign per-regulator data */
483 info
= &db8500_regulator_info
[i
];
484 info
->dev
= &pdev
->dev
;
486 /* register with the regulator framework */
487 info
->rdev
= regulator_register(&info
->desc
, &pdev
->dev
,
489 if (IS_ERR(info
->rdev
)) {
490 err
= PTR_ERR(info
->rdev
);
491 dev_err(&pdev
->dev
, "failed to register %s: err %i\n",
492 info
->desc
.name
, err
);
494 /* if failing, unregister all earlier regulators */
496 info
= &db8500_regulator_info
[i
];
497 regulator_unregister(info
->rdev
);
502 dev_dbg(rdev_get_dev(info
->rdev
),
503 "regulator-%s-probed\n", info
->desc
.name
);
509 static int __exit
db8500_regulator_remove(struct platform_device
*pdev
)
513 for (i
= 0; i
< ARRAY_SIZE(db8500_regulator_info
); i
++) {
514 struct db8500_regulator_info
*info
;
515 info
= &db8500_regulator_info
[i
];
517 dev_vdbg(rdev_get_dev(info
->rdev
),
518 "regulator-%s-remove\n", info
->desc
.name
);
520 regulator_unregister(info
->rdev
);
526 static struct platform_driver db8500_regulator_driver
= {
528 .name
= "db8500-prcmu-regulators",
529 .owner
= THIS_MODULE
,
531 .probe
= db8500_regulator_probe
,
532 .remove
= __exit_p(db8500_regulator_remove
),
535 static int __init
db8500_regulator_init(void)
537 return platform_driver_register(&db8500_regulator_driver
);
540 static void __exit
db8500_regulator_exit(void)
542 platform_driver_unregister(&db8500_regulator_driver
);
545 arch_initcall(db8500_regulator_init
);
546 module_exit(db8500_regulator_exit
);
548 MODULE_AUTHOR("STMicroelectronics/ST-Ericsson");
549 MODULE_DESCRIPTION("DB8500 regulator driver");
550 MODULE_LICENSE("GPL v2");