diff options
author | Alec Berg <alecaberg@chromium.org> | 2014-11-05 14:32:19 -0800 |
---|---|---|
committer | chrome-internal-fetch <chrome-internal-fetch@google.com> | 2014-11-11 00:11:06 +0000 |
commit | cb1b27ea8c48e1f9a4e9137e466c2cc84b06d283 (patch) | |
tree | ee398ec1344a2a9054ab1ae1bc8c94cf49742cf6 | |
parent | c33a78a3b1ccf4ff8f083f072636efe25809fce0 (diff) | |
download | chrome-ec-cb1b27ea8c48e1f9a4e9137e466c2cc84b06d283.tar.gz |
pd: wait to send source cap until port partner is showing UFP
Wait to send source cap packet until port partner is showing
UFP on CC line. This is necessary because while we are applying
VBUS, the other side could toggle its role, and when VBUS is
finally up, we must wait to send source cap until other side
is pulling down.
BUG=none
BRANCH=samus
TEST=make buildall
Change-Id: If7e811913f5ec9eed28171ffca0cec98712b96fe
Signed-off-by: Alec Berg <alecaberg@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/227722
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 12ea1f18de..77e383aea5 100644 --- a/common/usb_pd_protocol.c +++ b/common/usb_pd_protocol.c @@ -1334,7 +1334,7 @@ void pd_task(void) #endif /* CONFIG_USB_PD_DUAL_ROLE */ enum pd_states this_state; timestamp_t now; - int caps_count = 0, src_ready_vdms_sent = 0; + int caps_count = 0, src_ready_vdms_sent = 0, src_connected = 0; /* Initialize TX pins and put them in Hi-Z */ pd_tx_init(); @@ -1424,7 +1424,6 @@ void pd_task(void) #endif set_state(port, PD_STATE_SRC_STARTUP); - caps_count = 0; } #ifdef CONFIG_USB_PD_DUAL_ROLE /* Swap roles if time expired or VBUS is present */ @@ -1443,12 +1442,15 @@ void pd_task(void) break; case PD_STATE_SRC_STARTUP: /* Wait for power source to enable */ - if (pd[port].last_state != pd[port].task_state) + if (pd[port].last_state != pd[port].task_state) { + caps_count = 0; + src_connected = 0; set_state_timeout( port, get_time().val + PD_POWER_SUPPLY_TRANSITION_DELAY, PD_STATE_SRC_DISCOVERY); + } break; case PD_STATE_SRC_DISCOVERY: #ifdef CONFIG_USB_PD_DUAL_ROLE @@ -1456,6 +1458,21 @@ void pd_task(void) if (pd[port].last_state != pd[port].task_state) next_role_swap = get_time().val + PD_T_DRP_HOLD; #endif + /* + * While we were enabling VBUS, other side could have + * toggled roles, so now wait until other side settles + * on UFP, before sending source cap. + */ + if (!src_connected) { + cc1_volt = pd_adc_read(port, pd[port].polarity); + if (cc1_volt < PD_SRC_VNC) { + src_connected = 1; + } else { + timeout = 10*MSEC; + break; + } + } + /* Send source cap some minimum number of times */ if (caps_count < PD_CAPS_COUNT) { /* Query capabilites of the other side */ |