diff options
author | Diana Z <dzigterman@chromium.org> | 2020-04-20 16:11:48 -0600 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2020-04-28 23:41:50 +0000 |
commit | df4ef3ce0cf24574a90a2e5be1b23bd11dbe3875 (patch) | |
tree | e2d655c82ea542c761da972205d61db18fcb8302 /driver/charger | |
parent | 0ec4d5f9a9c200c64ce8f1e5a4a43af006e5f73e (diff) | |
download | chrome-ec-df4ef3ce0cf24574a90a2e5be1b23bd11dbe3875.tar.gz |
SM5803: Share setting of FLOW_REG1 between tasks better
Both the OTG and charger driver set_mode functions in the sm5803 driver
could clear the CHG_EN bit. This change will only clear CHG_EN from a
specific call to inhibit charging, and otherwise operations will only
modify the bits they strictly need to modify.
Also added a mutex to indicate FLOW_REG1 is being changed since it can
be changed from both the charger and PD tasks.
BRANCH=None
BUG=b:153906171
TEST=on waddledee, able to source out of both ports and seeing somewhat
reduced boot looping without a battery
Signed-off-by: Diana Z <dzigterman@chromium.org>
Change-Id: I52339548edb5eafc7605f435c8da17364d1fc48e
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2157950
Reviewed-by: Aseda Aboagye <aaboagye@chromium.org>
Diffstat (limited to 'driver/charger')
-rw-r--r-- | driver/charger/sm5803.c | 29 |
1 files changed, 20 insertions, 9 deletions
diff --git a/driver/charger/sm5803.c b/driver/charger/sm5803.c index 8da7ef33be..2b2ca572bf 100644 --- a/driver/charger/sm5803.c +++ b/driver/charger/sm5803.c @@ -39,6 +39,8 @@ static const struct charger_info sm5803_charger_info = { static uint32_t irq_pending; /* Bitmask of chips with interrupts pending */ +static struct mutex flow1_access_lock[CHARGER_NUM]; + static int sm5803_is_sourcing_otg_power(int chgnum, int port); static inline enum ec_error_list chg_read8(int chgnum, int offset, int *value) @@ -375,25 +377,31 @@ static enum ec_error_list sm5803_set_mode(int chgnum, int mode) enum ec_error_list rv; int flow1_reg, flow2_reg; + mutex_lock(&flow1_access_lock[chgnum]); + rv = chg_read8(chgnum, SM5803_REG_FLOW2, &flow2_reg); - if (rv) + rv |= chg_read8(chgnum, SM5803_REG_FLOW1, &flow1_reg); + if (rv) { + mutex_unlock(&flow1_access_lock[chgnum]); return rv; + } /* - * Note: when charging or inhibiting charge, ensure bits to source Vbus - * in flow1 are zeroed. + * Note: Charge may be enabled while OTG is enabled, but should be + * disabled whenever inhibit is called. */ if (mode & CHARGE_FLAG_INHIBIT_CHARGE) { flow1_reg = 0; flow2_reg &= ~SM5803_FLOW2_AUTO_ENABLED; } else { - flow1_reg = SM5803_FLOW1_CHG_EN; + flow1_reg |= SM5803_FLOW1_CHG_EN; flow2_reg |= SM5803_FLOW2_AUTO_ENABLED; } rv = chg_write8(chgnum, SM5803_REG_FLOW1, flow1_reg); rv |= chg_write8(chgnum, SM5803_REG_FLOW2, flow2_reg); + mutex_unlock(&flow1_access_lock[chgnum]); return rv; } @@ -589,9 +597,12 @@ static enum ec_error_list sm5803_enable_otg_power(int chgnum, int enabled) rv = chg_write8(chgnum, SM5803_REG_ANA_EN1, reg); } + mutex_lock(&flow1_access_lock[chgnum]); rv = chg_read8(chgnum, SM5803_REG_FLOW1, ®); - if (rv) + if (rv) { + mutex_unlock(&flow1_access_lock[chgnum]); return rv; + } /* * Enable: CHG_EN - turns on buck-boost @@ -599,18 +610,18 @@ static enum ec_error_list sm5803_enable_otg_power(int chgnum, int enabled) * DIRECTCHG_SOURCE_EN - enable current loop (for designs with * no external Vbus FET) * - * Disable: disable above, note this SHOULD NOT be done while the port - * is charging, as turning off CHG_EN will disable charging - * as well + * Disable: disable bits above except CHG_EN, which should only be + * disabled through set_mode. */ if (enabled) reg |= (SM5803_FLOW1_CHG_EN | SM5803_FLOW1_VBUSIN_DISCHG_EN | SM5803_FLOW1_DIRECTCHG_SRC_EN); else - reg &= ~(SM5803_FLOW1_CHG_EN | SM5803_FLOW1_VBUSIN_DISCHG_EN | + reg &= ~(SM5803_FLOW1_VBUSIN_DISCHG_EN | SM5803_FLOW1_DIRECTCHG_SRC_EN); rv = chg_write8(chgnum, SM5803_REG_FLOW1, reg); + mutex_unlock(&flow1_access_lock[chgnum]); return rv; } |