diff options
-rw-r--r-- | common/host_command.c | 3 | ||||
-rw-r--r-- | driver/build.mk | 1 | ||||
-rw-r--r-- | driver/usb_mux.c | 22 | ||||
-rw-r--r-- | driver/usb_mux_virtual.c | 49 | ||||
-rw-r--r-- | include/config.h | 3 | ||||
-rw-r--r-- | include/ec_commands.h | 21 | ||||
-rw-r--r-- | include/usb_mux.h | 9 | ||||
-rw-r--r-- | util/ectool.c | 43 |
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}, |