summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlec Berg <alecaberg@chromium.org>2014-11-05 14:32:19 -0800
committerchrome-internal-fetch <chrome-internal-fetch@google.com>2014-11-11 00:11:06 +0000
commitcb1b27ea8c48e1f9a4e9137e466c2cc84b06d283 (patch)
treeee398ec1344a2a9054ab1ae1bc8c94cf49742cf6
parentc33a78a3b1ccf4ff8f083f072636efe25809fce0 (diff)
downloadchrome-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.c23
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 */