summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Sarraf <asarraf@codeaurora.org>2015-09-16 15:51:50 -0700
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-23 20:58:02 -0700
commitd42067104fda96b4b05f7a9b3ae95e45b6d65dce (patch)
treed47a2733ac1cca95cf468381050aa5abfec92c27
parentd42befffb2fec4fd226c3c2d3ae332b1643586b3 (diff)
input: misc: hbtp_input: Add digital regulator support
Add support for the digital regulator in hbtp_input driver. Signed-off-by: Alex Sarraf <asarraf@codeaurora.org> Change-Id: I315d4b4c985917e55823a3c3951f2bffb20b39e6
-rw-r--r--Documentation/devicetree/bindings/input/hbtp-input.txt21
-rw-r--r--drivers/input/misc/hbtp_input.c167
2 files changed, 138 insertions, 50 deletions
diff --git a/Documentation/devicetree/bindings/input/hbtp-input.txt b/Documentation/devicetree/bindings/input/hbtp-input.txt
index d4a248bac085..da7057b25089 100644
--- a/Documentation/devicetree/bindings/input/hbtp-input.txt
+++ b/Documentation/devicetree/bindings/input/hbtp-input.txt
@@ -12,17 +12,24 @@ Required properties:
Optional properties:
- vcc_ana-supply : Analog power supply needed to power device
- - qcom,afe-load : AFE load in uA
- - qcom,afe-vtg-min : AFE minimum voltage in uV
- - qcom,afe-vtg-max : AFE maximum voltage in uV
+ - qcom,afe-load : AFE/Analog supply load in uA
+ - qcom,afe-vtg-min : AFE/Analog minimum voltage in uV
+ - qcom,afe-vtg-max : AFE/Analog maximum voltage in uV
+ - qcom,dig-load : Digital supply load in uA
+ - qcom,dig-vtg-min : Digital supply minimum voltage in uV
+ - qcom,dig-vtg-max : Digital supply maximum voltage in uV
Example:
&soc {
hbtp {
compatible = "qcom,hbtp-input";
- vcc_ana-supply = <&pm8941_l18>;
- qcom,afe-load = <150000>;
- qcom,afe-vtg-min = <2700000>;
- qcom,afe-vtg-max = <3300000>;
+ vcc_ana-supply = <&pm8941_l17>;
+ vcc_dig-supply = <&pm8950_l16>;
+ qcom,afe-load = <50000>;
+ qcom,afe-vtg-min = <2850000>;
+ qcom,afe-vtg-max = <2850000>;
+ qcom,dig-load = <15000>;
+ qcom,dig-vtg-min = <1800000>;
+ qcom,dig-vtg-max = <1800000>;
};
};
diff --git a/drivers/input/misc/hbtp_input.c b/drivers/input/misc/hbtp_input.c
index 74637c4d0428..29143cacda69 100644
--- a/drivers/input/misc/hbtp_input.c
+++ b/drivers/input/misc/hbtp_input.c
@@ -41,10 +41,15 @@ struct hbtp_data {
struct notifier_block fb_notif;
#endif
struct regulator *vcc_ana;
+ struct regulator *vcc_dig;
int afe_load_ua;
int afe_vtg_min_uv;
int afe_vtg_max_uv;
- bool manage_afe_power;
+ int dig_load_ua;
+ int dig_vtg_min_uv;
+ int dig_vtg_max_uv;
+ bool manage_afe_power_ana;
+ bool manage_power_dig;
};
static struct hbtp_data *hbtp;
@@ -204,40 +209,68 @@ static int reg_set_optimum_mode_check(struct regulator *reg, int load_uA)
static int hbtp_pdev_power_on(struct hbtp_data *hbtp, bool on)
{
- int ret, error;
+ int ret;
- if (!hbtp->vcc_ana) {
- pr_err("%s: regulator is not available\n", __func__);
+ if (!hbtp->vcc_ana)
+ pr_err("%s: analog regulator is not available\n", __func__);
+
+ if (!hbtp->vcc_dig)
+ pr_err("%s: digital regulator is not available\n", __func__);
+
+ if (!hbtp->vcc_ana && !hbtp->vcc_dig) {
+ pr_err("%s: no regulators available\n", __func__);
return -EINVAL;
}
if (!on)
goto reg_off;
- ret = reg_set_optimum_mode_check(hbtp->vcc_ana, hbtp->afe_load_ua);
- if (ret < 0) {
- pr_err("%s: Regulator vcc_ana set_opt failed rc=%d\n",
- __func__, ret);
- return -EINVAL;
+ if (hbtp->vcc_ana) {
+ ret = reg_set_optimum_mode_check(hbtp->vcc_ana,
+ hbtp->afe_load_ua);
+ if (ret < 0) {
+ pr_err("%s: Regulator vcc_ana set_opt failed rc=%d\n",
+ __func__, ret);
+ return ret;
+ }
+
+ ret = regulator_enable(hbtp->vcc_ana);
+ if (ret) {
+ pr_err("%s: Regulator vcc_ana enable failed rc=%d\n",
+ __func__, ret);
+ reg_set_optimum_mode_check(hbtp->vcc_ana, 0);
+ return ret;
+ }
}
+ if (hbtp->vcc_dig) {
+ ret = reg_set_optimum_mode_check(hbtp->vcc_dig,
+ hbtp->dig_load_ua);
+ if (ret < 0) {
+ pr_err("%s: Regulator vcc_dig set_opt failed rc=%d\n",
+ __func__, ret);
+ return ret;
+ }
- ret = regulator_enable(hbtp->vcc_ana);
- if (ret) {
- pr_err("%s: Regulator vcc_ana enable failed rc=%d\n",
- __func__, ret);
- error = -EINVAL;
- goto error_reg_en_vcc_ana;
+ ret = regulator_enable(hbtp->vcc_dig);
+ if (ret) {
+ pr_err("%s: Regulator vcc_dig enable failed rc=%d\n",
+ __func__, ret);
+ reg_set_optimum_mode_check(hbtp->vcc_dig, 0);
+ return ret;
+ }
}
return 0;
-error_reg_en_vcc_ana:
- reg_set_optimum_mode_check(hbtp->vcc_ana, 0);
- return error;
-
reg_off:
- reg_set_optimum_mode_check(hbtp->vcc_ana, 0);
- regulator_disable(hbtp->vcc_ana);
+ if (hbtp->vcc_ana) {
+ reg_set_optimum_mode_check(hbtp->vcc_ana, 0);
+ regulator_disable(hbtp->vcc_ana);
+ }
+ if (hbtp->vcc_dig) {
+ reg_set_optimum_mode_check(hbtp->vcc_dig, 0);
+ regulator_disable(hbtp->vcc_dig);
+ }
return 0;
}
@@ -387,9 +420,12 @@ static int hbtp_parse_dt(struct device *dev)
struct device_node *np = dev->of_node;
u32 temp_val;
- if (of_find_property(np, "vcc_ana-supply", NULL)) {
- hbtp->manage_afe_power = true;
+ if (of_find_property(np, "vcc_ana-supply", NULL))
+ hbtp->manage_afe_power_ana = true;
+ if (of_find_property(np, "vcc_dig-supply", NULL))
+ hbtp->manage_power_dig = true;
+ if (hbtp->manage_afe_power_ana) {
rc = of_property_read_u32(np, "qcom,afe-load", &temp_val);
if (!rc) {
hbtp->afe_load_ua = (int) temp_val;
@@ -414,6 +450,31 @@ static int hbtp_parse_dt(struct device *dev)
return rc;
}
}
+ if (hbtp->manage_power_dig) {
+ rc = of_property_read_u32(np, "qcom,dig-load", &temp_val);
+ if (!rc) {
+ hbtp->dig_load_ua = (int) temp_val;
+ } else {
+ dev_err(dev, "Unable to read digital load\n");
+ return rc;
+ }
+
+ rc = of_property_read_u32(np, "qcom,dig-vtg-min", &temp_val);
+ if (!rc) {
+ hbtp->dig_vtg_min_uv = (int) temp_val;
+ } else {
+ dev_err(dev, "Unable to read digital min voltage\n");
+ return rc;
+ }
+
+ rc = of_property_read_u32(np, "qcom,dig-vtg-max", &temp_val);
+ if (!rc) {
+ hbtp->dig_vtg_max_uv = (int) temp_val;
+ } else {
+ dev_err(dev, "Unable to read digital max voltage\n");
+ return rc;
+ }
+ }
return 0;
}
@@ -426,8 +487,8 @@ static int hbtp_parse_dt(struct device *dev)
static int hbtp_pdev_probe(struct platform_device *pdev)
{
- int error, ret;
- struct regulator *vcc_ana;
+ int error;
+ struct regulator *vcc_ana, *vcc_dig;
if (pdev->dev.of_node) {
error = hbtp_parse_dt(&pdev->dev);
@@ -437,43 +498,63 @@ static int hbtp_pdev_probe(struct platform_device *pdev)
}
}
- if (hbtp->manage_afe_power) {
+ if (hbtp->manage_afe_power_ana) {
vcc_ana = regulator_get(&pdev->dev, "vcc_ana");
if (IS_ERR(vcc_ana)) {
- ret = PTR_ERR(vcc_ana);
+ error = PTR_ERR(vcc_ana);
pr_err("%s: regulator get failed vcc_ana rc=%d\n",
- __func__, ret);
- return -EINVAL;
+ __func__, error);
+ return error;
}
if (regulator_count_voltages(vcc_ana) > 0) {
- ret = regulator_set_voltage(vcc_ana,
+ error = regulator_set_voltage(vcc_ana,
hbtp->afe_vtg_min_uv, hbtp->afe_vtg_max_uv);
- if (ret) {
- pr_err("%s: regulator set vtg failed rc=%d\n",
- __func__, ret);
- error = -EINVAL;
- goto error_set_vtg_vcc_ana;
+ if (error) {
+ pr_err("%s: regulator set vtg failed vcc_ana rc=%d\n",
+ __func__, error);
+ regulator_put(vcc_ana);
+ return error;
}
}
hbtp->vcc_ana = vcc_ana;
}
- hbtp->pdev = pdev;
+ if (hbtp->manage_power_dig) {
+ vcc_dig = regulator_get(&pdev->dev, "vcc_dig");
+ if (IS_ERR(vcc_dig)) {
+ error = PTR_ERR(vcc_dig);
+ pr_err("%s: regulator get failed vcc_dig rc=%d\n",
+ __func__, error);
+ return error;
+ }
- return 0;
+ if (regulator_count_voltages(vcc_dig) > 0) {
+ error = regulator_set_voltage(vcc_dig,
+ hbtp->dig_vtg_min_uv, hbtp->dig_vtg_max_uv);
+ if (error) {
+ pr_err("%s: regulator set vtg failed vcc_dig rc=%d\n",
+ __func__, error);
+ regulator_put(vcc_dig);
+ return error;
+ }
+ }
+ hbtp->vcc_dig = vcc_dig;
+ }
-error_set_vtg_vcc_ana:
- regulator_put(vcc_ana);
+ hbtp->pdev = pdev;
- return error;
-};
+ return 0;
+}
static int hbtp_pdev_remove(struct platform_device *pdev)
{
- if (hbtp->vcc_ana) {
+ if (hbtp->vcc_ana || hbtp->vcc_dig) {
hbtp_pdev_power_on(hbtp, false);
- regulator_put(hbtp->vcc_ana);
+ if (hbtp->vcc_ana)
+ regulator_put(hbtp->vcc_ana);
+ if (hbtp->vcc_dig)
+ regulator_put(hbtp->vcc_dig);
}
return 0;