summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVijay Hiremath <vijay.p.hiremath@intel.com>2018-11-16 12:35:35 -0800
committerchrome-bot <chrome-bot@chromium.org>2019-01-17 05:16:21 -0800
commitfdeda2324792fc4a5db61779c1b03bb740c2bc90 (patch)
tree2ac97a91b428379b9b59d8ced199b112cc03a931
parente8b6819b899cb8528f1ec1873bbc585bf8671405 (diff)
downloadchrome-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.c2
-rw-r--r--driver/usb_mux_virtual.c38
-rw-r--r--include/ec_commands.h9
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 */