summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVic Yang <victoryang@chromium.org>2014-08-12 13:38:19 -0700
committerchrome-internal-fetch <chrome-internal-fetch@google.com>2014-08-13 13:21:10 +0000
commit589e7f9e102f44863351e0d772403fa7344b66e6 (patch)
treeb57c3eb8d04abd601559fa7c3cd8b0f6d2286a28
parentfe1981a414384e30b9e2a197f893c6b281b9d49a (diff)
downloadchrome-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.c71
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);