From ce6cb6effaab1f050a39ccf2ef8ce5b3745f32c7 Mon Sep 17 00:00:00 2001 From: Alec Berg Date: Fri, 10 Oct 2014 14:59:50 -0700 Subject: [PATCH] pd: implement source recovery time after hard reset Implemented source recovery time following a hard reset. According to the spec: After a hard reset, the source must dissipate output voltage to vSafe5V. After establishing the safe voltage condition on VBUS, the power supply shall wait tSrcRecover before powering VBUS to vSafe5V. BUG=none BRANCH=samus TEST=plug in a type-c to type-a adapter to samus. then issue a hard reset from the console and verify that it takes nearly a second before samus re-enables vbus. Change-Id: Id21eb7cf03759b7ecd64ad11c3c57e66cf35370a Signed-off-by: Alec Berg Reviewed-on: https://chromium-review.googlesource.com/222935 Reviewed-by: Vic Yang Reviewed-by: Vincent Palatin --- common/usb_pd_protocol.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/common/usb_pd_protocol.c b/common/usb_pd_protocol.c index b84a34565a..6c8c8d8ed8 100644 --- a/common/usb_pd_protocol.c +++ b/common/usb_pd_protocol.c @@ -170,6 +170,7 @@ static const uint8_t dec4b5b[] = { /* DRP_SNK + DRP_SRC must be between 50ms and 100ms with 30%-70% duty cycle */ #define PD_T_DRP_SNK (40*MSEC) /* toggle time for sink DRP */ #define PD_T_DRP_SRC (30*MSEC) /* toggle time for source DRP */ +#define PD_T_SRC_RECOVER (760*MSEC) /* between 660ms and 1000ms */ /* Port role at startup */ #ifdef CONFIG_USB_PD_DUAL_ROLE @@ -214,6 +215,8 @@ static struct pd_protocol { enum pd_states timeout_state; /* Timeout for the current state. Set to 0 for no timeout. */ uint64_t timeout; + /* Time for source recovery after hard reset */ + uint64_t src_recover; /* Flag for sending pings in SRC_READY */ uint8_t ping_enabled; @@ -655,6 +658,7 @@ static void execute_hard_reset(int port) set_state(port, PD_STATE_SRC_DISCONNECTED); #endif pd_power_supply_reset(port); + pd[port].src_recover = get_time().val + PD_T_SRC_RECOVER; CPRINTF("HARD RESET!\n"); } @@ -1233,6 +1237,10 @@ void pd_task(void) cc2_volt = pd_adc_read(port, 1); if ((cc1_volt < PD_SRC_VNC) || (cc2_volt < PD_SRC_VNC)) { + /* Break if in hard reset recovery time */ + if (get_time().val < pd[port].src_recover) + break; + pd[port].polarity = GET_POLARITY(cc1_volt, cc2_volt); pd_select_polarity(port, pd[port].polarity);