summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDiana Z <dzigterman@chromium.org>2020-10-15 17:02:55 -0600
committerCommit Bot <commit-bot@chromium.org>2020-10-20 21:11:31 +0000
commit9fe1b8982470e4a5d300b98470d353afb3a9d8c1 (patch)
treed99bfe728af18a85ab9403723ed23c755054fd56
parent512823a8aa87d4b6a83f88bab05fe586de6c14aa (diff)
downloadchrome-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.c19
-rw-r--r--driver/charger/sm5803.h9
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, &reg);
+ rv |= chg_read8(chgnum, SM5803_REG_FLOW1, &reg);
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)