USB: phy: qusb: Turn on vdd along with 1p8/3p3 LDOs when PMI requests

QUSB PHY requires VDD, 1p8 and 3p1 regulators to remove any unwanted
pull downs on DP/DM lines. These pull downs may result in incorrect charger
detection by PMI. Avoid incorrect charger detection by turning on VDD,
1p8 and 3p1 whenever PMI requests DP/DM to be floating.

Change-Id: I27e68d5ebf2f49fb6571ad777318483f9c123407
Signed-off-by: Hemant Kumar <hemantk@codeaurora.org>
This commit is contained in:
Hemant Kumar 2017-04-27 17:51:11 -07:00
parent 65620a280f
commit 1fb7012ac6

View file

@ -160,15 +160,14 @@ static int qusb_phy_config_vdd(struct qusb_phy *qphy, int high)
return ret; return ret;
} }
static int qusb_phy_enable_power(struct qusb_phy *qphy, bool on, static int qusb_phy_enable_power(struct qusb_phy *qphy, bool on)
bool toggle_vdd)
{ {
int ret = 0; int ret = 0;
dev_dbg(qphy->phy.dev, "%s turn %s regulators. power_enabled:%d\n", dev_dbg(qphy->phy.dev, "%s turn %s regulators. power_enabled:%d\n",
__func__, on ? "on" : "off", qphy->power_enabled); __func__, on ? "on" : "off", qphy->power_enabled);
if (toggle_vdd && qphy->power_enabled == on) { if (qphy->power_enabled == on) {
dev_dbg(qphy->phy.dev, "PHYs' regulators are already ON.\n"); dev_dbg(qphy->phy.dev, "PHYs' regulators are already ON.\n");
return 0; return 0;
} }
@ -176,7 +175,6 @@ static int qusb_phy_enable_power(struct qusb_phy *qphy, bool on,
if (!on) if (!on)
goto disable_vdda33; goto disable_vdda33;
if (toggle_vdd) {
ret = qusb_phy_config_vdd(qphy, true); ret = qusb_phy_config_vdd(qphy, true);
if (ret) { if (ret) {
dev_err(qphy->phy.dev, "Unable to config VDD:%d\n", dev_err(qphy->phy.dev, "Unable to config VDD:%d\n",
@ -189,7 +187,6 @@ static int qusb_phy_enable_power(struct qusb_phy *qphy, bool on,
dev_err(qphy->phy.dev, "Unable to enable VDD\n"); dev_err(qphy->phy.dev, "Unable to enable VDD\n");
goto unconfig_vdd; goto unconfig_vdd;
} }
}
ret = regulator_set_load(qphy->vdda12, QUSB2PHY_1P2_HPM_LOAD); ret = regulator_set_load(qphy->vdda12, QUSB2PHY_1P2_HPM_LOAD);
if (ret < 0) { if (ret < 0) {
@ -251,7 +248,6 @@ static int qusb_phy_enable_power(struct qusb_phy *qphy, bool on,
goto unset_vdd33; goto unset_vdd33;
} }
if (toggle_vdd)
qphy->power_enabled = true; qphy->power_enabled = true;
pr_debug("%s(): QUSB PHY's regulators are turned ON.\n", __func__); pr_debug("%s(): QUSB PHY's regulators are turned ON.\n", __func__);
@ -304,7 +300,6 @@ put_vdda12_lpm:
dev_err(qphy->phy.dev, "Unable to set LPM of vdda12\n"); dev_err(qphy->phy.dev, "Unable to set LPM of vdda12\n");
disable_vdd: disable_vdd:
if (toggle_vdd) {
ret = regulator_disable(qphy->vdd); ret = regulator_disable(qphy->vdd);
if (ret) if (ret)
dev_err(qphy->phy.dev, "Unable to disable vdd:%d\n", dev_err(qphy->phy.dev, "Unable to disable vdd:%d\n",
@ -315,9 +310,7 @@ unconfig_vdd:
if (ret) if (ret)
dev_err(qphy->phy.dev, "Unable unconfig VDD:%d\n", dev_err(qphy->phy.dev, "Unable unconfig VDD:%d\n",
ret); ret);
}
err_vdd: err_vdd:
if (toggle_vdd)
qphy->power_enabled = false; qphy->power_enabled = false;
dev_dbg(qphy->phy.dev, "QUSB PHY's regulators are turned OFF.\n"); dev_dbg(qphy->phy.dev, "QUSB PHY's regulators are turned OFF.\n");
return ret; return ret;
@ -335,7 +328,7 @@ static int qusb_phy_update_dpdm(struct usb_phy *phy, int value)
case POWER_SUPPLY_DP_DM_DPF_DMF: case POWER_SUPPLY_DP_DM_DPF_DMF:
dev_dbg(phy->dev, "POWER_SUPPLY_DP_DM_DPF_DMF\n"); dev_dbg(phy->dev, "POWER_SUPPLY_DP_DM_DPF_DMF\n");
if (!qphy->rm_pulldown) { if (!qphy->rm_pulldown) {
ret = qusb_phy_enable_power(qphy, true, false); ret = qusb_phy_enable_power(qphy, true);
if (ret >= 0) { if (ret >= 0) {
qphy->rm_pulldown = true; qphy->rm_pulldown = true;
dev_dbg(phy->dev, "DP_DM_F: rm_pulldown:%d\n", dev_dbg(phy->dev, "DP_DM_F: rm_pulldown:%d\n",
@ -348,7 +341,7 @@ static int qusb_phy_update_dpdm(struct usb_phy *phy, int value)
case POWER_SUPPLY_DP_DM_DPR_DMR: case POWER_SUPPLY_DP_DM_DPR_DMR:
dev_dbg(phy->dev, "POWER_SUPPLY_DP_DM_DPR_DMR\n"); dev_dbg(phy->dev, "POWER_SUPPLY_DP_DM_DPR_DMR\n");
if (qphy->rm_pulldown) { if (qphy->rm_pulldown) {
ret = qusb_phy_enable_power(qphy, false, false); ret = qusb_phy_enable_power(qphy, false);
if (ret >= 0) { if (ret >= 0) {
qphy->rm_pulldown = false; qphy->rm_pulldown = false;
dev_dbg(phy->dev, "DP_DM_R: rm_pulldown:%d\n", dev_dbg(phy->dev, "DP_DM_R: rm_pulldown:%d\n",
@ -452,7 +445,7 @@ static int qusb_phy_init(struct usb_phy *phy)
dev_dbg(phy->dev, "%s\n", __func__); dev_dbg(phy->dev, "%s\n", __func__);
ret = qusb_phy_enable_power(qphy, true, true); ret = qusb_phy_enable_power(qphy, true);
if (ret) if (ret)
return ret; return ret;
@ -683,7 +676,7 @@ static int qusb_phy_set_suspend(struct usb_phy *phy, int suspend)
wmb(); wmb();
qusb_phy_enable_clocks(qphy, false); qusb_phy_enable_clocks(qphy, false);
qusb_phy_enable_power(qphy, false, true); qusb_phy_enable_power(qphy, false);
} }
qphy->suspended = true; qphy->suspended = true;
} else { } else {
@ -715,7 +708,7 @@ static int qusb_phy_set_suspend(struct usb_phy *phy, int suspend)
*/ */
wmb(); wmb();
qusb_phy_enable_power(qphy, true, true); qusb_phy_enable_power(qphy, true);
ret = reset_control_assert(qphy->phy_reset); ret = reset_control_assert(qphy->phy_reset);
if (ret) if (ret)
dev_err(phy->dev, "%s: phy_reset assert failed\n", dev_err(phy->dev, "%s: phy_reset assert failed\n",
@ -1100,7 +1093,7 @@ static int qusb_phy_remove(struct platform_device *pdev)
qphy->clocks_enabled = false; qphy->clocks_enabled = false;
} }
qusb_phy_enable_power(qphy, false, true); qusb_phy_enable_power(qphy, false);
return 0; return 0;
} }