diff options
author | Alec Berg <alecaberg@chromium.org> | 2015-09-10 15:27:31 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2015-09-11 13:51:00 -0700 |
commit | fd92f9bfebcf3125cf2a7e0f5931f3cd50e395e8 (patch) | |
tree | 7583ec2d0700c369daf696a185cda66788d74422 | |
parent | 17296409d8eec57bd3f11c8835ad13f22d4f13fc (diff) | |
download | chrome-ec-fd92f9bfebcf3125cf2a7e0f5931f3cd50e395e8.tar.gz |
pd: add swap commands to USB_PD_CONTROL host command
Add all swap commands to USB_PD_CONTROL host command: data,
power, and vconn swap.
BUG=none
BRANCH=smaug
TEST=tested on both samus and ryu while connected to each other.
Change-Id: I280a0da2d3c5a5436243134ab3f2ec353ebf6ab8
Signed-off-by: Alec Berg <alecaberg@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/299290
Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
-rw-r--r-- | common/usb_pd_protocol.c | 37 | ||||
-rw-r--r-- | include/ec_commands.h | 12 | ||||
-rw-r--r-- | util/ectool.c | 26 |
3 files changed, 64 insertions, 11 deletions
diff --git a/common/usb_pd_protocol.c b/common/usb_pd_protocol.c index 8ece6fd092..36da076710 100644 --- a/common/usb_pd_protocol.c +++ b/common/usb_pd_protocol.c @@ -789,7 +789,17 @@ void pd_request_power_swap(int port) set_state(port, PD_STATE_SNK_SWAP_INIT); task_wake(PD_PORT_TO_TASK_ID(port)); } + +#ifdef CONFIG_USBC_VCONN_SWAP +static void pd_request_vconn_swap(int port) +{ + if (pd[port].task_state == PD_STATE_SRC_READY || + pd[port].task_state == PD_STATE_SNK_READY) + set_state(port, PD_STATE_VCONN_SWAP_SEND); + task_wake(PD_PORT_TO_TASK_ID(port)); +} #endif +#endif /* CONFIG_USB_PD_DUAL_ROLE */ void pd_request_data_swap(int port) { @@ -2893,18 +2903,16 @@ static int command_pd(int argc, char **argv) if (argc < 4) return EC_ERROR_PARAM_COUNT; - if (!strncasecmp(argv[3], "power", 5)) { + if (!strncasecmp(argv[3], "power", 5)) pd_request_power_swap(port); - } else if (!strncasecmp(argv[3], "data", 4)) { + else if (!strncasecmp(argv[3], "data", 4)) pd_request_data_swap(port); #ifdef CONFIG_USBC_VCONN_SWAP - } else if (!strncasecmp(argv[3], "vconn", 5)) { - set_state(port, PD_STATE_VCONN_SWAP_SEND); - task_wake(PD_PORT_TO_TASK_ID(port)); + else if (!strncasecmp(argv[3], "vconn", 5)) + pd_request_vconn_swap(port); #endif - } else { + else return EC_ERROR_PARAM3; - } } else if (!strncasecmp(argv[2], "ping", 4)) { int enable; @@ -3027,6 +3035,17 @@ static int hc_usb_pd_control(struct host_cmd_handler_args *args) pd_get_polarity(p->port)); #endif /* CONFIG_USBC_SS_MUX */ + if (p->swap == USB_PD_CTRL_SWAP_DATA) + pd_request_data_swap(p->port); +#ifdef CONFIG_USB_PD_DUAL_ROLE + else if (p->swap == USB_PD_CTRL_SWAP_POWER) + pd_request_power_swap(p->port); +#ifdef CONFIG_USBC_VCONN_SWAP + else if (p->swap == USB_PD_CTRL_SWAP_VCONN) + pd_request_vconn_swap(p->port); +#endif +#endif + if (args->version == 0) { r->enabled = pd_comm_enabled; r->role = pd[p->port].power_role; @@ -3037,7 +3056,9 @@ static int hc_usb_pd_control(struct host_cmd_handler_args *args) r_v1->enabled = pd_comm_enabled | (pd_is_connected(p->port) << 1); r_v1->role = pd[p->port].power_role | - (pd[p->port].data_role << 1); + (pd[p->port].data_role << 1) | + ((pd[p->port].flags & PD_FLAGS_VCONN_ON) ? + 1 << 2 : 0); r_v1->polarity = pd[p->port].polarity; strzcpy(r_v1->state, pd_state_names[pd[p->port].task_state], diff --git a/include/ec_commands.h b/include/ec_commands.h index 14ef6fb20a..6fb784d5f9 100644 --- a/include/ec_commands.h +++ b/include/ec_commands.h @@ -3149,10 +3149,19 @@ enum usb_pd_control_mux { USB_PD_CTRL_MUX_COUNT }; +enum usb_pd_control_swap { + USB_PD_CTRL_SWAP_NONE = 0, + USB_PD_CTRL_SWAP_DATA = 1, + USB_PD_CTRL_SWAP_POWER = 2, + USB_PD_CTRL_SWAP_VCONN = 3, + USB_PD_CTRL_SWAP_COUNT +}; + struct ec_params_usb_pd_control { uint8_t port; uint8_t role; uint8_t mux; + uint8_t swap; } __packed; struct ec_response_usb_pd_control { @@ -3164,7 +3173,8 @@ struct ec_response_usb_pd_control { struct ec_response_usb_pd_control_v1 { uint8_t enabled; /* [0] comm enabled [1] connected */ - uint8_t role; /* [0] power: 0=SNK/1=SRC [1] data: 0=UFP/1=DFP */ + uint8_t role; /* [0] power: 0=SNK/1=SRC [1] data: 0=UFP/1=DFP + [2] vconn 0=off/1=on */ uint8_t polarity; char state[32]; } __packed; diff --git a/util/ectool.c b/util/ectool.c index 70f925f39b..d8197c7014 100644 --- a/util/ectool.c +++ b/util/ectool.c @@ -204,7 +204,8 @@ const char help_str[] = " usbmux <mux>\n" " Set USB mux switch state\n" " usbpd <port> <auto | " - "[toggle|toggle-off|sink|source] [none|usb|dp|dock]>\n" + "[toggle|toggle-off|sink|source] [none|usb|dp|dock] " + "[dr_swap|pr_swap|vconn_swap]>\n" " Control USB PD/type-C\n" " usbpdpower\n" " Get USB PD power information\n" @@ -3836,6 +3837,7 @@ int cmd_usb_pd(int argc, char *argv[]) { const char *role_str[] = {"", "toggle", "toggle-off", "sink", "source"}; const char *mux_str[] = {"", "none", "usb", "dp", "dock", "auto"}; + const char *swap_str[] = {"", "dr_swap", "pr_swap", "vconn_swap"}; struct ec_params_usb_pd_control p; struct ec_response_usb_pd_control_v1 *r_v1 = (struct ec_response_usb_pd_control_v1 *)ec_inbuf; @@ -3848,8 +3850,10 @@ int cmd_usb_pd(int argc, char *argv[]) BUILD_ASSERT(ARRAY_SIZE(role_str) == USB_PD_CTRL_ROLE_COUNT); BUILD_ASSERT(ARRAY_SIZE(mux_str) == USB_PD_CTRL_MUX_COUNT); + BUILD_ASSERT(ARRAY_SIZE(swap_str) == USB_PD_CTRL_SWAP_COUNT); p.role = USB_PD_CTRL_ROLE_NO_CHANGE; p.mux = USB_PD_CTRL_MUX_NO_CHANGE; + p.swap = USB_PD_CTRL_SWAP_NONE; if (!ec_cmd_version_supported(EC_CMD_USB_PD_CONTROL, cmdver)) cmdver = 0; @@ -3905,6 +3909,22 @@ int cmd_usb_pd(int argc, char *argv[]) break; } } + if (option_ok) + continue; + + for (j = 0; j < ARRAY_SIZE(swap_str); ++j) { + if (!strcmp(argv[i], swap_str[j])) { + if (p.swap != USB_PD_CTRL_SWAP_NONE) { + fprintf(stderr, + "Only one swap type allowed.\n"); + return -1; + } + p.swap = j; + option_ok = 1; + break; + } + } + if (!option_ok) { fprintf(stderr, "Unknown option: %s\n", argv[i]); @@ -3924,11 +3944,13 @@ int cmd_usb_pd(int argc, char *argv[]) r->role == PD_ROLE_SOURCE ? "SRC" : "SNK", r->polarity + 1, r->state); } else { - printf("Port C%d is %s,%s, Role:%s %s Polarity:CC%d State:%s\n", + printf("Port C%d is %s,%s, Role:%s %s%s Polarity:CC%d " + "State:%s\n", p.port, (r_v1->enabled & 1) ? "enabled" : "disabled", (r_v1->enabled & 2) ? "connected" : "disconnected", r_v1->role & PD_ROLE_SOURCE ? "SRC" : "SNK", r_v1->role & (PD_ROLE_DFP << 1) ? "DFP" : "UFP", + r_v1->role & (1 << 2) ? " VCONN" : "", r_v1->polarity + 1, r_v1->state); } return (rv < 0 ? rv : 0); |