summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorDenis Brockus <dbrockus@google.com>2020-05-29 20:23:37 -0600
committerCommit Bot <commit-bot@chromium.org>2020-06-04 18:29:17 +0000
commite38fa2719bdb9cd732b9ecd319fe29644104859a (patch)
tree94123a4fd6d607a01334714f3fbd459c085338e5 /common
parente802de1376c9733b49bcf18e5194392a55cdccbf (diff)
downloadchrome-ec-e38fa2719bdb9cd732b9ecd319fe29644104859a.tar.gz
TCPMv2: Wait for Safe0V on PR Swap SNK to SRC before PS_RDY
We were out of spec for PR Swap transitioning from SNK to SRC by sending PS_RDY before we were Safe0V. We only waited for the TC state machine to go from attached.snk to attached.src, which happened on the first state machine tick after pe_prs_src_snk_transition_to_off_entry was called and this does not guarantee Safe0V as is needed. Added an extra state to reflect what the PD spec requests and now waiting for Safe0V before indicating we are powered off. BUG=b:157755939 BRANCH=none TEST=ThinkPad Dock G2 should attach Signed-off-by: Denis Brockus <dbrockus@google.com> Change-Id: I93eb36acc64f273e8b30ca0a0bb76d6fa96b64ba Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2223723 Tested-by: Denis Brockus <dbrockus@chromium.org> Commit-Queue: Denis Brockus <dbrockus@chromium.org> Reviewed-by: Aseda Aboagye <aaboagye@chromium.org> Reviewed-by: Jett Rink <jettrink@chromium.org> Auto-Submit: Denis Brockus <dbrockus@chromium.org>
Diffstat (limited to 'common')
-rw-r--r--common/usbc/usb_pe_drp_sm.c30
1 files changed, 26 insertions, 4 deletions
diff --git a/common/usbc/usb_pe_drp_sm.c b/common/usbc/usb_pe_drp_sm.c
index c4e0fa0a58..751fd1a167 100644
--- a/common/usbc/usb_pe_drp_sm.c
+++ b/common/usbc/usb_pe_drp_sm.c
@@ -216,6 +216,7 @@ enum usb_pe_state {
PE_DRS_SEND_SWAP,
PE_PRS_SRC_SNK_EVALUATE_SWAP,
PE_PRS_SRC_SNK_TRANSITION_TO_OFF,
+ PE_PRS_SRC_SNK_ASSERT_RD,
PE_PRS_SRC_SNK_WAIT_SOURCE_ON,
PE_PRS_SRC_SNK_SEND_SWAP,
PE_PRS_SNK_SRC_EVALUATE_SWAP,
@@ -306,6 +307,7 @@ static const char * const pe_state_names[] = {
[PE_DRS_SEND_SWAP] = "PE_DRS_Send_Swap",
[PE_PRS_SRC_SNK_EVALUATE_SWAP] = "PE_PRS_SRC_SNK_Evaluate_Swap",
[PE_PRS_SRC_SNK_TRANSITION_TO_OFF] = "PE_PRS_SRC_SNK_Transition_To_Off",
+ [PE_PRS_SRC_SNK_ASSERT_RD] = "PE_PRS_SRC_SNK_Assert_Rd",
[PE_PRS_SRC_SNK_WAIT_SOURCE_ON] = "PE_PRS_SRC_SNK_Wait_Source_On",
[PE_PRS_SRC_SNK_SEND_SWAP] = "PE_PRS_SRC_SNK_Send_Swap",
[PE_PRS_SNK_SRC_EVALUATE_SWAP] = "PE_PRS_SNK_SRC_Evaluate_Swap",
@@ -3484,8 +3486,9 @@ static void pe_prs_src_snk_transition_to_off_entry(int port)
{
print_current_state(port);
- /* Tell TypeC to swap from Attached.SRC to Attached.SNK */
- tc_prs_src_snk_assert_rd(port);
+ /* Tell TypeC to power off the source */
+ tc_src_power_off(port);
+
pe[port].ps_source_timer =
get_time().val + PD_POWER_SUPPLY_TURN_OFF_DELAY;
}
@@ -3493,9 +3496,24 @@ static void pe_prs_src_snk_transition_to_off_entry(int port)
static void pe_prs_src_snk_transition_to_off_run(int port)
{
/* Give time for supply to power off */
- if (get_time().val < pe[port].ps_source_timer)
- return;
+ if (get_time().val > pe[port].ps_source_timer &&
+ tcpm_check_vbus_level(port, VBUS_SAFE0V))
+ set_state_pe(port, PE_PRS_SRC_SNK_ASSERT_RD);
+}
+
+/**
+ * PE_PRS_SRC_SNK_Assert_Rd
+ */
+static void pe_prs_src_snk_assert_rd_entry(int port)
+{
+ print_current_state(port);
+
+ /* Tell TypeC to swap from Attached.SRC to Attached.SNK */
+ tc_prs_src_snk_assert_rd(port);
+}
+static void pe_prs_src_snk_assert_rd_run(int port)
+{
/* Wait until Rd is asserted */
if (tc_is_attached_snk(port)) {
/* Contract is invalid */
@@ -5813,6 +5831,10 @@ static const struct usb_state pe_states[] = {
.entry = pe_prs_src_snk_transition_to_off_entry,
.run = pe_prs_src_snk_transition_to_off_run,
},
+ [PE_PRS_SRC_SNK_ASSERT_RD] = {
+ .entry = pe_prs_src_snk_assert_rd_entry,
+ .run = pe_prs_src_snk_assert_rd_run,
+ },
[PE_PRS_SRC_SNK_WAIT_SOURCE_ON] = {
.entry = pe_prs_src_snk_wait_source_on_entry,
.run = pe_prs_src_snk_wait_source_on_run,