diff options
author | Peter Marheine <pmarheine@chromium.org> | 2022-06-02 16:47:16 +1000 |
---|---|---|
committer | Chromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com> | 2022-06-03 07:00:50 +0000 |
commit | bf09eba02420f42e7a42a5e922c0e1409c615cbd (patch) | |
tree | 8293a070f8f733c2b3e0642afae110d1bdd14316 | |
parent | c5e39056c3f2b6a607492eaaca07dae57c087f71 (diff) | |
download | chrome-ec-bf09eba02420f42e7a42a5e922c0e1409c615cbd.tar.gz |
nereid: bring charger out of LPM on S0 entry
This appears to fix VBUS sourcing, though we don't understand why. It may
also prevent charger damage with as-yet-unexplained cause.
BUG=b:231920135,b:230712704
TEST=VBUS sourcing works when AP is in S0
BRANCH=none
Signed-off-by: Peter Marheine <pmarheine@chromium.org>
Change-Id: Ia4d74f4211eb97b532882914d077e3dde5e59f64
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3686012
Reviewed-by: Andrew McRae <amcrae@google.com>
-rw-r--r-- | zephyr/projects/nissa/src/nereid/usbc.c | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/zephyr/projects/nissa/src/nereid/usbc.c b/zephyr/projects/nissa/src/nereid/usbc.c index 95bb1a5fdc..5219c252e5 100644 --- a/zephyr/projects/nissa/src/nereid/usbc.c +++ b/zephyr/projects/nissa/src/nereid/usbc.c @@ -4,6 +4,7 @@ */ #include <zephyr/logging/log.h> +#include <ap_power/ap_power.h> #include "charge_state_v2.h" #include "chipset.h" @@ -80,6 +81,52 @@ __override bool pd_check_vbus_level(int port, enum vbus_level level) return false; } +/* + * Putting chargers into LPM when in suspend reduces power draw by about 8mW + * per charger, but also seems critical to correct operation in source mode: + * if chargers are not in LPM when a sink is first connected, VBUS sourcing + * works even if the partner is later removed (causing LPM entry) and + * reconnected (causing LPM exit). If in LPM initially, sourcing VBUS + * consistently causes the charger to report (apparently spurious) overcurrent + * failures. + * + * In short, this is important to making things work correctly but we don't + * understand why. + */ +static void board_chargers_suspend(struct ap_power_ev_callback *const cb, + const struct ap_power_ev_data data) +{ + void (*fn)(int chgnum); + + switch (data.event) { + case AP_POWER_SUSPEND: + fn = sm5803_enable_low_power_mode; + break; + case AP_POWER_RESUME: + fn = sm5803_disable_low_power_mode; + break; + default: + LOG_WRN("%s: power event %d is not recognized", + __func__, data.event); + return; + } + + fn(CHARGER_PRIMARY); + if (board_get_charger_chip_count() > 1) + fn(CHARGER_SECONDARY); +} + +static int board_chargers_suspend_init(const struct device *unused) +{ + static struct ap_power_ev_callback cb = { + .handler = board_chargers_suspend, + .events = AP_POWER_SUSPEND | AP_POWER_RESUME, + }; + ap_power_ev_add_callback(&cb); + return 0; +} +SYS_INIT(board_chargers_suspend_init, APPLICATION, 0); + int board_set_active_charge_port(int port) { int is_real_port = (port >= 0 && port < board_get_usb_pd_port_count()); |