diff options
author | Diana Z <dzigterman@chromium.org> | 2021-10-26 16:36:51 -0600 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2021-11-03 22:10:08 +0000 |
commit | 37493c0d4726d658902f41dbd521f30323b025ba (patch) | |
tree | ab76f9fab9b26ecb9c973ff7e66434b0e69b35b9 | |
parent | 7709b473263a7d8a740080ccbc848c54c76569d9 (diff) | |
download | chrome-ec-37493c0d4726d658902f41dbd521f30323b025ba.tar.gz |
Guybrush: Handle dead battery boot in more scenarios
When booting with no battery and multiple chargers (ex. suzy-q), we may
end up in scenarios where we have more than one TCPC in dead battery
mode. Attempt to get these TCPCs reset whenever we can, and always err
on the side of selecting the dead battery port as charge port.
This also corrects a typo in the case of no charge port selected.
BRANCH=None
BUG=b:183660105
TEST=on guybrush:
- boot with cutoff battery at 0% and two chargers, verify one is reset
and the other is selected. Re-plug charger that isn't selected and
verify it still isn't selected, Charge to 4% and verify new charger can
be selected and old port is reset.
- boot with cutoff battery at 9% and one charger, verify dead battery
port is immediately reset
Signed-off-by: Diana Z <dzigterman@chromium.org>
Change-Id: I4d4ebf314efbbcde99c820a78f5bd4639d08e0a5
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3248346
Reviewed-by: Edward Hill <ecgh@chromium.org>
-rw-r--r-- | baseboard/guybrush/baseboard.c | 70 |
1 files changed, 45 insertions, 25 deletions
diff --git a/baseboard/guybrush/baseboard.c b/baseboard/guybrush/baseboard.c index fe60fce1c6..26f212e986 100644 --- a/baseboard/guybrush/baseboard.c +++ b/baseboard/guybrush/baseboard.c @@ -433,7 +433,7 @@ int board_set_active_charge_port(int port) int is_valid_port = (port >= 0 && port < CONFIG_USB_PD_PORT_MAX_COUNT); int i; - int cur_port = charge_manager_get_active_charge_port(); + int rv; if (port == CHARGE_PORT_NONE) { CPRINTSUSB("Disabling all charger ports"); @@ -446,7 +446,7 @@ int board_set_active_charge_port(int port) */ if (nct38xx_get_boot_type(i) == NCT38XX_BOOT_DEAD_BATTERY) { - reset_nct38xx_port(cur_port); + reset_nct38xx_port(i); pd_set_error_recovery(i); } @@ -463,36 +463,56 @@ int board_set_active_charge_port(int port) return EC_ERROR_INVAL; } - - /* Check if the port is sourcing VBUS. */ - if (tcpm_get_src_ctrl(port)) { - CPRINTSUSB("Skip enable C%d", port); - return EC_ERROR_INVAL; - } - /* - * Disallow changing ports if we booted in dead battery mode and don't - * have sufficient power to withstand Vbus loss. The NCT3807 may - * continue to keep EN_SNK low on the original port and allow a - * dangerous level of voltage to pass through to the initial charge - * port (see b/183660105) + * Check if we can reset any ports in dead battery mode * - * If we do have sufficient power, then reset the dead battery port and - * set up Type-C error recovery on its connection. + * The NCT3807 may continue to keep EN_SNK low on the dead battery port + * and allow a dangerous level of voltage to pass through to the initial + * charge port (see b/183660105). We must reset the ports if we have + * sufficient battery to do so, which will bring EN_SNK back under + * normal control. */ - if (cur_port != CHARGE_PORT_NONE && - port != cur_port && - nct38xx_get_boot_type(cur_port) == + rv = EC_SUCCESS; + for (i = 0; i < board_get_usb_pd_port_count(); i++) { + if (nct38xx_get_boot_type(i) == NCT38XX_BOOT_DEAD_BATTERY) { + CPRINTSUSB("Found dead battery on %d", i); + /* + * If we have battery, get this port reset ASAP. + * This means temporarily rejecting charge manager + * sets to it. + */ + if (pd_is_battery_capable()) { + reset_nct38xx_port(i); + pd_set_error_recovery(i); + + if (port == i) + rv = EC_ERROR_INVAL; + } else if (port != i) { + /* + * If other port is selected and in dead battery + * mode, reset this port. Otherwise, reject + * change because we'll brown out. + */ + if (nct38xx_get_boot_type(port) == NCT38XX_BOOT_DEAD_BATTERY) { - if (pd_is_battery_capable()) { - reset_nct38xx_port(cur_port); - pd_set_error_recovery(cur_port); - } else { - CPRINTSUSB("Battery too low for charge port change"); - return EC_ERROR_INVAL; + reset_nct38xx_port(i); + pd_set_error_recovery(i); + } else { + rv = EC_ERROR_INVAL; + } + } } } + if (rv != EC_SUCCESS) + return rv; + + /* Check if the port is sourcing VBUS. */ + if (tcpm_get_src_ctrl(port)) { + CPRINTSUSB("Skip enable C%d", port); + return EC_ERROR_INVAL; + } + CPRINTSUSB("New charge port: C%d", port); /* |