diff options
author | Divagar Mohandass <divagar.mohandass@intel.com> | 2019-12-22 23:50:30 +0530 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2019-12-24 11:18:27 +0000 |
commit | d479bc2a0c48760f246bb91d2f231abdf45cfe21 (patch) | |
tree | 1e8c3c0e4919a9405d4d409296d6d8f9bde6d29c | |
parent | 28001a83d226a86f176bd92b699586d6c0858196 (diff) | |
download | chrome-ec-d479bc2a0c48760f246bb91d2f231abdf45cfe21.tar.gz |
driver/usb_mux: add ANX7440 USB Type-C mux driver
Add support to Analogix ANX7440 USB Type-C USB mux with
integrated Re-timers for USB3.1/DisplayPort
BRANCH=none
BUG=b:146683781
TEST=make buildall -j
verify the mux functionality with reference platform
Change-Id: I7847e67025385ca6ea044ee72da143c8e52e65cf
Signed-off-by: Divagar Mohandass <divagar.mohandass@intel.com>
Signed-off-by: Vijay Hiremath <vijay.p.hiremath@intel.com>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1980089
Reviewed-by: Denis Brockus <dbrockus@chromium.org>
-rw-r--r-- | driver/build.mk | 1 | ||||
-rw-r--r-- | driver/usb_mux/anx7440.c | 106 | ||||
-rw-r--r-- | driver/usb_mux/anx7440.h | 40 | ||||
-rw-r--r-- | include/config.h | 6 | ||||
-rw-r--r-- | include/usb_mux.h | 1 |
5 files changed, 154 insertions, 0 deletions
diff --git a/driver/build.mk b/driver/build.mk index f97a9f6d8b..9cbf97a63d 100644 --- a/driver/build.mk +++ b/driver/build.mk @@ -149,6 +149,7 @@ driver-$(CONFIG_USBC_SS_MUX)+=usb_mux/usb_mux.o # USB muxes driver-$(CONFIG_USB_MUX_AMD_FP5)+=usb_mux/amd_fp5.o +driver-$(CONFIG_USB_MUX_ANX7440)+=usb_mux/anx7440.o 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 diff --git a/driver/usb_mux/anx7440.c b/driver/usb_mux/anx7440.c new file mode 100644 index 0000000000..ec02b8f90b --- /dev/null +++ b/driver/usb_mux/anx7440.c @@ -0,0 +1,106 @@ +/* Copyright 2019 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. + * + * Analogix ANX7440 USB Type-C Active mux with + * Integrated Re-timers for USB3.1/DisplayPort. + */ + +#include "anx7440.h" +#include "common.h" +#include "console.h" +#include "i2c.h" +#include "usb_mux.h" +#include "util.h" + +#define CPRINTS(format, args...) cprints(CC_USBCHARGE, format, ## args) +#define CPRINTF(format, args...) cprintf(CC_USBCHARGE, format, ## args) + +static inline int anx7440_read(int port, uint8_t reg, int *val) +{ + return i2c_read8(I2C_PORT_USB_MUX, MUX_ADDR(port), reg, val); +} + +static inline int anx7440_write(int port, uint8_t reg, uint8_t val) +{ + return i2c_write8(I2C_PORT_USB_MUX, MUX_ADDR(port), reg, val); +} + +struct anx7440_id_t { + uint8_t val; + uint8_t reg; +}; + +static const struct anx7440_id_t anx7440_device_ids[] = { + { ANX7440_VENDOR_ID_L, ANX7440_REG_VENDOR_ID_L }, + { ANX7440_VENDOR_ID_H, ANX7440_REG_VENDOR_ID_H }, + { ANX7440_DEVICE_ID_L, ANX7440_REG_DEVICE_ID_L }, + { ANX7440_DEVICE_ID_H, ANX7440_REG_DEVICE_ID_H }, + { ANX7440_DEVICE_VERSION, ANX7440_REG_DEVICE_VERSION }, +}; + +static int anx7440_init(int port) +{ + int i; + int val; + int res; + + /* Verify device id / version registers */ + for (i = 0; i < ARRAY_SIZE(anx7440_device_ids); i++) { + res = anx7440_read(port, anx7440_device_ids[i].reg, &val); + if (res) + return res; + + if (val != anx7440_device_ids[i].val) + return EC_ERROR_UNKNOWN; + } + + return EC_SUCCESS; +} + +/* Writes control register to set switch mode */ +static int anx7440_set_mux(int port, mux_state_t mux_state) +{ + int reg, res; + + res = anx7440_read(port, ANX7440_REG_CHIP_CTRL, ®); + if (res) + return res; + + reg &= ~ANX7440_CHIP_CTRL_SW_OP_MODE_CLEAR; + if (mux_state & MUX_USB_ENABLED) + reg |= ANX7440_CHIP_CTRL_SW_OP_MODE_USB; + if (mux_state & MUX_DP_ENABLED) + reg |= ANX7440_CHIP_CTRL_SW_OP_MODE_DP; + if (mux_state & MUX_POLARITY_INVERTED) + reg |= ANX7440_CHIP_CTRL_SW_FLIP; + + return anx7440_write(port, ANX7440_REG_CHIP_CTRL, reg); +} + +/* Reads control register and updates mux_state accordingly */ +static int anx7440_get_mux(int port, mux_state_t *mux_state) +{ + int reg, res; + + *mux_state = 0; + res = anx7440_read(port, ANX7440_REG_CHIP_CTRL, ®); + if (res) + return res; + + if (reg & ANX7440_CHIP_CTRL_OP_MODE_FINAL_USB) + *mux_state |= MUX_USB_ENABLED; + if (reg & ANX7440_CHIP_CTRL_OP_MODE_FINAL_DP) + *mux_state |= MUX_DP_ENABLED; + if (reg & ANX7440_CHIP_CTRL_FINAL_FLIP) + *mux_state |= MUX_POLARITY_INVERTED; + + return EC_SUCCESS; +} + +const struct usb_mux_driver anx7440_usb_mux_driver = { + .init = anx7440_init, + .set = anx7440_set_mux, + .get = anx7440_get_mux, + /* TODO(b/146683781): add low power mode */ +}; diff --git a/driver/usb_mux/anx7440.h b/driver/usb_mux/anx7440.h new file mode 100644 index 0000000000..2147e3146a --- /dev/null +++ b/driver/usb_mux/anx7440.h @@ -0,0 +1,40 @@ +/* Copyright 2019 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. + * + * Analogix ANX7440 USB Type-C Active mux with + * Integrated Re-timers for USB3.1/DisplayPort. + */ + +#ifndef __CROS_EC_USB_MUX_ANX7440_H +#define __CROS_EC_USB_MUX_ANX7440_H + +/* I2C interface address */ +#define ANX7440_I2C_ADDR1_FLAGS 0x10 +#define ANX7440_I2C_ADDR2_FLAGS 0x12 +#define I2C_ADDR_USB_MUX0_FLAGS ANX7440_I2C_ADDR1_FLAGS +#define I2C_ADDR_USB_MUX1_FLAGS ANX7440_I2C_ADDR2_FLAGS + +/* Vendor / Device Id registers and expected fused values */ +#define ANX7440_REG_VENDOR_ID_L 0x00 +#define ANX7440_VENDOR_ID_L 0xaa +#define ANX7440_REG_VENDOR_ID_H 0x01 +#define ANX7440_VENDOR_ID_H 0xaa +#define ANX7440_REG_DEVICE_ID_L 0x02 +#define ANX7440_DEVICE_ID_L 0x40 +#define ANX7440_REG_DEVICE_ID_H 0x03 +#define ANX7440_DEVICE_ID_H 0x74 +#define ANX7440_REG_DEVICE_VERSION 0x04 +#define ANX7440_DEVICE_VERSION 0xCB + +/* Chip control register for checking mux state */ +#define ANX7440_REG_CHIP_CTRL 0x05 +#define ANX7440_CHIP_CTRL_FINAL_FLIP BIT(6) +#define ANX7440_CHIP_CTRL_OP_MODE_FINAL_DP BIT(5) +#define ANX7440_CHIP_CTRL_OP_MODE_FINAL_USB BIT(4) +#define ANX7440_CHIP_CTRL_SW_FLIP BIT(2) +#define ANX7440_CHIP_CTRL_SW_OP_MODE_DP BIT(1) +#define ANX7440_CHIP_CTRL_SW_OP_MODE_USB BIT(0) +#define ANX7440_CHIP_CTRL_SW_OP_MODE_CLEAR 0x7 + +#endif /* __CROS_EC_USB_MUX_ANX7440_H */ diff --git a/include/config.h b/include/config.h index 618af0131d..a2b248e7b3 100644 --- a/include/config.h +++ b/include/config.h @@ -4234,6 +4234,12 @@ /* Support the AMD FP5 USB/DP Mux */ #undef CONFIG_USB_MUX_AMD_FP5 +/* + * Support the Analogix ANX7440 USB Type-C Active mux with + * Integrated Re-timers for USB3.1/DisplayPort. + */ +#undef CONFIG_USB_MUX_ANX7440 + /* Support the ITE IT5205 Type-C USB alternate mode mux. */ #undef CONFIG_USB_MUX_IT5205 diff --git a/include/usb_mux.h b/include/usb_mux.h index d4e19e579d..6c2f46fa34 100644 --- a/include/usb_mux.h +++ b/include/usb_mux.h @@ -131,6 +131,7 @@ struct usb_mux { /* Supported USB mux drivers */ extern const struct usb_mux_driver amd_fp5_usb_mux_driver; +extern const struct usb_mux_driver anx7440_usb_mux_driver; 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; |