diff options
author | Dino Li <Dino.Li@ite.com.tw> | 2017-10-31 14:59:50 +0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2017-10-31 21:49:24 -0700 |
commit | 73d0ed0b794b13ceff5620b5c15ba7a3760d1f35 (patch) | |
tree | 3083fa0ba743eb5d70e90c15394c7d479f51c756 | |
parent | b979c8ade3c46d67ef739bfe22361b8fc5db6b34 (diff) | |
download | chrome-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.mk | 1 | ||||
-rw-r--r-- | driver/usb_mux_it5205.c | 120 | ||||
-rw-r--r-- | driver/usb_mux_it5205.h | 32 | ||||
-rw-r--r-- | include/config.h | 3 | ||||
-rw-r--r-- | include/usb_mux.h | 1 |
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, ®); + 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; |