diff options
author | Alec Berg <alecaberg@chromium.org> | 2014-08-18 17:17:14 -0700 |
---|---|---|
committer | chrome-internal-fetch <chrome-internal-fetch@google.com> | 2014-08-22 05:47:44 +0000 |
commit | 445691932cb08dbfb8c22a50c9071b5fd8df3c3c (patch) | |
tree | c2883e840fe30824af8995e31d50500ab1f77254 | |
parent | 08081ee2dc05fe08cadd19252f94db06664f1cc9 (diff) | |
download | chrome-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.c | 3 | ||||
-rw-r--r-- | common/usb_pd_protocol.c | 63 | ||||
-rw-r--r-- | include/usb_pd.h | 11 |
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 */ |