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

Commit 16d1a057 authored by Hemant Kumar's avatar Hemant Kumar Committed by Mayank Rana
Browse files

usb: phy: handle phy related regulators properly



Currently driver is enabling all the regulators in probe
even if usb cable is not connected which has power impact.
Hence enable regulators before the phy initialization sequence
and move regulator_set_voltage & enable/disable API for vdd supply
in msm_ssusb_qmp_ldo_enable() to handle all the regulators from one
place.

Change-Id: Ibc4cf8328c209dbf968b7d6c498e1462397be351
Signed-off-by: default avatarHemant Kumar <hemantk@codeaurora.org>
Signed-off-by: default avatarMayank Rana <mrana@codeaurora.org>
parent 813952b4
Loading
Loading
Loading
Loading
+49 −60
Original line number Diff line number Diff line
@@ -88,7 +88,7 @@ struct msm_ssphy_qmp {
	struct clk		*pipe_clk;
	struct reset_control	*phy_reset;
	struct reset_control	*phy_phy_reset;

	bool			power_enabled;
	bool			clk_enabled;
	bool			cable_connected;
	bool			in_suspend;
@@ -159,38 +159,47 @@ static void msm_ssusb_qmp_enable_autonomous(struct msm_ssphy_qmp *phy,
	}
}


static int msm_ssusb_qmp_config_vdd(struct msm_ssphy_qmp *phy, int high)
static int msm_ssusb_qmp_ldo_enable(struct msm_ssphy_qmp *phy, int on)
{
	int min, ret;
	int min, rc = 0;

	min = high ? 1 : 0; /* low or none? */
	ret = regulator_set_voltage(phy->vdd, phy->vdd_levels[min],
				    phy->vdd_levels[2]);
	if (ret) {
		dev_err(phy->phy.dev, "unable to set voltage for ssusb vdd\n");
		return ret;
	}
	dev_dbg(phy->phy.dev, "reg (%s)\n", on ? "HPM" : "LPM");

	dev_dbg(phy->phy.dev, "min_vol:%d max_vol:%d\n",
		phy->vdd_levels[min], phy->vdd_levels[2]);
	return ret;
	if (phy->power_enabled == on) {
		dev_dbg(phy->phy.dev, "PHYs' regulators status %d\n",
			phy->power_enabled);
		return 0;
	}

static int msm_ssusb_qmp_ldo_enable(struct msm_ssphy_qmp *phy, int on)
{
	int rc = 0;
	phy->power_enabled = on;

	dev_dbg(phy->phy.dev, "reg (%s)\n", on ? "HPM" : "LPM");
	min = on ? 1 : 0; /* low or none? */

	if (!on)
		goto disable_regulators;

	rc = regulator_set_voltage(phy->vdd, phy->vdd_levels[min],
				    phy->vdd_levels[2]);
	if (rc) {
		dev_err(phy->phy.dev, "unable to set voltage for ssusb vdd\n");
		return rc;
	}

	dev_dbg(phy->phy.dev, "min_vol:%d max_vol:%d\n",
		phy->vdd_levels[min], phy->vdd_levels[2]);

	rc = regulator_enable(phy->vdd);
	if (rc) {
		dev_err(phy->phy.dev,
			"regulator_enable(phy->vdd) failed, ret=%d",
			rc);
		goto unconfig_vdd;
	}

	rc = regulator_set_load(phy->core_ldo, USB_SSPHY_HPM_LOAD);
	if (rc < 0) {
		dev_err(phy->phy.dev, "Unable to set HPM of core_ldo\n");
		return rc;
		goto disable_vdd;
	}

	rc = regulator_set_voltage(phy->core_ldo,
@@ -226,6 +235,18 @@ static int msm_ssusb_qmp_ldo_enable(struct msm_ssphy_qmp *phy, int on)
	if (rc < 0)
		dev_err(phy->phy.dev, "Unable to set LPM of core_ldo\n");

disable_vdd:
	rc = regulator_disable(phy->vdd);
	if (rc)
		dev_err(phy->phy.dev, "regulator_disable(phy->vdd) failed, ret=%d",
			rc);

unconfig_vdd:
	rc = regulator_set_voltage(phy->vdd, phy->vdd_levels[min],
				    phy->vdd_levels[2]);
	if (rc)
		dev_err(phy->phy.dev, "unable to set voltage for ssusb vdd\n");

	return rc < 0 ? rc : 0;
}

@@ -263,6 +284,14 @@ static int msm_ssphy_qmp_init(struct usb_phy *uphy)
	if (phy->emulation)
		return 0;

	ret = msm_ssusb_qmp_ldo_enable(phy, 1);
	if (ret) {
		dev_err(phy->phy.dev,
		"msm_ssusb_qmp_ldo_enable(1) failed, ret=%d\n",
		ret);
		return ret;
	}

	if (!phy->clk_enabled) {
		if (phy->ref_clk_src)
			clk_prepare_enable(phy->ref_clk_src);
@@ -391,12 +420,6 @@ static int msm_ssphy_power_enable(struct msm_ssphy_qmp *phy, bool on)
	 */
	if (!host && !phy->cable_connected) {
		if (on) {
			ret = regulator_enable(phy->vdd);
			if (ret)
				dev_err(phy->phy.dev,
					"regulator_enable(phy->vdd) failed, ret=%d",
					ret);

			ret = msm_ssusb_qmp_ldo_enable(phy, 1);
			if (ret)
				dev_err(phy->phy.dev,
@@ -408,11 +431,6 @@ static int msm_ssphy_power_enable(struct msm_ssphy_qmp *phy, bool on)
				dev_err(phy->phy.dev,
					"msm_ssusb_qmp_ldo_enable(0) failed, ret=%d\n",
					ret);

			ret = regulator_disable(phy->vdd);
			if (ret)
				dev_err(phy->phy.dev, "regulator_disable(phy->vdd) failed, ret=%d",
					ret);
		}
	}

@@ -708,24 +726,6 @@ static int msm_ssphy_qmp_probe(struct platform_device *pdev)
		goto err;
	}

	ret = msm_ssusb_qmp_config_vdd(phy, 1);
	if (ret) {
		dev_err(dev, "ssusb vdd_dig configuration failed\n");
		goto err;
	}

	ret = regulator_enable(phy->vdd);
	if (ret) {
		dev_err(dev, "unable to enable the ssusb vdd_dig\n");
		goto unconfig_ss_vdd;
	}

	ret = msm_ssusb_qmp_ldo_enable(phy, 1);
	if (ret) {
		dev_err(dev, "ssusb vreg enable failed\n");
		goto disable_ss_vdd;
	}

	phy->ref_clk_src = devm_clk_get(dev, "ref_clk_src");
	if (IS_ERR(phy->ref_clk_src))
		phy->ref_clk_src = NULL;
@@ -747,16 +747,7 @@ static int msm_ssphy_qmp_probe(struct platform_device *pdev)
	phy->phy.type			= USB_PHY_TYPE_USB3;

	ret = usb_add_phy_dev(&phy->phy);
	if (ret)
		goto disable_ss_ldo;
	return 0;

disable_ss_ldo:
	msm_ssusb_qmp_ldo_enable(phy, 0);
disable_ss_vdd:
	regulator_disable(phy->vdd);
unconfig_ss_vdd:
	msm_ssusb_qmp_config_vdd(phy, 0);
err:
	return ret;
}
@@ -774,8 +765,6 @@ static int msm_ssphy_qmp_remove(struct platform_device *pdev)
	if (phy->ref_clk_src)
		clk_disable_unprepare(phy->ref_clk_src);
	msm_ssusb_qmp_ldo_enable(phy, 0);
	regulator_disable(phy->vdd);
	msm_ssusb_qmp_config_vdd(phy, 0);
	clk_disable_unprepare(phy->aux_clk);
	clk_disable_unprepare(phy->cfg_ahb_clk);
	clk_disable_unprepare(phy->pipe_clk);