diff options
author | Graeme Gregory <gg@slimlogic.co.uk> | 2012-08-28 07:47:40 -0400 |
---|---|---|
committer | Samuel Ortiz <sameo@linux.intel.com> | 2012-09-23 14:51:33 -0400 |
commit | a361cd9f2e9f2110e03ebeb6c4fb000a9a1adf2d (patch) | |
tree | 9ef627ac87ce7b1daf0d77f2f2db3680562a603e /drivers/regulator | |
parent | 7cc4c92fbc1b539597c00656b3236a57d76022f4 (diff) |
regulator: palmas: Add DT support
Add DT support to palmas regulator. This involved a little change to
the platform data structure. Regulator information can now come from
platform data or DT.
Signed-off-by: Graeme Gregory <gg@slimlogic.co.uk>
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'drivers/regulator')
-rw-r--r-- | drivers/regulator/palmas-regulator.c | 127 |
1 files changed, 119 insertions, 8 deletions
diff --git a/drivers/regulator/palmas-regulator.c b/drivers/regulator/palmas-regulator.c index 17d19fbbc490..a8294e5bcf36 100644 --- a/drivers/regulator/palmas-regulator.c +++ b/drivers/regulator/palmas-regulator.c | |||
@@ -22,6 +22,9 @@ | |||
22 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
23 | #include <linux/regmap.h> | 23 | #include <linux/regmap.h> |
24 | #include <linux/mfd/palmas.h> | 24 | #include <linux/mfd/palmas.h> |
25 | #include <linux/of.h> | ||
26 | #include <linux/of_platform.h> | ||
27 | #include <linux/regulator/of_regulator.h> | ||
25 | 28 | ||
26 | struct regs_info { | 29 | struct regs_info { |
27 | char *name; | 30 | char *name; |
@@ -603,10 +606,103 @@ static int palmas_ldo_init(struct palmas *palmas, int id, | |||
603 | return 0; | 606 | return 0; |
604 | } | 607 | } |
605 | 608 | ||
609 | static struct of_regulator_match palmas_matches[] = { | ||
610 | { .name = "smps12", }, | ||
611 | { .name = "smps123", }, | ||
612 | { .name = "smps3", }, | ||
613 | { .name = "smps45", }, | ||
614 | { .name = "smps457", }, | ||
615 | { .name = "smps6", }, | ||
616 | { .name = "smps7", }, | ||
617 | { .name = "smps8", }, | ||
618 | { .name = "smps9", }, | ||
619 | { .name = "smps10", }, | ||
620 | { .name = "ldo1", }, | ||
621 | { .name = "ldo2", }, | ||
622 | { .name = "ldo3", }, | ||
623 | { .name = "ldo4", }, | ||
624 | { .name = "ldo5", }, | ||
625 | { .name = "ldo6", }, | ||
626 | { .name = "ldo7", }, | ||
627 | { .name = "ldo8", }, | ||
628 | { .name = "ldo9", }, | ||
629 | { .name = "ldoln", }, | ||
630 | { .name = "ldousb", }, | ||
631 | }; | ||
632 | |||
633 | static void __devinit palmas_dt_to_pdata(struct device *dev, | ||
634 | struct device_node *node, | ||
635 | struct palmas_pmic_platform_data *pdata) | ||
636 | { | ||
637 | struct device_node *regulators; | ||
638 | u32 prop; | ||
639 | int idx, ret; | ||
640 | |||
641 | regulators = of_find_node_by_name(node, "regulators"); | ||
642 | if (!regulators) { | ||
643 | dev_info(dev, "regulator node not found\n"); | ||
644 | return; | ||
645 | } | ||
646 | |||
647 | ret = of_regulator_match(dev, regulators, palmas_matches, | ||
648 | PALMAS_NUM_REGS); | ||
649 | if (ret < 0) { | ||
650 | dev_err(dev, "Error parsing regulator init data: %d\n", ret); | ||
651 | return; | ||
652 | } | ||
653 | |||
654 | for (idx = 0; idx < PALMAS_NUM_REGS; idx++) { | ||
655 | if (!palmas_matches[idx].init_data || | ||
656 | !palmas_matches[idx].of_node) | ||
657 | continue; | ||
658 | |||
659 | pdata->reg_data[idx] = palmas_matches[idx].init_data; | ||
660 | |||
661 | pdata->reg_init[idx] = devm_kzalloc(dev, | ||
662 | sizeof(struct palmas_reg_init), GFP_KERNEL); | ||
663 | |||
664 | ret = of_property_read_u32(palmas_matches[idx].of_node, | ||
665 | "ti,warm_reset", &prop); | ||
666 | if (!ret) | ||
667 | pdata->reg_init[idx]->warm_reset = prop; | ||
668 | |||
669 | ret = of_property_read_u32(palmas_matches[idx].of_node, | ||
670 | "ti,roof_floor", &prop); | ||
671 | if (!ret) | ||
672 | pdata->reg_init[idx]->roof_floor = prop; | ||
673 | |||
674 | ret = of_property_read_u32(palmas_matches[idx].of_node, | ||
675 | "ti,mode_sleep", &prop); | ||
676 | if (!ret) | ||
677 | pdata->reg_init[idx]->mode_sleep = prop; | ||
678 | |||
679 | ret = of_property_read_u32(palmas_matches[idx].of_node, | ||
680 | "ti,warm_reset", &prop); | ||
681 | if (!ret) | ||
682 | pdata->reg_init[idx]->warm_reset = prop; | ||
683 | |||
684 | ret = of_property_read_u32(palmas_matches[idx].of_node, | ||
685 | "ti,tstep", &prop); | ||
686 | if (!ret) | ||
687 | pdata->reg_init[idx]->tstep = prop; | ||
688 | |||
689 | ret = of_property_read_u32(palmas_matches[idx].of_node, | ||
690 | "ti,vsel", &prop); | ||
691 | if (!ret) | ||
692 | pdata->reg_init[idx]->vsel = prop; | ||
693 | } | ||
694 | |||
695 | ret = of_property_read_u32(node, "ti,ldo6_vibrator", &prop); | ||
696 | if (!ret) | ||
697 | pdata->ldo6_vibrator = prop; | ||
698 | } | ||
699 | |||
700 | |||
606 | static __devinit int palmas_probe(struct platform_device *pdev) | 701 | static __devinit int palmas_probe(struct platform_device *pdev) |
607 | { | 702 | { |
608 | struct palmas *palmas = dev_get_drvdata(pdev->dev.parent); | 703 | struct palmas *palmas = dev_get_drvdata(pdev->dev.parent); |
609 | struct palmas_pmic_platform_data *pdata = pdev->dev.platform_data; | 704 | struct palmas_pmic_platform_data *pdata = pdev->dev.platform_data; |
705 | struct device_node *node = pdev->dev.of_node; | ||
610 | struct regulator_dev *rdev; | 706 | struct regulator_dev *rdev; |
611 | struct regulator_config config = { }; | 707 | struct regulator_config config = { }; |
612 | struct palmas_pmic *pmic; | 708 | struct palmas_pmic *pmic; |
@@ -614,10 +710,14 @@ static __devinit int palmas_probe(struct platform_device *pdev) | |||
614 | int id = 0, ret; | 710 | int id = 0, ret; |
615 | unsigned int addr, reg; | 711 | unsigned int addr, reg; |
616 | 712 | ||
617 | if (!pdata) | 713 | if (node && !pdata) { |
618 | return -EINVAL; | 714 | pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); |
619 | if (!pdata->reg_data) | 715 | |
620 | return -EINVAL; | 716 | if (!pdata) |
717 | return -ENOMEM; | ||
718 | |||
719 | palmas_dt_to_pdata(&pdev->dev, node, pdata); | ||
720 | } | ||
621 | 721 | ||
622 | pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL); | 722 | pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL); |
623 | if (!pmic) | 723 | if (!pmic) |
@@ -694,7 +794,7 @@ static __devinit int palmas_probe(struct platform_device *pdev) | |||
694 | pmic->desc[id].owner = THIS_MODULE; | 794 | pmic->desc[id].owner = THIS_MODULE; |
695 | 795 | ||
696 | /* Initialise sleep/init values from platform data */ | 796 | /* Initialise sleep/init values from platform data */ |
697 | if (pdata && pdata->reg_init) { | 797 | if (pdata) { |
698 | reg_init = pdata->reg_init[id]; | 798 | reg_init = pdata->reg_init[id]; |
699 | if (reg_init) { | 799 | if (reg_init) { |
700 | ret = palmas_smps_init(palmas, id, reg_init); | 800 | ret = palmas_smps_init(palmas, id, reg_init); |
@@ -718,11 +818,13 @@ static __devinit int palmas_probe(struct platform_device *pdev) | |||
718 | pmic->range[id] = 1; | 818 | pmic->range[id] = 1; |
719 | } | 819 | } |
720 | 820 | ||
721 | if (pdata && pdata->reg_data) | 821 | if (pdata) |
722 | config.init_data = pdata->reg_data[id]; | 822 | config.init_data = pdata->reg_data[id]; |
723 | else | 823 | else |
724 | config.init_data = NULL; | 824 | config.init_data = NULL; |
725 | 825 | ||
826 | config.of_node = palmas_matches[id].of_node; | ||
827 | |||
726 | rdev = regulator_register(&pmic->desc[id], &config); | 828 | rdev = regulator_register(&pmic->desc[id], &config); |
727 | if (IS_ERR(rdev)) { | 829 | if (IS_ERR(rdev)) { |
728 | dev_err(&pdev->dev, | 830 | dev_err(&pdev->dev, |
@@ -756,11 +858,13 @@ static __devinit int palmas_probe(struct platform_device *pdev) | |||
756 | palmas_regs_info[id].ctrl_addr); | 858 | palmas_regs_info[id].ctrl_addr); |
757 | pmic->desc[id].enable_mask = PALMAS_LDO1_CTRL_MODE_ACTIVE; | 859 | pmic->desc[id].enable_mask = PALMAS_LDO1_CTRL_MODE_ACTIVE; |
758 | 860 | ||
759 | if (pdata && pdata->reg_data) | 861 | if (pdata) |
760 | config.init_data = pdata->reg_data[id]; | 862 | config.init_data = pdata->reg_data[id]; |
761 | else | 863 | else |
762 | config.init_data = NULL; | 864 | config.init_data = NULL; |
763 | 865 | ||
866 | config.of_node = palmas_matches[id].of_node; | ||
867 | |||
764 | rdev = regulator_register(&pmic->desc[id], &config); | 868 | rdev = regulator_register(&pmic->desc[id], &config); |
765 | if (IS_ERR(rdev)) { | 869 | if (IS_ERR(rdev)) { |
766 | dev_err(&pdev->dev, | 870 | dev_err(&pdev->dev, |
@@ -774,7 +878,7 @@ static __devinit int palmas_probe(struct platform_device *pdev) | |||
774 | pmic->rdev[id] = rdev; | 878 | pmic->rdev[id] = rdev; |
775 | 879 | ||
776 | /* Initialise sleep/init values from platform data */ | 880 | /* Initialise sleep/init values from platform data */ |
777 | if (pdata->reg_init) { | 881 | if (pdata) { |
778 | reg_init = pdata->reg_init[id]; | 882 | reg_init = pdata->reg_init[id]; |
779 | if (reg_init) { | 883 | if (reg_init) { |
780 | ret = palmas_ldo_init(palmas, id, reg_init); | 884 | ret = palmas_ldo_init(palmas, id, reg_init); |
@@ -802,9 +906,15 @@ static int __devexit palmas_remove(struct platform_device *pdev) | |||
802 | return 0; | 906 | return 0; |
803 | } | 907 | } |
804 | 908 | ||
909 | static struct of_device_id __devinitdata of_palmas_match_tbl[] = { | ||
910 | { .compatible = "ti,palmas-pmic", }, | ||
911 | { /* end */ } | ||
912 | }; | ||
913 | |||
805 | static struct platform_driver palmas_driver = { | 914 | static struct platform_driver palmas_driver = { |
806 | .driver = { | 915 | .driver = { |
807 | .name = "palmas-pmic", | 916 | .name = "palmas-pmic", |
917 | .of_match_table = of_palmas_match_tbl, | ||
808 | .owner = THIS_MODULE, | 918 | .owner = THIS_MODULE, |
809 | }, | 919 | }, |
810 | .probe = palmas_probe, | 920 | .probe = palmas_probe, |
@@ -827,3 +937,4 @@ MODULE_AUTHOR("Graeme Gregory <gg@slimlogic.co.uk>"); | |||
827 | MODULE_DESCRIPTION("Palmas voltage regulator driver"); | 937 | MODULE_DESCRIPTION("Palmas voltage regulator driver"); |
828 | MODULE_LICENSE("GPL"); | 938 | MODULE_LICENSE("GPL"); |
829 | MODULE_ALIAS("platform:palmas-pmic"); | 939 | MODULE_ALIAS("platform:palmas-pmic"); |
940 | MODULE_DEVICE_TABLE(of, of_palmas_match_tbl); | ||