From 2cf2aaf54ce270f5d00393257f6283eba7e6dda3 Mon Sep 17 00:00:00 2001 From: Ashay Jaiswal Date: Mon, 17 Jul 2017 14:49:05 +0530 Subject: [PATCH] power: smb-lib: enable DPDM regulator at CC attach In case of quick back-to-back insertion/removal of USB there is a possibility that VBUS does not fall below the 1V usb-plugout threshold and hence the subsequent insertion does not generate a plug-in event. This keeps the DPDM regulator disabled at insertion thus impacting the APSD result. Fix this by voting to enable the DPDM regulator in the cc-attach handler. CRs-Fixed: 2042071 Change-Id: I37a32081f0847965e34eb1c4114602ec61e9a005 Signed-off-by: Ashay Jaiswal --- drivers/power/supply/qcom/smb-lib.c | 119 ++++++++++++++++++------------------ 1 file changed, 60 insertions(+), 59 deletions(-) diff --git a/drivers/power/supply/qcom/smb-lib.c b/drivers/power/supply/qcom/smb-lib.c index 52775a3bdf1b..5834c8102df3 100644 --- a/drivers/power/supply/qcom/smb-lib.c +++ b/drivers/power/supply/qcom/smb-lib.c @@ -488,6 +488,45 @@ static int smblib_set_usb_pd_allowed_voltage(struct smb_charger *chg, /******************** * HELPER FUNCTIONS * ********************/ +static int smblib_request_dpdm(struct smb_charger *chg, bool enable) +{ + int rc = 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)) { + rc = PTR_ERR(chg->dpdm_reg); + smblib_err(chg, "Couldn't get dpdm regulator rc=%d\n", + rc); + chg->dpdm_reg = NULL; + return rc; + } + } + + if (enable) { + 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); + } + } else { + if (chg->dpdm_reg && regulator_is_enabled(chg->dpdm_reg)) { + smblib_dbg(chg, PR_MISC, "disabling DPDM regulator\n"); + rc = regulator_disable(chg->dpdm_reg); + if (rc < 0) + smblib_err(chg, + "Couldn't disable dpdm regulator rc=%d\n", + rc); + } + } + + return rc; +} static void smblib_rerun_apsd(struct smb_charger *chg) { @@ -600,13 +639,9 @@ static void smblib_uusb_removal(struct smb_charger *chg) cancel_delayed_work_sync(&chg->pl_enable_work); - if (chg->dpdm_reg && regulator_is_enabled(chg->dpdm_reg)) { - smblib_dbg(chg, PR_MISC, "disabling DPDM regulator\n"); - rc = regulator_disable(chg->dpdm_reg); - if (rc < 0) - smblib_err(chg, "Couldn't disable dpdm regulator rc=%d\n", - rc); - } + rc = smblib_request_dpdm(chg, false); + if (rc < 0) + smblib_err(chg, "Couldn't to disable DPDM rc=%d\n", rc); if (chg->wa_flags & BOOST_BACK_WA) { data = chg->irq_info[SWITCH_POWER_OK_IRQ].irq_data; @@ -698,24 +733,9 @@ int smblib_rerun_apsd_if_required(struct smb_charger *chg) if (!val.intval) 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); - } + rc = smblib_request_dpdm(chg, true); + if (rc < 0) + smblib_err(chg, "Couldn't to enable DPDM rc=%d\n", rc); chg->uusb_apsd_rerun_done = true; smblib_rerun_apsd(chg); @@ -3173,25 +3193,10 @@ void smblib_usb_plugin_locked(struct smb_charger *chg) smblib_set_opt_freq_buck(chg, vbus_rising ? chg->chg_freq.freq_5V : chg->chg_freq.freq_removal); - /* 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 (vbus_rising) { - 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); - } + rc = smblib_request_dpdm(chg, true); + if (rc < 0) + smblib_err(chg, "Couldn't to enable DPDM rc=%d\n", rc); /* Schedule work to enable parallel charger */ vote(chg->awake_votable, PL_DELAY_VOTER, true, 0); @@ -3211,13 +3216,9 @@ void smblib_usb_plugin_locked(struct smb_charger *chg) } } - if (chg->dpdm_reg && regulator_is_enabled(chg->dpdm_reg)) { - smblib_dbg(chg, PR_MISC, "disabling DPDM regulator\n"); - rc = regulator_disable(chg->dpdm_reg); - if (rc < 0) - smblib_err(chg, "Couldn't disable dpdm regulator rc=%d\n", - rc); - } + rc = smblib_request_dpdm(chg, false); + if (rc < 0) + smblib_err(chg, "Couldn't disable DPDM rc=%d\n", rc); } if (chg->micro_usb_mode) @@ -3617,13 +3618,9 @@ static void smblib_handle_typec_removal(struct smb_charger *chg) chg->cc2_detach_wa_active = false; - if (chg->dpdm_reg && regulator_is_enabled(chg->dpdm_reg)) { - smblib_dbg(chg, PR_MISC, "disabling DPDM regulator\n"); - rc = regulator_disable(chg->dpdm_reg); - if (rc < 0) - smblib_err(chg, "Couldn't disable dpdm regulator rc=%d\n", - rc); - } + rc = smblib_request_dpdm(chg, false); + if (rc < 0) + smblib_err(chg, "Couldn't disable DPDM rc=%d\n", rc); if (chg->wa_flags & BOOST_BACK_WA) { data = chg->irq_info[SWITCH_POWER_OK_IRQ].irq_data; @@ -3759,10 +3756,14 @@ static void smblib_handle_typec_insertion(struct smb_charger *chg) smblib_err(chg, "Couldn't disable APSD_START_ON_CC rc=%d\n", rc); - if (chg->typec_status[3] & UFP_DFP_MODE_STATUS_BIT) + if (chg->typec_status[3] & UFP_DFP_MODE_STATUS_BIT) { typec_sink_insertion(chg); - else + } else { + rc = smblib_request_dpdm(chg, true); + if (rc < 0) + smblib_err(chg, "Couldn't to enable DPDM rc=%d\n", rc); typec_sink_removal(chg); + } } static void smblib_handle_rp_change(struct smb_charger *chg, int typec_mode) -- 2.11.0