summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAseda Aboagye <aaboagye@google.com>2018-12-17 19:42:09 -0800
committerchrome-bot <chrome-bot@chromium.org>2019-04-09 06:19:52 -0700
commitb0fc327b14d1c0a4729720e401f29b821be4e882 (patch)
tree0dd270010cde1d329d453c2fdd0674e2aa93a229
parent61b34b2cab9bd0ab65a3ef6ab7ad4d674cfa1255 (diff)
downloadchrome-ec-b0fc327b14d1c0a4729720e401f29b821be4e882.tar.gz
pd: Apply Rd prior to sending PS_RDY in PRSWAP.
According to the PD spec, in a Power Role swap, the initial source must change its termination from Rp to Rd prior to sending the PS_RDY control message. This commit fixes a bug where we were changing our termination *after* sending the PS_RDY control message. BUG=b:113207208, b:116340006 BRANCH=firmware-nocturne-10984.B,master TEST=Plug in charge thru hub with charger plugged into nocturne, verify PR swap succeeds and the CC lines don't float to vOpen. TEST=Plug in Pixel phone into nocturne, do a PR swap, verify that the CC lines don't float to vOpen. Change-Id: If041595baa77d2494c4caff3660151329bfd4926 Signed-off-by: Aseda Aboagye <aaboagye@google.com> Reviewed-on: https://chromium-review.googlesource.com/c/1381633 Tested-by: Aseda Aboagye <aaboagye@chromium.org> Reviewed-by: Daisuke Nojiri <dnojiri@chromium.org> Commit-Queue: Aseda Aboagye <aaboagye@chromium.org> (cherry picked from commit 31dfe0b1a6b43b01bc89f45e6d3a4ac78b823959) Reviewed-on: https://chromium-review.googlesource.com/1388845 Commit-Ready: ChromeOS CL Exonerator Bot <chromiumos-cl-exonerator@appspot.gserviceaccount.com> Reviewed-by: Aseda Aboagye <aaboagye@chromium.org>
-rw-r--r--common/usb_pd_protocol.c24
1 files changed, 19 insertions, 5 deletions
diff --git a/common/usb_pd_protocol.c b/common/usb_pd_protocol.c
index 2782dee5ec..932467826d 100644
--- a/common/usb_pd_protocol.c
+++ b/common/usb_pd_protocol.c
@@ -3466,9 +3466,26 @@ void pd_task(void *u)
PD_STATE_SRC_SWAP_SRC_DISABLE);
break;
case PD_STATE_SRC_SWAP_SRC_DISABLE:
- /* Turn power off */
if (pd[port].last_state != pd[port].task_state) {
+ /* Turn power off */
pd_power_supply_reset(port);
+
+ /*
+ * Switch to Rd and swap roles to sink
+ *
+ * The reason we do this as early as possible is
+ * to help prevent CC disconnection cases where
+ * both partners are applying an Rp. Certain PD
+ * stacks (e.g. qualcomm), reflexively apply
+ * their Rp once VBUS falls beneath
+ * ~3.67V. (b/77827528).
+ */
+ tcpm_set_cc(port, TYPEC_CC_RD);
+ pd_set_power_role(port, PD_ROLE_SINK);
+
+ /* Inform TCPC of power role update. */
+ pd_update_roles(port);
+
set_state_timeout(port,
get_time().val +
PD_POWER_SUPPLY_TURN_OFF_DELAY,
@@ -3486,9 +3503,6 @@ void pd_task(void *u)
PD_STATE_SRC_DISCONNECTED);
break;
}
- /* Switch to Rd and swap roles to sink */
- tcpm_set_cc(port, TYPEC_CC_RD);
- pd_set_power_role(port, PD_ROLE_SINK);
/* Wait for PS_RDY from new source */
set_state_timeout(port,
get_time().val +
@@ -3925,7 +3939,7 @@ void pd_task(void *u)
break;
case PD_STATE_SNK_SWAP_STANDBY:
if (pd[port].last_state != pd[port].task_state) {
- /* Switch to Rp and enable power supply */
+ /* Switch to Rp and enable power supply. */
tcpm_set_cc(port, TYPEC_CC_RP);
if (pd_set_power_supply_ready(port)) {
/* Restore Rd */