summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlec Berg <alecaberg@chromium.org>2015-09-10 15:27:31 -0700
committerchrome-bot <chrome-bot@chromium.org>2015-09-11 13:51:00 -0700
commitfd92f9bfebcf3125cf2a7e0f5931f3cd50e395e8 (patch)
tree7583ec2d0700c369daf696a185cda66788d74422
parent17296409d8eec57bd3f11c8835ad13f22d4f13fc (diff)
downloadchrome-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.c37
-rw-r--r--include/ec_commands.h12
-rw-r--r--util/ectool.c26
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);