summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDino Li <Dino.Li@ite.com.tw>2017-10-31 14:59:50 +0800
committerchrome-bot <chrome-bot@chromium.org>2017-10-31 21:49:24 -0700
commit73d0ed0b794b13ceff5620b5c15ba7a3760d1f35 (patch)
tree3083fa0ba743eb5d70e90c15394c7d479f51c756
parentb979c8ade3c46d67ef739bfe22361b8fc5db6b34 (diff)
downloadchrome-ec-73d0ed0b794b13ceff5620b5c15ba7a3760d1f35.tar.gz
driver: add IT5205 mux driver
Add support the ITE IT5205 Type-C USB alternate mode mux. BRANCH=none BUG=none TEST=1. Successfully verify chip ID. 2. Verify set_mux() and get_mux() functions set and return consistent values. 3. The mux control register setting as expected after set_mux(). Change-Id: I9ff066dc9e74683df1371b70290e2aeaa86cb96b Signed-off-by: Dino Li <Dino.Li@ite.com.tw> Reviewed-on: https://chromium-review.googlesource.com/741211 Reviewed-by: Shawn N <shawnn@chromium.org>
-rw-r--r--driver/build.mk1
-rw-r--r--driver/usb_mux_it5205.c120
-rw-r--r--driver/usb_mux_it5205.h32
-rw-r--r--include/config.h3
-rw-r--r--include/usb_mux.h1
5 files changed, 157 insertions, 0 deletions
diff --git a/driver/build.mk b/driver/build.mk
index 21579d44ae..4fa78d25bc 100644
--- a/driver/build.mk
+++ b/driver/build.mk
@@ -99,6 +99,7 @@ driver-$(CONFIG_USB_PD_TCPM_PS8805)+=tcpm/ps8xxx.o
driver-$(CONFIG_USBC_SS_MUX)+=usb_mux.o
# USB muxes
+driver-$(CONFIG_USB_MUX_IT5205)+=usb_mux_it5205.o
driver-$(CONFIG_USB_MUX_PI3USB30532)+=usb_mux_pi3usb30532.o
driver-$(CONFIG_USB_MUX_PS8740)+=usb_mux_ps874x.o
driver-$(CONFIG_USB_MUX_PS8743)+=usb_mux_ps874x.o
diff --git a/driver/usb_mux_it5205.c b/driver/usb_mux_it5205.c
new file mode 100644
index 0000000000..c6b9a91778
--- /dev/null
+++ b/driver/usb_mux_it5205.c
@@ -0,0 +1,120 @@
+/* Copyright 2017 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.
+ *
+ * ITE IT5205 Type-C USB alternate mode mux.
+ */
+
+#include "common.h"
+#include "console.h"
+#include "i2c.h"
+#include "usb_mux.h"
+#include "usb_mux_it5205.h"
+#include "util.h"
+
+#define MUX_STATE_DP_USB_MASK (MUX_USB_ENABLED | MUX_DP_ENABLED)
+
+static int it5205_read(int i2c_addr, uint8_t reg, int *val)
+{
+ return i2c_read8(I2C_PORT_USB_MUX, i2c_addr, reg, val);
+}
+
+static int it5205_write(int i2c_addr, uint8_t reg, uint8_t val)
+{
+ return i2c_write8(I2C_PORT_USB_MUX, i2c_addr, reg, val);
+}
+
+struct mux_chip_id_t {
+ uint8_t chip_id;
+ uint8_t reg;
+};
+
+static const struct mux_chip_id_t mux_chip_id_verify[] = {
+ { '5', IT5205_REG_CHIP_ID3},
+ { '2', IT5205_REG_CHIP_ID2},
+ { '0', IT5205_REG_CHIP_ID1},
+ { '5', IT5205_REG_CHIP_ID0},
+};
+
+static int it5205_init(int i2c_addr)
+{
+ int i, val, ret;
+
+ /* bit[0]: mux power on, bit[7-1]: reserved. */
+ ret = it5205_write(i2c_addr, IT5205_REG_MUXPDR, 0);
+ if (ret)
+ return ret;
+ /* Verify chip ID registers. */
+ for (i = 0; i < ARRAY_SIZE(mux_chip_id_verify); i++) {
+ ret = it5205_read(i2c_addr, mux_chip_id_verify[i].reg, &val);
+ if (ret)
+ return ret;
+
+ if (val != mux_chip_id_verify[i].chip_id)
+ return EC_ERROR_UNKNOWN;
+ }
+
+ return EC_SUCCESS;
+}
+
+/* Writes control register to set switch mode */
+static int it5205_set_mux(int i2c_addr, mux_state_t mux_state)
+{
+ uint8_t reg;
+
+ switch (mux_state & MUX_STATE_DP_USB_MASK) {
+ case MUX_USB_ENABLED:
+ reg = IT5205_USB;
+ break;
+ case MUX_DP_ENABLED:
+ reg = IT5205_DP;
+ break;
+ case MUX_STATE_DP_USB_MASK:
+ reg = IT5205_DP_USB;
+ break;
+ default:
+ reg = 0;
+ break;
+ }
+
+ if (mux_state & MUX_POLARITY_INVERTED)
+ reg |= IT5205_POLARITY_INVERTED;
+
+ return it5205_write(i2c_addr, IT5205_REG_MUXCR, reg);
+}
+
+/* Reads control register and updates mux_state accordingly */
+static int it5205_get_mux(int i2c_addr, mux_state_t *mux_state)
+{
+ int reg, ret;
+
+ ret = it5205_read(i2c_addr, IT5205_REG_MUXCR, &reg);
+ if (ret)
+ return ret;
+
+ switch (reg & IT5205_DP_USB_CTRL_MASK) {
+ case IT5205_USB:
+ *mux_state = MUX_USB_ENABLED;
+ break;
+ case IT5205_DP:
+ *mux_state = MUX_DP_ENABLED;
+ break;
+ case IT5205_DP_USB:
+ *mux_state = MUX_STATE_DP_USB_MASK;
+ break;
+ default:
+ *mux_state = 0;
+ break;
+ }
+
+ if (reg & IT5205_POLARITY_INVERTED)
+ *mux_state |= MUX_POLARITY_INVERTED;
+
+ return EC_SUCCESS;
+}
+
+const struct usb_mux_driver it5205_usb_mux_driver = {
+ .init = it5205_init,
+ .set = it5205_set_mux,
+ .get = it5205_get_mux,
+};
diff --git a/driver/usb_mux_it5205.h b/driver/usb_mux_it5205.h
new file mode 100644
index 0000000000..0cebeed71a
--- /dev/null
+++ b/driver/usb_mux_it5205.h
@@ -0,0 +1,32 @@
+/* Copyright 2017 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.
+ *
+ * ITE IT5205 Type-C USB alternate mode mux.
+ */
+
+#ifndef __CROS_EC_USB_MUX_IT5205_H
+#define __CROS_EC_USB_MUX_IT5205_H
+
+/* 8 bit i2c slave address is 0xb0 or 0x90 depends on address setting pin. */
+
+/* Chip ID registers */
+#define IT5205_REG_CHIP_ID3 0x4
+#define IT5205_REG_CHIP_ID2 0x5
+#define IT5205_REG_CHIP_ID1 0x6
+#define IT5205_REG_CHIP_ID0 0x7
+
+/* MUX power down register */
+#define IT5205_REG_MUXPDR 0x10
+#define IT5205_MUX_POWER_DOWN (1 << 0)
+
+/* MUX control register */
+#define IT5205_REG_MUXCR 0x11
+#define IT5205_POLARITY_INVERTED (1 << 4)
+
+#define IT5205_DP_USB_CTRL_MASK 0x0f
+#define IT5205_DP 0x0f
+#define IT5205_DP_USB 0x03
+#define IT5205_USB 0x07
+
+#endif /* __CROS_EC_USB_MUX_IT5205_H */
diff --git a/include/config.h b/include/config.h
index 9cd3698ea3..eb6d3e1d47 100644
--- a/include/config.h
+++ b/include/config.h
@@ -2836,6 +2836,9 @@
/******************************************************************************/
/* USB port switch */
+/* Support the ITE IT5205 Type-C USB alternate mode mux. */
+#undef CONFIG_USB_MUX_IT5205
+
/* Support the Pericom PI3USB30532 USB3.0/DP1.2 Matrix Switch */
#undef CONFIG_USB_MUX_PI3USB30532
diff --git a/include/usb_mux.h b/include/usb_mux.h
index 8df27af44b..151c397995 100644
--- a/include/usb_mux.h
+++ b/include/usb_mux.h
@@ -88,6 +88,7 @@ struct usb_mux {
};
/* Supported USB mux drivers */
+extern const struct usb_mux_driver it5205_usb_mux_driver;
extern const struct usb_mux_driver pi3usb30532_usb_mux_driver;
extern const struct usb_mux_driver ps874x_usb_mux_driver;
extern const struct usb_mux_driver tcpm_usb_mux_driver;