diff options
author | Vijay Hiremath <vijay.p.hiremath@intel.com> | 2018-11-16 12:35:35 -0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2019-01-17 05:16:21 -0800 |
commit | fdeda2324792fc4a5db61779c1b03bb740c2bc90 (patch) | |
tree | 2ac97a91b428379b9b59d8ced199b112cc03a931 | |
parent | e8b6819b899cb8528f1ec1873bbc585bf8671405 (diff) | |
download | chrome-ec-fdeda2324792fc4a5db61779c1b03bb740c2bc90.tar.gz |
usb_mux_virtual: Update the virtual MUX when HPD level or irq changes
HPD level changes when there is an attach or detach event of the HPD.
Hence virtual MUX level need to be updated with the current HPD level
and a host notification needs to be sent so that host can configure
the HPD MUX.
BUG=b:118477809
BRANCH=none
TEST=Manually tested on Dragonegg, observed HPD event updated by
EC is received by Kernel MUX driver.
Change-Id: Ib916ebb3f6cbcfe2cb3e738f5b3e14d29e1bc27c
Signed-off-by: Vijay Hiremath <vijay.p.hiremath@intel.com>
Reviewed-on: https://chromium-review.googlesource.com/1340491
Commit-Ready: ChromeOS CL Exonerator Bot <chromiumos-cl-exonerator@appspot.gserviceaccount.com>
Tested-by: Vijay P Hiremath <vijay.p.hiremath@intel.com>
Reviewed-by: Jett Rink <jettrink@chromium.org>
-rw-r--r-- | driver/usb_mux.c | 2 | ||||
-rw-r--r-- | driver/usb_mux_virtual.c | 38 | ||||
-rw-r--r-- | include/ec_commands.h | 9 |
3 files changed, 35 insertions, 14 deletions
diff --git a/driver/usb_mux.c b/driver/usb_mux.c index f1b687e24a..5ef11d7ac1 100644 --- a/driver/usb_mux.c +++ b/driver/usb_mux.c @@ -244,7 +244,7 @@ static int hc_usb_pd_mux_info(struct host_cmd_handler_args *args) /* Clear HPD IRQ event since we're about to inform host of it. */ if ((r->flags & USB_PD_MUX_HPD_IRQ) && mux->hpd_update == &virtual_hpd_update) - mux->hpd_update(port, 0, 0); + mux->hpd_update(port, r->flags & USB_PD_MUX_HPD_LVL, 0); #endif args->response_size = sizeof(*r); diff --git a/driver/usb_mux_virtual.c b/driver/usb_mux_virtual.c index 433c5bcdbe..b82cdf307a 100644 --- a/driver/usb_mux_virtual.c +++ b/driver/usb_mux_virtual.c @@ -11,8 +11,24 @@ #include "usb_mux.h" #include "util.h" +/* + * USB PD protocol configures the USB & DP mux state and USB PD policy + * configures the HPD mux state. Both states are independent of each other + * may differ when the PD role changes when in dock mode. + */ +#define USB_PD_MUX_HPD_STATE (USB_PD_MUX_HPD_LVL | USB_PD_MUX_HPD_IRQ) +#define USB_PD_MUX_USB_DP_STATE (USB_PD_MUX_USB_ENABLED | \ + USB_PD_MUX_DP_ENABLED | USB_PD_MUX_POLARITY_INVERTED) + static mux_state_t virtual_mux_state[CONFIG_USB_PD_PORT_COUNT]; -static int hpd_irq_state[CONFIG_USB_PD_PORT_COUNT]; + +static inline void virtual_mux_update_state(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); + } +} static int virtual_init(int port) { @@ -25,10 +41,12 @@ static int virtual_init(int port) */ 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); - } + /* Current USB & DP mux status + existing HPD related mux status */ + mux_state_t new_mux_state = (mux_state & ~USB_PD_MUX_HPD_STATE) | + (virtual_mux_state[port] & USB_PD_MUX_HPD_STATE); + + virtual_mux_update_state(port, new_mux_state); + return EC_SUCCESS; } @@ -40,16 +58,18 @@ static int virtual_set_mux(int port, mux_state_t mux_state) static int virtual_get_mux(int port, mux_state_t *mux_state) { *mux_state = virtual_mux_state[port]; - *mux_state |= hpd_irq_state[port] ? USB_PD_MUX_HPD_IRQ : 0; return EC_SUCCESS; } void virtual_hpd_update(int port, int hpd_lvl, int hpd_irq) { - hpd_irq_state[port] = hpd_irq; - if (hpd_irq) - host_set_single_event(EC_HOST_EVENT_USB_MUX); + /* Current HPD related mux status + existing USB & DP mux status */ + mux_state_t new_mux_state = (hpd_lvl ? USB_PD_MUX_HPD_LVL : 0) | + (hpd_irq ? USB_PD_MUX_HPD_IRQ : 0) | + (virtual_mux_state[port] & USB_PD_MUX_USB_DP_STATE); + + virtual_mux_update_state(port, new_mux_state); } const struct usb_mux_driver virtual_usb_mux_driver = { diff --git a/include/ec_commands.h b/include/ec_commands.h index 45198db0dc..82e1dab1a6 100644 --- a/include/ec_commands.h +++ b/include/ec_commands.h @@ -4925,10 +4925,11 @@ struct ec_params_usb_pd_mux_info { } __ec_align1; /* 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) -#define USB_PD_MUX_HPD_IRQ (1 << 3) +#define USB_PD_MUX_USB_ENABLED (1 << 0) /* USB connected */ +#define USB_PD_MUX_DP_ENABLED (1 << 1) /* DP connected */ +#define USB_PD_MUX_POLARITY_INVERTED (1 << 2) /* CC line Polarity inverted */ +#define USB_PD_MUX_HPD_IRQ (1 << 3) /* HPD IRQ is asserted */ +#define USB_PD_MUX_HPD_LVL (1 << 4) /* HPD level is asserted */ struct ec_response_usb_pd_mux_info { uint8_t flags; /* USB_PD_MUX_*-encoded USB mux state */ |