Merge "power: smb-lib: always assume legacy cable to prevent CC OV"

This commit is contained in:
Linux Build Service Account 2017-03-16 20:03:00 -07:00 committed by Gerrit - the friendly Code Review server
commit d53dae0046
5 changed files with 67 additions and 102 deletions

View file

@ -187,6 +187,38 @@ void unlock_votable(struct votable *votable)
mutex_unlock(&votable->vote_lock);
}
/**
* is_client_vote_enabled() -
* is_client_vote_enabled_locked() -
* The unlocked and locked variants of getting whether a client's
vote is enabled.
* @votable: the votable object
* @client_str: client of interest
*
* Returns:
* True if the client's vote is enabled; false otherwise.
*/
bool is_client_vote_enabled_locked(struct votable *votable,
const char *client_str)
{
int client_id = get_client_id(votable, client_str);
if (client_id < 0)
return false;
return votable->votes[client_id].enabled;
}
bool is_client_vote_enabled(struct votable *votable, const char *client_str)
{
bool enabled;
lock_votable(votable);
enabled = is_client_vote_enabled_locked(votable, client_str);
unlock_votable(votable);
return enabled;
}
/**
* get_client_vote() -
* get_client_vote_locked() -

View file

@ -24,6 +24,9 @@ enum votable_type {
NUM_VOTABLE_TYPES,
};
bool is_client_vote_enabled(struct votable *votable, const char *client_str);
bool is_client_vote_enabled_locked(struct votable *votable,
const char *client_str);
int get_client_vote(struct votable *votable, const char *client_str);
int get_client_vote_locked(struct votable *votable, const char *client_str);
int get_effective_result(struct votable *votable);

View file

@ -161,39 +161,14 @@ static int smblib_get_jeita_cc_delta(struct smb_charger *chg, int *cc_delta_ua)
int smblib_icl_override(struct smb_charger *chg, bool override)
{
int rc;
bool override_status;
u8 stat;
u16 reg;
switch (chg->smb_version) {
case PMI8998_SUBTYPE:
reg = APSD_RESULT_STATUS_REG;
break;
case PM660_SUBTYPE:
reg = AICL_STATUS_REG;
break;
default:
smblib_dbg(chg, PR_MISC, "Unknown chip version=%x\n",
chg->smb_version);
return -EINVAL;
}
rc = smblib_masked_write(chg, USBIN_LOAD_CFG_REG,
ICL_OVERRIDE_AFTER_APSD_BIT,
override ? ICL_OVERRIDE_AFTER_APSD_BIT : 0);
if (rc < 0)
smblib_err(chg, "Couldn't override ICL rc=%d\n", rc);
rc = smblib_read(chg, reg, &stat);
if (rc < 0) {
smblib_err(chg, "Couldn't read reg=%x rc=%d\n", reg, rc);
return rc;
}
override_status = (bool)(stat & ICL_OVERRIDE_LATCH_BIT);
if (override != override_status) {
rc = smblib_masked_write(chg, CMD_APSD_REG,
ICL_OVERRIDE_BIT, ICL_OVERRIDE_BIT);
if (rc < 0) {
smblib_err(chg, "Couldn't override ICL rc=%d\n", rc);
return rc;
}
}
return 0;
return rc;
}
/********************
@ -727,21 +702,6 @@ static void smblib_uusb_removal(struct smb_charger *chg)
rc);
}
static bool smblib_sysok_reason_usbin(struct smb_charger *chg)
{
int rc;
u8 stat;
rc = smblib_read(chg, SYSOK_REASON_STATUS_REG, &stat);
if (rc < 0) {
smblib_err(chg, "Couldn't get SYSOK_REASON_STATUS rc=%d\n", rc);
/* assuming 'not usbin' in case of read failure */
return false;
}
return stat & SYSOK_REASON_USBIN_BIT;
}
void smblib_suspend_on_debug_battery(struct smb_charger *chg)
{
int rc;
@ -1098,16 +1058,6 @@ static int smblib_apsd_disable_vote_callback(struct votable *votable,
int rc;
if (apsd_disable) {
/* Don't run APSD on CC debounce when APSD is disabled */
rc = smblib_masked_write(chg, TYPE_C_CFG_REG,
APSD_START_ON_CC_BIT,
0);
if (rc < 0) {
smblib_err(chg, "Couldn't disable APSD_START_ON_CC rc=%d\n",
rc);
return rc;
}
rc = smblib_masked_write(chg, USBIN_OPTIONS_1_CFG_REG,
AUTO_SRC_DETECT_BIT,
0);
@ -1123,15 +1073,6 @@ static int smblib_apsd_disable_vote_callback(struct votable *votable,
smblib_err(chg, "Couldn't enable APSD rc=%d\n", rc);
return rc;
}
rc = smblib_masked_write(chg, TYPE_C_CFG_REG,
APSD_START_ON_CC_BIT,
APSD_START_ON_CC_BIT);
if (rc < 0) {
smblib_err(chg, "Couldn't enable APSD_START_ON_CC rc=%d\n",
rc);
return rc;
}
}
return 0;
@ -2510,10 +2451,6 @@ int smblib_set_prop_usb_voltage_max(struct smb_charger *chg,
}
chg->voltage_max_uv = max_uv;
rc = smblib_rerun_aicl(chg);
if (rc < 0)
smblib_err(chg, "Couldn't re-run AICL rc=%d\n", rc);
return rc;
}
@ -2684,12 +2621,6 @@ int smblib_reg_block_restore(struct smb_charger *chg,
}
static struct reg_info cc2_detach_settings[] = {
{
.reg = TYPE_C_CFG_REG,
.mask = APSD_START_ON_CC_BIT,
.val = 0,
.desc = "TYPE_C_CFG_REG",
},
{
.reg = TYPE_C_CFG_2_REG,
.mask = TYPE_C_UFP_MODE_BIT | EN_TRY_SOURCE_MODE_BIT,
@ -3568,10 +3499,10 @@ static void typec_sink_removal(struct smb_charger *chg)
static void smblib_handle_typec_removal(struct smb_charger *chg)
{
int rc;
vote(chg->pd_disallowed_votable_indirect, CC_DETACHED_VOTER, true, 0);
vote(chg->pd_disallowed_votable_indirect, HVDCP_TIMEOUT_VOTER, true, 0);
vote(chg->pd_disallowed_votable_indirect, LEGACY_CABLE_VOTER, true, 0);
vote(chg->pd_disallowed_votable_indirect, VBUS_CC_SHORT_VOTER, true, 0);
vote(chg->pl_disable_votable, PL_DELAY_HVDCP_VOTER, true, 0);
/* reset votes from vbus_cc_short */
@ -3590,10 +3521,13 @@ static void smblib_handle_typec_removal(struct smb_charger *chg)
chg->pulse_cnt = 0;
chg->usb_icl_delta_ua = 0;
chg->usb_ever_removed = true;
/* enable APSD CC trigger for next insertion */
rc = smblib_masked_write(chg, TYPE_C_CFG_REG,
APSD_START_ON_CC_BIT, APSD_START_ON_CC_BIT);
if (rc < 0)
smblib_err(chg, "Couldn't enable APSD_START_ON_CC rc=%d\n", rc);
smblib_update_usb_type(chg);
typec_source_removal(chg);
typec_sink_removal(chg);
}
@ -3601,12 +3535,16 @@ static void smblib_handle_typec_removal(struct smb_charger *chg)
static void smblib_handle_typec_insertion(struct smb_charger *chg,
bool sink_attached, bool legacy_cable)
{
int rp;
bool vbus_cc_short = false;
bool valid_legacy_cable;
int rp, rc;
vote(chg->pd_disallowed_votable_indirect, CC_DETACHED_VOTER, false, 0);
/* disable APSD CC trigger since CC is attached */
rc = smblib_masked_write(chg, TYPE_C_CFG_REG, APSD_START_ON_CC_BIT, 0);
if (rc < 0)
smblib_err(chg, "Couldn't disable APSD_START_ON_CC rc=%d\n",
rc);
if (sink_attached) {
typec_source_removal(chg);
typec_sink_insertion(chg);
@ -3615,25 +3553,18 @@ static void smblib_handle_typec_insertion(struct smb_charger *chg,
typec_sink_removal(chg);
}
valid_legacy_cable = legacy_cable &&
(chg->usb_ever_removed || !smblib_sysok_reason_usbin(chg));
vote(chg->pd_disallowed_votable_indirect, LEGACY_CABLE_VOTER,
valid_legacy_cable, 0);
if (valid_legacy_cable) {
rp = smblib_get_prop_ufp_mode(chg);
if (rp == POWER_SUPPLY_TYPEC_SOURCE_HIGH
|| rp == POWER_SUPPLY_TYPEC_NON_COMPLIANT) {
vbus_cc_short = true;
smblib_err(chg, "Disabling PD and HVDCP, VBUS-CC shorted, rp = %d found\n",
rp);
}
rp = smblib_get_prop_ufp_mode(chg);
if (rp == POWER_SUPPLY_TYPEC_SOURCE_HIGH
|| rp == POWER_SUPPLY_TYPEC_NON_COMPLIANT) {
smblib_dbg(chg, PR_MISC, "VBUS & CC could be shorted; keeping HVDCP disabled\n");
/* HVDCP is not going to be enabled; enable parallel */
vote(chg->pl_disable_votable, PL_DELAY_HVDCP_VOTER, false, 0);
vote(chg->hvdcp_disable_votable_indirect, VBUS_CC_SHORT_VOTER,
true, 0);
} else {
vote(chg->hvdcp_disable_votable_indirect, VBUS_CC_SHORT_VOTER,
false, 0);
}
vote(chg->hvdcp_disable_votable_indirect, VBUS_CC_SHORT_VOTER,
vbus_cc_short, 0);
vote(chg->pd_disallowed_votable_indirect, VBUS_CC_SHORT_VOTER,
vbus_cc_short, 0);
}
static void smblib_handle_typec_debounce_done(struct smb_charger *chg,

View file

@ -47,7 +47,6 @@ enum print_reason {
#define PD_DISALLOWED_INDIRECT_VOTER "PD_DISALLOWED_INDIRECT_VOTER"
#define PD_HARD_RESET_VOTER "PD_HARD_RESET_VOTER"
#define VBUS_CC_SHORT_VOTER "VBUS_CC_SHORT_VOTER"
#define LEGACY_CABLE_VOTER "LEGACY_CABLE_VOTER"
#define PD_INACTIVE_VOTER "PD_INACTIVE_VOTER"
#define BOOST_BACK_VOTER "BOOST_BACK_VOTER"
#define HVDCP_INDIRECT_VOTER "HVDCP_INDIRECT_VOTER"
@ -316,7 +315,6 @@ struct smb_charger {
/* extcon for VBUS / ID notification to USB for uUSB */
struct extcon_dev *extcon;
bool usb_ever_removed;
int icl_reduction_ua;

View file

@ -628,6 +628,7 @@ enum {
#define USBIN_LOAD_CFG_REG (USBIN_BASE + 0x65)
#define USBIN_OV_CH_LOAD_OPTION_BIT BIT(7)
#define ICL_OVERRIDE_AFTER_APSD_BIT BIT(4)
#define USBIN_ICL_OPTIONS_REG (USBIN_BASE + 0x66)
#define CFG_USB3P0_SEL_BIT BIT(2)