aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjorn Andersson <bjorn.andersson@sonymobile.com>2015-04-06 19:33:59 -0400
committerMark Brown <broonie@kernel.org>2015-04-08 07:22:14 -0400
commit087a1b5cdd555970feb8a340dc008b6914f05128 (patch)
tree0765926362f9670c603f8f806441ecafd1534dbd
parent469a951446460da843028014a90100428ff6e0c1 (diff)
regulator: qcom: Rework to single platform device
Modeling the individual RPM resources as platform devices consumes at least 12-15kb of RAM, just to hold the platform_device structs. Rework this to instead have one device per pmic exposed by the RPM. With this representation we can more accurately define the input pins on the pmic and have the supply description match the data sheet. Suggested-by: Stephen Boyd <sboyd@codeaurora.org> Signed-off-by: Bjorn Andersson <bjorn.andersson@sonymobile.com> Reviewed-by: Stephen Boyd <sboyd@codeaurora.org> Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--drivers/regulator/qcom_rpm-regulator.c244
1 files changed, 161 insertions, 83 deletions
diff --git a/drivers/regulator/qcom_rpm-regulator.c b/drivers/regulator/qcom_rpm-regulator.c
index bd8360ca7750..40cf6ff0d1ff 100644
--- a/drivers/regulator/qcom_rpm-regulator.c
+++ b/drivers/regulator/qcom_rpm-regulator.c
@@ -607,31 +607,6 @@ static const struct qcom_rpm_reg smb208_smps = {
607 .supports_force_mode_bypass = false, 607 .supports_force_mode_bypass = false,
608}; 608};
609 609
610static const struct of_device_id rpm_of_match[] = {
611 { .compatible = "qcom,rpm-pm8058-pldo", .data = &pm8058_pldo },
612 { .compatible = "qcom,rpm-pm8058-nldo", .data = &pm8058_nldo },
613 { .compatible = "qcom,rpm-pm8058-smps", .data = &pm8058_smps },
614 { .compatible = "qcom,rpm-pm8058-ncp", .data = &pm8058_ncp },
615 { .compatible = "qcom,rpm-pm8058-switch", .data = &pm8058_switch },
616
617 { .compatible = "qcom,rpm-pm8901-pldo", .data = &pm8901_pldo },
618 { .compatible = "qcom,rpm-pm8901-nldo", .data = &pm8901_nldo },
619 { .compatible = "qcom,rpm-pm8901-ftsmps", .data = &pm8901_ftsmps },
620 { .compatible = "qcom,rpm-pm8901-switch", .data = &pm8901_switch },
621
622 { .compatible = "qcom,rpm-pm8921-pldo", .data = &pm8921_pldo },
623 { .compatible = "qcom,rpm-pm8921-nldo", .data = &pm8921_nldo },
624 { .compatible = "qcom,rpm-pm8921-nldo1200", .data = &pm8921_nldo1200 },
625 { .compatible = "qcom,rpm-pm8921-smps", .data = &pm8921_smps },
626 { .compatible = "qcom,rpm-pm8921-ftsmps", .data = &pm8921_ftsmps },
627 { .compatible = "qcom,rpm-pm8921-ncp", .data = &pm8921_ncp },
628 { .compatible = "qcom,rpm-pm8921-switch", .data = &pm8921_switch },
629
630 { .compatible = "qcom,rpm-smb208", .data = &smb208_smps },
631 { }
632};
633MODULE_DEVICE_TABLE(of, rpm_of_match);
634
635static int rpm_reg_set(struct qcom_rpm_reg *vreg, 610static int rpm_reg_set(struct qcom_rpm_reg *vreg,
636 const struct request_member *req, 611 const struct request_member *req,
637 const int value) 612 const int value)
@@ -773,74 +748,177 @@ static int rpm_reg_of_parse(struct device_node *node,
773 return 0; 748 return 0;
774} 749}
775 750
776static int rpm_reg_probe(struct platform_device *pdev) 751struct rpm_regulator_data {
777{ 752 const char *name;
778 struct regulator_init_data *initdata; 753 int resource;
779 const struct qcom_rpm_reg *template; 754 const struct qcom_rpm_reg *template;
780 const struct of_device_id *match; 755 const char *supply;
781 struct regulator_config config = { }; 756};
782 struct regulator_dev *rdev; 757
783 struct qcom_rpm_reg *vreg; 758static const struct rpm_regulator_data rpm_pm8058_regulators[] = {
784 const char *key; 759 { "l0", QCOM_RPM_PM8058_LDO0, &pm8058_nldo, "vdd_l0_l1_lvs" },
785 u32 val; 760 { "l1", QCOM_RPM_PM8058_LDO1, &pm8058_nldo, "vdd_l0_l1_lvs" },
786 int ret; 761 { "l2", QCOM_RPM_PM8058_LDO2, &pm8058_pldo, "vdd_l2_l11_l12" },
762 { "l3", QCOM_RPM_PM8058_LDO3, &pm8058_pldo, "vdd_l3_l4_l5" },
763 { "l4", QCOM_RPM_PM8058_LDO4, &pm8058_pldo, "vdd_l3_l4_l5" },
764 { "l5", QCOM_RPM_PM8058_LDO5, &pm8058_pldo, "vdd_l3_l4_l5" },
765 { "l6", QCOM_RPM_PM8058_LDO6, &pm8058_pldo, "vdd_l6_l7" },
766 { "l7", QCOM_RPM_PM8058_LDO7, &pm8058_pldo, "vdd_l6_l7" },
767 { "l8", QCOM_RPM_PM8058_LDO8, &pm8058_pldo, "vdd_l8" },
768 { "l9", QCOM_RPM_PM8058_LDO9, &pm8058_pldo, "vdd_l9" },
769 { "l10", QCOM_RPM_PM8058_LDO10, &pm8058_pldo, "vdd_l10" },
770 { "l11", QCOM_RPM_PM8058_LDO11, &pm8058_pldo, "vdd_l2_l11_l12" },
771 { "l12", QCOM_RPM_PM8058_LDO12, &pm8058_pldo, "vdd_l2_l11_l12" },
772 { "l13", QCOM_RPM_PM8058_LDO13, &pm8058_pldo, "vdd_l13_l16" },
773 { "l14", QCOM_RPM_PM8058_LDO14, &pm8058_pldo, "vdd_l14_l15" },
774 { "l15", QCOM_RPM_PM8058_LDO15, &pm8058_pldo, "vdd_l14_l15" },
775 { "l16", QCOM_RPM_PM8058_LDO16, &pm8058_pldo, "vdd_l13_l16" },
776 { "l17", QCOM_RPM_PM8058_LDO17, &pm8058_pldo, "vdd_l17_l18" },
777 { "l18", QCOM_RPM_PM8058_LDO18, &pm8058_pldo, "vdd_l17_l18" },
778 { "l19", QCOM_RPM_PM8058_LDO19, &pm8058_pldo, "vdd_l19_l20" },
779 { "l20", QCOM_RPM_PM8058_LDO20, &pm8058_pldo, "vdd_l19_l20" },
780 { "l21", QCOM_RPM_PM8058_LDO21, &pm8058_nldo, "vdd_l21" },
781 { "l22", QCOM_RPM_PM8058_LDO22, &pm8058_nldo, "vdd_l22" },
782 { "l23", QCOM_RPM_PM8058_LDO23, &pm8058_nldo, "vdd_l23_l24_l25" },
783 { "l24", QCOM_RPM_PM8058_LDO24, &pm8058_nldo, "vdd_l23_l24_l25" },
784 { "l25", QCOM_RPM_PM8058_LDO25, &pm8058_nldo, "vdd_l23_l24_l25" },
785
786 { "s0", QCOM_RPM_PM8058_SMPS0, &pm8058_smps, "vdd_s0" },
787 { "s1", QCOM_RPM_PM8058_SMPS1, &pm8058_smps, "vdd_s1" },
788 { "s2", QCOM_RPM_PM8058_SMPS2, &pm8058_smps, "vdd_s2" },
789 { "s3", QCOM_RPM_PM8058_SMPS3, &pm8058_smps, "vdd_s3" },
790 { "s4", QCOM_RPM_PM8058_SMPS4, &pm8058_smps, "vdd_s4" },
791
792 { "lvs0", QCOM_RPM_PM8058_LVS0, &pm8058_switch, "vdd_l0_l1_lvs" },
793 { "lvs1", QCOM_RPM_PM8058_LVS1, &pm8058_switch, "vdd_l0_l1_lvs" },
794
795 { "ncp", QCOM_RPM_PM8058_NCP, &pm8058_ncp, "vdd_ncp" },
796 { }
797};
787 798
788 match = of_match_device(rpm_of_match, &pdev->dev); 799static const struct rpm_regulator_data rpm_pm8901_regulators[] = {
789 template = match->data; 800 { "l0", QCOM_RPM_PM8901_LDO0, &pm8901_nldo, "vdd_l0" },
801 { "l1", QCOM_RPM_PM8901_LDO1, &pm8901_pldo, "vdd_l1" },
802 { "l2", QCOM_RPM_PM8901_LDO2, &pm8901_pldo, "vdd_l2" },
803 { "l3", QCOM_RPM_PM8901_LDO3, &pm8901_pldo, "vdd_l3" },
804 { "l4", QCOM_RPM_PM8901_LDO4, &pm8901_pldo, "vdd_l4" },
805 { "l5", QCOM_RPM_PM8901_LDO5, &pm8901_pldo, "vdd_l5" },
806 { "l6", QCOM_RPM_PM8901_LDO6, &pm8901_pldo, "vdd_l6" },
790 807
791 vreg = devm_kmalloc(&pdev->dev, sizeof(*vreg), GFP_KERNEL); 808 { "s0", QCOM_RPM_PM8901_SMPS0, &pm8901_ftsmps, "vdd_s0" },
792 if (!vreg) { 809 { "s1", QCOM_RPM_PM8901_SMPS1, &pm8901_ftsmps, "vdd_s1" },
793 dev_err(&pdev->dev, "failed to allocate vreg\n"); 810 { "s2", QCOM_RPM_PM8901_SMPS2, &pm8901_ftsmps, "vdd_s2" },
794 return -ENOMEM; 811 { "s3", QCOM_RPM_PM8901_SMPS3, &pm8901_ftsmps, "vdd_s3" },
795 } 812 { "s4", QCOM_RPM_PM8901_SMPS4, &pm8901_ftsmps, "vdd_s4" },
796 memcpy(vreg, template, sizeof(*vreg));
797 mutex_init(&vreg->lock);
798 vreg->dev = &pdev->dev;
799 vreg->desc.id = -1;
800 vreg->desc.owner = THIS_MODULE;
801 vreg->desc.type = REGULATOR_VOLTAGE;
802 vreg->desc.name = pdev->dev.of_node->name;
803 vreg->desc.supply_name = "vin";
804
805 vreg->rpm = dev_get_drvdata(pdev->dev.parent);
806 if (!vreg->rpm) {
807 dev_err(&pdev->dev, "unable to retrieve handle to rpm\n");
808 return -ENODEV;
809 }
810 813
811 initdata = of_get_regulator_init_data(&pdev->dev, pdev->dev.of_node, 814 { "lvs0", QCOM_RPM_PM8901_LVS0, &pm8901_switch, "lvs0_in" },
812 &vreg->desc); 815 { "lvs1", QCOM_RPM_PM8901_LVS1, &pm8901_switch, "lvs1_in" },
813 if (!initdata) 816 { "lvs2", QCOM_RPM_PM8901_LVS2, &pm8901_switch, "lvs2_in" },
814 return -EINVAL; 817 { "lvs3", QCOM_RPM_PM8901_LVS3, &pm8901_switch, "lvs3_in" },
815 818
816 key = "reg"; 819 { "mvs", QCOM_RPM_PM8901_MVS, &pm8901_switch, "mvs_in" },
817 ret = of_property_read_u32(pdev->dev.of_node, key, &val); 820 { }
818 if (ret) { 821};
819 dev_err(&pdev->dev, "failed to read %s\n", key);
820 return ret;
821 }
822 vreg->resource = val;
823 822
824 if ((vreg->parts->uV.mask || vreg->parts->mV.mask) && 823static const struct rpm_regulator_data rpm_pm8921_regulators[] = {
825 (!initdata->constraints.min_uV || !initdata->constraints.max_uV)) { 824 { "s1", QCOM_RPM_PM8921_SMPS1, &pm8921_smps, "vdd_s1" },
826 dev_err(&pdev->dev, "no voltage specified for regulator\n"); 825 { "s2", QCOM_RPM_PM8921_SMPS2, &pm8921_smps, "vdd_s2" },
827 return -EINVAL; 826 { "s3", QCOM_RPM_PM8921_SMPS3, &pm8921_smps },
828 } 827 { "s4", QCOM_RPM_PM8921_SMPS4, &pm8921_smps, "vdd_s4" },
828 { "s7", QCOM_RPM_PM8921_SMPS7, &pm8921_smps, "vdd_s7" },
829 { "s8", QCOM_RPM_PM8921_SMPS8, &pm8921_smps, "vdd_s8" },
830
831 { "l1", QCOM_RPM_PM8921_LDO1, &pm8921_nldo, "vdd_l1_l2_l12_l18" },
832 { "l2", QCOM_RPM_PM8921_LDO2, &pm8921_nldo, "vdd_l1_l2_l12_l18" },
833 { "l3", QCOM_RPM_PM8921_LDO3, &pm8921_pldo, "vdd_l3_l15_l17" },
834 { "l4", QCOM_RPM_PM8921_LDO4, &pm8921_pldo, "vdd_l4_l14" },
835 { "l5", QCOM_RPM_PM8921_LDO5, &pm8921_pldo, "vdd_l5_l8_l16" },
836 { "l6", QCOM_RPM_PM8921_LDO6, &pm8921_pldo, "vdd_l6_l7" },
837 { "l7", QCOM_RPM_PM8921_LDO7, &pm8921_pldo, "vdd_l6_l7" },
838 { "l8", QCOM_RPM_PM8921_LDO8, &pm8921_pldo, "vdd_l5_l8_l16" },
839 { "l9", QCOM_RPM_PM8921_LDO9, &pm8921_pldo, "vdd_l9_l11" },
840 { "l10", QCOM_RPM_PM8921_LDO10, &pm8921_pldo, "vdd_l10_l22" },
841 { "l11", QCOM_RPM_PM8921_LDO11, &pm8921_pldo, "vdd_l9_l11" },
842 { "l12", QCOM_RPM_PM8921_LDO12, &pm8921_nldo, "vdd_l1_l2_l12_l18" },
843 { "l14", QCOM_RPM_PM8921_LDO14, &pm8921_pldo, "vdd_l4_l14" },
844 { "l15", QCOM_RPM_PM8921_LDO15, &pm8921_pldo, "vdd_l3_l15_l17" },
845 { "l16", QCOM_RPM_PM8921_LDO16, &pm8921_pldo, "vdd_l5_l8_l16" },
846 { "l17", QCOM_RPM_PM8921_LDO17, &pm8921_pldo, "vdd_l3_l15_l17" },
847 { "l18", QCOM_RPM_PM8921_LDO18, &pm8921_nldo, "vdd_l1_l2_l12_l18" },
848 { "l21", QCOM_RPM_PM8921_LDO21, &pm8921_pldo, "vdd_l21_l23_l29" },
849 { "l22", QCOM_RPM_PM8921_LDO22, &pm8921_pldo, "vdd_l10_l22" },
850 { "l23", QCOM_RPM_PM8921_LDO23, &pm8921_pldo, "vdd_l21_l23_l29" },
851 { "l24", QCOM_RPM_PM8921_LDO24, &pm8921_nldo1200, "vdd_l24" },
852 { "l25", QCOM_RPM_PM8921_LDO25, &pm8921_nldo1200, "vdd_l25" },
853 { "l26", QCOM_RPM_PM8921_LDO26, &pm8921_nldo1200, "vdd_l26" },
854 { "l27", QCOM_RPM_PM8921_LDO27, &pm8921_nldo1200, "vdd_l27" },
855 { "l28", QCOM_RPM_PM8921_LDO28, &pm8921_nldo1200, "vdd_l28" },
856 { "l29", QCOM_RPM_PM8921_LDO29, &pm8921_pldo, "vdd_l21_l23_l29" },
857
858 { "lvs1", QCOM_RPM_PM8921_LVS1, &pm8921_switch, "vin_lvs1_3_6" },
859 { "lvs2", QCOM_RPM_PM8921_LVS2, &pm8921_switch, "vin_lvs2" },
860 { "lvs3", QCOM_RPM_PM8921_LVS3, &pm8921_switch, "vin_lvs1_3_6" },
861 { "lvs4", QCOM_RPM_PM8921_LVS4, &pm8921_switch, "vin_lvs4_5_7" },
862 { "lvs5", QCOM_RPM_PM8921_LVS5, &pm8921_switch, "vin_lvs4_5_7" },
863 { "lvs6", QCOM_RPM_PM8921_LVS6, &pm8921_switch, "vin_lvs1_3_6" },
864 { "lvs7", QCOM_RPM_PM8921_LVS7, &pm8921_switch, "vin_lvs4_5_7" },
865
866 { "usb-switch", QCOM_RPM_USB_OTG_SWITCH, &pm8921_switch, "vin_5vs" },
867 { "hdmi-switch", QCOM_RPM_HDMI_SWITCH, &pm8921_switch, "vin_5vs" },
868 { "ncp", QCOM_RPM_PM8921_NCP, &pm8921_ncp, "vdd_ncp" },
869 { }
870};
829 871
872static const struct of_device_id rpm_of_match[] = {
873 { .compatible = "qcom,rpm-pm8058-regulators", .data = &rpm_pm8058_regulators },
874 { .compatible = "qcom,rpm-pm8901-regulators", .data = &rpm_pm8901_regulators },
875 { .compatible = "qcom,rpm-pm8921-regulators", .data = &rpm_pm8921_regulators },
876 { }
877};
878MODULE_DEVICE_TABLE(of, rpm_of_match);
830 879
831 config.dev = &pdev->dev; 880static int rpm_reg_probe(struct platform_device *pdev)
832 config.init_data = initdata; 881{
833 config.driver_data = vreg; 882 const struct rpm_regulator_data *reg;
834 config.of_node = pdev->dev.of_node; 883 const struct of_device_id *match;
884 struct regulator_config config = { };
885 struct regulator_dev *rdev;
886 struct qcom_rpm_reg *vreg;
835 887
836 ret = rpm_reg_of_parse(pdev->dev.of_node, &vreg->desc, &config); 888 match = of_match_device(rpm_of_match, &pdev->dev);
837 if (ret) 889 for (reg = match->data; reg->name; reg++) {
838 return ret; 890 vreg = devm_kmalloc(&pdev->dev, sizeof(*vreg), GFP_KERNEL);
891 if (!vreg) {
892 dev_err(&pdev->dev, "failed to allocate vreg\n");
893 return -ENOMEM;
894 }
895 memcpy(vreg, reg->template, sizeof(*vreg));
896 mutex_init(&vreg->lock);
897
898 vreg->dev = &pdev->dev;
899 vreg->resource = reg->resource;
900
901 vreg->desc.id = -1;
902 vreg->desc.owner = THIS_MODULE;
903 vreg->desc.type = REGULATOR_VOLTAGE;
904 vreg->desc.name = reg->name;
905 vreg->desc.supply_name = reg->supply;
906 vreg->desc.of_match = reg->name;
907 vreg->desc.of_parse_cb = rpm_reg_of_parse;
908
909 vreg->rpm = dev_get_drvdata(pdev->dev.parent);
910 if (!vreg->rpm) {
911 dev_err(&pdev->dev, "unable to retrieve handle to rpm\n");
912 return -ENODEV;
913 }
839 914
840 rdev = devm_regulator_register(&pdev->dev, &vreg->desc, &config); 915 config.dev = &pdev->dev;
841 if (IS_ERR(rdev)) { 916 config.driver_data = vreg;
842 dev_err(&pdev->dev, "can't register regulator\n"); 917 rdev = devm_regulator_register(&pdev->dev, &vreg->desc, &config);
843 return PTR_ERR(rdev); 918 if (IS_ERR(rdev)) {
919 dev_err(&pdev->dev, "can't register regulator\n");
920 return PTR_ERR(rdev);
921 }
844 } 922 }
845 923
846 return 0; 924 return 0;