diff options
author | Aseda Aboagye <aaboagye@google.com> | 2018-12-17 19:42:09 -0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2019-04-09 06:19:52 -0700 |
commit | b0fc327b14d1c0a4729720e401f29b821be4e882 (patch) | |
tree | 0dd270010cde1d329d453c2fdd0674e2aa93a229 /common | |
parent | 61b34b2cab9bd0ab65a3ef6ab7ad4d674cfa1255 (diff) | |
download | chrome-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>
Diffstat (limited to 'common')
-rw-r--r-- | common/usb_pd_protocol.c | 24 |
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 */ |