summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorShawn Nematbakhsh <shawnn@chromium.org>2017-01-26 15:04:25 -0800
committerchrome-bot <chrome-bot@chromium.org>2017-02-11 13:06:38 -0800
commit050ea0226844252d33285461b490372fe8c02f8e (patch)
treebdc7867bfaef422652251eb905863d35c8522e15 /common
parentae3996fb2fda2a970c45ebf347ee2011f9f34b28 (diff)
downloadchrome-ec-050ea0226844252d33285461b490372fe8c02f8e.tar.gz
pd: Ensure PD is interrupted on EC reset
If PD is negotiated and the EC is reset, a source partner port will continue providing its negotiated voltage (eg. 20V in the case of zinger). Ensure the partner port is in a known state by providing Rp for a brief period after resetting to RO. BUG=chrome-os-partner:62281 BRANCH=Reef TEST=On kevin, attach zinger, wait for 20V negotiation, and press F3 + power to cause EC reset. Verify VBUS drops to approximately 0V before going back to 5V / 20V. Verify the same with kevin OEM charger as well. Also verify kevin boots with no battery. Change-Id: I1b769a76188d8a9a515388996fbc4cb3d46840a5 Signed-off-by: Shawn Nematbakhsh <shawnn@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/433367 Commit-Ready: Shawn N <shawnn@chromium.org> Tested-by: Shawn N <shawnn@chromium.org> Reviewed-by: Daisuke Nojiri <dnojiri@chromium.org>
Diffstat (limited to 'common')
-rw-r--r--common/usb_pd_protocol.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/common/usb_pd_protocol.c b/common/usb_pd_protocol.c
index 2d10581801..c6d8712fa4 100644
--- a/common/usb_pd_protocol.c
+++ b/common/usb_pd_protocol.c
@@ -1420,6 +1420,31 @@ static int pd_is_power_swapping(int port)
pd[port].task_state == PD_STATE_SRC_SWAP_STANDBY;
}
+/*
+ * Provide Rp to ensure the partner port is in a known state (eg. not
+ * PD negotiated, not sourcing 20V).
+ */
+static void pd_partner_port_reset(int port)
+{
+ uint64_t timeout;
+
+ /*
+ * If we already ran RO, then PD comms were disabled, and we are
+ * already in a known state. Likewise, if the board is powering up,
+ * we're also in a known state.
+ */
+ if (system_get_image_copy() != SYSTEM_IMAGE_RO ||
+ system_get_reset_flags() &
+ (RESET_FLAG_BROWNOUT | RESET_FLAG_POWER_ON))
+ return;
+
+ /* Provide Rp for 100 msec. or until we no longer have VBUS. */
+ tcpm_set_cc(port, TYPEC_CC_RP);
+ timeout = get_time().val + 100 * MSEC;
+
+ while (get_time().val < timeout && pd_is_vbus_present(port))
+ msleep(10);
+}
#endif /* CONFIG_USB_PD_DUAL_ROLE */
int pd_get_polarity(int port)
@@ -1613,6 +1638,11 @@ void pd_task(void)
/* Initialize TCPM driver and wait for TCPC to be ready */
res = tcpm_init(port);
+
+#ifdef CONFIG_USB_PD_DUAL_ROLE
+ pd_partner_port_reset(port);
+#endif
+
CPRINTS("TCPC p%d init %s", port, res ? "failed" : "ready");
this_state = res ? PD_STATE_SUSPENDED : PD_DEFAULT_STATE(port);
#ifndef CONFIG_USB_PD_TCPC