From d9749262e8afcaa7d4448a9dbbfe31235e709aa0 Mon Sep 17 00:00:00 2001 From: Umang Agrawal Date: Mon, 16 Apr 2018 14:41:11 +0530 Subject: [PATCH] power: smb-lib: Add support for SW based OV detection Add support for software based USBIN OV detection, once OV condition is detected, software will force USBIN to 5V and continue charging with 5V. Change-Id: Ie8f00f69db4ac6330d9da82b3455e4efab43861a Signed-off-by: Umang Agrawal --- drivers/power/supply/qcom/qpnp-smb2.c | 2 +- drivers/power/supply/qcom/smb-lib.c | 30 +++++++++++++++++++++++++++ drivers/power/supply/qcom/smb-lib.h | 2 ++ 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/drivers/power/supply/qcom/qpnp-smb2.c b/drivers/power/supply/qcom/qpnp-smb2.c index 4beaddff47b3..ddb1d7e118fd 100644 --- a/drivers/power/supply/qcom/qpnp-smb2.c +++ b/drivers/power/supply/qcom/qpnp-smb2.c @@ -1844,7 +1844,7 @@ static int smb2_chg_config_init(struct smb2 *chip) break; case PM660_SUBTYPE: chip->chg.smb_version = PM660_SUBTYPE; - chip->chg.wa_flags |= BOOST_BACK_WA | OTG_WA; + chip->chg.wa_flags |= BOOST_BACK_WA | OTG_WA | OV_IRQ_WA_BIT; chg->param.freq_buck = pm660_params.freq_buck; chg->param.freq_boost = pm660_params.freq_boost; chg->chg_freq.freq_5V = 650; diff --git a/drivers/power/supply/qcom/smb-lib.c b/drivers/power/supply/qcom/smb-lib.c index 56a42e23bb61..b70e16400d63 100644 --- a/drivers/power/supply/qcom/smb-lib.c +++ b/drivers/power/supply/qcom/smb-lib.c @@ -670,6 +670,7 @@ static void smblib_uusb_removal(struct smb_charger *chg) vote(chg->pl_enable_votable_indirect, USBIN_V_VOTER, false, 0); vote(chg->usb_icl_votable, SW_QC3_VOTER, false, 0); vote(chg->usb_icl_votable, USBIN_USBIN_BOOST_VOTER, false, 0); + vote(chg->hvdcp_hw_inov_dis_votable, OV_VOTER, false, 0); cancel_delayed_work_sync(&chg->hvdcp_detect_work); @@ -3453,6 +3454,33 @@ static void smblib_handle_sdp_enumeration_done(struct smb_charger *chg, rising ? "rising" : "falling"); } +#define MICRO_10P3V 10300000 +static void smblib_check_ov_condition(struct smb_charger *chg) +{ + union power_supply_propval pval = {0, }; + int rc; + + if (chg->wa_flags & OV_IRQ_WA_BIT) { + rc = power_supply_get_property(chg->usb_psy, + POWER_SUPPLY_PROP_VOLTAGE_NOW, &pval); + if (rc < 0) { + smblib_err(chg, "Couldn't get current voltage, rc=%d\n", + rc); + return; + } + + if (pval.intval > MICRO_10P3V) { + smblib_err(chg, "USBIN OV detected\n"); + vote(chg->hvdcp_hw_inov_dis_votable, OV_VOTER, true, + 0); + pval.intval = POWER_SUPPLY_DP_DM_FORCE_5V; + rc = power_supply_set_property(chg->batt_psy, + POWER_SUPPLY_PROP_DP_DM, &pval); + return; + } + } +} + #define QC3_PULSES_FOR_6V 5 #define QC3_PULSES_FOR_9V 20 #define QC3_PULSES_FOR_12V 35 @@ -3462,6 +3490,7 @@ static void smblib_hvdcp_adaptive_voltage_change(struct smb_charger *chg) u8 stat; int pulses; + smblib_check_ov_condition(chg); power_supply_changed(chg->usb_main_psy); if (chg->real_charger_type == POWER_SUPPLY_TYPE_USB_HVDCP) { rc = smblib_read(chg, QC_CHANGE_STATUS_REG, &stat); @@ -3994,6 +4023,7 @@ static void smblib_handle_typec_removal(struct smb_charger *chg) /* reset hvdcp voters */ vote(chg->hvdcp_disable_votable_indirect, VBUS_CC_SHORT_VOTER, true, 0); vote(chg->hvdcp_disable_votable_indirect, PD_INACTIVE_VOTER, true, 0); + vote(chg->hvdcp_hw_inov_dis_votable, OV_VOTER, false, 0); /* reset power delivery voters */ vote(chg->pd_allowed_votable, PD_VOTER, false, 0); diff --git a/drivers/power/supply/qcom/smb-lib.h b/drivers/power/supply/qcom/smb-lib.h index f292ca09f532..4b30d8a4cf21 100644 --- a/drivers/power/supply/qcom/smb-lib.h +++ b/drivers/power/supply/qcom/smb-lib.h @@ -66,6 +66,7 @@ enum print_reason { #define USBIN_I_VOTER "USBIN_I_VOTER" #define WEAK_CHARGER_VOTER "WEAK_CHARGER_VOTER" #define WBC_VOTER "WBC_VOTER" +#define OV_VOTER "OV_VOTER" #define VCONN_MAX_ATTEMPTS 3 #define OTG_MAX_ATTEMPTS 3 @@ -84,6 +85,7 @@ enum { TYPEC_CC2_REMOVAL_WA_BIT = BIT(2), QC_AUTH_INTERRUPT_WA_BIT = BIT(3), OTG_WA = BIT(4), + OV_IRQ_WA_BIT = BIT(5), }; enum smb_irq_index {