summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShawn Nematbakhsh <shawnn@chromium.org>2016-06-22 17:55:38 -0700
committerchrome-bot <chrome-bot@chromium.org>2016-06-24 17:23:14 -0700
commit203063609b52f4125ee91c474cf5f58178572050 (patch)
treecf8560d8304a59b558efca9eb90649019b7dbba4
parent3bc0223b48a73a9fcc70cdbec886f22dd6c35cd3 (diff)
downloadchrome-ec-203063609b52f4125ee91c474cf5f58178572050.tar.gz
usb_mux: Add support for host-controlled 'virtual' USB mux
For designs where the host SOC is responsible for setting the USB-C SS mux, the EC must track the desired mux state and inform the host when the desired state changes. Then, the host must ask the EC for the new desired state and set the mux accordingly. BUG=chrome-os-partner:52639 BRANCH=None TEST=Manual on gru with subsequent commit. Attach USB dongle in port 1 and DP dongle in port 0, then verify `ectool usbpdmuxinfo` output: Port 0: DP Port 1: USB Flip DP dongle and verify output changes: Port 0: DP INV Signed-off-by: Shawn Nematbakhsh <shawnn@chromium.org> Change-Id: I6a99ce93a76c3197f9195cfaa25c5217d09aeb75 Reviewed-on: https://chromium-review.googlesource.com/355281 Commit-Ready: Shawn N <shawnn@chromium.org> Tested-by: Shawn N <shawnn@chromium.org> Reviewed-by: Shawn N <shawnn@chromium.org>
-rw-r--r--common/host_command.c3
-rw-r--r--driver/build.mk1
-rw-r--r--driver/usb_mux.c22
-rw-r--r--driver/usb_mux_virtual.c49
-rw-r--r--include/config.h3
-rw-r--r--include/ec_commands.h21
-rw-r--r--include/usb_mux.h9
-rw-r--r--util/ectool.c43
8 files changed, 147 insertions, 4 deletions
diff --git a/common/host_command.c b/common/host_command.c
index 80838efc52..91bd2ded6e 100644
--- a/common/host_command.c
+++ b/common/host_command.c
@@ -752,6 +752,9 @@ static int host_command_get_features(struct host_cmd_handler_args *args)
#ifdef CONFIG_VSTORE
| EC_FEATURE_MASK_0(EC_FEATURE_VSTORE)
#endif
+#ifdef CONFIG_USB_MUX_VIRTUAL
+ | EC_FEATURE_MASK_0(EC_FEATURE_USBC_SS_MUX_VIRTUAL)
+#endif
;
return EC_RES_SUCCESS;
}
diff --git a/driver/build.mk b/driver/build.mk
index e3d17ecb74..cfa8781fc4 100644
--- a/driver/build.mk
+++ b/driver/build.mk
@@ -92,6 +92,7 @@ driver-$(CONFIG_USBC_SS_MUX)+=usb_mux.o
# USB muxes
driver-$(CONFIG_USB_MUX_PI3USB30532)+=usb_mux_pi3usb30532.o
driver-$(CONFIG_USB_MUX_PS8740)+=usb_mux_ps8740.o
+driver-$(CONFIG_USB_MUX_VIRTUAL)+=usb_mux_virtual.o
# Firmware Update
driver-$(CONFIG_SB_FIRMWARE_UPDATE)+=battery/sb_fw_update.o
diff --git a/driver/usb_mux.c b/driver/usb_mux.c
index 619c32ba21..db2a03bdd2 100644
--- a/driver/usb_mux.c
+++ b/driver/usb_mux.c
@@ -7,6 +7,7 @@
#include "common.h"
#include "console.h"
+#include "host_command.h"
#include "usb_mux.h"
#include "util.h"
@@ -154,3 +155,24 @@ DECLARE_CONSOLE_COMMAND(typec, command_typec,
"Control type-C connector muxing",
NULL);
#endif
+
+static int hc_usb_pd_mux_info(struct host_cmd_handler_args *args)
+{
+ const struct ec_params_usb_pd_mux_info *p = args->params;
+ struct ec_response_usb_pd_mux_info *r = args->response;
+ int port = p->port;
+ const struct usb_mux *mux;
+
+ if (port >= CONFIG_USB_PD_PORT_COUNT)
+ return EC_RES_INVALID_PARAM;
+
+ mux = &usb_muxes[port];
+ if (mux->driver->get(mux->port_addr, &r->flags) != EC_SUCCESS)
+ return EC_RES_ERROR;
+
+ args->response_size = sizeof(*r);
+ return EC_RES_SUCCESS;
+}
+DECLARE_HOST_COMMAND(EC_CMD_USB_PD_MUX_INFO,
+ hc_usb_pd_mux_info,
+ EC_VER_MASK(0));
diff --git a/driver/usb_mux_virtual.c b/driver/usb_mux_virtual.c
new file mode 100644
index 0000000000..564bff952b
--- /dev/null
+++ b/driver/usb_mux_virtual.c
@@ -0,0 +1,49 @@
+/* Copyright 2016 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * Virtual USB mux driver for host-controlled USB muxes.
+ */
+
+#include "common.h"
+#include "console.h"
+#include "host_command.h"
+#include "usb_mux.h"
+#include "util.h"
+
+static mux_state_t virtual_mux_state[CONFIG_USB_PD_PORT_COUNT];
+
+static int virtual_init(int port)
+{
+ return EC_SUCCESS;
+}
+
+/*
+ * Set the state of our 'virtual' mux. The EC does not actually control this
+ * mux, so update the desired state, then notify the host of the update.
+ */
+static int virtual_set_mux(int port, mux_state_t mux_state)
+{
+ if (virtual_mux_state[port] != mux_state) {
+ virtual_mux_state[port] = mux_state;
+ host_set_single_event(EC_HOST_EVENT_USB_MUX);
+ }
+ return EC_SUCCESS;
+}
+
+/*
+ * Get the state of our 'virtual' mux. Since we the EC does not actually
+ * control this mux, and the EC has no way of knowing its actual status,
+ * we return the desired state here.
+ */
+static int virtual_get_mux(int port, mux_state_t *mux_state)
+{
+ *mux_state = virtual_mux_state[port];
+ return EC_SUCCESS;
+}
+
+const struct usb_mux_driver virtual_usb_mux_driver = {
+ .init = virtual_init,
+ .set = virtual_set_mux,
+ .get = virtual_get_mux,
+};
diff --git a/include/config.h b/include/config.h
index fca9942f62..df6ddcde4e 100644
--- a/include/config.h
+++ b/include/config.h
@@ -2072,6 +2072,9 @@
/* Support the Parade PS8740 Type-C Redriving Switch */
#undef CONFIG_USB_MUX_PS8740
+/* 'Virtual' USB mux under host (not EC) control */
+#undef CONFIG_USB_MUX_VIRTUAL
+
/*****************************************************************************/
/* USB GPIO config */
#undef CONFIG_USB_GPIO
diff --git a/include/ec_commands.h b/include/ec_commands.h
index 226d3bf04f..18343ef104 100644
--- a/include/ec_commands.h
+++ b/include/ec_commands.h
@@ -440,6 +440,9 @@ enum host_event_code {
/* Emulate MKBP event */
EC_HOST_EVENT_MKBP = 27,
+ /* EC desires to change state of host-controlled USB mux */
+ EC_HOST_EVENT_USB_MUX = 28,
+
/*
* The high bit of the event mask is not used as a host event code. If
* it reads back as set, then the entire event mask should be
@@ -950,6 +953,8 @@ enum ec_feature_code {
EC_FEATURE_MOTION_SENSE_FIFO = 24,
/* Support temporary secure vstore */
EC_FEATURE_VSTORE = 25,
+ /* EC decides on USB-C SS mux state, muxes configured by host */
+ EC_FEATURE_USBC_SS_MUX_VIRTUAL = 26,
};
#define EC_FEATURE_MASK_0(event_code) (1UL << (event_code % 32))
@@ -3665,6 +3670,22 @@ struct ec_params_pd_control {
uint8_t subcmd;
} __packed;
+/* Get info about USB-C SS muxes */
+#define EC_CMD_USB_PD_MUX_INFO 0x11a
+
+struct ec_params_usb_pd_mux_info {
+ uint8_t port; /* USB-C port number */
+} __packed;
+
+/* Flags representing mux state */
+#define USB_PD_MUX_USB_ENABLED (1 << 0)
+#define USB_PD_MUX_DP_ENABLED (1 << 1)
+#define USB_PD_MUX_POLARITY_INVERTED (1 << 2)
+
+struct ec_response_usb_pd_mux_info {
+ uint8_t flags; /* USB_PD_MUX_*-encoded USB mux state */
+} __packed;
+
#endif /* !__ACPI__ */
/*****************************************************************************/
diff --git a/include/usb_mux.h b/include/usb_mux.h
index 52917efb45..daad2792de 100644
--- a/include/usb_mux.h
+++ b/include/usb_mux.h
@@ -8,6 +8,7 @@
#ifndef __CROS_EC_USB_MUX_H
#define __CROS_EC_USB_MUX_H
+#include "ec_commands.h"
#include "usb_charge.h"
#include "usb_pd.h"
@@ -15,9 +16,10 @@
typedef uint8_t mux_state_t;
/* Mux state attributes */
-#define MUX_USB_ENABLED (1 << 0) /* USB is enabled */
-#define MUX_DP_ENABLED (1 << 1) /* DP is enabled */
-#define MUX_POLARITY_INVERTED (1 << 2) /* Polarity is inverted */
+/* TODO: Directly use USB_PD_MUX_* everywhere and remove these 3 defines */
+#define MUX_USB_ENABLED USB_PD_MUX_USB_ENABLED
+#define MUX_DP_ENABLED USB_PD_MUX_DP_ENABLED
+#define MUX_POLARITY_INVERTED USB_PD_MUX_POLARITY_INVERTED
/* Mux modes, decoded to attributes */
enum typec_mux {
@@ -87,6 +89,7 @@ struct usb_mux {
extern const struct usb_mux_driver pi3usb30532_usb_mux_driver;
extern const struct usb_mux_driver ps8740_usb_mux_driver;
extern const struct usb_mux_driver tcpm_usb_mux_driver;
+extern const struct usb_mux_driver virtual_usb_mux_driver;
/* USB muxes present in system, ordered by PD port #, defined at board-level */
extern struct usb_mux usb_muxes[];
diff --git a/util/ectool.c b/util/ectool.c
index 4b83f3fc04..07bd5adeb9 100644
--- a/util/ectool.c
+++ b/util/ectool.c
@@ -162,7 +162,7 @@ const char help_str[] =
" port80read\n"
" Print history of port 80 write\n"
" powerinfo\n"
- " Prints power-related information\n"
+ " Prints power-related information\n"
" protoinfo\n"
" Prints EC host protocol information\n"
" pstoreinfo\n"
@@ -223,6 +223,8 @@ const char help_str[] =
"[toggle|toggle-off|sink|source] [none|usb|dp|dock] "
"[dr_swap|pr_swap|vconn_swap]>\n"
" Control USB PD/type-C\n"
+ " usbpdmuxinfo\n"
+ " Get USB-C SS mux info\n"
" usbpdpower\n"
" Get USB PD power information\n"
" version\n"
@@ -469,6 +471,8 @@ static const char * const ec_feature_names[] = {
[EC_FEATURE_USB_PD] = "USB Cros Power Delievery",
[EC_FEATURE_USB_MUX] = "USB Multiplexer",
[EC_FEATURE_MOTION_SENSE_FIFO] = "FIFO for Motion Sensors events",
+ [EC_FEATURE_VSTORE] = "Temporary secure vstore",
+ [EC_FEATURE_USBC_SS_MUX_VIRTUAL] = "Host-controlled USB-C SS mux",
};
int cmd_inventory(int argc, char *argv[])
@@ -4232,6 +4236,42 @@ static void print_pd_power_info(struct ec_response_usb_pd_power_info *r)
printf("\n");
}
+int cmd_usb_pd_mux_info(int argc, char *argv[])
+{
+ struct ec_params_usb_pd_mux_info p;
+ struct ec_response_usb_pd_mux_info r;
+ int num_ports, rv, i;
+
+ rv = ec_command(EC_CMD_USB_PD_PORTS, 0, NULL, 0,
+ ec_inbuf, ec_max_insize);
+ if (rv < 0)
+ return rv;
+ num_ports = ((struct ec_response_usb_pd_ports *)ec_inbuf)->num_ports;
+
+ for (i = 0; i < num_ports; i++) {
+ p.port = i;
+ rv = ec_command(EC_CMD_USB_PD_MUX_INFO, 0,
+ &p, sizeof(p),
+ &r, sizeof(r));
+ if (rv < 0)
+ return rv;
+
+ printf("Port %d: ", i);
+ if (r.flags & USB_PD_MUX_USB_ENABLED)
+ printf("USB ");
+ if (r.flags & USB_PD_MUX_DP_ENABLED)
+ printf("DP ");
+ if (!(r.flags & (USB_PD_MUX_DP_ENABLED |
+ USB_PD_MUX_USB_ENABLED)))
+ printf("OPEN ");
+ if (r.flags & USB_PD_MUX_POLARITY_INVERTED)
+ printf("INV ");
+ printf("\n");
+ }
+
+ return 0;
+}
+
int cmd_usb_pd_power(int argc, char *argv[])
{
struct ec_params_usb_pd_power_info p;
@@ -6865,6 +6905,7 @@ const struct command commands[] = {
{"usbchargemode", cmd_usb_charge_set_mode},
{"usbmux", cmd_usb_mux},
{"usbpd", cmd_usb_pd},
+ {"usbpdmuxinfo", cmd_usb_pd_mux_info},
{"usbpdpower", cmd_usb_pd_power},
{"version", cmd_version},
{"wireless", cmd_wireless},