Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e9fe8a50 authored by Alex Sarraf's avatar Alex Sarraf
Browse files

input: misc: hbtp_input: Add digital regulator support



Add support for the digital regulator in hbtp_input driver.

Signed-off-by: default avatarAlex Sarraf <asarraf@codeaurora.org>
Change-Id: I315d4b4c985917e55823a3c3951f2bffb20b39e6
parent 266cc964
Loading
Loading
Loading
Loading
+14 −7
Original line number Diff line number Diff line
@@ -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>;
		};
	};
+124 −43
Original line number Diff line number Diff line
@@ -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 (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 -EINVAL;
			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;
			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;
		}

	return 0;
		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;
		}
	}

error_reg_en_vcc_ana:
	reg_set_optimum_mode_check(hbtp->vcc_ana, 0);
	return error;
	return 0;

reg_off:
	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);
		if (hbtp->vcc_ana)
			regulator_put(hbtp->vcc_ana);
		if (hbtp->vcc_dig)
			regulator_put(hbtp->vcc_dig);
	}

	return 0;