diff options
author | Shawn Nematbakhsh <shawnn@chromium.org> | 2017-01-26 15:04:25 -0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2017-02-11 13:06:38 -0800 |
commit | 050ea0226844252d33285461b490372fe8c02f8e (patch) | |
tree | bdc7867bfaef422652251eb905863d35c8522e15 /common | |
parent | ae3996fb2fda2a970c45ebf347ee2011f9f34b28 (diff) | |
download | chrome-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.c | 30 |
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 |