From 5ff9ae6d013ef9bb302ae8334f722b32b3172ffc Mon Sep 17 00:00:00 2001 From: Abhijeet Dharmapurikar Date: Fri, 24 Feb 2017 14:06:22 -0800 Subject: qcom: smb-lib: float D+/D- before running APSD at init If D+/D- line are grounded while apsd is being rerun, it causes incorrect detection of the usb type when apsd is rerun. Ensure that D+/D- lines are floated. Moreover there is a situation where hvdcp could be momentarily enabled and disabled again in the initialization sequence. Fix it by changing the order of votes on the hvdcp_disable_votable. Change-Id: Ifaa55b5f24e2a30e93655c072e123316d886ed00 Signed-off-by: Abhijeet Dharmapurikar --- drivers/power/supply/qcom/qpnp-smb2.c | 4 ++-- drivers/power/supply/qcom/smb-lib.c | 27 ++++++++++++++++++++++++--- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/drivers/power/supply/qcom/qpnp-smb2.c b/drivers/power/supply/qcom/qpnp-smb2.c index 64f4d46df9a0..dd9321017bc0 100644 --- a/drivers/power/supply/qcom/qpnp-smb2.c +++ b/drivers/power/supply/qcom/qpnp-smb2.c @@ -1420,10 +1420,10 @@ static int smb2_init_hw(struct smb2 *chip) DEFAULT_VOTER, true, chip->dt.fv_uv); vote(chg->dc_icl_votable, DEFAULT_VOTER, true, chip->dt.dc_icl_ua); - vote(chg->hvdcp_disable_votable_indirect, DEFAULT_VOTER, - chip->dt.hvdcp_disable, 0); vote(chg->hvdcp_disable_votable_indirect, PD_INACTIVE_VOTER, true, 0); + vote(chg->hvdcp_disable_votable_indirect, DEFAULT_VOTER, + chip->dt.hvdcp_disable, 0); vote(chg->pd_disallowed_votable_indirect, CC_DETACHED_VOTER, true, 0); vote(chg->pd_disallowed_votable_indirect, HVDCP_TIMEOUT_VOTER, diff --git a/drivers/power/supply/qcom/smb-lib.c b/drivers/power/supply/qcom/smb-lib.c index 9d296a911daa..b7940651bdf8 100644 --- a/drivers/power/supply/qcom/smb-lib.c +++ b/drivers/power/supply/qcom/smb-lib.c @@ -779,11 +779,32 @@ int smblib_rerun_apsd_if_required(struct smb_charger *chg) return 0; apsd_result = smblib_get_apsd_result(chg); - if ((apsd_result->pst == POWER_SUPPLY_TYPE_UNKNOWN) - || (apsd_result->pst == POWER_SUPPLY_TYPE_USB)) { - smblib_rerun_apsd(chg); + if ((apsd_result->pst != POWER_SUPPLY_TYPE_UNKNOWN) + && (apsd_result->pst != POWER_SUPPLY_TYPE_USB)) + /* if type is not usb or unknown no need to rerun apsd */ + return 0; + + /* fetch the DPDM regulator */ + if (!chg->dpdm_reg && of_get_property(chg->dev->of_node, + "dpdm-supply", NULL)) { + chg->dpdm_reg = devm_regulator_get(chg->dev, "dpdm"); + if (IS_ERR(chg->dpdm_reg)) { + smblib_err(chg, "Couldn't get dpdm regulator rc=%ld\n", + PTR_ERR(chg->dpdm_reg)); + chg->dpdm_reg = NULL; + } + } + + if (chg->dpdm_reg && !regulator_is_enabled(chg->dpdm_reg)) { + smblib_dbg(chg, PR_MISC, "enabling DPDM regulator\n"); + rc = regulator_enable(chg->dpdm_reg); + if (rc < 0) + smblib_err(chg, "Couldn't enable dpdm regulator rc=%d\n", + rc); } + smblib_rerun_apsd(chg); + return 0; } -- cgit v1.2.3