diff options
author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2012-12-09 22:43:00 -0500 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2012-12-09 22:43:00 -0500 |
commit | 9e218670737e01ef37bd1ac400482462049dfeff (patch) | |
tree | 84a6552a500127fac1bf860d2766c6a99e1d4827 /drivers/regulator | |
parent | f675649e70a494aa13ae695480a3d51bf15dd3e2 (diff) | |
parent | b87d07b13c779c42e4929e590003c9eb8c2f06fa (diff) |
Merge remote-tracking branch 'regulator/topic/max8997' into regulator-next
Diffstat (limited to 'drivers/regulator')
-rw-r--r-- | drivers/regulator/max8997.c | 181 |
1 files changed, 164 insertions, 17 deletions
diff --git a/drivers/regulator/max8997.c b/drivers/regulator/max8997.c index cea9ec9093eb..df0eafb0dc7e 100644 --- a/drivers/regulator/max8997.c +++ b/drivers/regulator/max8997.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/bug.h> | 24 | #include <linux/bug.h> |
25 | #include <linux/err.h> | 25 | #include <linux/err.h> |
26 | #include <linux/gpio.h> | 26 | #include <linux/gpio.h> |
27 | #include <linux/of_gpio.h> | ||
27 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
28 | #include <linux/module.h> | 29 | #include <linux/module.h> |
29 | #include <linux/platform_device.h> | 30 | #include <linux/platform_device.h> |
@@ -31,6 +32,7 @@ | |||
31 | #include <linux/regulator/machine.h> | 32 | #include <linux/regulator/machine.h> |
32 | #include <linux/mfd/max8997.h> | 33 | #include <linux/mfd/max8997.h> |
33 | #include <linux/mfd/max8997-private.h> | 34 | #include <linux/mfd/max8997-private.h> |
35 | #include <linux/regulator/of_regulator.h> | ||
34 | 36 | ||
35 | struct max8997_data { | 37 | struct max8997_data { |
36 | struct device *dev; | 38 | struct device *dev; |
@@ -933,22 +935,163 @@ static struct regulator_desc regulators[] = { | |||
933 | max8997_charger_fixedstate_ops), | 935 | max8997_charger_fixedstate_ops), |
934 | }; | 936 | }; |
935 | 937 | ||
938 | #ifdef CONFIG_OF | ||
939 | static int max8997_pmic_dt_parse_dvs_gpio(struct max8997_dev *iodev, | ||
940 | struct max8997_platform_data *pdata, | ||
941 | struct device_node *pmic_np) | ||
942 | { | ||
943 | int i, gpio; | ||
944 | |||
945 | for (i = 0; i < 3; i++) { | ||
946 | gpio = of_get_named_gpio(pmic_np, | ||
947 | "max8997,pmic-buck125-dvs-gpios", i); | ||
948 | if (!gpio_is_valid(gpio)) { | ||
949 | dev_err(iodev->dev, "invalid gpio[%d]: %d\n", i, gpio); | ||
950 | return -EINVAL; | ||
951 | } | ||
952 | pdata->buck125_gpios[i] = gpio; | ||
953 | } | ||
954 | return 0; | ||
955 | } | ||
956 | |||
957 | static int max8997_pmic_dt_parse_pdata(struct max8997_dev *iodev, | ||
958 | struct max8997_platform_data *pdata) | ||
959 | { | ||
960 | struct device_node *pmic_np, *regulators_np, *reg_np; | ||
961 | struct max8997_regulator_data *rdata; | ||
962 | unsigned int i, dvs_voltage_nr = 1, ret; | ||
963 | |||
964 | pmic_np = iodev->dev->of_node; | ||
965 | if (!pmic_np) { | ||
966 | dev_err(iodev->dev, "could not find pmic sub-node\n"); | ||
967 | return -ENODEV; | ||
968 | } | ||
969 | |||
970 | regulators_np = of_find_node_by_name(pmic_np, "regulators"); | ||
971 | if (!regulators_np) { | ||
972 | dev_err(iodev->dev, "could not find regulators sub-node\n"); | ||
973 | return -EINVAL; | ||
974 | } | ||
975 | |||
976 | /* count the number of regulators to be supported in pmic */ | ||
977 | pdata->num_regulators = 0; | ||
978 | for_each_child_of_node(regulators_np, reg_np) | ||
979 | pdata->num_regulators++; | ||
980 | |||
981 | rdata = devm_kzalloc(iodev->dev, sizeof(*rdata) * | ||
982 | pdata->num_regulators, GFP_KERNEL); | ||
983 | if (!rdata) { | ||
984 | dev_err(iodev->dev, "could not allocate memory for " | ||
985 | "regulator data\n"); | ||
986 | return -ENOMEM; | ||
987 | } | ||
988 | |||
989 | pdata->regulators = rdata; | ||
990 | for_each_child_of_node(regulators_np, reg_np) { | ||
991 | for (i = 0; i < ARRAY_SIZE(regulators); i++) | ||
992 | if (!of_node_cmp(reg_np->name, regulators[i].name)) | ||
993 | break; | ||
994 | |||
995 | if (i == ARRAY_SIZE(regulators)) { | ||
996 | dev_warn(iodev->dev, "don't know how to configure " | ||
997 | "regulator %s\n", reg_np->name); | ||
998 | continue; | ||
999 | } | ||
1000 | |||
1001 | rdata->id = i; | ||
1002 | rdata->initdata = of_get_regulator_init_data( | ||
1003 | iodev->dev, reg_np); | ||
1004 | rdata->reg_node = reg_np; | ||
1005 | rdata++; | ||
1006 | } | ||
1007 | |||
1008 | if (of_get_property(pmic_np, "max8997,pmic-buck1-uses-gpio-dvs", NULL)) | ||
1009 | pdata->buck1_gpiodvs = true; | ||
1010 | |||
1011 | if (of_get_property(pmic_np, "max8997,pmic-buck2-uses-gpio-dvs", NULL)) | ||
1012 | pdata->buck2_gpiodvs = true; | ||
1013 | |||
1014 | if (of_get_property(pmic_np, "max8997,pmic-buck5-uses-gpio-dvs", NULL)) | ||
1015 | pdata->buck5_gpiodvs = true; | ||
1016 | |||
1017 | if (pdata->buck1_gpiodvs || pdata->buck2_gpiodvs || | ||
1018 | pdata->buck5_gpiodvs) { | ||
1019 | ret = max8997_pmic_dt_parse_dvs_gpio(iodev, pdata, pmic_np); | ||
1020 | if (ret) | ||
1021 | return -EINVAL; | ||
1022 | |||
1023 | if (of_property_read_u32(pmic_np, | ||
1024 | "max8997,pmic-buck125-default-dvs-idx", | ||
1025 | &pdata->buck125_default_idx)) { | ||
1026 | pdata->buck125_default_idx = 0; | ||
1027 | } else { | ||
1028 | if (pdata->buck125_default_idx >= 8) { | ||
1029 | pdata->buck125_default_idx = 0; | ||
1030 | dev_info(iodev->dev, "invalid value for " | ||
1031 | "default dvs index, using 0 instead\n"); | ||
1032 | } | ||
1033 | } | ||
1034 | |||
1035 | if (of_get_property(pmic_np, | ||
1036 | "max8997,pmic-ignore-gpiodvs-side-effect", NULL)) | ||
1037 | pdata->ignore_gpiodvs_side_effect = true; | ||
1038 | |||
1039 | dvs_voltage_nr = 8; | ||
1040 | } | ||
1041 | |||
1042 | if (of_property_read_u32_array(pmic_np, | ||
1043 | "max8997,pmic-buck1-dvs-voltage", | ||
1044 | pdata->buck1_voltage, dvs_voltage_nr)) { | ||
1045 | dev_err(iodev->dev, "buck1 voltages not specified\n"); | ||
1046 | return -EINVAL; | ||
1047 | } | ||
1048 | |||
1049 | if (of_property_read_u32_array(pmic_np, | ||
1050 | "max8997,pmic-buck2-dvs-voltage", | ||
1051 | pdata->buck2_voltage, dvs_voltage_nr)) { | ||
1052 | dev_err(iodev->dev, "buck2 voltages not specified\n"); | ||
1053 | return -EINVAL; | ||
1054 | } | ||
1055 | |||
1056 | if (of_property_read_u32_array(pmic_np, | ||
1057 | "max8997,pmic-buck5-dvs-voltage", | ||
1058 | pdata->buck5_voltage, dvs_voltage_nr)) { | ||
1059 | dev_err(iodev->dev, "buck5 voltages not specified\n"); | ||
1060 | return -EINVAL; | ||
1061 | } | ||
1062 | |||
1063 | return 0; | ||
1064 | } | ||
1065 | #else | ||
1066 | static int max8997_pmic_dt_parse_pdata(struct max8997_dev *iodev, | ||
1067 | struct max8997_platform_data *pdata) | ||
1068 | { | ||
1069 | return 0; | ||
1070 | } | ||
1071 | #endif /* CONFIG_OF */ | ||
1072 | |||
936 | static int max8997_pmic_probe(struct platform_device *pdev) | 1073 | static int max8997_pmic_probe(struct platform_device *pdev) |
937 | { | 1074 | { |
938 | struct max8997_dev *iodev = dev_get_drvdata(pdev->dev.parent); | 1075 | struct max8997_dev *iodev = dev_get_drvdata(pdev->dev.parent); |
939 | struct max8997_platform_data *pdata = dev_get_platdata(iodev->dev); | 1076 | struct max8997_platform_data *pdata = iodev->pdata; |
940 | struct regulator_config config = { }; | 1077 | struct regulator_config config = { }; |
941 | struct regulator_dev **rdev; | 1078 | struct regulator_dev **rdev; |
942 | struct max8997_data *max8997; | 1079 | struct max8997_data *max8997; |
943 | struct i2c_client *i2c; | 1080 | struct i2c_client *i2c; |
944 | int i, ret, size; | 1081 | int i, ret, size, nr_dvs; |
945 | u8 max_buck1 = 0, max_buck2 = 0, max_buck5 = 0; | 1082 | u8 max_buck1 = 0, max_buck2 = 0, max_buck5 = 0; |
946 | 1083 | ||
947 | if (!pdata) { | 1084 | if (IS_ERR_OR_NULL(pdata)) { |
948 | dev_err(pdev->dev.parent, "No platform init data supplied.\n"); | 1085 | dev_err(pdev->dev.parent, "No platform init data supplied.\n"); |
949 | return -ENODEV; | 1086 | return -ENODEV; |
950 | } | 1087 | } |
951 | 1088 | ||
1089 | if (iodev->dev->of_node) { | ||
1090 | ret = max8997_pmic_dt_parse_pdata(iodev, pdata); | ||
1091 | if (ret) | ||
1092 | return ret; | ||
1093 | } | ||
1094 | |||
952 | max8997 = devm_kzalloc(&pdev->dev, sizeof(struct max8997_data), | 1095 | max8997 = devm_kzalloc(&pdev->dev, sizeof(struct max8997_data), |
953 | GFP_KERNEL); | 1096 | GFP_KERNEL); |
954 | if (!max8997) | 1097 | if (!max8997) |
@@ -973,7 +1116,10 @@ static int max8997_pmic_probe(struct platform_device *pdev) | |||
973 | memcpy(max8997->buck125_gpios, pdata->buck125_gpios, sizeof(int) * 3); | 1116 | memcpy(max8997->buck125_gpios, pdata->buck125_gpios, sizeof(int) * 3); |
974 | max8997->ignore_gpiodvs_side_effect = pdata->ignore_gpiodvs_side_effect; | 1117 | max8997->ignore_gpiodvs_side_effect = pdata->ignore_gpiodvs_side_effect; |
975 | 1118 | ||
976 | for (i = 0; i < 8; i++) { | 1119 | nr_dvs = (pdata->buck1_gpiodvs || pdata->buck2_gpiodvs || |
1120 | pdata->buck5_gpiodvs) ? 8 : 1; | ||
1121 | |||
1122 | for (i = 0; i < nr_dvs; i++) { | ||
977 | max8997->buck1_vol[i] = ret = | 1123 | max8997->buck1_vol[i] = ret = |
978 | max8997_get_voltage_proper_val( | 1124 | max8997_get_voltage_proper_val( |
979 | &buck1245_voltage_map_desc, | 1125 | &buck1245_voltage_map_desc, |
@@ -1019,6 +1165,19 @@ static int max8997_pmic_probe(struct platform_device *pdev) | |||
1019 | max_buck5, 0x3f); | 1165 | max_buck5, 0x3f); |
1020 | } | 1166 | } |
1021 | 1167 | ||
1168 | /* Initialize all the DVS related BUCK registers */ | ||
1169 | for (i = 0; i < nr_dvs; i++) { | ||
1170 | max8997_update_reg(i2c, MAX8997_REG_BUCK1DVS1 + i, | ||
1171 | max8997->buck1_vol[i], | ||
1172 | 0x3f); | ||
1173 | max8997_update_reg(i2c, MAX8997_REG_BUCK2DVS1 + i, | ||
1174 | max8997->buck2_vol[i], | ||
1175 | 0x3f); | ||
1176 | max8997_update_reg(i2c, MAX8997_REG_BUCK5DVS1 + i, | ||
1177 | max8997->buck5_vol[i], | ||
1178 | 0x3f); | ||
1179 | } | ||
1180 | |||
1022 | /* | 1181 | /* |
1023 | * If buck 1, 2, and 5 do not care DVS GPIO settings, ignore them. | 1182 | * If buck 1, 2, and 5 do not care DVS GPIO settings, ignore them. |
1024 | * If at least one of them cares, set gpios. | 1183 | * If at least one of them cares, set gpios. |
@@ -1068,19 +1227,6 @@ static int max8997_pmic_probe(struct platform_device *pdev) | |||
1068 | max8997_update_reg(i2c, MAX8997_REG_BUCK5CTRL, (pdata->buck5_gpiodvs) ? | 1227 | max8997_update_reg(i2c, MAX8997_REG_BUCK5CTRL, (pdata->buck5_gpiodvs) ? |
1069 | (1 << 1) : (0 << 1), 1 << 1); | 1228 | (1 << 1) : (0 << 1), 1 << 1); |
1070 | 1229 | ||
1071 | /* Initialize all the DVS related BUCK registers */ | ||
1072 | for (i = 0; i < 8; i++) { | ||
1073 | max8997_update_reg(i2c, MAX8997_REG_BUCK1DVS1 + i, | ||
1074 | max8997->buck1_vol[i], | ||
1075 | 0x3f); | ||
1076 | max8997_update_reg(i2c, MAX8997_REG_BUCK2DVS1 + i, | ||
1077 | max8997->buck2_vol[i], | ||
1078 | 0x3f); | ||
1079 | max8997_update_reg(i2c, MAX8997_REG_BUCK5DVS1 + i, | ||
1080 | max8997->buck5_vol[i], | ||
1081 | 0x3f); | ||
1082 | } | ||
1083 | |||
1084 | /* Misc Settings */ | 1230 | /* Misc Settings */ |
1085 | max8997->ramp_delay = 10; /* set 10mV/us, which is the default */ | 1231 | max8997->ramp_delay = 10; /* set 10mV/us, which is the default */ |
1086 | max8997_write_reg(i2c, MAX8997_REG_BUCKRAMP, (0xf << 4) | 0x9); | 1232 | max8997_write_reg(i2c, MAX8997_REG_BUCKRAMP, (0xf << 4) | 0x9); |
@@ -1101,6 +1247,7 @@ static int max8997_pmic_probe(struct platform_device *pdev) | |||
1101 | config.dev = max8997->dev; | 1247 | config.dev = max8997->dev; |
1102 | config.init_data = pdata->regulators[i].initdata; | 1248 | config.init_data = pdata->regulators[i].initdata; |
1103 | config.driver_data = max8997; | 1249 | config.driver_data = max8997; |
1250 | config.of_node = pdata->regulators[i].reg_node; | ||
1104 | 1251 | ||
1105 | rdev[i] = regulator_register(®ulators[id], &config); | 1252 | rdev[i] = regulator_register(®ulators[id], &config); |
1106 | if (IS_ERR(rdev[i])) { | 1253 | if (IS_ERR(rdev[i])) { |