summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlec Berg <alecaberg@chromium.org>2014-11-20 18:50:20 -0800
committerchrome-internal-fetch <chrome-internal-fetch@google.com>2014-11-22 09:34:07 +0000
commit7ca92127a4ebdbead58dd9cfb5c0ca136ad4168e (patch)
treed33bb3e7e124c8c8d9802d465fbe84aa3df35910
parent94082f6f53f1d9c124401139730c033d37bd9cac (diff)
downloadchrome-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.c23
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;