diff options
author | Alec Berg <alecaberg@chromium.org> | 2014-11-20 18:50:20 -0800 |
---|---|---|
committer | chrome-internal-fetch <chrome-internal-fetch@google.com> | 2014-11-22 09:34:07 +0000 |
commit | 7ca92127a4ebdbead58dd9cfb5c0ca136ad4168e (patch) | |
tree | d33bb3e7e124c8c8d9802d465fbe84aa3df35910 | |
parent | 94082f6f53f1d9c124401139730c033d37bd9cac (diff) | |
download | chrome-ec-7ca92127a4ebdbead58dd9cfb5c0ca136ad4168e.tar.gz |
pd: restore CC resistor if fail power swap
Fix bug where if a power swap fails in the final stages, it
will have switched its CC resistor, but will not have actually
switched roles, which causes all sorts of weirdness.
BUG=none
BRANCH=samus
TEST=make buildall. tested power swap between two samus'. modified
one samus to never send PS_RDY when in PD_STATE_SNK_SWAP_COMPLETE,
and verified that when source asks for power swap and fails, that
it properly resets CC to pull-up.
Change-Id: If0fc8d3d51ede3be1160ae3b106061edabeaa948
Signed-off-by: Alec Berg <alecaberg@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/231193
Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
Reviewed-by: Todd Broch <tbroch@chromium.org>
-rw-r--r-- | common/usb_pd_protocol.c | 23 |
1 files changed, 20 insertions, 3 deletions
diff --git a/common/usb_pd_protocol.c b/common/usb_pd_protocol.c index abc07ae84e..525ee732e7 100644 --- a/common/usb_pd_protocol.c +++ b/common/usb_pd_protocol.c @@ -1803,11 +1803,11 @@ void pd_task(void) PD_STATE_HARD_RESET_SEND); /* Switch to Rd */ pd_set_host_mode(port, 0); - /* Wait for PD_RDY from sink */ + /* Wait for PS_RDY from sink */ set_state_timeout(port, get_time().val + PD_T_PS_SOURCE_ON, - PD_STATE_HARD_RESET_SEND); + PD_STATE_HARD_RESET_EXECUTE); } break; case PD_STATE_SUSPENDED: @@ -2082,6 +2082,8 @@ void pd_task(void) /* Switch to Rp and enable power supply */ pd_set_host_mode(port, 1); if (pd_set_power_supply_ready(port)) { + /* Restore Rd */ + pd_set_host_mode(port, 0); set_state(port, PD_STATE_HARD_RESET_SEND); break; @@ -2097,8 +2099,11 @@ void pd_task(void) case PD_STATE_SNK_SWAP_COMPLETE: /* Send PS_RDY and change to source role */ res = send_control(port, PD_CTRL_PS_RDY); - if (res < 0) + if (res < 0) { + /* Restore Rd */ + pd_set_host_mode(port, 0); set_state(port, PD_STATE_HARD_RESET_SEND); + } caps_count = 0; pd[port].msg_id = 0; @@ -2148,6 +2153,18 @@ void pd_task(void) } break; case PD_STATE_HARD_RESET_EXECUTE: +#ifdef CONFIG_USB_PD_DUAL_ROLE + /* + * If hard reset while in the last stages of power + * swap, then we need to restore our CC resistor. + */ + if (pd[port].last_state == PD_STATE_SRC_SWAP_STANDBY) + pd_set_host_mode(port, 1); + else if (pd[port].last_state == + PD_STATE_SNK_SWAP_STANDBY) + pd_set_host_mode(port, 0); +#endif + /* reset our own state machine */ execute_hard_reset(port); timeout = 10*MSEC; |