diff options
author | Xin Ji <xji@analogixsemi.com> | 2022-01-12 10:42:44 +0800 |
---|---|---|
committer | Chromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com> | 2023-03-13 19:13:46 +0000 |
commit | 38d981d3a0d7298770f318c6c8c50e0ac5c39bf2 (patch) | |
tree | 87cf27cdbe0645f6c5937204e96f2c70de511198 | |
parent | 89bd1915da0cf5b496b522063927091692d49b4d (diff) | |
download | chrome-ec-38d981d3a0d7298770f318c6c8c50e0ac5c39bf2.tar.gz |
tcpm: anx7406: add PD anx7406 support
Add ANX7406 tcpci driver, support external retimer control.
PD 20V@3A Request, DP Alt mode. Disable low power mode.
BUG=b:212509565
BRANCH=none
TEST=1. Verify DP Alt mode.
2. Verify PD charging.
Change-Id: I0d82349578eb6a6f9c938fb4b9e33b94853a4d04
Signed-off-by: Xin Ji <xji@analogix.corp-partner.google.com>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3460777
Reviewed-by: Daisuke Nojiri <dnojiri@chromium.org>
Commit-Queue: Daisuke Nojiri <dnojiri@chromium.org>
Tested-by: Daisuke Nojiri <dnojiri@chromium.org>
-rw-r--r-- | driver/build.mk | 1 | ||||
-rw-r--r-- | driver/tcpm/anx7406.c | 376 | ||||
-rw-r--r-- | driver/tcpm/anx7406.h | 135 | ||||
-rw-r--r-- | include/config.h | 1 | ||||
-rw-r--r-- | zephyr/Kconfig.tcpm | 13 |
5 files changed, 526 insertions, 0 deletions
diff --git a/driver/build.mk b/driver/build.mk index 622201e886..23e6dcd149 100644 --- a/driver/build.mk +++ b/driver/build.mk @@ -162,6 +162,7 @@ driver-y +=tcpm/ite_pd_intc.o driver-$(CONFIG_USB_PD_TCPM_DRIVER_IT83XX)+=tcpm/it83xx.o driver-$(CONFIG_USB_PD_TCPM_DRIVER_IT8XXX2)+=tcpm/it8xxx2.o endif +driver-$(CONFIG_USB_PD_TCPM_ANX7406)+=tcpm/anx7406.o driver-$(CONFIG_USB_PD_TCPM_ANX74XX)+=tcpm/anx74xx.o driver-$(CONFIG_USB_PD_TCPM_ANX7688)+=tcpm/anx7688.o driver-$(CONFIG_USB_PD_TCPM_ANX7447)+=tcpm/anx7447.o diff --git a/driver/tcpm/anx7406.c b/driver/tcpm/anx7406.c new file mode 100644 index 0000000000..d270be0099 --- /dev/null +++ b/driver/tcpm/anx7406.c @@ -0,0 +1,376 @@ +/* Copyright 2023 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* ANX7406 port manager */ + +#include "anx7406.h" +#include "common.h" +#include "console.h" +#include "hooks.h" +#include "tcpm/tcpci.h" +#include "tcpm/tcpm.h" +#include "timer.h" +#include "usb_pd.h" +#include "util.h" + +#define CPRINTS(format, args...) cprints(CC_USBPD, format, ##args) + +const struct anx7406_i2c_addr anx7406_i2c_addrs_flags[] = { + { ANX7406_TCPC0_I2C_ADDR_FLAGS, ANX7406_TOP0_I2C_ADDR_FLAGS }, + { ANX7406_TCPC1_I2C_ADDR_FLAGS, ANX7406_TOP1_I2C_ADDR_FLAGS }, + { ANX7406_TCPC2_I2C_ADDR_FLAGS, ANX7406_TOP2_I2C_ADDR_FLAGS }, + { ANX7406_TCPC3_I2C_ADDR_FLAGS, ANX7406_TOP3_I2C_ADDR_FLAGS }, + { ANX7406_TCPC4_I2C_ADDR_FLAGS, ANX7406_TOP4_I2C_ADDR_FLAGS }, + { ANX7406_TCPC5_I2C_ADDR_FLAGS, ANX7406_TOP5_I2C_ADDR_FLAGS }, + { ANX7406_TCPC6_I2C_ADDR_FLAGS, ANX7406_TOP6_I2C_ADDR_FLAGS }, + { ANX7406_TCPC7_I2C_ADDR_FLAGS, ANX7406_TOP7_I2C_ADDR_FLAGS }, +}; + +static struct anx7406_i2c_addr i2c_peripheral[CONFIG_USB_PD_PORT_MAX_COUNT]; + +static int anx7406_set_hpd(int port, int hpd_lvl) +{ + int val; + + if (hpd_lvl) { + CPRINTS("set hpd to HIGH"); + val = ANX7406_REG_HPD_OEN | HPD_DEGLITCH_TIME; + } else { + CPRINTS("set hpd to LOW"); + val = HPD_DEGLITCH_TIME; + } + + return i2c_write8(tcpc_config[port].i2c_info.port, + i2c_peripheral[port].top_addr_flags, + ANX7406_REG_HPD_DEGLITCH_H, val); +} + +int anx7406_hpd_reset(const int port) +{ + int rv; + + CPRINTS("HPD reset"); + rv = i2c_write8(tcpc_config[port].i2c_info.port, + i2c_peripheral[port].top_addr_flags, + ANX7406_REG_HPD_CTRL_0, 0); + if (rv) { + CPRINTS("Clear HPD_MODE failed: %d", rv); + return rv; + } + + return anx7406_set_hpd(port, 0); +} + +/* + * timestamp of the next possible toggle to ensure the 2-ms spacing + * between IRQ_HPD. + */ +static uint64_t hpd_timestamp[CONFIG_USB_PD_PORT_MAX_COUNT]; +void anx7406_update_hpd_status(const struct usb_mux *mux, mux_state_t mux_state) +{ + int port = mux->usb_port; + int hpd_lvl = (mux_state & USB_PD_MUX_HPD_LVL) ? 1 : 0; + int hpd_irq = (mux_state & USB_PD_MUX_HPD_IRQ) ? 1 : 0; + int rv; + + /* + * All calls within this method need to update to a mux_read/write calls + * that use the secondary address. This is a non-trival change and no + * one is using the anx7406 as a mux only (and probably never will since + * it doesn't have a re-driver). If that changes, we need to update this + * code. + */ + ASSERT(!(mux->flags & USB_MUX_FLAG_NOT_TCPC)); + + anx7406_set_hpd(port, hpd_lvl); + + if (hpd_irq) { + uint64_t now = get_time().val; + /* wait for the minimum spacing between IRQ_HPD if needed */ + if (now < hpd_timestamp[port]) + usleep(hpd_timestamp[port] - now); + + /* + * For generate hardware HPD IRQ, need set bit + * ANX7406_REG_HPD_IRQ0 first, then clear it. This bit is not + * write clear. + */ + rv = i2c_write8(tcpc_config[port].i2c_info.port, + i2c_peripheral[port].top_addr_flags, + ANX7406_REG_HPD_CTRL_0, ANX7406_REG_HPD_IRQ0); + rv |= i2c_write8(tcpc_config[port].i2c_info.port, + i2c_peripheral[port].top_addr_flags, + ANX7406_REG_HPD_CTRL_0, 0); + if (rv) + CPRINTS("Generate HPD IRQ failed: %d", rv); + } + /* enforce 2-ms delay between HPD pulses */ + hpd_timestamp[port] = get_time().val + HPD_USTREAM_DEBOUNCE_LVL; +} + +static int anx7406_init(int port) +{ + int rv, i; + + CPRINTS("C%d: %s", port, __func__); + /* + * find corresponding anx7406 TOP address according to + * specified TCPC address + */ + for (i = 0; i < ARRAY_SIZE(anx7406_i2c_addrs_flags); i++) { + if (I2C_STRIP_FLAGS(tcpc_config[port].i2c_info.addr_flags) == + I2C_STRIP_FLAGS( + anx7406_i2c_addrs_flags[i].tcpc_addr_flags)) { + i2c_peripheral[port].tcpc_addr_flags = + anx7406_i2c_addrs_flags[i].tcpc_addr_flags; + i2c_peripheral[port].top_addr_flags = + anx7406_i2c_addrs_flags[i].top_addr_flags; + break; + } + } + if (!I2C_STRIP_FLAGS(i2c_peripheral[port].top_addr_flags)) { + CPRINTS("C%d: 0x%x is invalid for anx7406", port, + i2c_peripheral[port].top_addr_flags); + return EC_ERROR_UNKNOWN; + } + + /* Set VBUS OCP */ + rv = tcpc_write(port, ANX7406_REG_VBUS_OCP, OCP_THRESHOLD); + if (rv) + return rv; + + /* Disable CAP write protect */ + rv = tcpc_update8(port, ANX7406_REG_TCPCCTRL, ANX7406_REG_CAP_WP, + MASK_CLR); + /* Disable bleed discharge */ + rv |= tcpc_update16(port, TCPC_REG_DEV_CAP_1, + TCPC_REG_DEV_CAP_1_BLEED_DISCHARGE, MASK_CLR); + CPRINTS("C%d: TCPC config disable bleed discharge", port); + /* Enable CAP write protect */ + rv |= tcpc_update8(port, ANX7406_REG_TCPCCTRL, ANX7406_REG_CAP_WP, + MASK_SET); + if (rv) + return rv; + + rv = tcpc_update8(port, TCPC_REG_POWER_STATUS, + TCPC_REG_POWER_STATUS_UNINIT, MASK_CLR); + if (rv) + return rv; + + rv = tcpci_tcpm_init(port); + if (rv) + return rv; + + /* Let sink_ctrl & source_ctrl GPIO pin controlled by TCPC */ + tcpc_write(port, ANX7406_REG_VBUS_SOURCE_CTRL, SOURCE_GPIO_OEN); + tcpc_write(port, ANX7406_REG_VBUS_SINK_CTRL, SINK_GPIO_OEN); + + /* Clear CABLE DETECT signale */ + rv = tcpc_update8(port, ANX7406_REG_ANALOG_SETTING, + ANX7406_REG_CABLE_DET_DIG, MASK_CLR); + if (rv) + return rv; + + /* + * Specifically disable voltage alarms, as VBUS_VOLTAGE_ALARM_HI may + * trigger repeatedly despite being masked (b/153989733) + */ + rv = tcpc_update16(port, TCPC_REG_POWER_CTRL, + TCPC_REG_POWER_CTRL_VBUS_VOL_MONITOR_DIS, MASK_SET); + if (rv) + return rv; + + /* TCPC Filter set to 512uS */ + rv = tcpc_write(port, ANX7406_REG_TCPCFILTER, 0xFF); + rv |= tcpc_update8(port, ANX7406_REG_TCPCCTRL, + ANX7406_REG_TCPCFILTERBIT8, MASK_SET); + if (rv) + CPRINTS("C%d: TCPC filter set failed: %d", port, rv); + + rv = anx7406_hpd_reset(port); + + CPRINTS("C%d: TCPC anx7406 initial success", port); + return rv; +} + +static int anx7406_release(int port) +{ + return EC_SUCCESS; +} + +static int anx7406_set_polarity(int port, enum tcpc_cc_polarity polarity) +{ + int rv; + + if (polarity_rm_dts(polarity)) + rv = tcpc_write(port, ANX7406_REG_VCONN_CTRL, + VCONN_PWR_CTRL_SEL | VCONN_CC1_PWR_ENABLE); + else + rv = tcpc_write(port, ANX7406_REG_VCONN_CTRL, + VCONN_PWR_CTRL_SEL | VCONN_CC2_PWR_ENABLE); + if (rv) + CPRINTS("Update VCONN power failed: %d, polarity: %d", rv, + polarity); + + return tcpci_tcpm_set_polarity(port, polarity); +} + +static int anx7406_m1_config(int port, int slave, int offset) +{ + int rv; + + /* Configure external I2C slave address */ + rv = i2c_write8(tcpc_config[port].i2c_info.port, + i2c_peripheral[port].top_addr_flags, EXT_I2C1_ADDR, + slave); + /* Configure external I2C slave offset */ + rv |= i2c_write8(tcpc_config[port].i2c_info.port, + i2c_peripheral[port].top_addr_flags, EXT_I2C1_OFFSET, + offset); + /* Configure external I2C transfer byte count */ + rv |= i2c_write8(tcpc_config[port].i2c_info.port, + i2c_peripheral[port].top_addr_flags, + EXT_I2C1_ACCESS_DATA_BYTE_CNT, 1); + /* Clear DATA buffer */ + rv |= i2c_write8(tcpc_config[port].i2c_info.port, + i2c_peripheral[port].top_addr_flags, + EXT_I2C1_ACCESS_CTRL, I2C1_DATA_CLR); + /* Clear release */ + rv |= i2c_write8(tcpc_config[port].i2c_info.port, + i2c_peripheral[port].top_addr_flags, + EXT_I2C1_ACCESS_CTRL, 0); + + return rv; +} + +int anx7406_m1_read(int port, int slave, int offset) +{ + int rv, val; + + rv = anx7406_m1_config(port, slave, offset); + + /* Send I2C read command */ + rv |= i2c_write8(tcpc_config[port].i2c_info.port, + i2c_peripheral[port].top_addr_flags, EXT_I2C1_CTRL, + I2C1_CMD_READ | I2C1_SPEED_100K); + if (rv) { + CPRINTS("initial cisco I2C master failed!"); + return rv; + } + + usleep(1000); + + /* Read I2C data out */ + rv = i2c_read8(tcpc_config[port].i2c_info.port, + i2c_peripheral[port].top_addr_flags, + EXT_I2C1_ACCESS_DATA, &val); + if (rv) { + CPRINTS("read cisco register failed!"); + return rv; + } + + return val; +} + +static int anx7406_m1_write(int port, int slave, int offset, int data) +{ + int rv; + + /* Configure external I2C slave address */ + rv = anx7406_m1_config(port, slave, offset); + + /* Configure I2C data */ + rv |= i2c_write8(tcpc_config[port].i2c_info.port, + i2c_peripheral[port].top_addr_flags, + EXT_I2C1_ACCESS_DATA, data); + /* Send I2C write command */ + rv |= i2c_write8(tcpc_config[port].i2c_info.port, + i2c_peripheral[port].top_addr_flags, EXT_I2C1_CTRL, + I2C1_CMD_WRITE | I2C1_SPEED_100K); + if (rv) { + CPRINTS("write data to cisco register failed!"); + return rv; + } + + return 0; +} + +int anx7406_set_aux(int port, int flip) +{ + int rv; + + CPRINTS("Set SBU %s flip", flip ? "" : "un"); + /* Configure SBU orientation */ + rv = anx7406_m1_write(port, I2C1_CISCO_SLAVE, I2C1_CISCO_LOCAL_REG, + SELECT_SBU_1_2); + if (rv) { + CPRINTS("Config CISCO_LOCAL_REG register failed"); + return rv; + } + + /* Disable pull up/down */ + rv = anx7406_m1_write(port, I2C1_CISCO_SLAVE, I2C1_CISCO_CTRL_3, + flip ? AUX_FLIP_EN : 0); + if (rv) { + CPRINTS("Config CISCO_CTRL_3 register failed"); + return rv; + } + + /* Disable pull up/down */ + rv = anx7406_m1_write(port, I2C1_CISCO_SLAVE, I2C1_CISCO_CTRL_1, + VBUS_PROTECT_750MA | AUX_PULL_DISABLE); + if (rv) { + CPRINTS("Config CISCO_CTRL_1 register failed"); + return rv; + } + + return 0; +} + +/* + * ANX7406 is a TCPCI compatible port controller, with some caveats. + * It seems to require both CC lines to be set always, instead of just + * one at a time, according to TCPCI spec. Thus, now that the TCPCI + * driver more closely follows the spec, this driver requires + * overrides for set_cc and set_polarity. + */ +const struct tcpm_drv anx7406_tcpm_drv = { + .init = &anx7406_init, + .release = &anx7406_release, + .get_cc = &tcpci_tcpm_get_cc, +#ifdef CONFIG_USB_PD_VBUS_DETECT_TCPC + .check_vbus_level = &tcpci_tcpm_check_vbus_level, +#endif + .select_rp_value = &tcpci_tcpm_select_rp_value, + .set_cc = &tcpci_tcpm_set_cc, + .set_polarity = &anx7406_set_polarity, +#ifdef CONFIG_USB_PD_DECODE_SOP + .sop_prime_enable = &tcpci_tcpm_sop_prime_enable, +#endif + .set_vconn = &tcpci_tcpm_set_vconn, + .set_msg_header = &tcpci_tcpm_set_msg_header, + .set_rx_enable = &tcpci_tcpm_set_rx_enable, + .get_message_raw = &tcpci_tcpm_get_message_raw, + .transmit = &tcpci_tcpm_transmit, + .tcpc_alert = &tcpci_tcpc_alert, +#ifdef CONFIG_USB_PD_DISCHARGE_TCPC + .tcpc_discharge_vbus = &tcpci_tcpc_discharge_vbus, +#endif +#ifdef CONFIG_USB_PD_DUAL_ROLE_AUTO_TOGGLE + .drp_toggle = tcpci_tcpc_drp_toggle, +#endif + .get_chip_info = &tcpci_get_chip_info, +#ifdef CONFIG_USB_PD_PPC + .set_snk_ctrl = &tcpci_tcpm_set_snk_ctrl, + .set_src_ctrl = &tcpci_tcpm_set_src_ctrl, +#endif +#ifdef CONFIG_USB_PD_TCPC_LOW_POWER + .enter_low_power_mode = &tcpci_enter_low_power_mode, +#endif + .set_bist_test_mode = &tcpci_set_bist_test_mode, +#ifdef CONFIG_CMD_TCPC_DUMP + .dump_registers = &tcpc_dump_std_registers, +#endif +}; diff --git a/driver/tcpm/anx7406.h b/driver/tcpm/anx7406.h new file mode 100644 index 0000000000..83651b9573 --- /dev/null +++ b/driver/tcpm/anx7406.h @@ -0,0 +1,135 @@ +/* Copyright 2023 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef __CROS_EC_USB_PD_TCPM_ANX7406_H +#define __CROS_EC_USB_PD_TCPM_ANX7406_H + +#include "usb_mux.h" + +struct anx7406_i2c_addr { + uint16_t tcpc_addr_flags; + uint16_t top_addr_flags; +}; + +#define ANX7406_TCPC0_I2C_ADDR_FLAGS (0x58 >> 1) +#define ANX7406_TCPC1_I2C_ADDR_FLAGS (0x56 >> 1) +#define ANX7406_TCPC2_I2C_ADDR_FLAGS (0x54 >> 1) +#define ANX7406_TCPC3_I2C_ADDR_FLAGS (0x52 >> 1) +#define ANX7406_TCPC4_I2C_ADDR_FLAGS (0x90 >> 1) +#define ANX7406_TCPC5_I2C_ADDR_FLAGS (0x9A >> 1) +#define ANX7406_TCPC6_I2C_ADDR_FLAGS (0xA4 >> 1) +#define ANX7406_TCPC7_I2C_ADDR_FLAGS (0xAE >> 1) + +#define ANX7406_TOP0_I2C_ADDR_FLAGS (0x7E >> 1) +#define ANX7406_TOP1_I2C_ADDR_FLAGS (0x6E >> 1) +#define ANX7406_TOP2_I2C_ADDR_FLAGS (0x64 >> 1) +#define ANX7406_TOP3_I2C_ADDR_FLAGS (0x62 >> 1) +#define ANX7406_TOP4_I2C_ADDR_FLAGS (0x92 >> 1) +#define ANX7406_TOP5_I2C_ADDR_FLAGS (0x9C >> 1) +#define ANX7406_TOP6_I2C_ADDR_FLAGS (0xA6 >> 1) +#define ANX7406_TOP7_I2C_ADDR_FLAGS (0xB0 >> 1) + +/* Registers: TCPC address used */ +#define ANX7406_REG_ANALOG_SETTING 0x0C +#define ANX7406_REG_CABLE_DET_DIG BIT(6) +#define ANX7406_REG_DIGITAL_RDY BIT(5) + +#define ANX7406_REG_TCPCFILTER 0x9F +#define ANX7406_REG_TCPCCTRL 0xCD +#define ANX7406_REG_TCPCFILTERBIT8 BIT(0) +#define ANX7406_REG_CAP_WP BIT(2) + +#define ANX7406_REG_VBUS_SOURCE_CTRL 0xC2 +#define SOURCE_GPIO_OEN BIT(2) +#define ANX7406_REG_VBUS_SINK_CTRL 0xC3 +#define SINK_GPIO_OEN BIT(2) + +#define ANX7406_REG_VBUS_OCP 0xD2 +#define OCP_THRESHOLD 0xFF + +#define ANX7406_REG_ADC_CTRL_1 0xE3 +#define ANX7406_REG_ADC_FSM_EN BIT(0) +#define ANX7406_REG_ADC_MEASURE_VCONN BIT(1) +#define ANX7406_REG_ADC_MEASURE_VBUS BIT(2) +#define ANX7406_REG_ADC_MEASURE_OCP BIT(3) + +#define ANX7406_REG_VCONN_CTRL 0xEB +#define VCONN_PWR_CTRL_SEL BIT(2) +#define VCONN_CC2_PWR_ENABLE BIT(1) +#define VCONN_CC1_PWR_ENABLE BIT(0) + +/* Registers: TOP address used */ +#define ANX7406_REG_HPD_CTRL_0 0x7E +#define ANX7406_REG_HPD_IRQ0 BIT(2) + +#define ANX7406_REG_HPD_DEGLITCH_H 0x80 +#define ANX7406_REG_HPD_OEN BIT(6) +#define HPD_DEGLITCH_TIME 0x0D + +#define EXT_I2C_OP_DELAY 1000 +/* Internal I2C0 master */ +/* External I2C0 address & offset */ +#define EXT_I2C0_ADDR 0x5E +#define EXT_I2C0_OFFSET 0x5F +/* External I2C0 master control bit */ +#define EXT_I2C0_CTRL 0x60 +#define I2C0_CMD_RESET BIT(6) +#define I2C0_CMD_WRITE BIT(4) +#define I2C0_CMD_READ 0 +#define I2C0_CMD_CISCO_READ (BIT(5) | BIT(6)) +#define I2C0_SPEED_100K (BIT(2) | BIT(3)) +#define I2C0_NO_STOP BIT(1) +#define I2C0_NO_ACK BIT(0) + +#define EXT_I2C0_ACCESS_DATA_BYTE_CNT 0x61 +#define EXT_I2C0_ACCESS_DATA 0x65 + +#define EXT_I2C0_ACCESS_CTRL 0x66 +#define I2C0_DATA_FULL BIT(7) +#define I2C0_DATA_EMPTY BIT(6) +#define I2C0_TIMING_SET_EN BIT(1) +#define I2C0_DATA_CLR BIT(0) + +/* Internal I2C1 master */ +/* External I2C1 address & offset */ +#define EXT_I2C1_ADDR 0xCC +#define EXT_I2C1_OFFSET 0xCD +/* External I2C1 master control bit */ +#define EXT_I2C1_CTRL 0xCE +#define I2C1_CMD_RESET BIT(6) +#define I2C1_CMD_WRITE BIT(4) +#define I2C1_CMD_READ 0 +#define I2C1_CMD_CISCO_READ (BIT(5) | BIT(6)) +#define I2C1_SPEED_100K (BIT(2) | BIT(3)) +#define I2C1_NO_STOP BIT(1) +#define I2C1_NO_ACK BIT(0) + +#define EXT_I2C1_ACCESS_DATA_BYTE_CNT 0xCF +#define EXT_I2C1_ACCESS_DATA 0xD3 + +#define EXT_I2C1_ACCESS_CTRL 0xD4 +#define I2C1_DATA_FULL BIT(7) +#define I2C1_DATA_EMPTY BIT(6) +#define I2C1_TIMING_SET_EN BIT(1) +#define I2C1_DATA_CLR BIT(0) + +#define I2C1_CISCO_SLAVE 0x80 +#define I2C1_CISCO_CTRL_1 0x01 +#define VBUS_PROTECT_750MA BIT(1) +#define AUX_PULL_DISABLE BIT(3) + +#define I2C1_CISCO_CTRL_3 0x03 +#define AUX_FLIP_EN BIT(0) + +#define I2C1_CISCO_LOCAL_REG 0x06 +#define SELECT_SBU_1_2 BIT(6) + +extern const struct tcpm_drv anx7406_tcpm_drv; +int anx7406_set_aux(int port, int flip); +int anx7406_hpd_reset(const int port); +void anx7406_update_hpd_status(const struct usb_mux *mux, + mux_state_t mux_state); + +#endif /* __CROS_EC_USB_PD_TCPM_ANX7406_H */ diff --git a/include/config.h b/include/config.h index d08214c17a..af7ef8d94d 100644 --- a/include/config.h +++ b/include/config.h @@ -4898,6 +4898,7 @@ #undef CONFIG_USB_PD_TCPM_FUSB302 #undef CONFIG_USB_PD_TCPM_ITE_ON_CHIP #undef CONFIG_USB_PD_TCPM_ANX3429 +#undef CONFIG_USB_PD_TCPM_ANX7406 #undef CONFIG_USB_PD_TCPM_ANX740X #undef CONFIG_USB_PD_TCPM_ANX741X #undef CONFIG_USB_PD_TCPM_ANX7447 diff --git a/zephyr/Kconfig.tcpm b/zephyr/Kconfig.tcpm index 6651336954..e2f50cfb39 100644 --- a/zephyr/Kconfig.tcpm +++ b/zephyr/Kconfig.tcpm @@ -72,6 +72,19 @@ config PLATFORM_EC_USB_PD_TCPC_RUNTIME_CONFIG factory. Without this, multiple EC images would need to be installed depending on the board. +config PLATFORM_EC_USB_PD_TCPM_ANX7406 + bool "Analogix ANX7406 USB-C Gen 2 Type-C Port Controller" + select PLATFORM_EC_USB_PD_TCPM_MUX + help + The Analogix ANX7406 is a USB Type-C Port Controller (TCPC) + for USB Type-C v1.2 Host, USB3.1 Gen2 and DisplayPort applications. + It has an on-chip microcontroller (OCM) to manage the signal + switching. It supports Power Delivery Rev. 3.0 and the DisplayPort + Alt Mode version 1.4a HBR3. + + Supported chips are: + ANX7406 + config PLATFORM_EC_USB_PD_TCPM_ANX7447 bool "Analogix ANX7447 USB-C Gen 2 Type-C Port Controller" select PLATFORM_EC_USB_PD_TCPM_MUX |