summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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},