summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAseda Aboagye <aaboagye@google.com>2018-06-08 18:19:59 -0700
committerchrome-bot <chrome-bot@chromium.org>2018-07-04 05:43:46 -0700
commit62c0a7e74cac24cc24a3d0f1876bed598eb8e2a5 (patch)
tree0078e3c5293116bda0b05dce76dae5969c3ab97d
parenta84165968ca78fe7d783e522f79dd01abc6303fd (diff)
downloadchrome-ec-62c0a7e74cac24cc24a3d0f1876bed598eb8e2a5.tar.gz
USB PD: Initialize CC polarity during init.
Previously, explicit PD contracts were not maintained after a reset, but that has recently changed. Now, if a PD contract is in place, a SoftReset is sent to the port partner to renogotiate the contract without dropping VBUS. However, the CC polarity was not initialized in this code path. On a system with external TCPCs, we may have been lucky and depending upon the orientation, the right CC line may have been used. This was actually breaking boards that did lose their TCPC state after reset. This commit simply initializes the CC polarity before potentially sending any PD messages. BUG=b:111114159 BRANCH=whichever take the new SoftReset after reset patches. TEST=Flash servo_v4; Plug in PD source to CHG port, reboot, verify that PD communication still works with the source following a reboot. TEST=Flash scarlet; Plug in a charge through hub with a charger and USB storage devices plugged in, reboot, verify that PD communication still works with the source following a reboot. Repeat the test in the other orientation. Change-Id: I85a16dd8982747a66883579bb8cf3673dbdd95d8 Signed-off-by: Aseda Aboagye <aaboagye@google.com> Reviewed-on: https://chromium-review.googlesource.com/1094264 Commit-Ready: Aseda Aboagye <aaboagye@chromium.org> Tested-by: Aseda Aboagye <aaboagye@chromium.org> Reviewed-by: Jonathan Brandmeyer <jbrandmeyer@chromium.org>
-rw-r--r--common/usb_pd_protocol.c45
1 files changed, 36 insertions, 9 deletions
diff --git a/common/usb_pd_protocol.c b/common/usb_pd_protocol.c
index 0cae3bde9e..567d9240d9 100644
--- a/common/usb_pd_protocol.c
+++ b/common/usb_pd_protocol.c
@@ -2245,9 +2245,6 @@ void pd_task(void *u)
pd_set_data_role(port,
(saved_flgs & PD_BBRMFLG_DATA_ROLE) ?
PD_ROLE_DFP : PD_ROLE_UFP);
- /* Set the terminations to match our power role. */
- tcpm_set_cc(port, pd[port].power_role ?
- TYPEC_CC_RP : TYPEC_CC_RD);
/*
* Since there is an explicit contract in place, let's
@@ -2258,13 +2255,17 @@ void pd_task(void *u)
this_state = PD_STATE_SOFT_RESET;
/*
- * Enable TCPC RX so we can hear back from our port
- * partner.
+ * Set the TCPC reset event such that we can set our CC
+ * terminations, determine polarity, and enable RX so we
+ * can hear back from our port partner.
*/
- tcpm_set_rx_enable(port, 1);
+ task_set_event(task_get_current(),
+ PD_EVENT_TCPC_RESET,
+ 0);
}
}
#endif /* defined(CONFIG_USB_PD_DUAL_ROLE) */
+
pd[port].vdm_state = VDM_STATE_DONE;
set_state(port, this_state);
#ifdef CONFIG_USB_PD_MAX_SINGLE_SOURCE_CURRENT
@@ -2348,9 +2349,34 @@ void pd_task(void *u)
if ((evt & PD_EVENT_TCPC_RESET) &&
(pd[port].task_state != PD_STATE_DRP_AUTO_TOGGLE)) {
#endif
- /* Ensure CC termination is default */
- tcpm_set_cc(port, PD_ROLE_DEFAULT(port) ==
- PD_ROLE_SOURCE ? TYPEC_CC_RP : TYPEC_CC_RD);
+#ifdef CONFIG_USB_PD_DUAL_ROLE
+ if (pd[port].task_state == PD_STATE_SOFT_RESET) {
+ int cc1, cc2;
+
+ /*
+ * Set the terminations to match our power
+ * role.
+ */
+ tcpm_set_cc(port, pd[port].power_role ?
+ TYPEC_CC_RP : TYPEC_CC_RD);
+
+ /* Determine the polarity. */
+ tcpm_get_cc(port, &cc1, &cc2);
+ if (pd[port].power_role == PD_ROLE_SINK) {
+ pd[port].polarity =
+ get_snk_polarity(cc1, cc2);
+ } else {
+ pd[port].polarity =
+ (cc1 != TYPEC_CC_VOLT_RD);
+ }
+ } else
+#endif /* CONFIG_USB_PD_DUAL_ROLE */
+ {
+ /* Ensure CC termination is default */
+ tcpm_set_cc(port, PD_ROLE_DEFAULT(port) ==
+ PD_ROLE_SOURCE ? TYPEC_CC_RP :
+ TYPEC_CC_RD);
+ }
/*
* If we have a stable contract in the default role,
@@ -2363,6 +2389,7 @@ void pd_task(void *u)
#ifdef CONFIG_USB_PD_DUAL_ROLE
(PD_ROLE_DEFAULT(port) == PD_ROLE_SINK &&
pd[port].task_state == PD_STATE_SNK_READY) ||
+ (pd[port].task_state == PD_STATE_SOFT_RESET) ||
#endif
(PD_ROLE_DEFAULT(port) == PD_ROLE_SOURCE &&
pd[port].task_state == PD_STATE_SRC_READY))) {