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 <adharmap@codeaurora.org>
This commit is contained in:
Abhijeet Dharmapurikar 2017-02-09 22:55:51 +05:30 committed by Ashay Jaiswal
parent dd6494d94e
commit 0591184767
3 changed files with 42 additions and 21 deletions

View file

@ -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,

View file

@ -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)

View file

@ -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