diff options
author | Vic Yang <victoryang@chromium.org> | 2014-08-12 13:38:19 -0700 |
---|---|---|
committer | chrome-internal-fetch <chrome-internal-fetch@google.com> | 2014-08-13 13:21:10 +0000 |
commit | 589e7f9e102f44863351e0d772403fa7344b66e6 (patch) | |
tree | b57c3eb8d04abd601559fa7c3cd8b0f6d2286a28 | |
parent | fe1981a414384e30b9e2a197f893c6b281b9d49a (diff) | |
download | chrome-ec-589e7f9e102f44863351e0d772403fa7344b66e6.tar.gz |
pd: Implement PD soft reset
Currently, when we receive soft reset request, we only reset message ID.
According to the spec, we should also reset the state machine without
cutting power. This CL implements this, along with a console command to
issue soft reset request.
BUG=chrome-os-partner:31296
TEST=Issue soft reset from Ryu to Zinger. Check that we go back to
discovery state and re-negociate a contract.
BRANCH=None
Change-Id: Ib00b0d9dddaf6ac2a1ec5c46dbc2824d6d7814ed
Signed-off-by: Vic Yang <victoryang@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/212122
Reviewed-by: Alec Berg <alecaberg@chromium.org>
-rw-r--r-- | common/usb_pd_protocol.c | 71 |
1 files changed, 51 insertions, 20 deletions
diff --git a/common/usb_pd_protocol.c b/common/usb_pd_protocol.c index cb3e28bd64..2b3ccfec4d 100644 --- a/common/usb_pd_protocol.c +++ b/common/usb_pd_protocol.c @@ -157,6 +157,7 @@ enum pd_states { PD_STATE_SRC_TRANSITION, PD_STATE_SRC_READY, + PD_STATE_SOFT_RESET, PD_STATE_HARD_RESET, PD_STATE_BIST, }; @@ -574,6 +575,29 @@ static int pd_is_connected(int port) return pd[port].task_state != PD_STATE_SRC_DISCONNECTED; } +static void execute_hard_reset(int port) +{ + pd[port].msg_id = 0; +#ifdef CONFIG_USB_PD_DUAL_ROLE + set_state(port, pd[port].role == PD_ROLE_SINK ? + PD_STATE_SNK_DISCONNECTED : PD_STATE_SRC_DISCONNECTED); + + /* Clear the input current limit */ + pd_set_input_current_limit(0); +#else + set_state(port, PD_STATE_SRC_DISCONNECTED); +#endif + pd_power_supply_reset(port); + CPRINTF("HARD RESET!\n"); +} + +static void execute_soft_reset(int port) +{ + pd[port].msg_id = 0; + set_state(port, PD_STATE_SOFT_RESET); + CPRINTF("Soft Reset\n"); +} + #ifdef CONFIG_USB_PD_DUAL_ROLE static void pd_store_src_cap(int port, int cnt, uint32_t *src_caps) { @@ -696,9 +720,7 @@ static void handle_ctrl_request(int port, uint16_t head, case PD_CTRL_ACCEPT: break; case PD_CTRL_SOFT_RESET: - /* Just reset message counters */ - pd[port].msg_id = 0; - CPRINTF("Soft Reset\n"); + execute_soft_reset(port); /* We are done, acknowledge with an Accept packet */ send_control(port, PD_CTRL_ACCEPT); break; @@ -899,22 +921,6 @@ packet_err: return bit; } -static void execute_hard_reset(int port) -{ - pd[port].msg_id = 0; -#ifdef CONFIG_USB_PD_DUAL_ROLE - set_state(port, pd[port].role == PD_ROLE_SINK ? - PD_STATE_SNK_DISCONNECTED : PD_STATE_SRC_DISCONNECTED); - - /* Clear the input current limit */ - pd_set_input_current_limit(0); -#else - set_state(port, PD_STATE_SRC_DISCONNECTED); -#endif - pd_power_supply_reset(port); - CPRINTF("HARD RESET!\n"); -} - void pd_send_vdm(int port, uint32_t vid, int cmd, uint32_t *data, int count) { int i; @@ -1243,6 +1249,27 @@ void pd_task(void) timeout = 100*MSEC; break; #endif /* CONFIG_USB_PD_DUAL_ROLE */ + case PD_STATE_SOFT_RESET: + /* + * Delay for 30 ms in case the port partner is not + * ready + */ + if (pd[port].last_state != pd[port].task_state) { +#ifdef CONFIG_USB_PD_DUAL_ROLE + enum pd_states discovery_state = + (pd[port].role == PD_ROLE_SINK ? + PD_STATE_SNK_DISCOVERY : + PD_STATE_SRC_DISCOVERY); +#else + enum pd_states discovery_state = + PD_STATE_SRC_DISCOVERY; +#endif + set_state_timeout( + port, + get_time().val + (30 * MSEC), + discovery_state); + } + break; case PD_STATE_HARD_RESET: send_hard_reset(port); /* reset our own state machine */ @@ -1467,6 +1494,10 @@ static int command_pd(int argc, char **argv) } else if (!strncasecmp(argv[2], "hard", 4)) { set_state(port, PD_STATE_HARD_RESET); task_wake(PORT_TO_TASK_ID(port)); + } else if (!strncasecmp(argv[2], "soft", 4)) { + execute_soft_reset(port); + send_control(port, PD_CTRL_SOFT_RESET); + task_wake(PORT_TO_TASK_ID(port)); } else if (!strncasecmp(argv[2], "ping", 4)) { pd[port].role = PD_ROLE_SOURCE; pd_set_host_mode(port, 1); @@ -1526,7 +1557,7 @@ static int command_pd(int argc, char **argv) DECLARE_CONSOLE_COMMAND(pd, command_pd, "<port> " "[tx|bist|charger|dev|dump|dualrole|enable" - "|hard|clock|ping|state]", + "|soft|hard|clock|ping|state]", "USB PD", NULL); |