diff options
author | Diana Z <dzigterman@chromium.org> | 2020-10-15 17:02:55 -0600 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2020-10-20 21:11:31 +0000 |
commit | 9fe1b8982470e4a5d300b98470d353afb3a9d8c1 (patch) | |
tree | d99bfe728af18a85ab9403723ed23c755054fd56 /driver/charger/sm5803.c | |
parent | 512823a8aa87d4b6a83f88bab05fe586de6c14aa (diff) | |
download | chrome-ec-9fe1b8982470e4a5d300b98470d353afb3a9d8c1.tar.gz |
SM5803: Clear out bad state in OTG disable
When sourcing fails to a port partner, the discharge status should be
cleared before clearing out the FLOW1 register. Since the source bit
may be unreliable after sourcing fails, use this status as an indication
for whether it's safe to clear out the mode from FLOW1.
BRANCH=None
BUG=b:169966133,b:170517117
TEST=on drawlat, attach bad dongle and observe the port works with a
good dongle after the bad one is unplugged
Signed-off-by: Diana Z <dzigterman@chromium.org>
Change-Id: I128e292b3f2bfe5362e51b6967f62e4191809149
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2476670
Reviewed-by: Aseda Aboagye <aaboagye@chromium.org>
Diffstat (limited to 'driver/charger/sm5803.c')
-rw-r--r-- | driver/charger/sm5803.c | 19 |
1 files changed, 16 insertions, 3 deletions
diff --git a/driver/charger/sm5803.c b/driver/charger/sm5803.c index ebb2b4b02a..14c81469ef 100644 --- a/driver/charger/sm5803.c +++ b/driver/charger/sm5803.c @@ -1319,7 +1319,7 @@ static enum ec_error_list sm5803_set_otg_current_voltage(int chgnum, static enum ec_error_list sm5803_enable_otg_power(int chgnum, int enabled) { enum ec_error_list rv; - int reg; + int reg, status; if (enabled) { int selected_current; @@ -1357,18 +1357,31 @@ static enum ec_error_list sm5803_enable_otg_power(int chgnum, int enabled) sm5803_set_otg_current_voltage(chgnum, selected_current, 5000); } else { + /* Always clear out discharge status before clearing FLOW1 */ + rv = chg_read8(chgnum, SM5803_REG_STATUS_DISCHG, &status); + if (rv) + return rv; + + if (status) + CPRINTS("%s %d: Discharge failure 0x%02x", CHARGER_NAME, + chgnum, status); + + rv |= chg_write8(chgnum, SM5803_REG_STATUS_DISCHG, status); + /* * PD tasks will always turn off previous sourcing on init. * Protect ourselves from brown out on init by checking if we're * sinking right now. The init process should only leave sink * mode enabled if a charger is plugged in; otherwise it's * expected to be 0. + * + * Always clear out sourcing if the previous source-out failed. */ - rv = chg_read8(chgnum, SM5803_REG_FLOW1, ®); + rv |= chg_read8(chgnum, SM5803_REG_FLOW1, ®); if (rv) return rv; - if ((reg & SM5803_FLOW1_MODE) != CHARGER_MODE_SINK) + if ((reg & SM5803_FLOW1_MODE) != CHARGER_MODE_SINK || status) rv = sm5803_flow1_update(chgnum, CHARGER_MODE_SOURCE | SM5803_FLOW1_DIRECTCHG_SRC_EN, MASK_CLR); |