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 | |
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>
-rw-r--r-- | driver/charger/sm5803.c | 19 | ||||
-rw-r--r-- | driver/charger/sm5803.h | 9 |
2 files changed, 25 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); diff --git a/driver/charger/sm5803.h b/driver/charger/sm5803.h index ab8bd65657..a4989ab09e 100644 --- a/driver/charger/sm5803.h +++ b/driver/charger/sm5803.h @@ -307,6 +307,15 @@ enum sm5803_charger_modes { #define SM5803_STATUS_CHG_TIMEOUT BIT(6) #define SM5803_STATUS_CHG_OV_ITEMP BIT(7) +#define SM5803_REG_STATUS_DISCHG 0x49 +#define SM5803_STATUS_DISCHG_BATT_REM BIT(0) +#define SM5803_STATUS_DISCHG_UV_VBAT BIT(1) +#define SM5803_STATUS_DISCHG_VBUS_OC BIT(2) +#define SM5803_STATUS_DISCHG_VBUS_PWR GENMASK(4, 3) +#define SM5803_STATUS_DISCHG_ISO_CURR BIT(5) +#define SM5803_STATUS_DISCHG_VBUS_SHORT BIT(6) +#define SM5803_STATUS_DISCHG_OV_ITEMP BIT(7) + #define SM5803_REG_PHOT1 0x72 #define SM5803_PHOT1_IBAT_PHOT_COMP_EN BIT(0) #define SM5803_PHOT1_IBUS_PHOT_COMP_EN BIT(1) |