summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlec Berg <alecaberg@chromium.org>2015-01-09 14:02:53 -0800
committerAlec Berg <alecaberg@chromium.org>2015-01-10 23:44:22 +0000
commit347c7313a03fff7f268d17a84d2d65ddd0699e41 (patch)
tree876f95392191bfe8dbba2531d5dfd58336704939
parent5c26087ef381fbe8469498eb65ecb10fc62ba349 (diff)
downloadchrome-ec-347c7313a03fff7f268d17a84d2d65ddd0699e41.tar.gz
pd: ensure power role matches CC pull resistor after hard reset
Make sure the power role and the CC pull resistor match after receiving hard reset command in the middle of a swap. BUG=none BRANCH=samus TEST=on samus connect left and right ports together with C to C cable. note that after some collisions and some hard resets, it eventually stabilizes with one port in SNK_READY, the other in SRC_READY. without this CL, we get stuck executing a power swap and our power role and CC resistor get out of sync, requiring a reboot. Change-Id: Ia1385eb3a1c503052ad5bfd0d1595ecc096cd5f4 Signed-off-by: Alec Berg <alecaberg@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/239976 Reviewed-by: Vincent Palatin <vpalatin@chromium.org> Reviewed-by: Todd Broch <tbroch@chromium.org>
-rw-r--r--common/usb_pd_protocol.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/common/usb_pd_protocol.c b/common/usb_pd_protocol.c
index 8a837be345..cedf027094 100644
--- a/common/usb_pd_protocol.c
+++ b/common/usb_pd_protocol.c
@@ -813,6 +813,20 @@ static void execute_hard_reset(int port)
#endif
#ifdef CONFIG_USB_PD_DUAL_ROLE
+ /*
+ * If we are swapping to a source and have changed to Rp, restore back
+ * to Rd to match our power_role.
+ */
+ if (pd[port].task_state == PD_STATE_SNK_SWAP_STANDBY ||
+ pd[port].task_state == PD_STATE_SNK_SWAP_COMPLETE)
+ pd_set_host_mode(port, 0);
+ /*
+ * If we are swapping to a sink and have changed to Rd, change role to
+ * sink to match the CC pull resistor.
+ */
+ if (pd[port].task_state == PD_STATE_SRC_SWAP_STANDBY)
+ pd[port].power_role = PD_ROLE_SINK;
+
if (pd[port].power_role == PD_ROLE_SINK) {
/* Clear the input current limit */
pd_set_input_current_limit(port, 0, 0);