From 059118476764090b5fc6ee4bdfb5491f6571cb34 Mon Sep 17 00:00:00 2001 From: Abhijeet Dharmapurikar Date: Thu, 9 Feb 2017 22:55:51 +0530 Subject: smb-lib: Handle icl voter priorities between DCP, SDP and PD type Cleanup the code such that when PD is activated, DCP_VOTER and USB_PSY_VOTER (the voter for SDP and CDP types) are disabled. While at it DCP_VOTER is intended to enforce a different value from the hw defaults. Set it only when type is confirmed DCP. Also to handle the situation when the PD profile allows to suspend based on the phy, use a different voter PD_SUSPEND_SUPPORTED_VOTER to activate that situation. Change-Id: I0cb1a0aad9c94fdd233ec3103779e1a13449472e Signed-off-by: Abhijeet Dharmapurikar --- drivers/power/supply/qcom/qpnp-smb2.c | 5 ++-- drivers/power/supply/qcom/smb-lib.c | 56 ++++++++++++++++++++++++----------- drivers/power/supply/qcom/smb-lib.h | 2 +- 3 files changed, 42 insertions(+), 21 deletions(-) (limited to 'drivers/power') diff --git a/drivers/power/supply/qcom/qpnp-smb2.c b/drivers/power/supply/qcom/qpnp-smb2.c index 4e9d2894479a..46e920d1076d 100644 --- a/drivers/power/supply/qcom/qpnp-smb2.c +++ b/drivers/power/supply/qcom/qpnp-smb2.c @@ -385,6 +385,8 @@ static int smb2_parse_dt(struct smb2 *chip) chg->micro_usb_mode = of_property_read_bool(node, "qcom,micro-usb"); + chg->dcp_icl_ua = chip->dt.usb_icl_ua; + return 0; } @@ -1338,7 +1340,6 @@ static int smb2_init_hw(struct smb2 *chip) return rc; } - chg->dcp_icl_ua = chip->dt.usb_icl_ua; chg->boost_threshold_ua = chip->dt.boost_threshold_ua; rc = smblib_read(chg, APSD_RESULT_STATUS_REG, &stat); @@ -1367,8 +1368,6 @@ static int smb2_init_hw(struct smb2 *chip) DEFAULT_VOTER, true, chip->dt.fcc_ua); vote(chg->fv_votable, DEFAULT_VOTER, true, chip->dt.fv_uv); - vote(chg->usb_icl_votable, - DCP_VOTER, true, chip->dt.usb_icl_ua); vote(chg->dc_icl_votable, DEFAULT_VOTER, true, chip->dt.dc_icl_ua); vote(chg->hvdcp_disable_votable_indirect, DEFAULT_VOTER, diff --git a/drivers/power/supply/qcom/smb-lib.c b/drivers/power/supply/qcom/smb-lib.c index 16edf875de96..5c5ad200b3e0 100644 --- a/drivers/power/supply/qcom/smb-lib.c +++ b/drivers/power/supply/qcom/smb-lib.c @@ -1996,11 +1996,11 @@ int smblib_set_prop_usb_current_max(struct smb_charger *chg, true, val->intval); } else if (chg->system_suspend_supported) { if (val->intval <= USBIN_25MA) - rc = vote(chg->usb_icl_votable, USB_PSY_VOTER, - true, val->intval); + rc = vote(chg->usb_icl_votable, + PD_SUSPEND_SUPPORTED_VOTER, true, val->intval); else - rc = vote(chg->usb_icl_votable, USB_PSY_VOTER, - false, 0); + rc = vote(chg->usb_icl_votable, + PD_SUSPEND_SUPPORTED_VOTER, false, 0); } return rc; } @@ -2137,7 +2137,11 @@ int smblib_set_prop_pd_active(struct smb_charger *chg, "Couldn't enable vconn on CC line rc=%d\n", rc); return rc; } - + /* + * Enforce 500mA for PD until the real vote comes in later. + * It is guaranteed that pd_active is set prior to + * pd_current_max + */ rc = vote(chg->usb_icl_votable, PD_VOTER, true, USBIN_500MA); if (rc < 0) { smblib_err(chg, "Couldn't vote for USB ICL rc=%d\n", @@ -2145,10 +2149,17 @@ int smblib_set_prop_pd_active(struct smb_charger *chg, return rc; } + /* remove DCP_VOTER */ rc = vote(chg->usb_icl_votable, DCP_VOTER, false, 0); if (rc < 0) { - smblib_err(chg, "Couldn't vote for USB ICL rc=%d\n", - rc); + smblib_err(chg, "Couldn't unvote DCP rc=%d\n", rc); + return rc; + } + + /* remove USB_PSY_VOTER */ + rc = vote(chg->usb_icl_votable, USB_PSY_VOTER, false, 0); + if (rc < 0) { + smblib_err(chg, "Couldn't unvote USB_PSY rc=%d\n", rc); return rc; } @@ -2168,14 +2179,6 @@ int smblib_set_prop_pd_active(struct smb_charger *chg, return rc; } } else { - rc = vote(chg->usb_icl_votable, DCP_VOTER, true, - chg->dcp_icl_ua); - if (rc < 0) { - smblib_err(chg, "Couldn't vote for USB ICL rc=%d\n", - rc); - return rc; - } - rc = smblib_masked_write(chg, CMD_APSD_REG, ICL_OVERRIDE_BIT, 0); if (rc < 0) { @@ -2791,6 +2794,8 @@ static void smblib_handle_hvdcp_3p0_auth_done(struct smb_charger *chg, static void smblib_handle_hvdcp_check_timeout(struct smb_charger *chg, bool rising, bool qc_charger) { + const struct apsd_result *apsd_result = smblib_update_usb_type(chg); + /* Hold off PD only until hvdcp 2.0 detection timeout */ if (rising) { vote(chg->pd_disallowed_votable_indirect, HVDCP_TIMEOUT_VOTER, @@ -2799,6 +2804,16 @@ static void smblib_handle_hvdcp_check_timeout(struct smb_charger *chg, /* could be a legacy cable, try doing hvdcp */ try_rerun_apsd_for_hvdcp(chg); } + /* + * HVDCP detection timeout done + * If adapter is not QC2.0/QC3.0 - it is a plain old DCP. + * Otherwise if adapter is QC2.0/QC3.0 wait for authentication + * to complete. + */ + if (!qc_charger && (apsd_result->bit & DCP_CHARGER_BIT)) + /* enforce DCP ICL if specified */ + vote(chg->usb_icl_votable, DCP_VOTER, + chg->dcp_icl_ua != -EINVAL, chg->dcp_icl_ua); smblib_dbg(chg, PR_INTERRUPT, "IRQ: smblib_handle_hvdcp_check_timeout %s\n", rising ? "rising" : "falling"); @@ -2923,12 +2938,19 @@ static void typec_source_removal(struct smb_charger *chg) /* clear USB ICL vote for PD_VOTER */ rc = vote(chg->usb_icl_votable, PD_VOTER, false, 0); if (rc < 0) - smblib_err(chg, "Couldn't un-vote for USB ICL rc=%d\n", rc); + smblib_err(chg, "Couldn't un-vote PD from USB ICL rc=%d\n", rc); /* clear USB ICL vote for USB_PSY_VOTER */ rc = vote(chg->usb_icl_votable, USB_PSY_VOTER, false, 0); if (rc < 0) - smblib_err(chg, "Couldn't un-vote for USB ICL rc=%d\n", rc); + smblib_err(chg, + "Couldn't un-vote USB_PSY from USB ICL rc=%d\n", rc); + + /* clear USB ICL vote for DCP_VOTER */ + rc = vote(chg->usb_icl_votable, DCP_VOTER, false, 0); + if (rc < 0) + smblib_err(chg, + "Couldn't un-vote DCP from USB ICL rc=%d\n", rc); } static void typec_source_insertion(struct smb_charger *chg) diff --git a/drivers/power/supply/qcom/smb-lib.h b/drivers/power/supply/qcom/smb-lib.h index e341484bc2ec..5bb42f2ce7d9 100644 --- a/drivers/power/supply/qcom/smb-lib.h +++ b/drivers/power/supply/qcom/smb-lib.h @@ -52,7 +52,7 @@ enum print_reason { #define HVDCP_INDIRECT_VOTER "HVDCP_INDIRECT_VOTER" #define MICRO_USB_VOTER "MICRO_USB_VOTER" #define DEBUG_BOARD_VOTER "DEBUG_BOARD_VOTER" - +#define PD_SUSPEND_SUPPORTED_VOTER "PD_SUSPEND_SUPPORTED_VOTER" #define VCONN_MAX_ATTEMPTS 3 #define OTG_MAX_ATTEMPTS 3 -- cgit v1.2.3