summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlec Berg <alecaberg@chromium.org>2014-08-18 17:17:14 -0700
committerchrome-internal-fetch <chrome-internal-fetch@google.com>2014-08-22 05:47:44 +0000
commit445691932cb08dbfb8c22a50c9071b5fd8df3c3c (patch)
treec2883e840fe30824af8995e31d50500ab1f77254
parent08081ee2dc05fe08cadd19252f94db06664f1cc9 (diff)
downloadchrome-ec-445691932cb08dbfb8c22a50c9071b5fd8df3c3c.tar.gz
pd: zinger: Turn off pings by default
Turn off sending pings in SRC_READY by default. Added custom VDM to turn pings back on, which only zinger supports right now. Changed the "pd ping" console command to be used to enabled/disable pings in SRC_READY. BUG=chrome-os-partner:31409 BRANCH=none TEST=loaded onto samus and zinger. on samus_pd, enabled highest level of debug info: "pd 0 debug 2" to allow printing ping received. Then plugged in zinger. By default, we negotiate to SNK_READY and receive no pings. Then send "pd 0 vdm ping 1" to send VDM to zinger to enable pings, and verified we start receiving pings. Sending "pd 0 vdm ping 0" sends VDM to stop sending pings. Change-Id: I4f64c6fc59bb734146eeca5e3ea3a24954c786b2 Signed-off-by: Alec Berg <alecaberg@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/212965 Reviewed-by: Vic Yang <victoryang@chromium.org> Reviewed-by: Todd Broch <tbroch@chromium.org>
-rw-r--r--board/zinger/usb_pd_policy.c3
-rw-r--r--common/usb_pd_protocol.c63
-rw-r--r--include/usb_pd.h11
3 files changed, 63 insertions, 14 deletions
diff --git a/board/zinger/usb_pd_policy.c b/board/zinger/usb_pd_policy.c
index f3d817f728..b73b7fbaf0 100644
--- a/board/zinger/usb_pd_policy.c
+++ b/board/zinger/usb_pd_policy.c
@@ -326,6 +326,9 @@ int pd_custom_vdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload)
flash_write_rw(CONFIG_FW_RW_SIZE - 32, 4*cnt,
(const char *)(payload+1));
break;
+ case VDO_CMD_PING_ENABLE:
+ pd_ping_enable(0, payload[1]);
+ break;
default:
/* Unknown : do not answer */
return 0;
diff --git a/common/usb_pd_protocol.c b/common/usb_pd_protocol.c
index 91575052fe..0d6fbb7ef6 100644
--- a/common/usb_pd_protocol.c
+++ b/common/usb_pd_protocol.c
@@ -206,6 +206,8 @@ static struct pd_protocol {
enum pd_states timeout_state;
/* Timeout for the current state. Set to 0 for no timeout. */
uint64_t timeout;
+ /* Flag for sending pings in SRC_READY */
+ uint8_t ping_enabled;
#ifdef CONFIG_USB_PD_DUAL_ROLE
/* Current limit based on the last request message */
@@ -1057,6 +1059,11 @@ void pd_comm_enable(int enable)
pd_comm_enabled = enable;
}
+void pd_ping_enable(int port, int enable)
+{
+ pd[port].ping_enabled = enable;
+}
+
void pd_task(void)
{
int head;
@@ -1078,6 +1085,7 @@ void pd_task(void)
/* Initialize PD protocol state variables for each port. */
pd[port].role = PD_ROLE_DEFAULT;
pd[port].vdm_state = VDM_STATE_DONE;
+ pd[port].ping_enabled = 0;
set_state(port, PD_DEFAULT_STATE);
/* Ensure the power supply is in the default state */
@@ -1202,16 +1210,21 @@ void pd_task(void)
}
break;
case PD_STATE_SRC_READY:
- /* Verify that the sink is alive */
- res = send_control(port, PD_CTRL_PING);
- if (res >= 0) {
- /* schedule next keep-alive */
- timeout = PD_T_SOURCE_ACTIVITY;
+ if (pd[port].ping_enabled) {
+ /* Verify that the sink is alive */
+ res = send_control(port, PD_CTRL_PING);
+ if (res >= 0) {
+ /* schedule next keep-alive */
+ timeout = PD_T_SOURCE_ACTIVITY;
+ } else {
+ /* The sink died ... */
+ pd_power_supply_reset(port);
+ set_state(port,
+ PD_STATE_SRC_DISCONNECTED);
+ timeout = PD_T_SEND_SOURCE_CAP;
+ }
} else {
- /* The sink died ... */
- pd_power_supply_reset(port);
- set_state(port, PD_STATE_SRC_DISCONNECTED);
- timeout = PD_T_SEND_SOURCE_CAP;
+ timeout = PD_T_SOURCE_ACTIVITY;
}
break;
#ifdef CONFIG_USB_PD_DUAL_ROLE
@@ -1545,10 +1558,32 @@ static int command_pd(int argc, char **argv)
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);
- set_state(port, PD_STATE_SRC_READY);
- task_wake(PORT_TO_TASK_ID(port));
+ int enable;
+
+ if (argc > 3) {
+ enable = strtoi(argv[3], &e, 10);
+ if (*e)
+ return EC_ERROR_PARAM3;
+ pd[port].ping_enabled = enable;
+ }
+
+ ccprintf("Pings %s\n", pd[port].ping_enabled ? "on" : "off");
+ } else if (!strncasecmp(argv[2], "vdm", 3)) {
+ if (argc < 4)
+ return EC_ERROR_PARAM_COUNT;
+
+ if (!strncasecmp(argv[3], "ping", 4)) {
+ uint32_t enable;
+ if (argc < 5)
+ return EC_ERROR_PARAM_COUNT;
+ enable = strtoi(argv[4], &e, 10);
+ if (*e)
+ return EC_ERROR_PARAM4;
+ pd_send_vdm(port, USB_VID_GOOGLE, VDO_CMD_PING_ENABLE,
+ &enable, 1);
+ } else {
+ return EC_ERROR_PARAM_COUNT;
+ }
} else if (!strcasecmp(argv[2], "dualrole")) {
if (argc < 4) {
ccprintf("dual-role toggling: ");
@@ -1603,7 +1638,7 @@ static int command_pd(int argc, char **argv)
DECLARE_CONSOLE_COMMAND(pd, command_pd,
"<port> "
"[tx|bist|charger|dev|dump|dualrole|enable"
- "|soft|hard|clock|ping|state]",
+ "|soft|hard|clock|ping|state|vdm [ping]]",
"USB PD",
NULL);
diff --git a/include/usb_pd.h b/include/usb_pd.h
index 2267a2f84d..fc2d59b6bd 100644
--- a/include/usb_pd.h
+++ b/include/usb_pd.h
@@ -127,6 +127,7 @@ enum pd_errors {
#define VDO_CMD_FLASH_ERASE VDO_CMD_VENDOR(6)
#define VDO_CMD_FLASH_WRITE VDO_CMD_VENDOR(7)
#define VDO_CMD_FLASH_HASH VDO_CMD_VENDOR(8)
+#define VDO_CMD_PING_ENABLE VDO_CMD_VENDOR(10)
#define PD_VDO_VID(vdo) ((vdo) >> 16)
#define PD_VDO_CMD(vdo) ((vdo) & 0x1f)
@@ -503,4 +504,14 @@ int pd_get_polarity(int port);
*/
void pd_comm_enable(int enable);
+/**
+ * Set the PD pings enabled flag. When source has negotiated power over
+ * PD successfully, it can optionally send pings periodically based on
+ * this enable flag.
+ *
+ * @param port USB-C port number
+ * @param enable Enable flag to set
+ */
+void pd_ping_enable(int port, int enable);
+
#endif /* __USB_PD_H */