aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/regulator/wm831x-dcdc.c
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2009-07-28 10:22:23 -0400
committerSamuel Ortiz <sameo@linux.intel.com>2009-09-17 03:47:10 -0400
commit8267a9ba8299e1e70d54c7666da6aada637de4fc (patch)
tree552a2a1f9641421d572b4e4f0a74de2af4083764 /drivers/regulator/wm831x-dcdc.c
parentd1c6b4fe668b2ae02f490deee86eaab60822a362 (diff)
regulator: Add WM831x EPE support
The WM831x series of PMICs provide two optional outputs for controlling external devices during power sequencing, for example an external regulator. While in essence these are GPIOs the hardware presents them as DCDCs with very little control so provide support via the regulator API in that fashion. Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com> Acked-by: Liam Girdwood <lrg@slimlogic.co.uk> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'drivers/regulator/wm831x-dcdc.c')
-rw-r--r--drivers/regulator/wm831x-dcdc.c88
1 files changed, 88 insertions, 0 deletions
diff --git a/drivers/regulator/wm831x-dcdc.c b/drivers/regulator/wm831x-dcdc.c
index fa5126e38acc..88a7dbac750a 100644
--- a/drivers/regulator/wm831x-dcdc.c
+++ b/drivers/regulator/wm831x-dcdc.c
@@ -613,6 +613,89 @@ static struct platform_driver wm831x_buckp_driver = {
613 }, 613 },
614}; 614};
615 615
616/*
617 * External Power Enable
618 *
619 * These aren't actually DCDCs but look like them in hardware so share
620 * code.
621 */
622
623#define WM831X_EPE_BASE 6
624
625static struct regulator_ops wm831x_epe_ops = {
626 .is_enabled = wm831x_dcdc_is_enabled,
627 .enable = wm831x_dcdc_enable,
628 .disable = wm831x_dcdc_disable,
629 .get_status = wm831x_dcdc_get_status,
630};
631
632static __devinit int wm831x_epe_probe(struct platform_device *pdev)
633{
634 struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
635 struct wm831x_pdata *pdata = wm831x->dev->platform_data;
636 int id = pdev->id % ARRAY_SIZE(pdata->epe);
637 struct wm831x_dcdc *dcdc;
638 int ret;
639
640 dev_dbg(&pdev->dev, "Probing EPE%d\n", id + 1);
641
642 if (pdata == NULL || pdata->epe[id] == NULL)
643 return -ENODEV;
644
645 dcdc = kzalloc(sizeof(struct wm831x_dcdc), GFP_KERNEL);
646 if (dcdc == NULL) {
647 dev_err(&pdev->dev, "Unable to allocate private data\n");
648 return -ENOMEM;
649 }
650
651 dcdc->wm831x = wm831x;
652
653 /* For current parts this is correct; probably need to revisit
654 * in future.
655 */
656 snprintf(dcdc->name, sizeof(dcdc->name), "EPE%d", id + 1);
657 dcdc->desc.name = dcdc->name;
658 dcdc->desc.id = id + WM831X_EPE_BASE; /* Offset in DCDC registers */
659 dcdc->desc.ops = &wm831x_epe_ops;
660 dcdc->desc.type = REGULATOR_VOLTAGE;
661 dcdc->desc.owner = THIS_MODULE;
662
663 dcdc->regulator = regulator_register(&dcdc->desc, &pdev->dev,
664 pdata->epe[id], dcdc);
665 if (IS_ERR(dcdc->regulator)) {
666 ret = PTR_ERR(dcdc->regulator);
667 dev_err(wm831x->dev, "Failed to register EPE%d: %d\n",
668 id + 1, ret);
669 goto err;
670 }
671
672 platform_set_drvdata(pdev, dcdc);
673
674 return 0;
675
676err:
677 kfree(dcdc);
678 return ret;
679}
680
681static __devexit int wm831x_epe_remove(struct platform_device *pdev)
682{
683 struct wm831x_dcdc *dcdc = platform_get_drvdata(pdev);
684
685 regulator_unregister(dcdc->regulator);
686 kfree(dcdc);
687
688 return 0;
689}
690
691static struct platform_driver wm831x_epe_driver = {
692 .probe = wm831x_epe_probe,
693 .remove = __devexit_p(wm831x_epe_remove),
694 .driver = {
695 .name = "wm831x-epe",
696 },
697};
698
616static int __init wm831x_dcdc_init(void) 699static int __init wm831x_dcdc_init(void)
617{ 700{
618 int ret; 701 int ret;
@@ -624,12 +707,17 @@ static int __init wm831x_dcdc_init(void)
624 if (ret != 0) 707 if (ret != 0)
625 pr_err("Failed to register WM831x BUCKP driver: %d\n", ret); 708 pr_err("Failed to register WM831x BUCKP driver: %d\n", ret);
626 709
710 ret = platform_driver_register(&wm831x_epe_driver);
711 if (ret != 0)
712 pr_err("Failed to register WM831x EPE driver: %d\n", ret);
713
627 return 0; 714 return 0;
628} 715}
629subsys_initcall(wm831x_dcdc_init); 716subsys_initcall(wm831x_dcdc_init);
630 717
631static void __exit wm831x_dcdc_exit(void) 718static void __exit wm831x_dcdc_exit(void)
632{ 719{
720 platform_driver_unregister(&wm831x_epe_driver);
633 platform_driver_unregister(&wm831x_buckp_driver); 721 platform_driver_unregister(&wm831x_buckp_driver);
634 platform_driver_unregister(&wm831x_buckv_driver); 722 platform_driver_unregister(&wm831x_buckv_driver);
635} 723}