diff options
author | Mary Ruthven <mruthven@chromium.org> | 2021-01-05 13:35:59 -0800 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2021-01-06 21:56:53 +0000 |
commit | 7103bc89ed2a4460a606b62b63df02e7f0ecb3df (patch) | |
tree | 0634b852aff059895a6ced19dcdb52c6570ec5c2 /driver | |
parent | 2495bc0a9744f9733c59daeeb81c8be3c54243d8 (diff) | |
download | chrome-ec-7103bc89ed2a4460a606b62b63df02e7f0ecb3df.tar.gz |
coil: remove usbc, usb_pd, charge_manager, and tcpm
This code uses coil terms we're removing, but we don't use it in
platform/cr50. Remove the code instead of replacing the terms.
BUG=b:175244613
TEST=make buildall -j
Change-Id: Ia64e1ff4df941d2fe19e95e84dee8b743616aa88
Signed-off-by: Mary Ruthven <mruthven@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2613135
Reviewed-by: Namyoon Woo <namyoon@chromium.org>
Diffstat (limited to 'driver')
-rw-r--r-- | driver/build.mk | 14 | ||||
-rw-r--r-- | driver/tcpm/anx7447.c | 680 | ||||
-rw-r--r-- | driver/tcpm/anx7447.h | 141 | ||||
-rw-r--r-- | driver/tcpm/anx74xx.c | 1180 | ||||
-rw-r--r-- | driver/tcpm/anx74xx.h | 226 | ||||
-rw-r--r-- | driver/tcpm/anx7688.c | 213 | ||||
-rw-r--r-- | driver/tcpm/anx7688.h | 21 | ||||
-rw-r--r-- | driver/tcpm/fusb302.c | 1036 | ||||
-rw-r--r-- | driver/tcpm/fusb302.h | 213 | ||||
-rw-r--r-- | driver/tcpm/it83xx.c | 644 | ||||
-rw-r--r-- | driver/tcpm/it83xx_pd.h | 109 | ||||
-rw-r--r-- | driver/tcpm/mt6370.c | 218 | ||||
-rw-r--r-- | driver/tcpm/mt6370.h | 200 | ||||
-rw-r--r-- | driver/tcpm/nct38xx.c | 384 | ||||
-rw-r--r-- | driver/tcpm/nct38xx.h | 68 | ||||
-rw-r--r-- | driver/tcpm/ps8xxx.c | 321 | ||||
-rw-r--r-- | driver/tcpm/ps8xxx.h | 81 | ||||
-rw-r--r-- | driver/tcpm/stub.c | 155 | ||||
-rw-r--r-- | driver/tcpm/tcpci.c | 1014 | ||||
-rw-r--r-- | driver/tcpm/tcpci.h | 191 | ||||
-rw-r--r-- | driver/tcpm/tcpm.h | 418 | ||||
-rw-r--r-- | driver/tcpm/tusb422.c | 66 | ||||
-rw-r--r-- | driver/tcpm/tusb422.h | 16 |
23 files changed, 0 insertions, 7609 deletions
diff --git a/driver/build.mk b/driver/build.mk index 020ee211a7..db6949f8ca 100644 --- a/driver/build.mk +++ b/driver/build.mk @@ -125,20 +125,6 @@ driver-$(CONFIG_TOUCHPAD_ST)+=touchpad_st.o driver-$(CONFIG_THERMISTOR)+=temp_sensor/thermistor.o driver-$(CONFIG_THERMISTOR_NCP15WB)+=temp_sensor/thermistor_ncp15wb.o -# Type-C port controller (TCPC) drivers -driver-$(CONFIG_USB_PD_TCPM_STUB)+=tcpm/stub.o -driver-$(CONFIG_USB_PD_TCPM_TCPCI)+=tcpm/tcpci.o -driver-$(CONFIG_USB_PD_TCPM_FUSB302)+=tcpm/fusb302.o -driver-$(CONFIG_USB_PD_TCPM_MT6370)+=tcpm/mt6370.o -driver-$(CONFIG_USB_PD_TCPM_ITE83XX)+=tcpm/it83xx.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 -driver-$(CONFIG_USB_PD_TCPM_PS8751)+=tcpm/ps8xxx.o -driver-$(CONFIG_USB_PD_TCPM_PS8805)+=tcpm/ps8xxx.o -driver-$(CONFIG_USB_PD_TCPM_TUSB422)+=tcpm/tusb422.o -driver-$(CONFIG_USB_PD_TCPM_NCT38XX)+=tcpm/nct38xx.o - # Type-C Retimer drivers driver-$(CONFIG_USBC_RETIMER_INTEL_BB)+=retimer/bb_retimer.o driver-$(CONFIG_USBC_RETIMER_PI3DPX1207)+=retimer/pi3dpx1207.o diff --git a/driver/tcpm/anx7447.c b/driver/tcpm/anx7447.c deleted file mode 100644 index 0af495251c..0000000000 --- a/driver/tcpm/anx7447.c +++ /dev/null @@ -1,680 +0,0 @@ -/* Copyright 2018 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. - */ - -/* ANX7447 port manager */ - -#include "common.h" -#include "anx7447.h" -#include "console.h" -#include "hooks.h" -#include "tcpci.h" -#include "tcpm.h" -#include "timer.h" -#include "usb_mux.h" -#include "usb_pd.h" -#include "util.h" - -#define CPRINTS(format, args...) cprints(CC_USBCHARGE, format, ## args) -#define CPRINTF(format, args...) cprintf(CC_USBCHARGE, format, ## args) - -#define ANX7447_VENDOR_ALERT BIT(15) - -#define ANX7447_REG_STATUS 0x82 -#define ANX7447_REG_STATUS_LINK BIT(0) - -#define ANX7447_REG_HPD 0x83 -#define ANX7447_REG_HPD_HIGH BIT(0) -#define ANX7447_REG_HPD_IRQ BIT(1) -#define ANX7447_REG_HPD_ENABLE BIT(2) - -#define vsafe5v_min (3800/25) -#define vsafe0v_max (800/25) -/* - * These interface are workable while ADC is enabled, before - * calling them should make sure ec driver finished chip initilization. - */ -#define is_equal_greater_safe5v(port) \ - (((anx7447_get_vbus_voltage(port))) > vsafe5v_min) -#define is_equal_greater_safe0v(port) \ - (((anx7447_get_vbus_voltage(port))) > vsafe0v_max) - -struct anx_state { - uint16_t i2c_slave_addr_flags; -}; - -struct anx_usb_mux { - int state; -}; - -static int anx7447_mux_set(int port, mux_state_t mux_state); - -static struct anx_state anx[CONFIG_USB_PD_PORT_MAX_COUNT]; -static struct anx_usb_mux mux[CONFIG_USB_PD_PORT_MAX_COUNT]; - -/* - * ANX7447 has two co-existence I2C slave addresses, TCPC slave address and - * SPI slave address. The registers of TCPC slave address are partly compliant - * with standard USB TCPC specification, and the registers in SPI slave - * address controls the other functions (ex, hpd_level, mux_switch, and - * so on). It can't use tcpc_read() and tcpc_write() to access SPI slave - * address because its slave address has been set as TCPC in the structure - * tcpc_config_t. - * anx7447_reg_write() and anx7447_reg_read() are implemented here to access - * ANX7447 SPI slave address. - */ -const struct anx7447_i2c_addr anx7447_i2c_addrs_flags[] = { - {AN7447_TCPC0_I2C_ADDR_FLAGS, AN7447_SPI0_I2C_ADDR_FLAGS}, - {AN7447_TCPC1_I2C_ADDR_FLAGS, AN7447_SPI1_I2C_ADDR_FLAGS}, - {AN7447_TCPC2_I2C_ADDR_FLAGS, AN7447_SPI2_I2C_ADDR_FLAGS}, - {AN7447_TCPC3_I2C_ADDR_FLAGS, AN7447_SPI3_I2C_ADDR_FLAGS} -}; - -static inline int anx7447_reg_write(int port, int reg, int val) -{ - int rv = i2c_write8(tcpc_config[port].i2c_info.port, - anx[port].i2c_slave_addr_flags, - reg, val); -#ifdef CONFIG_USB_PD_TCPC_LOW_POWER - pd_device_accessed(port); -#endif - return rv; -} - -static inline int anx7447_reg_read(int port, int reg, int *val) -{ - int rv = i2c_read8(tcpc_config[port].i2c_info.port, - anx[port].i2c_slave_addr_flags, - reg, val); -#ifdef CONFIG_USB_PD_TCPC_LOW_POWER - pd_device_accessed(port); -#endif - return rv; -} - -void anx7447_hpd_mode_en(int port) -{ - int reg, rv; - - rv = anx7447_reg_read(port, ANX7447_REG_HPD_CTRL_0, ®); - if (rv) - return; - - reg |= ANX7447_REG_HPD_MODE; - anx7447_reg_write(port, ANX7447_REG_HPD_CTRL_0, reg); -} - -void anx7447_hpd_output_en(int port) -{ - int reg, rv; - - rv = anx7447_reg_read(port, ANX7447_REG_HPD_DEGLITCH_H, ®); - if (rv) - return; - - reg |= ANX7447_REG_HPD_OEN; - anx7447_reg_write(port, ANX7447_REG_HPD_DEGLITCH_H, reg); -} - -void anx7447_set_hpd_level(int port, int hpd_lvl) -{ - int reg, rv; - - rv = anx7447_reg_read(port, ANX7447_REG_HPD_CTRL_0, ®); - if (rv) - return; - - if (hpd_lvl) - reg |= ANX7447_REG_HPD_OUT; - else - reg &= ~ANX7447_REG_HPD_OUT; - anx7447_reg_write(port, ANX7447_REG_HPD_CTRL_0, reg); -} - -#ifdef CONFIG_USB_PD_TCPM_ANX7447_OCM_ERASE_COMMAND -static inline void anx7447_reg_write_and(int port, int reg, int v_and) -{ - int val; - - if (!anx7447_reg_read(port, reg, &val)) - anx7447_reg_write(port, reg, (val & v_and)); -} - -static inline void anx7447_reg_write_or(int port, int reg, int v_or) -{ - int val; - - if (!anx7447_reg_read(port, reg, &val)) - anx7447_reg_write(port, reg, (val | v_or)); -} - -#define ANX7447_FLASH_DONE_TIMEOUT_US (100 * MSEC) - -static int anx7447_wait_for_flash_done(int port) -{ - timestamp_t deadline; - int rv; - int r; - - deadline.val = get_time().val + ANX7447_FLASH_DONE_TIMEOUT_US; - do { - if (timestamp_expired(deadline, NULL)) - return EC_ERROR_TIMEOUT; - rv = anx7447_reg_read(port, ANX7447_REG_R_RAM_CTRL, &r); - if (rv) - return rv; - } while (!(r & ANX7447_R_RAM_CTRL_FLASH_DONE)); - - return EC_SUCCESS; -} - -static int anx7447_flash_write_en(int port) -{ - anx7447_reg_write(port, ANX7447_REG_FLASH_INST_TYPE, - ANX7447_FLASH_INST_TYPE_WRITEENABLE); - anx7447_reg_write_or(port, ANX7447_REG_R_FLASH_RW_CTRL, - ANX7447_R_FLASH_RW_CTRL_GENERAL_INST_EN); - return anx7447_wait_for_flash_done(port); -} - -static int anx7447_flash_op_init(int port) -{ - int rv; - - anx7447_reg_write_or(port, ANX7447_REG_OCM_CTRL_0, - ANX7447_OCM_CTRL_OCM_RESET); - anx7447_reg_write_or(port, ANX7447_REG_ADDR_GPIO_CTRL_0, - ANX7447_ADDR_GPIO_CTRL_0_SPI_WP); - - rv = anx7447_flash_write_en(port); - if (rv) - return rv; - - anx7447_reg_write_and(port, ANX7447_REG_R_FLASH_STATUS_0, - ANX7447_FLASH_STATUS_SPI_STATUS_0); - anx7447_reg_write_or(port, ANX7447_REG_R_FLASH_RW_CTRL, - ANX7447_R_FLASH_RW_CTRL_WRITE_STATUS_EN); - - return anx7447_wait_for_flash_done(port); -} - -static int anx7447_flash_is_empty(int port) -{ - int r; - - anx7447_reg_read(port, ANX7447_REG_OCM_VERSION, &r); - - return ((r == 0) ? 1 : 0); -} - -static int anx7447_flash_erase_internal(int port, int write_console_if_empty) -{ - int rv; - int r; - - tcpc_read(port, TCPC_REG_COMMAND, &r); - usleep(ANX7447_DELAY_IN_US); - - if (anx7447_flash_is_empty(port) == 1) { - if (write_console_if_empty) - CPRINTS("C%d: Nothing to erase!", port); - return EC_SUCCESS; - } - CPRINTS("C%d: Erasing OCM flash...", port); - - rv = anx7447_flash_op_init(port); - if (rv) - return rv; - - usleep(ANX7447_DELAY_IN_US); - - rv = anx7447_flash_write_en(port); - if (rv) - return rv; - - anx7447_reg_write(port, ANX7447_REG_FLASH_ERASE_TYPE, - ANX7447_FLASH_ERASE_TYPE_CHIPERASE); - anx7447_reg_write_or(port, ANX7447_REG_R_FLASH_RW_CTRL, - ANX7447_R_FLASH_RW_CTRL_FLASH_ERASE_EN); - - return anx7447_wait_for_flash_done(port); -} - -int anx7447_flash_erase(int port) -{ - return anx7447_flash_erase_internal(port, - 0 /* suppress console if empty */); -} - -/* Add console command to erase OCM flash if needed. */ -static int command_anx_ocm(int argc, char **argv) -{ - char *e = NULL; - int port; - - if (argc < 2) - return EC_ERROR_PARAM_COUNT; - - /* Get port number from first parameter */ - port = strtoi(argv[1], &e, 0); - if (*e) - return EC_ERROR_PARAM1; - - if (argc > 2) { - int rv; - if (strcasecmp(argv[2], "erase")) - return EC_ERROR_PARAM2; - rv = anx7447_flash_erase_internal( - port, 1 /* write to console if empty */); - if (rv) - ccprintf("C%d: Failed to erase OCM flash (%d)\n", - port, rv); - } - - ccprintf("C%d: OCM flash is %sempty.\n", - port, anx7447_flash_is_empty(port) ? "" : "not "); - - return EC_SUCCESS; -} -DECLARE_CONSOLE_COMMAND(anx_ocm, command_anx_ocm, - "port [erase]", - "Print OCM status or erases OCM for a given port."); -#endif - -static int anx7447_init(int port) -{ - int rv, reg, i; - - ASSERT(port < CONFIG_USB_PD_PORT_MAX_COUNT); - - memset(&anx[port], 0, sizeof(struct anx_state)); - - /* - * find corresponding anx7447 SPI slave address according to - * specified TCPC slave address - */ - for (i = 0; i < ARRAY_SIZE(anx7447_i2c_addrs_flags); i++) { - if (I2C_GET_ADDR(tcpc_config[port].i2c_info.addr_flags) == - I2C_GET_ADDR( - anx7447_i2c_addrs_flags[i].tcpc_slave_addr_flags)) { - anx[port].i2c_slave_addr_flags = - anx7447_i2c_addrs_flags[i].spi_slave_addr_flags; - break; - } - } - if (!I2C_GET_ADDR(anx[port].i2c_slave_addr_flags)) { - ccprintf("TCPC I2C slave addr 0x%x is invalid for ANX7447\n", - I2C_GET_ADDR(tcpc_config[port] - .i2c_info.addr_flags)); - return EC_ERROR_UNKNOWN; - } - - - rv = tcpci_tcpm_init(port); - if (rv) - return rv; - -#ifdef CONFIG_USB_PD_TCPM_ANX7447_OCM_ERASE_COMMAND - /* Check and print OCM status to console. */ - CPRINTS("C%d: OCM flash is %sempty", - port, anx7447_flash_is_empty(port) ? "" : "not "); -#endif - - /* - * 7447 has a physical pin to detect the presence of VBUS, VBUS_SENSE - * , and 7447 has a VBUS current protection mechanism through another - * pin input VBUS_OCP. To enable VBUS OCP, OVP protection, driver needs - * to set the threshold to the registers VBUS_VOLTAGE_ALARM_HI_CFG - * (0x76 & 0x77) and VBUS_OCP_HI_THRESHOLD (0xDD &0xDE). These values - * could be customized based on different platform design. - * Disable VBUS protection here since the default values of - * VBUS_VOLTAGE_ALARM_HI_CFG and VBUS_OCP_HI_THRESHOLD are zero. - */ - rv = tcpc_read(port, ANX7447_REG_TCPC_CTRL_2, ®); - if (rv) - return rv; - reg &= ~ANX7447_REG_ENABLE_VBUS_PROTECT; - rv = tcpc_write(port, ANX7447_REG_TCPC_CTRL_2, reg); - if (rv) - return rv; - - /* ADC enable, use to monitor VBUS voltage */ - rv = tcpc_read(port, ANX7447_REG_ADC_CTRL_1, ®); - if (rv) - return rv; - reg |= ANX7447_REG_ADCFSM_EN; - rv = tcpc_write(port, ANX7447_REG_ADC_CTRL_1, reg); - if (rv) - return rv; - - /* Set VCONN OCP(Over Current Protection) threshold */ - rv = tcpc_read(port, ANX7447_REG_ANALOG_CTRL_8, ®); - if (rv) - return rv; - reg &= ~ANX7447_REG_VCONN_OCP_MASK; - reg |= ANX7447_REG_VCONN_OCP_440mA; - rv = tcpc_write(port, ANX7447_REG_ANALOG_CTRL_8, reg); - - /* Vconn SW protection time of inrush current */ - rv = tcpc_read(port, ANX7447_REG_ANALOG_CTRL_10, ®); - if (rv) - return rv; - reg &= ~ANX7447_REG_R_VCONN_PWR_PRT_INRUSH_TIME_MASK; - reg |= ANX7447_REG_R_VCONN_PWR_PRT_INRUSH_TIME_2430US; - rv = tcpc_write(port, ANX7447_REG_ANALOG_CTRL_10, reg); - -#ifdef CONFIG_USB_PD_TCPM_MUX - /* - * Run mux_set() here for considering CCD(Case-Closed Debugging) case - * If this TCPC is not also the MUX then don't initialize to NONE - */ - if (!(usb_muxes[port].flags & USB_MUX_FLAG_NOT_TCPC)) - rv |= anx7447_mux_set(port, TYPEC_MUX_NONE); -#endif /* CONFIG_USB_PD_TCPM_MUX */ - - return rv; -} - -static int anx7447_release(int port) -{ - return EC_SUCCESS; -} - -static void anx7447_update_hpd_enable(int port) -{ - int status, reg, rv; - - rv = tcpc_read(port, ANX7447_REG_STATUS, &status); - rv |= tcpc_read(port, ANX7447_REG_HPD, ®); - if (rv) - return; - - if (!(reg & ANX7447_REG_HPD_ENABLE) || - !(status & ANX7447_REG_STATUS_LINK)) { - reg &= ~ANX7447_REG_HPD_IRQ; - tcpc_write(port, ANX7447_REG_HPD, - (status & ANX7447_REG_STATUS_LINK) - ? reg | ANX7447_REG_HPD_ENABLE - : reg & ~ANX7447_REG_HPD_ENABLE); - } -} - -#ifdef CONFIG_USB_PD_VBUS_DETECT_TCPC -static int anx7447_get_vbus_voltage(int port) -{ - int vbus_volt = 0; - - tcpc_read16(port, TCPC_REG_VBUS_VOLTAGE, &vbus_volt); - - return vbus_volt; -} - -int anx7447_set_power_supply_ready(int port) -{ - int count = 0; - - while (is_equal_greater_safe0v(port)) { - if (count >= 10) - break; - msleep(100); - count++; - } - - return tcpc_write(port, TCPC_REG_COMMAND, 0x77); -} -#endif /* CONFIG_USB_PD_VBUS_DETECT_TCPC */ - -int anx7447_power_supply_reset(int port) -{ - return tcpc_write(port, TCPC_REG_COMMAND, 0x66); -} - -int anx7447_board_charging_enable(int port, int enable) -{ - return tcpc_write(port, TCPC_REG_COMMAND, enable ? 0x55 : 0x44); -} - -static void anx7447_tcpc_alert(int port) -{ - int alert, rv; - - rv = tcpc_read16(port, TCPC_REG_ALERT, &alert); - /* process and clear alert status */ - tcpci_tcpc_alert(port); - - if (!rv && (alert & ANX7447_VENDOR_ALERT)) - anx7447_update_hpd_enable(port); -} - -/* - * timestamp of the next possible toggle to ensure the 2-ms spacing - * between IRQ_HPD. - */ -static uint64_t hpd_deadline[CONFIG_USB_PD_PORT_MAX_COUNT]; - -void anx7447_tcpc_update_hpd_status(int port, int hpd_lvl, int hpd_irq) -{ - int reg = 0; - - /* - * 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 anx7447 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(!(usb_muxes[port].flags & USB_MUX_FLAG_NOT_TCPC)); - - anx7447_set_hpd_level(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_deadline[port]) - usleep(hpd_deadline[port] - now); - - anx7447_reg_read(port, ANX7447_REG_HPD_CTRL_0, ®); - reg &= ~ANX7447_REG_HPD_OUT; - anx7447_reg_write(port, ANX7447_REG_HPD_CTRL_0, reg); - usleep(HPD_DSTREAM_DEBOUNCE_IRQ); - reg |= ANX7447_REG_HPD_OUT; - anx7447_reg_write(port, ANX7447_REG_HPD_CTRL_0, reg); - } - /* enforce 2-ms delay between HPD pulses */ - hpd_deadline[port] = get_time().val + HPD_USTREAM_DEBOUNCE_LVL; -} - -void anx7447_tcpc_clear_hpd_status(int port) -{ - anx7447_hpd_output_en(port); - anx7447_set_hpd_level(port, 0); -} - -#ifdef CONFIG_USB_PD_TCPM_MUX -static int anx7447_mux_init(int port) -{ - ASSERT(port < CONFIG_USB_PD_PORT_MAX_COUNT); - - memset(&mux[port], 0, sizeof(struct anx_usb_mux)); - - /* init hpd status */ - anx7447_hpd_mode_en(port); - anx7447_set_hpd_level(port, 0); - anx7447_hpd_output_en(port); - - /* - * ANX initializes its muxes to (MUX_USB_ENABLED | MUX_DP_ENABLED) - * when reinitialized, we need to force initialize it to - * TYPEC_MUX_NONE - */ - return anx7447_mux_set(port, TYPEC_MUX_NONE); -} - -#ifdef CONFIG_USB_PD_TCPM_ANX7447_AUX_PU_PD -static void anx7447_mux_safemode(int port, int on_off) -{ - int reg; - - mux_read(port, ANX7447_REG_ANALOG_CTRL_9, ®); - - if (on_off) - reg |= ANX7447_REG_SAFE_MODE; - else - reg &= ~(ANX7447_REG_SAFE_MODE); - - mux_write(port, ANX7447_REG_ANALOG_CTRL_9, reg); - CPRINTS("C%d set mux to safemode %s, reg = 0x%x", - port, (on_off) ? "on" : "off", reg); -} - -static inline void anx7447_configure_aux_src(int port, int on_off) -{ - int reg; - - mux_read(port, ANX7447_REG_ANALOG_CTRL_9, ®); - - if (on_off) - reg |= ANX7447_REG_R_AUX_RES_PULL_SRC; - else - reg &= ~(ANX7447_REG_R_AUX_RES_PULL_SRC); - - mux_write(port, ANX7447_REG_ANALOG_CTRL_9, reg); - - CPRINTS("C%d set aux_src to %s, reg = 0x%x", - port, (on_off) ? "on" : "off", reg); -} -#endif - -/* - * Set mux. - * - * sstx and ssrx are the USB superspeed transmit and receive pairs. ml is the - * DisplayPort Main Link. There are four lanes total. For example, DP cases - * connect them all and dock cases connect 2 DP and USB. - * - * a2, a3, a10, a11, b2, b3, b10, b11 are pins on the USB-C connector. - */ -static int anx7447_mux_set(int port, mux_state_t mux_state) -{ - int cc_direction; - mux_state_t mux_type; - int sw_sel = 0x00, aux_sw = 0x00; - int rv; - - cc_direction = mux_state & MUX_POLARITY_INVERTED; - mux_type = mux_state & TYPEC_MUX_DOCK; - CPRINTS("C%d mux_state = 0x%x, mux_type = 0x%x", - port, mux_state, mux_type); - if (cc_direction == 0) { - /* cc1 connection */ - if (mux_type == TYPEC_MUX_DOCK) { - /* ml0-a10/11, ml1-b2/b3, sstx-a2/a3, ssrx-b10/11 */ - sw_sel = 0x21; - /* aux+ <-> sbu1, aux- <-> sbu2 */ - aux_sw = 0x03; - } else if (mux_type == TYPEC_MUX_DP) { - /* ml0-a10/11, ml1-b2/b3, ml2-a2/a3, ml3-b10/11 */ - sw_sel = 0x09; - /* aux+ <-> sbu1, aux- <-> sbu2 */ - aux_sw = 0x03; - } else if (mux_type == TYPEC_MUX_USB) { - /* ssrxp<->b11, ssrxn<->b10, sstxp<->a2, sstxn<->a3 */ - sw_sel = 0x20; - } - } else { - /* cc2 connection */ - if (mux_type == TYPEC_MUX_DOCK) { - /* ml0-b10/11, ml1-a2/b3, sstx-b2/a3, ssrx-a10/11 */ - sw_sel = 0x12; - /* aux+ <-> sbu2, aux- <-> sbu1 */ - aux_sw = 0x0C; - } else if (mux_type == TYPEC_MUX_DP) { - /* ml0-b10/11, ml1-a2/b3, ml2-b2/a3, ml3-a10/11 */ - sw_sel = 0x06; - /* aux+ <-> sbu2, aux- <-> sbu1 */ - aux_sw = 0x0C; - } else if (mux_type == TYPEC_MUX_USB) { - /* ssrxp<->a11, ssrxn<->a10, sstxp<->b2, sstxn<->b3 */ - sw_sel = 0x10; - } - } - - /* - * Once need to configure the Mux, should set the mux to safe mode - * first. After the mux configured, should set mux to normal mode. - */ -#ifdef CONFIG_USB_PD_TCPM_ANX7447_AUX_PU_PD - anx7447_mux_safemode(port, 1); -#endif - rv = mux_write(port, ANX7447_REG_TCPC_SWITCH_0, sw_sel); - rv |= mux_write(port, ANX7447_REG_TCPC_SWITCH_1, sw_sel); - rv |= mux_write(port, ANX7447_REG_TCPC_AUX_SWITCH, aux_sw); - - mux[port].state = mux_state; - -#ifdef CONFIG_USB_PD_TCPM_ANX7447_AUX_PU_PD - /* - * DP and Dock mode: after configured the Mux, change the Mux to - * normal mode, otherwise: keep safe mode. - */ - if (mux_type != TYPEC_MUX_NONE) { - anx7447_configure_aux_src(port, 1); - anx7447_mux_safemode(port, 0); - } else - anx7447_configure_aux_src(port, 0); -#endif - - return rv; -} - -/* current mux state */ -static int anx7447_mux_get(int port, mux_state_t *mux_state) -{ - *mux_state = mux[port].state; - - return EC_SUCCESS; -} -#endif /* CONFIG_USB_PD_TCPM_MUX */ - -/* ANX7447 is a TCPCI compatible port controller */ -const struct tcpm_drv anx7447_tcpm_drv = { - .init = &anx7447_init, - .release = &anx7447_release, - .get_cc = &tcpci_tcpm_get_cc, -#ifdef CONFIG_USB_PD_VBUS_DETECT_TCPC - .get_vbus_level = &tcpci_tcpm_get_vbus_level, -#endif - .select_rp_value = &tcpci_tcpm_select_rp_value, - .set_cc = &tcpci_tcpm_set_cc, - .set_polarity = &tcpci_tcpm_set_polarity, - .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 = &anx7447_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_USBC_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 -}; - -#ifdef CONFIG_USB_PD_TCPM_MUX -const struct usb_mux_driver anx7447_usb_mux_driver = { - .init = anx7447_mux_init, - .set = anx7447_mux_set, - .get = anx7447_mux_get, -}; -#endif /* CONFIG_USB_PD_TCPM_MUX */ - diff --git a/driver/tcpm/anx7447.h b/driver/tcpm/anx7447.h deleted file mode 100644 index 4da300884c..0000000000 --- a/driver/tcpm/anx7447.h +++ /dev/null @@ -1,141 +0,0 @@ -/* Copyright 2018 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. - */ - -/* USB Power delivery port management */ - -#ifndef __CROS_EC_USB_PD_TCPM_ANX7447_H -#define __CROS_EC_USB_PD_TCPM_ANX7447_H - -/* Registers: TCPC slave address used */ -#define ANX7447_REG_TCPC_SWITCH_0 0xB4 -#define ANX7447_REG_TCPC_SWITCH_1 0xB5 -#define ANX7447_REG_TCPC_AUX_SWITCH 0xB6 - -#define ANX7447_REG_INTR_ALERT_MASK_0 0xC9 - -#define ANX7447_REG_TCPC_CTRL_2 0xCD -#define ANX7447_REG_ENABLE_VBUS_PROTECT 0x20 - -#define ANX7447_REG_ADC_CTRL_1 0xBF -#define ANX7447_REG_ADCFSM_EN 0x20 - -/* Registers: SPI slave address used */ -#define ANX7447_REG_HPD_CTRL_0 0x7E -#define ANX7447_REG_HPD_MODE 0x01 -#define ANX7447_REG_HPD_OUT 0x02 - -#define ANX7447_REG_HPD_DEGLITCH_H 0x80 -#define ANX7447_REG_HPD_OEN 0x40 - -#define ANX7447_REG_INTP_CTRL_0 0x9E - -#define ANX7447_REG_ANALOG_CTRL_8 0xA8 -#define ANX7447_REG_VCONN_OCP_MASK 0x0C -#define ANX7447_REG_VCONN_OCP_240mA 0x00 -#define ANX7447_REG_VCONN_OCP_310mA 0x04 -#define ANX7447_REG_VCONN_OCP_370mA 0x08 -#define ANX7447_REG_VCONN_OCP_440mA 0x0C - -#define ANX7447_REG_ANALOG_CTRL_10 0xAA -#define ANX7447_REG_R_VCONN_PWR_PRT_INRUSH_TIME_MASK 0x38 -#define ANX7447_REG_R_VCONN_PWR_PRT_INRUSH_TIME_19US 0x00 -#define ANX7447_REG_R_VCONN_PWR_PRT_INRUSH_TIME_38US 0x08 -#define ANX7447_REG_R_VCONN_PWR_PRT_INRUSH_TIME_76US 0x10 -#define ANX7447_REG_R_VCONN_PWR_PRT_INRUSH_TIME_152US 0x18 -#define ANX7447_REG_R_VCONN_PWR_PRT_INRUSH_TIME_303US 0x20 -#define ANX7447_REG_R_VCONN_PWR_PRT_INRUSH_TIME_607US 0x28 -#define ANX7447_REG_R_VCONN_PWR_PRT_INRUSH_TIME_1210US 0x30 -#define ANX7447_REG_R_VCONN_PWR_PRT_INRUSH_TIME_2430US 0x38 - -#define ANX7447_REG_ANALOG_CTRL_9 0xA9 -#define ANX7447_REG_SAFE_MODE 0x80 -#define ANX7447_REG_R_AUX_RES_PULL_SRC 0x20 - -/* - * This section of defines are only required to support the config option - * CONFIG_USB_PD_TCPM_ANX7447_OCM_ERASE_COMMAND. - */ -/* SPI registers used for OCM flash operations */ -#define ANX7447_DELAY_IN_US (20*1000) - -#define ANX7447_REG_R_RAM_CTRL 0x05 -#define ANX7447_REG_R_FLASH_RW_CTRL 0x30 -#define ANX7447_REG_R_FLASH_STATUS_0 0x31 -#define ANX7447_REG_FLASH_INST_TYPE 0x33 -#define ANX7447_REG_FLASH_ERASE_TYPE 0x34 -#define ANX7447_REG_OCM_CTRL_0 0x6E -#define ANX7447_REG_ADDR_GPIO_CTRL_0 0x88 -#define ANX7447_REG_OCM_VERSION 0xB4 - -/* R_RAM_CTRL bit definitions */ -#define ANX7447_R_RAM_CTRL_FLASH_DONE (1<<7) - -/* R_FLASH_RW_CTRL bit definitions */ -#define ANX7447_R_FLASH_RW_CTRL_GENERAL_INST_EN (1<<6) -#define ANX7447_R_FLASH_RW_CTRL_FLASH_ERASE_EN (1<<5) -#define ANX7447_R_FLASH_RW_CTRL_WRITE_STATUS_EN (1<<2) -#define ANX7447_R_FLASH_RW_CTRL_FLASH_READ (1<<1) -#define ANX7447_R_FLASH_RW_CTRL_FLASH_WRITE (1<<0) - -/* R_FLASH_STATUS_0 definitions */ -#define ANX7447_FLASH_STATUS_SPI_STATUS_0 0x43 - -/* FLASH_ERASE_TYPE bit definitions */ -#define ANX7447_FLASH_INST_TYPE_WRITEENABLE 0x06 -#define ANX7447_FLASH_ERASE_TYPE_CHIPERASE 0x60 - -/* OCM_CTRL_0 bit definitions */ -#define ANX7447_OCM_CTRL_OCM_RESET (1<<6) - -/* ADDR_GPIO_CTRL_0 bit definitions */ -#define ANX7447_ADDR_GPIO_CTRL_0_SPI_WP (1<<7) -#define ANX7447_ADDR_GPIO_CTRL_0_SPI_CLK_ENABLE (1<<6) -/* End of defines used for CONFIG_USB_PD_TCPM_ANX7447_OCM_ERASE_COMMAND */ - -struct anx7447_i2c_addr { - uint16_t tcpc_slave_addr_flags; - uint16_t spi_slave_addr_flags; -}; - -#define AN7447_TCPC0_I2C_ADDR_FLAGS 0x2C -#define AN7447_TCPC1_I2C_ADDR_FLAGS 0x2B -#define AN7447_TCPC2_I2C_ADDR_FLAGS 0x2A -#define AN7447_TCPC3_I2C_ADDR_FLAGS 0x29 - -#define AN7447_SPI0_I2C_ADDR_FLAGS 0x3F -#define AN7447_SPI1_I2C_ADDR_FLAGS 0x37 -#define AN7447_SPI2_I2C_ADDR_FLAGS 0x32 -#define AN7447_SPI3_I2C_ADDR_FLAGS 0x31 - -/* - * Time TEST_R must be held high for a reset - */ -#define ANX74XX_RESET_HOLD_MS 1 -/* - * Time after TEST_R reset to wait for eFuse loading - */ -#define ANX74XX_RESET_FINISH_MS 2 - -int anx7447_set_power_supply_ready(int port); -int anx7447_power_supply_reset(int port); -int anx7447_board_charging_enable(int port, int enable); - -void anx7447_hpd_mode_en(int port); -void anx7447_hpd_output_en(int port); - -extern const struct tcpm_drv anx7447_tcpm_drv; -extern const struct usb_mux_driver anx7447_usb_mux_driver; -void anx7447_tcpc_update_hpd_status(int port, int hpd_lvl, int hpd_irq); -void anx7447_tcpc_clear_hpd_status(int port); - -/** - * Erase OCM flash if it's not empty - * - * @param port: USB-C port number - * @return: EC_SUCCESS or EC_ERROR_* - */ -int anx7447_flash_erase(int port); - -#endif /* __CROS_EC_USB_PD_TCPM_ANX7688_H */ diff --git a/driver/tcpm/anx74xx.c b/driver/tcpm/anx74xx.c deleted file mode 100644 index 0e7ec021d8..0000000000 --- a/driver/tcpm/anx74xx.c +++ /dev/null @@ -1,1180 +0,0 @@ -/* Copyright 2016 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. - * - * Author : Analogix Semiconductor. - */ - -/* Type-C port manager for Analogix's anx74xx chips */ - -#include "console.h" -#include "anx74xx.h" -#include "task.h" -#include "tcpci.h" -#include "tcpm.h" -#include "timer.h" -#include "usb_charge.h" -#include "usb_mux.h" -#include "usb_pd.h" -#include "usb_pd_tcpc.h" -#include "util.h" - -#if !defined(CONFIG_USB_PD_TCPM_TCPCI) -#error "ANX74xx is using part of standard TCPCI control" -#error "Please upgrade your board configuration" -#endif - -#define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args) -#define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args) - -struct anx_state { - int polarity; - int vconn_en; - int mux_state; -#ifdef CONFIG_USB_PD_TCPC_LOW_POWER - int prev_mode; -#endif -}; -#define clear_recvd_msg_int(port) do {\ - int reg, rv; \ - rv = tcpc_read(port, ANX74XX_REG_RECVD_MSG_INT, ®); \ - if (!rv) \ - tcpc_write(port, ANX74XX_REG_RECVD_MSG_INT, \ - reg | 0x01); \ - } while (0) - -static struct anx_state anx[CONFIG_USB_PD_PORT_MAX_COUNT]; - -/* Save the selected rp value */ -static int selected_rp[CONFIG_USB_PD_PORT_MAX_COUNT]; - -#ifdef CONFIG_USB_PD_DECODE_SOP -/* Save the message address */ -static int msg_sop[CONFIG_USB_PD_PORT_MAX_COUNT]; -#endif - -static int anx74xx_tcpm_init(int port); - -static void anx74xx_tcpm_set_auto_good_crc(int port, int enable) -{ - int reply_sop_en = 0; - - if (enable) { - reply_sop_en = ANX74XX_REG_REPLY_SOP_EN; -#ifdef CONFIG_USB_PD_DECODE_SOP - /* - * Only the VCONN Source is allowed to communicate - * with the Cable Plugs. - */ - if (anx[port].vconn_en) { - reply_sop_en |= ANX74XX_REG_REPLY_SOP_1_EN | - ANX74XX_REG_REPLY_SOP_2_EN; - } -#endif - } - - tcpc_write(port, ANX74XX_REG_TX_AUTO_GOODCRC_2, reply_sop_en); -} - -static void anx74xx_update_cable_det(int port, int mode) -{ -#ifdef CONFIG_USB_PD_TCPC_LOW_POWER - int reg; - - if (anx[port].prev_mode == mode) - return; - - /* Update power mode */ - anx[port].prev_mode = mode; - - /* Get ANALOG_CTRL_0 for cable det bit */ - if (tcpc_read(port, ANX74XX_REG_ANALOG_CTRL_0, ®)) - return; - - if (mode == ANX74XX_STANDBY_MODE) { - int cc_reg; - - /* - * The ANX4329 enters standby mode by setting PWR_EN signal - * low. In addition, RESET_L must be set low to keep the ANX3429 - * in standby mode. - * - * Clearing bit 7 of ANX74XX_REG_ANALOG_CTRL_0 will cause the - * ANX3429 to clear the cable_det signal that goes from the - * ANX3429 to the EC. If this bit is cleared when a cable is - * attached then cable_det will go high once standby is entered. - * - * In some cases, such as when the chipset power state is - * S3/S5/G3 and a sink only adapter is connected to the port, - * this behavior is undesirable. The constant toggling between - * standby and normal mode means that effectively the ANX3429 is - * not in standby mode only consumes ~1 mW less than just - * remaining in normal mode. However when an E mark cable is - * connected, clearing bit 7 is required so that while the E - * mark cable configuration happens, the USB PD state machine - * will continue to wake up until the USB PD attach event can be - * regtistered. - * - * Therefore, the decision to clear bit 7 is based on the - * current CC status of the port. If the CC status is open for - * both CC lines OR if either CC line is showing Ra, then clear - * bit 7. Not clearing bit 7 has no impact for normal cables and - * prevents the constant toggle of standby<->normal when an - * adapter is connected that isn't allowed to attach. Clearing - * bit 7 when CC status reads Ra for either CC line allows the - * USB PD state machine to be woken until the attach event can - * happen. Note that in the case an E mark cable is connected - * and can't attach (i.e. sink only port <- Emark cable -> sink - * only adapter), then the ANX3429 will toggle indefinitely, - * until either the cable is removed, or the port drp status - * changes so the attach event can occur. - * . - */ - - /* Read CC status to see if cable_det bit should be cleared */ - if (tcpc_read(port, ANX74XX_REG_CC_STATUS, &cc_reg)) - return; - /* If open or either CC line is Ra, then clear cable_det */ - if (!cc_reg || (cc_reg & ANX74XX_CC_RA_MASK && - !(cc_reg & ANX74XX_CC_RD_MASK))) - reg &= ~ANX74XX_REG_R_PIN_CABLE_DET; - } else { - reg |= ANX74XX_REG_R_PIN_CABLE_DET; - } - - tcpc_write(port, ANX74XX_REG_ANALOG_CTRL_0, reg); -#endif -} - -static void anx74xx_set_power_mode(int port, int mode) -{ - /* - * Update PWR_EN and RESET_N signals to the correct level. High for - * Normal mode and low for Standby mode. When transitioning from standby - * to normal mode, must set the PWR_EN and RESET_N before attempting to - * modify cable_det bit of analog_ctrl_0. If going from Normal to - * Standby, updating analog_ctrl_0 must happen before setting PWR_EN and - * RESET_N low. - */ - if (mode == ANX74XX_NORMAL_MODE) { - /* Take chip out of standby mode */ - board_set_tcpc_power_mode(port, mode); - /* Update the cable det signal */ - anx74xx_update_cable_det(port, mode); - } else { - /* Update cable cable det signal */ - anx74xx_update_cable_det(port, mode); - /* - * Delay between setting cable_det low and setting RESET_L low - * as recommended the ANX3429 datasheet. - */ - msleep(1); - /* Put chip into standby mode */ - board_set_tcpc_power_mode(port, mode); - } -} - -#if defined(CONFIG_USB_PD_DUAL_ROLE_AUTO_TOGGLE) && \ - defined(CONFIG_USB_PD_TCPC_LOW_POWER) - -static int anx74xx_tcpc_drp_toggle(int port) -{ - /* - * The ANX3429 always auto-toggles when in low power mode. Since this is - * not configurable, there is nothing to do here. DRP auto-toggle will - * happen once low power mode is set via anx74xx_enter_low_power_mode(). - * Note: this means the ANX3429 auto-toggles in PD_DRP_FORCE_SINK mode, - * which is undesirable (b/72007056). - */ - return EC_SUCCESS; -} - -static int anx74xx_enter_low_power_mode(int port) -{ - anx74xx_set_power_mode(port, ANX74XX_STANDBY_MODE); - return EC_SUCCESS; -} - -#endif - -void anx74xx_tcpc_set_vbus(int port, int enable) -{ - int reg; - - tcpc_read(port, ANX74XX_REG_GPIO_CTRL_4_5, ®); - if (enable) - reg |= ANX74XX_REG_SET_VBUS; - else - reg &= ~ANX74XX_REG_SET_VBUS; - tcpc_write(port, ANX74XX_REG_GPIO_CTRL_4_5, reg); -} - -#ifdef CONFIG_USB_PD_DISCHARGE_TCPC -static void anx74xx_tcpc_discharge_vbus(int port, int enable) -{ - int reg; - - tcpc_read(port, ANX74XX_REG_HPD_CTRL_0, ®); - if (enable) - reg |= ANX74XX_REG_DISCHARGE_CTRL; - else - reg &= ~ANX74XX_REG_DISCHARGE_CTRL; - tcpc_write(port, ANX74XX_REG_HPD_CTRL_0, reg); -} -#endif - -/* - * timestamp of the next possible toggle to ensure the 2-ms spacing - * between IRQ_HPD. - */ -static uint64_t hpd_deadline[CONFIG_USB_PD_PORT_MAX_COUNT]; - -void anx74xx_tcpc_update_hpd_status(int port, int hpd_lvl, int hpd_irq) -{ - int reg; - - mux_read(port, ANX74XX_REG_HPD_CTRL_0, ®); - if (hpd_lvl) - reg |= ANX74XX_REG_HPD_OUT_DATA; - else - reg &= ~ANX74XX_REG_HPD_OUT_DATA; - mux_write(port, ANX74XX_REG_HPD_CTRL_0, reg); - - if (hpd_irq) { - uint64_t now = get_time().val; - /* wait for the minimum spacing between IRQ_HPD if needed */ - if (now < hpd_deadline[port]) - usleep(hpd_deadline[port] - now); - - mux_read(port, ANX74XX_REG_HPD_CTRL_0, ®); - reg &= ~ANX74XX_REG_HPD_OUT_DATA; - mux_write(port, ANX74XX_REG_HPD_CTRL_0, reg); - usleep(HPD_DSTREAM_DEBOUNCE_IRQ); - reg |= ANX74XX_REG_HPD_OUT_DATA; - mux_write(port, ANX74XX_REG_HPD_CTRL_0, reg); - } - /* enforce 2-ms delay between HPD pulses */ - hpd_deadline[port] = get_time().val + HPD_USTREAM_DEBOUNCE_LVL; -} - -void anx74xx_tcpc_clear_hpd_status(int port) -{ - int reg; - - tcpc_read(port, ANX74XX_REG_HPD_CTRL_0, ®); - reg &= 0xcf; - tcpc_write(port, ANX74XX_REG_HPD_CTRL_0, reg); -} - -#ifdef CONFIG_USB_PD_TCPM_MUX -static int anx74xx_tcpm_mux_init(int port) -{ - /* Nothing to do here, ANX initializes its muxes - * as (MUX_USB_ENABLED | MUX_DP_ENABLED) - */ - anx[port].mux_state = MUX_USB_ENABLED | MUX_DP_ENABLED; - - return EC_SUCCESS; -} - -static int anx74xx_tcpm_mux_enter_safe_mode(int port) -{ - int reg; - - if (mux_read(port, ANX74XX_REG_ANALOG_CTRL_2, ®)) - return EC_ERROR_UNKNOWN; - if (mux_write(port, ANX74XX_REG_ANALOG_CTRL_2, reg | - ANX74XX_REG_MODE_TRANS)) - return EC_ERROR_UNKNOWN; - - - return EC_SUCCESS; -} - -static int anx74xx_tcpm_mux_exit_safe_mode(int port) -{ - int reg; - - if (mux_read(port, ANX74XX_REG_ANALOG_CTRL_2, ®)) - return EC_ERROR_UNKNOWN; - if (mux_write(port, ANX74XX_REG_ANALOG_CTRL_2, reg & - ~ANX74XX_REG_MODE_TRANS)) - return EC_ERROR_UNKNOWN; - - - return EC_SUCCESS; -} - -static int anx74xx_tcpm_mux_exit(int port) -{ - int reg; - - /* - * Safe mode must be entered before any changes are made to the mux - * settings used to enable ALT_DP mode. This funciton is called either - * from anx74xx_tcpm_mux_set when TYPEC_MUX_NONE is selected as the new - * mux state, or when both cc lines are determined to be - * TYPEC_CC_VOLT_OPEN. Therefore, safe mode must be entered and exited - * here so that both entry paths are handled. - */ - if (anx74xx_tcpm_mux_enter_safe_mode(port)) - return EC_ERROR_UNKNOWN; - - /* Disconnect aux from sbu */ - if (mux_read(port, ANX74XX_REG_ANALOG_CTRL_2, ®)) - return EC_ERROR_UNKNOWN; - if (mux_write(port, ANX74XX_REG_ANALOG_CTRL_2, reg & 0xf)) - return EC_ERROR_UNKNOWN; - - /* Clear Bit[7:0] R_SWITCH */ - if (mux_write(port, ANX74XX_REG_ANALOG_CTRL_1, 0x0)) - return EC_ERROR_UNKNOWN; - /* Clear Bit[7:4] R_SWITCH_H */ - if (mux_read(port, ANX74XX_REG_ANALOG_CTRL_5, ®)) - return EC_ERROR_UNKNOWN; - if (mux_write(port, ANX74XX_REG_ANALOG_CTRL_5, reg & 0x0f)) - return EC_ERROR_UNKNOWN; - - /* Exit safe mode */ - if (anx74xx_tcpm_mux_exit_safe_mode(port)) - return EC_ERROR_UNKNOWN; - - return EC_SUCCESS; -} - - -static int anx74xx_mux_aux_to_sbu(int port, int polarity, int enabled) -{ - int reg; - const int aux_mask = ANX74XX_REG_AUX_SWAP_SET_CC2 | - ANX74XX_REG_AUX_SWAP_SET_CC1; - - /* - * Get the current value of analog_ctrl_2 register. Note, that safe mode - * is enabled and exited by the calling function, so only have to worry - * about setting the correct value for the upper 4 bits of analog_ctrl_2 - * here. - */ - if (mux_read(port, ANX74XX_REG_ANALOG_CTRL_2, ®)) - return EC_ERROR_UNKNOWN; - - /* Assume aux_p/n lines are not connected */ - reg &= ~aux_mask; - - if (enabled) { - /* If enabled, connect aux to sbu based on desired polarity */ - if (polarity) - reg |= ANX74XX_REG_AUX_SWAP_SET_CC2; - else - reg |= ANX74XX_REG_AUX_SWAP_SET_CC1; - } - /* Write new aux <-> sbu settings */ - if (mux_write(port, ANX74XX_REG_ANALOG_CTRL_2, reg)) - return EC_ERROR_UNKNOWN; - - return EC_SUCCESS; -} - -static int anx74xx_tcpm_mux_set(int i2c_addr, mux_state_t mux_state) -{ - int ctrl5; - int ctrl1 = 0; - int rv; - int port = i2c_addr; - - if (!(mux_state & ~MUX_POLARITY_INVERTED)) { - anx[port].mux_state = mux_state; - return anx74xx_tcpm_mux_exit(port); - } - - rv = mux_read(port, ANX74XX_REG_ANALOG_CTRL_5, &ctrl5); - if (rv) - return EC_ERROR_UNKNOWN; - ctrl5 &= 0x0f; - - if (mux_state & MUX_USB_ENABLED) { - /* Connect USB SS switches */ - if (mux_state & MUX_POLARITY_INVERTED) { - ctrl1 = ANX74XX_REG_MUX_SSRX_RX2; - ctrl5 |= ANX74XX_REG_MUX_SSTX_TX2; - } else { - ctrl1 = ANX74XX_REG_MUX_SSRX_RX1; - ctrl5 |= ANX74XX_REG_MUX_SSTX_TX1; - } - if (mux_state & MUX_DP_ENABLED) { - /* Set pin assignment D */ - if (mux_state & MUX_POLARITY_INVERTED) - ctrl1 |= (ANX74XX_REG_MUX_ML0_RX1 | - ANX74XX_REG_MUX_ML1_TX1); - else - ctrl1 |= (ANX74XX_REG_MUX_ML0_RX2 | - ANX74XX_REG_MUX_ML1_TX2); - } - /* Keep ML0/ML1 unconnected if DP is not enabled */ - } else if (mux_state & MUX_DP_ENABLED) { - /* Set pin assignment C */ - if (mux_state & MUX_POLARITY_INVERTED) { - ctrl1 = (ANX74XX_REG_MUX_ML0_RX1 | - ANX74XX_REG_MUX_ML1_TX1 | - ANX74XX_REG_MUX_ML3_RX2); - ctrl5 |= ANX74XX_REG_MUX_ML2_TX2; - } else { - ctrl1 = (ANX74XX_REG_MUX_ML0_RX2 | - ANX74XX_REG_MUX_ML1_TX2 | - ANX74XX_REG_MUX_ML3_RX1); - ctrl5 |= ANX74XX_REG_MUX_ML2_TX1; - } - } else if (!mux_state) { - return anx74xx_tcpm_mux_exit(port); - } else { - return EC_ERROR_UNIMPLEMENTED; - } - - /* - * Safe mode must be entererd prior to any changes to the mux related to - * ALT_DP mode. Therefore, first enable safe mode prior to updating the - * values for analog_ctrl_1, analog_ctrl_5, and analog_ctrl_2. - */ - if (anx74xx_tcpm_mux_enter_safe_mode(port)) - return EC_ERROR_UNKNOWN; - - /* Write updated pin assignment */ - rv = mux_write(port, ANX74XX_REG_ANALOG_CTRL_1, ctrl1); - /* Write Rswitch config bits */ - rv |= mux_write(port, ANX74XX_REG_ANALOG_CTRL_5, ctrl5); - if (rv) - return EC_ERROR_UNKNOWN; - - /* Configure DP aux to sbu settings */ - if (anx74xx_mux_aux_to_sbu(port, mux_state & MUX_POLARITY_INVERTED, - mux_state & MUX_DP_ENABLED)) - return EC_ERROR_UNKNOWN; - - /* Exit safe mode */ - if (anx74xx_tcpm_mux_exit_safe_mode(port)) - return EC_ERROR_UNKNOWN; - - anx[port].mux_state = mux_state; - - return EC_SUCCESS; -} - -/* current mux state */ -static int anx74xx_tcpm_mux_get(int port, mux_state_t *mux_state) -{ - *mux_state = anx[port].mux_state; - - return EC_SUCCESS; -} - -const struct usb_mux_driver anx74xx_tcpm_usb_mux_driver = { - .init = anx74xx_tcpm_mux_init, - .set = anx74xx_tcpm_mux_set, - .get = anx74xx_tcpm_mux_get, -}; -#endif /* CONFIG_USB_PD_TCPM_MUX */ - -static int anx74xx_init_analog(int port) -{ - int reg, rv = EC_SUCCESS; - - /* Analog settings for chip */ - rv |= tcpc_write(port, ANX74XX_REG_HPD_CONTROL, - ANX74XX_REG_HPD_OP_MODE); - rv |= tcpc_write(port, ANX74XX_REG_HPD_CTRL_0, - ANX74XX_REG_HPD_DEFAULT); - if (rv) - return rv; - rv = tcpc_read(port, ANX74XX_REG_GPIO_CTRL_4_5, ®); - if (rv) - return rv; - reg &= ANX74XX_REG_VBUS_GPIO_MODE; - reg |= ANX74XX_REG_VBUS_OP_ENABLE; - rv = tcpc_write(port, ANX74XX_REG_GPIO_CTRL_4_5, reg); - if (rv) - return rv; - rv = tcpc_read(port, ANX74XX_REG_CC_SOFTWARE_CTRL, ®); - if (rv) - return rv; - reg |= ANX74XX_REG_TX_MODE_ENABLE; - rv = tcpc_write(port, ANX74XX_REG_CC_SOFTWARE_CTRL, reg); - - return rv; -} - -static int anx74xx_send_message(int port, uint16_t header, - const uint32_t *payload, - int type, - uint8_t len) -{ - int reg, rv = EC_SUCCESS; - uint8_t *buf = NULL; - int num_retry = 0, i = 0; - /* If sending Soft_reset, clear received message */ - /* Soft Reset Message type = 1101 and Number of Data Object = 0 */ - if ((header & 0x700f) == 0x000d) { - /* - * When sending soft reset, - * the Rx buffer of ANX3429 shall be clear - */ - rv = tcpc_read(port, ANX74XX_REG_CTRL_FW, ®); - rv |= tcpc_write( - port, ANX74XX_REG_CTRL_FW, reg | CLEAR_RX_BUFFER); - if (rv) - return EC_ERROR_UNKNOWN; - tcpc_write(port, ANX74XX_REG_RECVD_MSG_INT, 0xFF); - } - /* Inform chip about message length and TX type - * type->bit-0..2, len->bit-3..7 - */ - reg = (len << 3) & 0xf8; - reg |= type & 0x07; - rv |= tcpc_write(port, ANX74XX_REG_TX_CTRL_2, reg); - if (rv) - return EC_ERROR_UNKNOWN; - - /* Enqueue Header */ - rv = tcpc_write(port, ANX74XX_REG_TX_HEADER_L, (header & 0xff)); - if (rv) - return EC_ERROR_UNKNOWN; - rv = tcpc_write(port, ANX74XX_REG_TX_HEADER_H, (header >> 8)); - if (rv) - return EC_ERROR_UNKNOWN; - /* Enqueue payload */ - if (len > 2) { - len -= 2; - buf = (uint8_t *)payload; - while (1) { - if (i < 18) - rv = tcpc_write(port, - ANX74XX_REG_TX_START_ADDR_0 + i, - *buf); - else - rv = tcpc_write(port, - ANX74XX_REG_TX_START_ADDR_1 + i - 18, - *buf); - if (rv) { - num_retry++; - } else { - buf++; - len--; - num_retry = 0; - i++; - } - if (len == 0 || num_retry >= 3) - break; - } - /* If enqueue failed, do not request anx to transmit - * messages, FIFO will get cleared in next call - * before enqueue. - * num_retry = 0, refer to success - */ - if (num_retry) - return EC_ERROR_UNKNOWN; - } - /* Request a data transmission - * This bit will be cleared by ANX after TX success - */ - rv = tcpc_read(port, ANX74XX_REG_CTRL_COMMAND, ®); - if (rv) - return EC_ERROR_UNKNOWN; - reg |= ANX74XX_REG_TX_SEND_DATA_REQ; - rv |= tcpc_write(port, ANX74XX_REG_CTRL_COMMAND, reg); - - return rv; -} - -static int anx74xx_read_pd_obj(int port, - uint8_t *buf, - int plen) -{ - int rv = EC_SUCCESS, i; - int reg, addr = ANX74XX_REG_PD_RX_DATA_OBJ; - - /* Read PD data objects from ANX */ - for (i = 0; i < plen ; i++) { - /* Register sequence changes for last two bytes, if - * plen is greater than 26 - */ - if (i == 26) - addr = ANX74XX_REG_PD_RX_DATA_OBJ_M; - rv = tcpc_read(port, addr + i, ®); - if (rv) - break; - buf[i] = reg; - } - clear_recvd_msg_int(port); - return rv; -} - -static int anx74xx_check_cc_type(int cc_reg) -{ - int cc; - - switch (cc_reg & ANX74XX_REG_CC_STATUS_MASK) { - case BIT_VALUE_OF_SRC_CC_RD: - cc = TYPEC_CC_VOLT_RD; - break; - - case BIT_VALUE_OF_SRC_CC_RA: - cc = TYPEC_CC_VOLT_RA; - break; - - case BIT_VALUE_OF_SNK_CC_DEFAULT: - cc = TYPEC_CC_VOLT_RP_DEF; - break; - - case BIT_VALUE_OF_SNK_CC_1_P_5: - cc = TYPEC_CC_VOLT_RP_1_5; - break; - - case BIT_VALUE_OF_SNK_CC_3_P_0: - cc = TYPEC_CC_VOLT_RP_3_0; - break; - - default: - /* If no bits are set, then nothing is attached */ - cc = TYPEC_CC_VOLT_OPEN; - } - - return cc; -} - -static int anx74xx_tcpm_get_cc(int port, enum tcpc_cc_voltage_status *cc1, - enum tcpc_cc_voltage_status *cc2) -{ - int rv = EC_SUCCESS; - int reg = 0; - - /* Read tcpc cc status register */ - rv |= tcpc_read(port, ANX74XX_REG_CC_STATUS, ®); - /* Check for cc1 type */ - *cc1 = anx74xx_check_cc_type(reg); - /* - * Check for cc2 type (note cc2 bits are upper 4 of cc status - * register. - */ - *cc2 = anx74xx_check_cc_type(reg >> 4); - - /* clear HPD status*/ - if (!(*cc1) && !(*cc2)) { - anx74xx_tcpc_clear_hpd_status(port); -#ifdef CONFIG_USB_PD_TCPM_MUX - anx74xx_tcpm_mux_exit(port); -#endif - } - - return EC_SUCCESS; -} - -static int anx74xx_rp_control(int port, int rp) -{ - int reg; - int rv; - - rv = tcpc_read(port, ANX74XX_REG_ANALOG_CTRL_6, ®); - if (rv) - return EC_ERROR_UNKNOWN; - - /* clear Bit[0,1] R_RP to default Rp's value */ - reg &= ~0x03; - - switch (rp) { - case TYPEC_RP_1A5: - /* Set Rp strength to 12K for presenting 1.5A */ - reg |= ANX74XX_REG_CC_PULL_RP_12K; - break; - case TYPEC_RP_3A0: - /* Set Rp strength to 4K for presenting 3A */ - reg |= ANX74XX_REG_CC_PULL_RP_4K; - break; - case TYPEC_RP_USB: - default: - /* default: Set Rp strength to 36K */ - break; - } - - return tcpc_write(port, ANX74XX_REG_ANALOG_CTRL_6, reg); -} - -static int anx74xx_tcpm_select_rp_value(int port, int rp) -{ - /* For ANX3429 cannot get cc correctly when Rp != USB_Default */ - selected_rp[port] = rp; - return EC_SUCCESS; -} - - -static int anx74xx_cc_software_ctrl(int port, int enable) -{ - int rv; - int reg; - - rv = tcpc_read(port, ANX74XX_REG_CC_SOFTWARE_CTRL, ®); - if (rv) - return EC_ERROR_UNKNOWN; - - if (enable) - reg |= ANX74XX_REG_CC_SW_CTRL_ENABLE; - else - reg &= ~ANX74XX_REG_CC_SW_CTRL_ENABLE; - - rv |= tcpc_write(port, ANX74XX_REG_CC_SOFTWARE_CTRL, reg); - return rv; -} - -static int anx74xx_tcpm_set_cc(int port, int pull) -{ - int rv = EC_SUCCESS; - int reg; - - /* Enable CC software Control */ - rv = anx74xx_cc_software_ctrl(port, 1); - if (rv) - return EC_ERROR_UNKNOWN; - - switch (pull) { - case TYPEC_CC_RP: - /* Enable Rp */ - rv |= tcpc_read(port, ANX74XX_REG_ANALOG_STATUS, ®); - if (rv) - return EC_ERROR_UNKNOWN; - reg |= ANX74XX_REG_CC_PULL_RP; - rv |= tcpc_write(port, ANX74XX_REG_ANALOG_STATUS, reg); - break; - case TYPEC_CC_RD: - /* Enable Rd */ - rv |= tcpc_read(port, ANX74XX_REG_ANALOG_STATUS, ®); - if (rv) - return EC_ERROR_UNKNOWN; - reg &= ANX74XX_REG_CC_PULL_RD; - rv |= tcpc_write(port, ANX74XX_REG_ANALOG_STATUS, reg); - break; - default: - rv = EC_ERROR_UNKNOWN; - break; - } - - return rv; -} - -static int anx74xx_tcpm_set_polarity(int port, int polarity) -{ - int reg, mux_state, rv = EC_SUCCESS; - - rv |= tcpc_read(port, ANX74XX_REG_CC_SOFTWARE_CTRL, ®); - if (polarity) /* Inform ANX to use CC2 */ - reg &= ~ANX74XX_REG_SELECT_CC1; - else /* Inform ANX to use CC1 */ - reg |= ANX74XX_REG_SELECT_CC1; - rv |= tcpc_write(port, ANX74XX_REG_CC_SOFTWARE_CTRL, reg); - - anx[port].polarity = polarity; - - /* Update mux polarity */ -#ifdef CONFIG_USB_PD_TCPM_MUX - mux_state = anx[port].mux_state & ~MUX_POLARITY_INVERTED; - if (polarity) - mux_state |= MUX_POLARITY_INVERTED; - anx74xx_tcpm_mux_set(port, mux_state); -#endif - return rv; -} - -static int anx74xx_tcpm_set_vconn(int port, int enable) -{ - int reg, rv = EC_SUCCESS; - - /* switch VCONN to Non CC line */ - rv |= tcpc_read(port, ANX74XX_REG_INTP_VCONN_CTRL, ®); - if (rv) - return EC_ERROR_UNKNOWN; - if (enable) { - if (anx[port].polarity) - reg |= ANX74XX_REG_VCONN_1_ENABLE; - else - reg |= ANX74XX_REG_VCONN_2_ENABLE; - } else { - reg &= ANX74XX_REG_VCONN_DISABLE; - } - rv |= tcpc_write(port, ANX74XX_REG_INTP_VCONN_CTRL, reg); - anx[port].vconn_en = enable; - -#ifdef CONFIG_USB_PD_DECODE_SOP - rv |= tcpc_read(port, ANX74XX_REG_TX_AUTO_GOODCRC_2, ®); - if (rv) - return EC_ERROR_UNKNOWN; - - if (reg & ANX74XX_REG_REPLY_SOP_EN) { - if (enable) { - reg |= ANX74XX_REG_REPLY_SOP_1_EN | - ANX74XX_REG_REPLY_SOP_2_EN; - } else { - reg &= ~(ANX74XX_REG_REPLY_SOP_1_EN | - ANX74XX_REG_REPLY_SOP_2_EN); - } - - tcpc_write(port, ANX74XX_REG_TX_AUTO_GOODCRC_2, reg); - } -#endif - return rv; -} - -static int anx74xx_tcpm_set_msg_header(int port, int power_role, int data_role) -{ - return tcpc_write(port, ANX74XX_REG_TX_AUTO_GOODCRC_1, - ANX74XX_REG_AUTO_GOODCRC_SET(!!data_role, !!power_role)); -} - -static int anx74xx_tcpm_set_rx_enable(int port, int enable) -{ - int reg, rv; - - rv = tcpc_read(port, ANX74XX_REG_IRQ_SOURCE_RECV_MSG_MASK, ®); - if (rv) - return rv; - if (enable) { - reg &= ~(ANX74XX_REG_IRQ_CC_MSG_INT); - anx74xx_tcpm_set_auto_good_crc(port, 1); - anx74xx_rp_control(port, selected_rp[port]); - } else { - /* Disable RX message by masking interrupt */ - reg |= (ANX74XX_REG_IRQ_CC_MSG_INT); - anx74xx_tcpm_set_auto_good_crc(port, 0); - anx74xx_rp_control(port, TYPEC_RP_USB); - } - /*When this function was call, the interrupt status shall be cleared*/ - tcpc_write(port, ANX74XX_REG_IRQ_SOURCE_RECV_MSG, 0); - - return tcpc_write(port, ANX74XX_REG_IRQ_SOURCE_RECV_MSG_MASK, reg); -} - -#ifdef CONFIG_USB_PD_VBUS_DETECT_TCPC -static int anx74xx_tcpm_get_vbus_level(int port) -{ - int reg = 0; - - tcpc_read(port, ANX74XX_REG_ANALOG_STATUS, ®); - return ((reg & ANX74XX_REG_VBUS_STATUS) ? 1 : 0); -} -#endif - -static int anx74xx_tcpm_get_message_raw(int port, uint32_t *payload, int *head) -{ - int reg; - int len; - - /* Fetch the header */ - if (tcpc_read16(port, ANX74XX_REG_PD_HEADER, ®)) { - clear_recvd_msg_int(port); - return EC_ERROR_UNKNOWN; - } - *head = reg; -#ifdef CONFIG_USB_PD_DECODE_SOP - *head |= PD_HEADER_SOP(msg_sop[port]); -#endif - - len = PD_HEADER_CNT(*head) * 4; - if (!len) { - clear_recvd_msg_int(port); - return EC_SUCCESS; - } - - /* Receive message : assuming payload have enough - * memory allocated - */ - return anx74xx_read_pd_obj(port, (uint8_t *)payload, len); -} - -static int anx74xx_tcpm_transmit(int port, enum tcpm_transmit_type type, - uint16_t header, - const uint32_t *data) -{ - uint8_t len = 0; - int ret = 0, reg = 0; - - switch (type) { - /* ANX is aware of type */ - case TCPC_TX_SOP: - case TCPC_TX_SOP_PRIME: - case TCPC_TX_SOP_PRIME_PRIME: - len = PD_HEADER_CNT(header) * 4 + 2; - ret = anx74xx_send_message(port, header, - data, type, len); - break; - case TCPC_TX_HARD_RESET: - /* Request HARD RESET */ - tcpc_read(port, ANX74XX_REG_TX_CTRL_1, ®); - reg |= ANX74XX_REG_TX_HARD_RESET_REQ; - ret = tcpc_write(port, ANX74XX_REG_TX_CTRL_1, reg); - /*After Hard Reset, TCPM shall disable goodCRC*/ - anx74xx_tcpm_set_auto_good_crc(port, 0); - break; - case TCPC_TX_CABLE_RESET: - /* Request CABLE RESET */ - tcpc_read(port, ANX74XX_REG_TX_CTRL_1, ®); - reg |= ANX74XX_REG_TX_CABLE_RESET_REQ; - ret = tcpc_write(port, ANX74XX_REG_TX_CTRL_1, reg); - break; - case TCPC_TX_BIST_MODE_2: - /* Request BIST MODE 2 */ - reg = ANX74XX_REG_TX_BIST_START - | ANX74XX_REG_TX_BIXT_FOREVER | (0x02 << 4); - ret = tcpc_write(port, ANX74XX_REG_TX_BIST_CTRL, reg); - msleep(1); - ret = tcpc_write(port, ANX74XX_REG_TX_BIST_CTRL, - reg | ANX74XX_REG_TX_BIST_ENABLE); - msleep(30); - tcpc_read(port, ANX74XX_REG_TX_BIST_CTRL, ®); - ret = tcpc_write(port, ANX74XX_REG_TX_BIST_CTRL, - reg | ANX74XX_REG_TX_BIST_STOP); - ret = tcpc_write(port, ANX74XX_REG_TX_BIST_CTRL, - reg & (~ANX74XX_REG_TX_BIST_STOP)); - ret = tcpc_write(port, ANX74XX_REG_TX_BIST_CTRL, 0); - break; - default: - return EC_ERROR_UNIMPLEMENTED; - } - - return ret; -} - -/* - * Don't let the TCPC try to pull from the RX buffer forever. We typical only - * have 1 or 2 messages waiting. - */ -#define MAX_ALLOW_FAILED_RX_READS 10 - -void anx74xx_tcpc_alert(int port) -{ - int reg; - int failed_attempts; - - /* Clear soft irq bit */ - tcpc_write(port, ANX74XX_REG_IRQ_EXT_SOURCE_3, - ANX74XX_REG_CLEAR_SOFT_IRQ); - - /* Read main alert register for pending alerts */ - reg = 0; - tcpc_read(port, ANX74XX_REG_IRQ_SOURCE_RECV_MSG, ®); - - /* Prioritize TX completion because PD state machine is waiting */ - if (reg & ANX74XX_REG_IRQ_GOOD_CRC_INT) - pd_transmit_complete(port, TCPC_TX_COMPLETE_SUCCESS); - - if (reg & ANX74XX_REG_IRQ_TX_FAIL_INT) - pd_transmit_complete(port, TCPC_TX_COMPLETE_FAILED); - - /* Pull all RX messages from TCPC into EC memory */ - failed_attempts = 0; - while (reg & ANX74XX_REG_IRQ_CC_MSG_INT) { - if (tcpm_enqueue_message(port)) - ++failed_attempts; - if (tcpc_read(port, ANX74XX_REG_IRQ_SOURCE_RECV_MSG, ®)) - ++failed_attempts; - - /* Ensure we don't loop endlessly */ - if (failed_attempts >= MAX_ALLOW_FAILED_RX_READS) { - CPRINTF("C%d Cannot consume RX buffer after %d failed " - "attempts!", port, failed_attempts); - /* - * The port is in a bad state, we don't want to consume - * all EC resources so suspend the port for a little - * while. - */ - pd_set_suspend(port, 1); - pd_deferred_resume(port); - return; - } - } - - /* Clear all pending alerts */ - tcpc_write(port, ANX74XX_REG_RECVD_MSG_INT, reg); - - if (reg & ANX74XX_REG_IRQ_CC_STATUS_INT) - /* CC status changed, wake task */ - task_set_event(PD_PORT_TO_TASK_ID(port), PD_EVENT_CC, 0); - - /* Read and clear extended alert register 1 */ - reg = 0; - tcpc_read(port, ANX74XX_REG_IRQ_EXT_SOURCE_1, ®); - tcpc_write(port, ANX74XX_REG_IRQ_EXT_SOURCE_1, reg); - -#ifdef CONFIG_USB_PD_DECODE_SOP - if (reg & ANX74XX_REG_EXT_SOP) - msg_sop[port] = PD_MSG_SOP; - else if (reg & ANX74XX_REG_EXT_SOP_PRIME) - msg_sop[port] = PD_MSG_SOPP; -#endif - - /* Check for Hard Reset done bit */ - if (reg & ANX74XX_REG_ALERT_TX_HARD_RESETOK) - /* ANX hardware clears the request bit */ - pd_transmit_complete(port, TCPC_TX_COMPLETE_SUCCESS); - - /* Read and clear TCPC extended alert register 2 */ - reg = 0; - tcpc_read(port, ANX74XX_REG_IRQ_EXT_SOURCE_2, ®); - tcpc_write(port, ANX74XX_REG_IRQ_EXT_SOURCE_2, reg); - -#ifdef CONFIG_USB_PD_DECODE_SOP - if (reg & ANX74XX_REG_EXT_SOP_PRIME_PRIME) - msg_sop[port] = PD_MSG_SOPPP; -#endif - - if (reg & ANX74XX_REG_EXT_HARD_RST) { - /* hard reset received */ - pd_execute_hard_reset(port); - task_wake(PD_PORT_TO_TASK_ID(port)); - } -} - -static int anx74xx_tcpm_init(int port) -{ - int rv = 0, reg; - - memset(&anx[port], 0, sizeof(struct anx_state)); - /* Bring chip in normal mode to work */ - anx74xx_set_power_mode(port, ANX74XX_NORMAL_MODE); - - /* Initialize analog section of ANX */ - rv |= anx74xx_init_analog(port); - - /* disable all interrupts */ - rv |= tcpc_write(port, ANX74XX_REG_IRQ_EXT_MASK_1, - ANX74XX_REG_CLEAR_SET_BITS); - - /* Initialize interrupt open-drain */ - rv |= tcpc_read(port, ANX74XX_REG_INTP_VCONN_CTRL, ®); - if (tcpc_config[port].flags & TCPC_FLAGS_ALERT_OD) - reg |= ANX74XX_REG_R_INTERRUPT_OPEN_DRAIN; - else - reg &= ~ANX74XX_REG_R_INTERRUPT_OPEN_DRAIN; - rv |= tcpc_write(port, ANX74XX_REG_INTP_VCONN_CTRL, reg); - - /* Initialize interrupt polarity */ - reg = tcpc_config[port].flags & TCPC_FLAGS_ALERT_ACTIVE_HIGH ? - ANX74XX_REG_IRQ_POL_HIGH : ANX74XX_REG_IRQ_POL_LOW; - rv |= tcpc_write(port, ANX74XX_REG_IRQ_STATUS, reg); - - /* unmask interrupts */ - rv |= tcpc_read(port, ANX74XX_REG_IRQ_EXT_MASK_1, ®); - reg &= (~ANX74XX_REG_ALERT_TX_MSG_ERROR); - reg &= (~ANX74XX_REG_ALERT_TX_CABLE_RESETOK); - reg &= (~ANX74XX_REG_ALERT_TX_HARD_RESETOK); - rv |= tcpc_write(port, ANX74XX_REG_IRQ_EXT_MASK_1, reg); - - rv |= tcpc_read(port, ANX74XX_REG_IRQ_EXT_MASK_2, ®); - reg &= (~ANX74XX_REG_EXT_HARD_RST); - rv |= tcpc_write(port, ANX74XX_REG_IRQ_EXT_MASK_2, reg); - - /* HPD pin output enable*/ - rv |= tcpc_write(port, ANX74XX_REG_HPD_CTRL_0, ANX74XX_REG_HPD_DEFAULT); - - if (rv) - return EC_ERROR_UNKNOWN; - - /* Set AVDD10_BMC to 1.08 */ - rv |= tcpc_read(port, ANX74XX_REG_ANALOG_CTRL_5, ®); - if (rv) - return EC_ERROR_UNKNOWN; - rv = tcpc_write(port, ANX74XX_REG_ANALOG_CTRL_5, (reg & 0xf3)); - if (rv) - return EC_ERROR_UNKNOWN; - - /* Decrease BMC TX lowest swing voltage */ - rv |= tcpc_read(port, ANX74XX_REG_ANALOG_CTRL_11, ®); - if (rv) - return EC_ERROR_UNKNOWN; - rv = tcpc_write(port, ANX74XX_REG_ANALOG_CTRL_11, (reg & 0x3f) | 0x40); - if (rv) - return EC_ERROR_UNKNOWN; - - /* Set BMC TX cap slew rate to 400ns */ - rv = tcpc_write(port, ANX74XX_REG_ANALOG_CTRL_12, 0x4); - if (rv) - return EC_ERROR_UNKNOWN; - - tcpm_get_chip_info(port, 1, NULL); - - return EC_SUCCESS; -} - -static int anx74xx_get_chip_info(int port, int live, - struct ec_response_pd_chip_info_v1 **chip_info) -{ - int rv = tcpci_get_chip_info(port, live, chip_info); - int val; - - if (rv) - return rv; - - if ((*chip_info)->fw_version_number == 0 || - (*chip_info)->fw_version_number == -1 || live) { - rv = tcpc_read(port, ANX74XX_REG_FW_VERSION, &val); - - if (rv) - return rv; - - (*chip_info)->fw_version_number = val; - } - -#ifdef CONFIG_USB_PD_TCPM_ANX3429 - /* - * Min firmware version of ANX3429 to ensure that false SOP' detection - * doesn't occur for e-marked cables. See b/116255749#comment8 and - * b/64752060#comment11 - */ - (*chip_info)->min_req_fw_version_number = 0x16; -#endif - - return rv; -} - -/* - * Dissociate from the TCPC. - */ - -static int anx74xx_tcpm_release(int port) -{ - return EC_SUCCESS; -} - -const struct tcpm_drv anx74xx_tcpm_drv = { - .init = &anx74xx_tcpm_init, - .release = &anx74xx_tcpm_release, - .get_cc = &anx74xx_tcpm_get_cc, -#ifdef CONFIG_USB_PD_VBUS_DETECT_TCPC - .get_vbus_level = &anx74xx_tcpm_get_vbus_level, -#endif - .select_rp_value = &anx74xx_tcpm_select_rp_value, - .set_cc = &anx74xx_tcpm_set_cc, - .set_polarity = &anx74xx_tcpm_set_polarity, - .set_vconn = &anx74xx_tcpm_set_vconn, - .set_msg_header = &anx74xx_tcpm_set_msg_header, - .set_rx_enable = &anx74xx_tcpm_set_rx_enable, - .get_message_raw = &anx74xx_tcpm_get_message_raw, - .transmit = &anx74xx_tcpm_transmit, - .tcpc_alert = &anx74xx_tcpc_alert, -#ifdef CONFIG_USB_PD_DISCHARGE_TCPC - .tcpc_discharge_vbus = &anx74xx_tcpc_discharge_vbus, -#endif - .get_chip_info = &anx74xx_get_chip_info, -#if defined(CONFIG_USB_PD_DUAL_ROLE_AUTO_TOGGLE) && \ - defined(CONFIG_USB_PD_TCPC_LOW_POWER) - .drp_toggle = &anx74xx_tcpc_drp_toggle, - .enter_low_power_mode = &anx74xx_enter_low_power_mode, -#endif -}; - -#ifdef CONFIG_CMD_I2C_STRESS_TEST_TCPC -struct i2c_stress_test_dev anx74xx_i2c_stress_test_dev = { - .reg_info = { - .read_reg = ANX74XX_REG_VENDOR_ID_L, - .read_val = ANX74XX_VENDOR_ID & 0xFF, - .write_reg = ANX74XX_REG_CC_SOFTWARE_CTRL, - }, - .i2c_read = &tcpc_i2c_read, - .i2c_write = &tcpc_i2c_write, -}; -#endif /* CONFIG_CMD_I2C_STRESS_TEST_TCPC */ diff --git a/driver/tcpm/anx74xx.h b/driver/tcpm/anx74xx.h deleted file mode 100644 index 2648013abf..0000000000 --- a/driver/tcpm/anx74xx.h +++ /dev/null @@ -1,226 +0,0 @@ -/* Copyright 2016 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. - * - * Author : Analogix Semiconductor. - */ - -/* USB Power delivery port management */ - -#ifndef __CROS_EC_USB_PD_TCPM_ANX74XX_H -#define __CROS_EC_USB_PD_TCPM_ANX74XX_H - -/* I2C interface */ -#define ANX74XX_I2C_ADDR1_FLAGS 0x28 -#define ANX74XX_I2C_ADDR2_FLAGS 0x39 -#define ANX74XX_I2C_ADDR3_FLAGS 0x3E -#define ANX74XX_I2C_ADDR4_FLAGS 0x40 - -#define ANX74XX_REG_IRQ_POL_LOW 0x00 -#define ANX74XX_REG_IRQ_POL_HIGH 0x02 - -#define ANX74XX_REG_VENDOR_ID_L 0x00 -#define ANX74XX_REG_VENDOR_ID_H 0x01 -#define ANX74XX_VENDOR_ID 0xAAAA - -/* ANX F/W version:0x50:0x44 which contains otp firmware version */ -#define ANX74XX_REG_FW_VERSION 0x44 - -#define ANX74XX_REG_IRQ_STATUS 0x53 - -#define ANX74XX_REG_INTP_VCONN_CTRL 0x33 -#define ANX74XX_REG_VCONN_DISABLE 0x0f -#define ANX74XX_REG_VCONN_1_ENABLE BIT(4) -#define ANX74XX_REG_VCONN_2_ENABLE BIT(5) -#define ANX74XX_REG_R_INTERRUPT_OPEN_DRAIN BIT(2) - -#define ANX74XX_STANDBY_MODE (0) -#define ANX74XX_NORMAL_MODE (1) - -#define ANX74XX_REG_TX_CTRL_1 0x81 -#define ANX74XX_REG_TX_HARD_RESET_REQ BIT(1) -#define ANX74XX_REG_TX_CABLE_RESET_REQ BIT(2) - -#define ANX74XX_REG_TX_CTRL_2 0x82 -#define ANX74XX_REG_TX_WR_FIFO 0x83 -#define ANX74XX_REG_TX_FIFO_CTRL 0x9a -#define ANX74XX_REG_TX_HEADER_L 0x2c -#define ANX74XX_REG_TX_HEADER_H 0x2d -#define ANX74XX_REG_TX_START_ADDR_0 0x6d -#define ANX74XX_REG_TX_START_ADDR_1 0xd0 - -#define ANX74XX_REG_CTRL_COMMAND 0xdb -#define ANX74XX_REG_TX_SEND_DATA_REQ BIT(0) -#define ANX74XX_REG_TX_HARD_RST_REQ BIT(1) - -#define ANX74XX_REG_TX_BIST_CTRL 0x9D -#define ANX74XX_REG_TX_BIST_MODE BIT(4) -#define ANX74XX_REG_TX_BIST_STOP BIT(3) -#define ANX74XX_REG_TX_BIXT_FOREVER BIT(2) -#define ANX74XX_REG_TX_BIST_ENABLE BIT(1) -#define ANX74XX_REG_TX_BIST_START BIT(0) - -#define ANX74XX_REG_PD_HEADER 0x69 -#define ANX74XX_REG_PD_RX_DATA_OBJ 0x11 -#define ANX74XX_REG_PD_RX_DATA_OBJ_M 0x4d - -#define ANX74XX_REG_ANALOG_STATUS 0x40 -#define ANX74XX_REG_VBUS_STATUS BIT(4) -#define ANX74XX_REG_CC_PULL_RD 0xfd -#define ANX74XX_REG_CC_PULL_RP 0x02 - - -#define ANX74XX_REG_TX_AUTO_GOODCRC_2 0x94 -#define ANX74XX_REG_REPLY_SOP_EN BIT(3) -#define ANX74XX_REG_REPLY_SOP_1_EN BIT(4) -#define ANX74XX_REG_REPLY_SOP_2_EN BIT(5) - -#define ANX74XX_REG_TX_AUTO_GOODCRC_1 0x9c -#define ANX74XX_REG_SPEC_REV_BIT_POS (3) -#define ANX74XX_REG_DATA_ROLE_BIT_POS (2) -#define ANX74XX_REG_PWR_ROLE_BIT_POS (1) -#define ANX74XX_REG_AUTO_GOODCRC_EN BIT(0) -#define ANX74XX_REG_AUTO_GOODCRC_SET(drole, prole) \ - ((PD_REV20 << ANX74XX_REG_SPEC_REV_BIT_POS) | \ - ((drole) << ANX74XX_REG_DATA_ROLE_BIT_POS) | \ - ((prole) << ANX74XX_REG_PWR_ROLE_BIT_POS) | \ - ANX74XX_REG_AUTO_GOODCRC_EN) - - -#define ANX74XX_REG_ANALOG_CTRL_0 0x41 -#define ANX74XX_REG_R_PIN_CABLE_DET BIT(7) - -#define ANX74XX_REG_ANALOG_CTRL_1 0x42 -#define ANX74XX_REG_ANALOG_CTRL_5 0x46 -#define ANX74XX_REG_ANALOG_CTRL_6 0x47 -#define ANX74XX_REG_CC_PULL_RP_36K 0x00 -#define ANX74XX_REG_CC_PULL_RP_12K 0x01 -#define ANX74XX_REG_CC_PULL_RP_4K 0x02 - -#define ANX74XX_REG_R_SWITCH_CC_CLR 0x0f -#define ANX74XX_REG_R_SWITCH_CC2_SET 0x10 -#define ANX74XX_REG_R_SWITCH_CC1_SET 0x20 -#define ANX74XX_REG_AUX_SWAP_SET_CC1 0x30 -#define ANX74XX_REG_AUX_SWAP_SET_CC2 0xc0 - -#define ANX74XX_REG_ANALOG_CTRL_11 0x4c -#define ANX74XX_REG_ANALOG_CTRL_12 0x4d - -#define ANX74XX_REG_MUX_ML0_RX2 BIT(0) -#define ANX74XX_REG_MUX_ML0_RX1 BIT(1) -#define ANX74XX_REG_MUX_ML3_RX2 BIT(2) -#define ANX74XX_REG_MUX_ML3_RX1 BIT(3) -#define ANX74XX_REG_MUX_SSRX_RX2 BIT(4) -#define ANX74XX_REG_MUX_SSRX_RX1 BIT(5) -#define ANX74XX_REG_MUX_ML1_TX2 BIT(6) -#define ANX74XX_REG_MUX_ML1_TX1 BIT(7) - -#define ANX74XX_REG_MUX_ML2_TX2 BIT(4) -#define ANX74XX_REG_MUX_ML2_TX1 BIT(5) -#define ANX74XX_REG_MUX_SSTX_TX2 BIT(6) -#define ANX74XX_REG_MUX_SSTX_TX1 BIT(7) - -#define ANX74XX_REG_CC_SOFTWARE_CTRL 0x4a -#define ANX74XX_REG_CC_SW_CTRL_ENABLE 0x01 -#define ANX74XX_REG_TX_MODE_ENABLE 0x04 - -#define ANX74XX_REG_SELECT_CC1 0x02 - -#define ANX74XX_REG_GPIO_CTRL_4_5 0x3f -#define ANX74XX_REG_VBUS_OP_ENABLE 0x04 -#define ANX74XX_REG_VBUS_GPIO_MODE 0xfe - -#define ANX74XX_REG_IRQ_EXT_MASK_1 0x3b -#define ANX74XX_REG_IRQ_EXT_MASK_2 0x3c -#define ANX74XX_REG_IRQ_EXT_SOURCE_1 0x3e -#define ANX74XX_REG_EXT_SOP BIT(6) -#define ANX74XX_REG_EXT_SOP_PRIME BIT(7) -#define ANX74XX_REG_IRQ_EXT_SOURCE_2 0x4e -#define ANX74XX_REG_EXT_SOP_PRIME_PRIME BIT(0) -#define ANX74XX_REG_EXT_HARD_RST BIT(2) -#define ANX74XX_REG_IRQ_EXT_SOURCE_3 0x4f -#define ANX74XX_REG_CLEAR_SOFT_IRQ BIT(2) - -#define ANX74XX_REG_IRQ_SOURCE_RECV_MSG 0x6b -#define ANX74XX_REG_IRQ_CC_MSG_INT BIT(0) -#define ANX74XX_REG_IRQ_CC_STATUS_INT BIT(1) -#define ANX74XX_REG_IRQ_GOOD_CRC_INT BIT(2) -#define ANX74XX_REG_IRQ_TX_FAIL_INT BIT(3) -#define ANX74XX_REG_IRQ_SOURCE_RECV_MSG_MASK 0x6c - -#define ANX74XX_REG_CLEAR_SET_BITS 0xff -#define ANX74XX_REG_ALERT_HARD_RST_RECV BIT(6) -#define ANX74XX_REG_ALERT_MSG_RECV BIT(5) -#define ANX74XX_REG_ALERT_TX_MSG_ERROR BIT(4) -#define ANX74XX_REG_ALERT_TX_ACK_RECV BIT(3) -#define ANX74XX_REG_ALERT_TX_CABLE_RESETOK BIT(2) -#define ANX74XX_REG_ALERT_TX_HARD_RESETOK BIT(1) -#define ANX74XX_REG_ALERT_CC_CHANGE BIT(0) - -#define ANX74XX_REG_ANALOG_CTRL_2 0x43 -#define ANX74XX_REG_MODE_TRANS 0x01 - -#define ANX74XX_REG_SET_VBUS 0x20 - -#define ANX74XX_REG_ANALOG_CTRL_7 0x48 -#define ANX74XX_REG_STATUS_CC_RD 0x01 -#define ANX74XX_REG_STATUS_CC_RA 0x03 -#define ANX74XX_REG_STATUS_CC1(reg) ((reg & 0x0C) >> 2) -#define ANX74XX_REG_STATUS_CC2(reg) ((reg & 0x03) >> 0) - -#define ANX74XX_REG_HPD_CONTROL 0xfd - -#define ANX74XX_REG_HPD_CTRL_0 0x36 -#define ANX74XX_REG_DISCHARGE_CTRL 0x80 -#define ANX74XX_REG_HPD_OP_MODE 0x08 -#define ANX74XX_REG_HPD_DEFAULT 0x00 -#define ANX74XX_REG_HPD_OUT_DATA 0x10 - -#define ANX74XX_REG_RECVD_MSG_INT 0x98 -#define ANX74XX_REG_CC_STATUS 0x99 -#define ANX74XX_REG_CTRL_FW 0x2E -#define CLEAR_RX_BUFFER (1) -#define ANX74XX_REG_POWER_DOWN_CTRL 0x0d -#define ANX74XX_REG_STATUS_CC1_VRD_USB BIT(7) -#define ANX74XX_REG_STATUS_CC1_VRD_1P5 BIT(6) -#define ANX74XX_REG_STATUS_CC1_VRD_3P0 BIT(5) -#define ANX74XX_REG_STATUS_CC2_VRD_USB BIT(4) -#define ANX74XX_REG_STATUS_CC2_VRD_1P5 BIT(3) -#define ANX74XX_REG_STATUS_CC2_VRD_3P0 BIT(2) - -/* defined in the inter-bock Spec: 4.2.10 CC Detect Status */ -#define ANX74XX_REG_CC_STATUS_MASK 0xf -#define BIT_VALUE_OF_SRC_CC_RD 0x01 -#define BIT_VALUE_OF_SRC_CC_RA 0x02 -#define BIT_VALUE_OF_SNK_CC_DEFAULT 0x04 -#define BIT_VALUE_OF_SNK_CC_1_P_5 0x08 -#define BIT_VALUE_OF_SNK_CC_3_P_0 0x0C -#define ANX74XX_CC_RA_MASK (BIT_VALUE_OF_SRC_CC_RA | \ - (BIT_VALUE_OF_SRC_CC_RA << 4)) -#define ANX74XX_CC_RD_MASK (BIT_VALUE_OF_SRC_CC_RD | \ - (BIT_VALUE_OF_SRC_CC_RD << 4)) - -/* - * RESETN low to PWR_EN low delay - */ -#define ANX74XX_RST_L_PWR_L_DELAY_MS 1 -/* - * minimum power off-to-on delay to reset chip - */ -#define ANX74XX_PWR_L_PWR_H_DELAY_MS 10 -/* - * parameter T4: PWR_EN high to RESETN high delay - */ -#define ANX74XX_PWR_H_RST_H_DELAY_MS 10 - -extern const struct tcpm_drv anx74xx_tcpm_drv; -extern const struct usb_mux_driver anx74xx_tcpm_usb_mux_driver; -void anx74xx_tcpc_set_vbus(int port, int enable); -void anx74xx_tcpc_update_hpd_status(int port, int hpd_lvl, int hpd_irq); -void anx74xx_tcpc_clear_hpd_status(int port); - -#ifdef CONFIG_CMD_I2C_STRESS_TEST_TCPC -extern struct i2c_stress_test_dev anx74xx_i2c_stress_test_dev; -#endif - -#endif /* __CROS_EC_USB_PD_TCPM_ANX74XX_H */ diff --git a/driver/tcpm/anx7688.c b/driver/tcpm/anx7688.c deleted file mode 100644 index fe1d2498d4..0000000000 --- a/driver/tcpm/anx7688.c +++ /dev/null @@ -1,213 +0,0 @@ -/* Copyright 2016 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. - */ - -/* ANX7688 port manager */ - -#include "hooks.h" -#include "tcpci.h" -#include "tcpm.h" -#include "timer.h" -#include "usb_mux.h" - -#if defined(CONFIG_USB_PD_DUAL_ROLE_AUTO_TOGGLE) || \ - defined(CONFIG_USB_PD_TCPC_LOW_POWER) || \ - defined(CONFIG_USB_PD_DISCHARGE_TCPC) -#error "Unsupported config options of anx7688 PD driver" -#endif - -#define ANX7688_VENDOR_ALERT BIT(15) - -#define ANX7688_REG_STATUS 0x82 -#define ANX7688_REG_STATUS_LINK BIT(0) - -#define ANX7688_REG_HPD 0x83 -#define ANX7688_REG_HPD_HIGH BIT(0) -#define ANX7688_REG_HPD_IRQ BIT(1) -#define ANX7688_REG_HPD_ENABLE BIT(2) - -#define ANX7688_USBC_ADDR_FLAGS 0x28 -#define ANX7688_REG_RAMCTRL 0xe7 -#define ANX7688_REG_RAMCTRL_BOOT_DONE BIT(6) - -static int anx7688_init(int port) -{ - int rv = 0; - int mask = 0; - - /* - * 7688 POWER_STATUS[6] is not reliable for tcpci_tcpm_init() to poll - * due to it is default 0 in HW, and we cannot write TCPC until it is - * ready, or something goes wrong. (Issue 52772) - * Instead we poll TCPC 0x50:0xe7 bit6 here to make sure bootdone is - * ready(50ms). Then PD main flow can process cc debounce in 50ms ~ - * 100ms to follow cts. - */ - while (1) { - rv = i2c_read8(I2C_PORT_TCPC, ANX7688_USBC_ADDR_FLAGS, - ANX7688_REG_RAMCTRL, &mask); - - if (rv == EC_SUCCESS && (mask & ANX7688_REG_RAMCTRL_BOOT_DONE)) - break; - msleep(10); - } - - rv = tcpci_tcpm_drv.init(port); - if (rv) - return rv; - - rv = tcpc_read16(port, TCPC_REG_ALERT_MASK, &mask); - if (rv) - return rv; - - /* enable vendor specific alert */ - mask |= ANX7688_VENDOR_ALERT; - rv = tcpc_write16(port, TCPC_REG_ALERT_MASK, mask); - return rv; -} - -static int anx7688_release(int port) -{ - return EC_ERROR_UNIMPLEMENTED; -} - -static void anx7688_update_hpd_enable(int port) -{ - int status, reg, rv; - - rv = tcpc_read(port, ANX7688_REG_STATUS, &status); - rv |= tcpc_read(port, ANX7688_REG_HPD, ®); - if (rv) - return; - - if (!(reg & ANX7688_REG_HPD_ENABLE) || - !(status & ANX7688_REG_STATUS_LINK)) { - reg &= ~ANX7688_REG_HPD_IRQ; - tcpc_write(port, ANX7688_REG_HPD, - (status & ANX7688_REG_STATUS_LINK) - ? reg | ANX7688_REG_HPD_ENABLE - : reg & ~ANX7688_REG_HPD_ENABLE); - } -} - -int anx7688_hpd_disable(int port) -{ - return tcpc_write(port, ANX7688_REG_HPD, 0); -} - -int anx7688_update_hpd(int port, int level, int irq) -{ - int reg, rv; - - rv = tcpc_read(port, ANX7688_REG_HPD, ®); - if (rv) - return rv; - - if (level) - reg |= ANX7688_REG_HPD_HIGH; - else - reg &= ~ANX7688_REG_HPD_HIGH; - - if (irq) - reg |= ANX7688_REG_HPD_IRQ; - else - reg &= ~ANX7688_REG_HPD_IRQ; - - return tcpc_write(port, ANX7688_REG_HPD, reg); -} - -int anx7688_enable_cable_detection(int port) -{ - return tcpc_write(port, TCPC_REG_COMMAND, 0xff); -} - -int anx7688_set_power_supply_ready(int port) -{ - return tcpc_write(port, TCPC_REG_COMMAND, 0x77); -} - -int anx7688_power_supply_reset(int port) -{ - return tcpc_write(port, TCPC_REG_COMMAND, 0x66); -} - -static void anx7688_tcpc_alert(int port) -{ - int alert, rv; - - rv = tcpc_read16(port, TCPC_REG_ALERT, &alert); - /* process and clear alert status */ - tcpci_tcpc_alert(port); - - if (!rv && (alert & ANX7688_VENDOR_ALERT)) - anx7688_update_hpd_enable(port); -} - -static int anx7688_mux_set(int port, mux_state_t mux_state) -{ - int reg = 0; - int rv, polarity; - - rv = mux_read(port, TCPC_REG_CONFIG_STD_OUTPUT, ®); - if (rv != EC_SUCCESS) - return rv; - - reg &= ~TCPC_REG_CONFIG_STD_OUTPUT_MUX_MASK; - if (mux_state & MUX_USB_ENABLED) - reg |= TCPC_REG_CONFIG_STD_OUTPUT_MUX_USB; - if (mux_state & MUX_DP_ENABLED) - reg |= TCPC_REG_CONFIG_STD_OUTPUT_MUX_DP; - - /* ANX7688 needs to set bit0 */ - rv = mux_read(port, TCPC_REG_TCPC_CTRL, &polarity); - if (rv != EC_SUCCESS) - return rv; - - /* copy the polarity from TCPC_CTRL[0], take care clear then set */ - reg &= ~TCPC_REG_TCPC_CTRL_POLARITY(1); - reg |= TCPC_REG_TCPC_CTRL_POLARITY(polarity); - return mux_write(port, TCPC_REG_CONFIG_STD_OUTPUT, reg); -} - -#ifdef CONFIG_USB_PD_VBUS_DETECT_TCPC -static int anx7688_tcpm_get_vbus_level(int port) -{ - int reg = 0; - - /* On ANX7688, POWER_STATUS.VBusPresent (bit 2) is averaged 16 times, so - * its value may not be set to 1 quickly enough during power role swap. - * Therefore, we use a proprietary register to read the unfiltered VBus - * value. See crosbug.com/p/55221 . - */ - i2c_read8(I2C_PORT_TCPC, 0x28, 0x40, ®); - return ((reg & 0x10) ? 1 : 0); -} -#endif - -/* ANX7688 is a TCPCI compatible port controller */ -const struct tcpm_drv anx7688_tcpm_drv = { - .init = &anx7688_init, - .release = &anx7688_release, - .get_cc = &tcpci_tcpm_get_cc, -#ifdef CONFIG_USB_PD_VBUS_DETECT_TCPC - .get_vbus_level = &anx7688_tcpm_get_vbus_level, -#endif - .select_rp_value = &tcpci_tcpm_select_rp_value, - .set_cc = &tcpci_tcpm_set_cc, - .set_polarity = &tcpci_tcpm_set_polarity, - .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 = &anx7688_tcpc_alert, -}; - -#ifdef CONFIG_USB_PD_TCPM_MUX -const struct usb_mux_driver anx7688_usb_mux_driver = { - .init = tcpci_tcpm_mux_init, - .set = anx7688_mux_set, - .get = tcpci_tcpm_mux_get, -}; -#endif /* CONFIG_USB_PD_TCPM_MUX */ diff --git a/driver/tcpm/anx7688.h b/driver/tcpm/anx7688.h deleted file mode 100644 index 534e4155b1..0000000000 --- a/driver/tcpm/anx7688.h +++ /dev/null @@ -1,21 +0,0 @@ -/* Copyright 2016 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. - */ - -/* USB Power delivery port management */ - -#ifndef __CROS_EC_USB_PD_TCPM_ANX7688_H -#define __CROS_EC_USB_PD_TCPM_ANX7688_H - -int anx7688_update_hpd(int port, int level, int irq); -int anx7688_set_dp_pin_mode(int port, int pin_mode); -int anx7688_enable_cable_detection(int port); -int anx7688_set_power_supply_ready(int port); -int anx7688_power_supply_reset(int port); -int anx7688_hpd_disable(int port); - -extern struct tcpm_drv anx7688_tcpm_drv; -extern struct usb_mux_driver anx7688_usb_mux_driver; - -#endif /* __CROS_EC_USB_PD_TCPM_ANX7688_H */ diff --git a/driver/tcpm/fusb302.c b/driver/tcpm/fusb302.c deleted file mode 100644 index 66c131fb37..0000000000 --- a/driver/tcpm/fusb302.c +++ /dev/null @@ -1,1036 +0,0 @@ -/* Copyright 2015 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. - * - * Author: Gabe Noblesmith - */ - -/* Type-C port manager for Fairchild's FUSB302 */ - -#include "console.h" -#include "fusb302.h" -#include "task.h" -#include "hooks.h" -#include "tcpm.h" -#include "timer.h" -#include "usb_charge.h" -#include "usb_pd.h" -#include "usb_pd_tcpc.h" -#include "util.h" - -#if defined(CONFIG_USB_PD_DUAL_ROLE_AUTO_TOGGLE) || \ - defined(CONFIG_USB_PD_DISCHARGE_TCPC) -#error "Unsupported config options of fusb302 PD driver" -#endif - -#define PACKET_IS_GOOD_CRC(head) (PD_HEADER_TYPE(head) == PD_CTRL_GOOD_CRC && \ - PD_HEADER_CNT(head) == 0) - -static struct fusb302_chip_state { - int cc_polarity; - int vconn_enabled; - /* 1 = pulling up (DFP) 0 = pulling down (UFP) */ - int pulling_up; - int rx_enable; - uint8_t mdac_vnc; - uint8_t mdac_rd; -} state[CONFIG_USB_PD_PORT_MAX_COUNT]; - -/* - * Bring the FUSB302 out of reset after Hard Reset signaling. This will - * automatically flush both the Rx and Tx FIFOs. - */ -static void fusb302_pd_reset(int port) -{ - tcpc_write(port, TCPC_REG_RESET, TCPC_REG_RESET_PD_RESET); -} - -/* - * Flush our Rx FIFO. To prevent packet framing issues, this function should - * only be called when Rx is disabled. - */ -static void fusb302_flush_rx_fifo(int port) -{ - /* - * other bits in the register _should_ be 0 - * until the day we support other SOP* types... - * then we'll have to keep a shadow of what this register - * value should be so we don't clobber it here! - */ - tcpc_write(port, TCPC_REG_CONTROL1, TCPC_REG_CONTROL1_RX_FLUSH); -} - -static void fusb302_flush_tx_fifo(int port) -{ - int reg; - - tcpc_read(port, TCPC_REG_CONTROL0, ®); - reg |= TCPC_REG_CONTROL0_TX_FLUSH; - tcpc_write(port, TCPC_REG_CONTROL0, reg); -} - -static void fusb302_auto_goodcrc_enable(int port, int enable) -{ - int reg; - - tcpc_read(port, TCPC_REG_SWITCHES1, ®); - - if (enable) - reg |= TCPC_REG_SWITCHES1_AUTO_GCRC; - else - reg &= ~TCPC_REG_SWITCHES1_AUTO_GCRC; - - tcpc_write(port, TCPC_REG_SWITCHES1, reg); -} - -/* Convert BC LVL values (in FUSB302) to Type-C CC Voltage Status */ -static int convert_bc_lvl(int port, int bc_lvl) -{ - /* assume OPEN unless one of the following conditions is true... */ - int ret = TYPEC_CC_VOLT_OPEN; - - if (state[port].pulling_up) { - if (bc_lvl == 0x00) - ret = TYPEC_CC_VOLT_RA; - else if (bc_lvl < 0x3) - ret = TYPEC_CC_VOLT_RD; - } else { - if (bc_lvl == 0x1) - ret = TYPEC_CC_VOLT_RP_DEF; - else if (bc_lvl == 0x2) - ret = TYPEC_CC_VOLT_RP_1_5; - else if (bc_lvl == 0x3) - ret = TYPEC_CC_VOLT_RP_3_0; - } - - return ret; -} - -static int measure_cc_pin_source(int port, int cc_measure) -{ - int switches0_reg; - int reg; - int cc_lvl; - - /* Read status register */ - tcpc_read(port, TCPC_REG_SWITCHES0, ®); - /* Save current value */ - switches0_reg = reg; - /* Clear pull-up register settings and measure bits */ - reg &= ~(TCPC_REG_SWITCHES0_MEAS_CC1 | TCPC_REG_SWITCHES0_MEAS_CC2); - /* Set desired pullup register bit */ - if (cc_measure == TCPC_REG_SWITCHES0_MEAS_CC1) - reg |= TCPC_REG_SWITCHES0_CC1_PU_EN; - else - reg |= TCPC_REG_SWITCHES0_CC2_PU_EN; - /* Set CC measure bit */ - reg |= cc_measure; - - /* Set measurement switch */ - tcpc_write(port, TCPC_REG_SWITCHES0, reg); - - /* Set MDAC for Open vs Rd/Ra comparison */ - tcpc_write(port, TCPC_REG_MEASURE, state[port].mdac_vnc); - - /* Wait on measurement */ - usleep(250); - - /* Read status register */ - tcpc_read(port, TCPC_REG_STATUS0, ®); - - /* Assume open */ - cc_lvl = TYPEC_CC_VOLT_OPEN; - - /* CC level is below the 'no connect' threshold (vOpen) */ - if ((reg & TCPC_REG_STATUS0_COMP) == 0) { - /* Set MDAC for Rd vs Ra comparison */ - tcpc_write(port, TCPC_REG_MEASURE, state[port].mdac_rd); - - /* Wait on measurement */ - usleep(250); - - /* Read status register */ - tcpc_read(port, TCPC_REG_STATUS0, ®); - - cc_lvl = (reg & TCPC_REG_STATUS0_COMP) ? TYPEC_CC_VOLT_RD - : TYPEC_CC_VOLT_RA; - } - - /* Restore SWITCHES0 register to its value prior */ - tcpc_write(port, TCPC_REG_SWITCHES0, switches0_reg); - - return cc_lvl; -} - -/* Determine cc pin state for source when in manual detect mode */ -static void detect_cc_pin_source_manual(int port, - enum tcpc_cc_voltage_status *cc1_lvl, - enum tcpc_cc_voltage_status *cc2_lvl) -{ - int cc1_measure = TCPC_REG_SWITCHES0_MEAS_CC1; - int cc2_measure = TCPC_REG_SWITCHES0_MEAS_CC2; - - if (state[port].vconn_enabled) { - /* If VCONN enabled, measure cc_pin that matches polarity */ - if (state[port].cc_polarity) - *cc2_lvl = measure_cc_pin_source(port, cc2_measure); - else - *cc1_lvl = measure_cc_pin_source(port, cc1_measure); - } else { - /* If VCONN not enabled, measure both cc1 and cc2 */ - *cc1_lvl = measure_cc_pin_source(port, cc1_measure); - *cc2_lvl = measure_cc_pin_source(port, cc2_measure); - } - -} - -/* Determine cc pin state for sink */ -static void detect_cc_pin_sink(int port, enum tcpc_cc_voltage_status *cc1, - enum tcpc_cc_voltage_status *cc2) -{ - int reg; - int orig_meas_cc1; - int orig_meas_cc2; - int bc_lvl_cc1; - int bc_lvl_cc2; - - /* - * Measure CC1 first. - */ - tcpc_read(port, TCPC_REG_SWITCHES0, ®); - - /* save original state to be returned to later... */ - if (reg & TCPC_REG_SWITCHES0_MEAS_CC1) - orig_meas_cc1 = 1; - else - orig_meas_cc1 = 0; - - if (reg & TCPC_REG_SWITCHES0_MEAS_CC2) - orig_meas_cc2 = 1; - else - orig_meas_cc2 = 0; - - - /* Disable CC2 measurement switch, enable CC1 measurement switch */ - reg &= ~TCPC_REG_SWITCHES0_MEAS_CC2; - reg |= TCPC_REG_SWITCHES0_MEAS_CC1; - - tcpc_write(port, TCPC_REG_SWITCHES0, reg); - - /* CC1 is now being measured by FUSB302. */ - - /* Wait on measurement */ - usleep(250); - - tcpc_read(port, TCPC_REG_STATUS0, &bc_lvl_cc1); - - /* mask away unwanted bits */ - bc_lvl_cc1 &= (TCPC_REG_STATUS0_BC_LVL0 | TCPC_REG_STATUS0_BC_LVL1); - - /* - * Measure CC2 next. - */ - - tcpc_read(port, TCPC_REG_SWITCHES0, ®); - - /* Disable CC1 measurement switch, enable CC2 measurement switch */ - reg &= ~TCPC_REG_SWITCHES0_MEAS_CC1; - reg |= TCPC_REG_SWITCHES0_MEAS_CC2; - - tcpc_write(port, TCPC_REG_SWITCHES0, reg); - - /* CC2 is now being measured by FUSB302. */ - - /* Wait on measurement */ - usleep(250); - - tcpc_read(port, TCPC_REG_STATUS0, &bc_lvl_cc2); - - /* mask away unwanted bits */ - bc_lvl_cc2 &= (TCPC_REG_STATUS0_BC_LVL0 | TCPC_REG_STATUS0_BC_LVL1); - - *cc1 = convert_bc_lvl(port, bc_lvl_cc1); - *cc2 = convert_bc_lvl(port, bc_lvl_cc2); - - /* return MEAS_CC1/2 switches to original state */ - tcpc_read(port, TCPC_REG_SWITCHES0, ®); - if (orig_meas_cc1) - reg |= TCPC_REG_SWITCHES0_MEAS_CC1; - else - reg &= ~TCPC_REG_SWITCHES0_MEAS_CC1; - if (orig_meas_cc2) - reg |= TCPC_REG_SWITCHES0_MEAS_CC2; - else - reg &= ~TCPC_REG_SWITCHES0_MEAS_CC2; - - tcpc_write(port, TCPC_REG_SWITCHES0, reg); -} - -/* Parse header bytes for the size of packet */ -static int get_num_bytes(uint16_t header) -{ - int rv; - - /* Grab the Number of Data Objects field.*/ - rv = PD_HEADER_CNT(header); - - /* Multiply by four to go from 32-bit words -> bytes */ - rv *= 4; - - /* Plus 2 for header */ - rv += 2; - - return rv; -} - -static int fusb302_send_message(int port, uint16_t header, const uint32_t *data, - uint8_t *buf, int buf_pos) -{ - int rv; - int reg; - int len; - - len = get_num_bytes(header); - - /* - * packsym tells the TXFIFO that the next X bytes are payload, - * and should not be interpreted as special tokens. - * The 5 LSBs represent X, the number of bytes. - */ - reg = FUSB302_TKN_PACKSYM; - reg |= (len & 0x1F); - - buf[buf_pos++] = reg; - - /* write in the header */ - reg = header; - buf[buf_pos++] = reg & 0xFF; - - reg >>= 8; - buf[buf_pos++] = reg & 0xFF; - - /* header is done, subtract from length to make this for-loop simpler */ - len -= 2; - - /* write data objects, if present */ - memcpy(&buf[buf_pos], data, len); - buf_pos += len; - - /* put in the CRC */ - buf[buf_pos++] = FUSB302_TKN_JAMCRC; - - /* put in EOP */ - buf[buf_pos++] = FUSB302_TKN_EOP; - - /* Turn transmitter off after sending message */ - buf[buf_pos++] = FUSB302_TKN_TXOFF; - - /* Start transmission */ - reg = FUSB302_TKN_TXON; - buf[buf_pos++] = FUSB302_TKN_TXON; - - /* burst write for speed! */ - rv = tcpc_xfer(port, buf, buf_pos, 0, 0); - - return rv; -} - -static int fusb302_tcpm_select_rp_value(int port, int rp) -{ - int reg; - int rv; - uint8_t vnc, rd; - - rv = tcpc_read(port, TCPC_REG_CONTROL0, ®); - if (rv) - return rv; - - /* Set the current source for Rp value */ - reg &= ~TCPC_REG_CONTROL0_HOST_CUR_MASK; - switch (rp) { - case TYPEC_RP_1A5: - reg |= TCPC_REG_CONTROL0_HOST_CUR_1A5; - vnc = TCPC_REG_MEASURE_MDAC_MV(PD_SRC_1_5_VNC_MV); - rd = TCPC_REG_MEASURE_MDAC_MV(PD_SRC_1_5_RD_THRESH_MV); - break; - case TYPEC_RP_3A0: - reg |= TCPC_REG_CONTROL0_HOST_CUR_3A0; - vnc = TCPC_REG_MEASURE_MDAC_MV(PD_SRC_3_0_VNC_MV); - rd = TCPC_REG_MEASURE_MDAC_MV(PD_SRC_3_0_RD_THRESH_MV); - break; - case TYPEC_RP_USB: - default: - reg |= TCPC_REG_CONTROL0_HOST_CUR_USB; - vnc = TCPC_REG_MEASURE_MDAC_MV(PD_SRC_DEF_VNC_MV); - rd = TCPC_REG_MEASURE_MDAC_MV(PD_SRC_DEF_RD_THRESH_MV); - } - state[port].mdac_vnc = vnc; - state[port].mdac_rd = rd; - return tcpc_write(port, TCPC_REG_CONTROL0, reg); -} - -static int fusb302_tcpm_init(int port) -{ - int reg; - - /* set default */ - state[port].cc_polarity = -1; - - /* set the voltage threshold for no connect detection (vOpen) */ - state[port].mdac_vnc = TCPC_REG_MEASURE_MDAC_MV(PD_SRC_DEF_VNC_MV); - /* set the voltage threshold for Rd vs Ra detection */ - state[port].mdac_rd = TCPC_REG_MEASURE_MDAC_MV(PD_SRC_DEF_RD_THRESH_MV); - - /* all other variables assumed to default to 0 */ - - /* Restore default settings */ - tcpc_write(port, TCPC_REG_RESET, TCPC_REG_RESET_SW_RESET); - - /* Turn on retries and set number of retries */ - tcpc_read(port, TCPC_REG_CONTROL3, ®); - reg |= TCPC_REG_CONTROL3_AUTO_RETRY; - reg |= (PD_RETRY_COUNT & 0x3) << - TCPC_REG_CONTROL3_N_RETRIES_POS; - tcpc_write(port, TCPC_REG_CONTROL3, reg); - - /* Create interrupt masks */ - reg = 0xFF; - /* CC level changes */ - reg &= ~TCPC_REG_MASK_BC_LVL; - /* collisions */ - reg &= ~TCPC_REG_MASK_COLLISION; - /* misc alert */ - reg &= ~TCPC_REG_MASK_ALERT; -#ifdef CONFIG_USB_PD_VBUS_DETECT_TCPC - /* TODO(crbug.com/791109): Clean up VBUS notification. */ - - /* VBUS threshold crossed (~4.0V) */ - reg &= ~TCPC_REG_MASK_VBUSOK; -#endif - tcpc_write(port, TCPC_REG_MASK, reg); - - reg = 0xFF; - /* when all pd message retries fail... */ - reg &= ~TCPC_REG_MASKA_RETRYFAIL; - /* when fusb302 send a hard reset. */ - reg &= ~TCPC_REG_MASKA_HARDSENT; - /* when fusb302 receives GoodCRC ack for a pd message */ - reg &= ~TCPC_REG_MASKA_TX_SUCCESS; - /* when fusb302 receives a hard reset */ - reg &= ~TCPC_REG_MASKA_HARDRESET; - tcpc_write(port, TCPC_REG_MASKA, reg); - - reg = 0xFF; - /* when fusb302 sends GoodCRC to ack a pd message */ - reg &= ~TCPC_REG_MASKB_GCRCSENT; - tcpc_write(port, TCPC_REG_MASKB, reg); - - /* Interrupt Enable */ - tcpc_read(port, TCPC_REG_CONTROL0, ®); - reg &= ~TCPC_REG_CONTROL0_INT_MASK; - tcpc_write(port, TCPC_REG_CONTROL0, reg); - - /* Set VCONN switch defaults */ - tcpm_set_polarity(port, 0); - tcpm_set_vconn(port, 0); - - /* Turn on the power! */ - /* TODO: Reduce power consumption */ - tcpc_write(port, TCPC_REG_POWER, TCPC_REG_POWER_PWR_ALL); - -#if defined(CONFIG_USB_PD_VBUS_DETECT_TCPC) && defined(CONFIG_USB_CHARGER) - /* Wait for the reference voltage to stablize */ - usleep(250); - /* - * Initialize VBUS supplier when VBUS is already present before - * init (e.g. Cold reboot with charger plugged). - */ - tcpc_read(port, TCPC_REG_STATUS0, ®); - if (reg & TCPC_REG_STATUS0_VBUSOK) - usb_charger_vbus_change(port, 1); -#endif - - return 0; -} - -static int fusb302_tcpm_release(int port) -{ - return EC_ERROR_UNIMPLEMENTED; -} - -static int fusb302_tcpm_get_cc(int port, enum tcpc_cc_voltage_status *cc1, - enum tcpc_cc_voltage_status *cc2) -{ - if (state[port].pulling_up) { - /* Source mode? */ - detect_cc_pin_source_manual(port, cc1, cc2); - } else { - /* Sink mode? */ - detect_cc_pin_sink(port, cc1, cc2); - } - - return 0; -} - -static int fusb302_tcpm_set_cc(int port, int pull) -{ - int reg; - - /* NOTE: FUSB302 toggles a single pull-up between CC1 and CC2 */ - /* NOTE: FUSB302 Does not support Ra. */ - switch (pull) { - case TYPEC_CC_RP: - /* enable the pull-up we know to be necessary */ - tcpc_read(port, TCPC_REG_SWITCHES0, ®); - - reg &= ~(TCPC_REG_SWITCHES0_CC2_PU_EN | - TCPC_REG_SWITCHES0_CC1_PU_EN | - TCPC_REG_SWITCHES0_CC1_PD_EN | - TCPC_REG_SWITCHES0_CC2_PD_EN | - TCPC_REG_SWITCHES0_VCONN_CC1 | - TCPC_REG_SWITCHES0_VCONN_CC2); - - reg |= TCPC_REG_SWITCHES0_CC1_PU_EN | - TCPC_REG_SWITCHES0_CC2_PU_EN; - - if (state[port].vconn_enabled) - reg |= state[port].cc_polarity ? - TCPC_REG_SWITCHES0_VCONN_CC1 : - TCPC_REG_SWITCHES0_VCONN_CC2; - - tcpc_write(port, TCPC_REG_SWITCHES0, reg); - - state[port].pulling_up = 1; - break; - case TYPEC_CC_RD: - /* Enable UFP Mode */ - - /* turn off toggle */ - tcpc_read(port, TCPC_REG_CONTROL2, ®); - reg &= ~TCPC_REG_CONTROL2_TOGGLE; - tcpc_write(port, TCPC_REG_CONTROL2, reg); - - /* enable pull-downs, disable pullups */ - tcpc_read(port, TCPC_REG_SWITCHES0, ®); - - reg &= ~(TCPC_REG_SWITCHES0_CC2_PU_EN); - reg &= ~(TCPC_REG_SWITCHES0_CC1_PU_EN); - reg |= (TCPC_REG_SWITCHES0_CC1_PD_EN); - reg |= (TCPC_REG_SWITCHES0_CC2_PD_EN); - tcpc_write(port, TCPC_REG_SWITCHES0, reg); - - state[port].pulling_up = 0; - break; - case TYPEC_CC_OPEN: - /* Disable toggling */ - tcpc_read(port, TCPC_REG_CONTROL2, ®); - reg &= ~TCPC_REG_CONTROL2_TOGGLE; - tcpc_write(port, TCPC_REG_CONTROL2, reg); - - /* Ensure manual switches are opened */ - tcpc_read(port, TCPC_REG_SWITCHES0, ®); - reg &= ~TCPC_REG_SWITCHES0_CC1_PU_EN; - reg &= ~TCPC_REG_SWITCHES0_CC2_PU_EN; - reg &= ~TCPC_REG_SWITCHES0_CC1_PD_EN; - reg &= ~TCPC_REG_SWITCHES0_CC2_PD_EN; - tcpc_write(port, TCPC_REG_SWITCHES0, reg); - - state[port].pulling_up = 0; - break; - default: - /* Unsupported... */ - return EC_ERROR_UNIMPLEMENTED; - } - return 0; -} - -static int fusb302_tcpm_set_polarity(int port, int polarity) -{ - /* Port polarity : 0 => CC1 is CC line, 1 => CC2 is CC line */ - int reg; - - tcpc_read(port, TCPC_REG_SWITCHES0, ®); - - /* clear VCONN switch bits */ - reg &= ~TCPC_REG_SWITCHES0_VCONN_CC1; - reg &= ~TCPC_REG_SWITCHES0_VCONN_CC2; - - if (state[port].vconn_enabled) { - /* set VCONN switch to be non-CC line */ - if (polarity) - reg |= TCPC_REG_SWITCHES0_VCONN_CC1; - else - reg |= TCPC_REG_SWITCHES0_VCONN_CC2; - } - - /* clear meas_cc bits (RX line select) */ - reg &= ~TCPC_REG_SWITCHES0_MEAS_CC1; - reg &= ~TCPC_REG_SWITCHES0_MEAS_CC2; - - /* set rx polarity */ - if (polarity) - reg |= TCPC_REG_SWITCHES0_MEAS_CC2; - else - reg |= TCPC_REG_SWITCHES0_MEAS_CC1; - - tcpc_write(port, TCPC_REG_SWITCHES0, reg); - - tcpc_read(port, TCPC_REG_SWITCHES1, ®); - - /* clear tx_cc bits */ - reg &= ~TCPC_REG_SWITCHES1_TXCC1_EN; - reg &= ~TCPC_REG_SWITCHES1_TXCC2_EN; - - /* set tx polarity */ - if (polarity) - reg |= TCPC_REG_SWITCHES1_TXCC2_EN; - else - reg |= TCPC_REG_SWITCHES1_TXCC1_EN; - - tcpc_write(port, TCPC_REG_SWITCHES1, reg); - - /* Save the polarity for later */ - state[port].cc_polarity = polarity; - - return 0; -} - -static int fusb302_tcpm_set_vconn(int port, int enable) -{ - /* - * FUSB302 does not have dedicated VCONN Enable switch. - * We'll get through this by disabling both of the - * VCONN - CC* switches to disable, and enabling the - * saved polarity when enabling. - * Therefore at startup, tcpm_set_polarity should be called first, - * or else live with the default put into tcpm_init. - */ - int reg; - - /* save enable state for later use */ - state[port].vconn_enabled = enable; - - if (enable) { - /* set to saved polarity */ - tcpm_set_polarity(port, state[port].cc_polarity); - -#ifdef CONFIG_USB_PD_DECODE_SOP - if (state[port].rx_enable) { - if (tcpc_read(port, TCPC_REG_CONTROL1, ®)) - return EC_ERROR_UNKNOWN; - - reg |= (TCPC_REG_CONTROL1_ENSOP1 | - TCPC_REG_CONTROL1_ENSOP2); - tcpc_write(port, TCPC_REG_CONTROL1, reg); - } -#endif - } else { - - tcpc_read(port, TCPC_REG_SWITCHES0, ®); - - /* clear VCONN switch bits */ - reg &= ~TCPC_REG_SWITCHES0_VCONN_CC1; - reg &= ~TCPC_REG_SWITCHES0_VCONN_CC2; - - tcpc_write(port, TCPC_REG_SWITCHES0, reg); - -#ifdef CONFIG_USB_PD_DECODE_SOP - if (state[port].rx_enable) { - if (tcpc_read(port, TCPC_REG_CONTROL1, ®)) - return EC_ERROR_UNKNOWN; - - reg &= ~(TCPC_REG_CONTROL1_ENSOP1 | - TCPC_REG_CONTROL1_ENSOP2); - tcpc_write(port, TCPC_REG_CONTROL1, reg); - } -#endif - } - - return 0; -} - -static int fusb302_tcpm_set_msg_header(int port, int power_role, int data_role) -{ - int reg; - - tcpc_read(port, TCPC_REG_SWITCHES1, ®); - - reg &= ~TCPC_REG_SWITCHES1_POWERROLE; - reg &= ~TCPC_REG_SWITCHES1_DATAROLE; - - if (power_role) - reg |= TCPC_REG_SWITCHES1_POWERROLE; - if (data_role) - reg |= TCPC_REG_SWITCHES1_DATAROLE; - - tcpc_write(port, TCPC_REG_SWITCHES1, reg); - - return 0; -} - -static int fusb302_tcpm_set_rx_enable(int port, int enable) -{ - int reg; - - state[port].rx_enable = enable; - - /* Get current switch state */ - tcpc_read(port, TCPC_REG_SWITCHES0, ®); - - /* Clear CC1/CC2 measure bits */ - reg &= ~TCPC_REG_SWITCHES0_MEAS_CC1; - reg &= ~TCPC_REG_SWITCHES0_MEAS_CC2; - - if (enable) { - switch (state[port].cc_polarity) { - /* if CC polarity hasnt been determined, can't enable */ - case -1: - return EC_ERROR_UNKNOWN; - case 0: - reg |= TCPC_REG_SWITCHES0_MEAS_CC1; - break; - case 1: - reg |= TCPC_REG_SWITCHES0_MEAS_CC2; - break; - default: - /* "shouldn't get here" */ - return EC_ERROR_UNKNOWN; - } - tcpc_write(port, TCPC_REG_SWITCHES0, reg); - - /* Disable BC_LVL interrupt when enabling PD comm */ - if (!tcpc_read(port, TCPC_REG_MASK, ®)) - tcpc_write(port, TCPC_REG_MASK, - reg | TCPC_REG_MASK_BC_LVL); - - /* flush rx fifo in case messages have been coming our way */ - fusb302_flush_rx_fifo(port); - - - } else { - tcpc_write(port, TCPC_REG_SWITCHES0, reg); - - /* Enable BC_LVL interrupt when disabling PD comm */ - if (!tcpc_read(port, TCPC_REG_MASK, ®)) - tcpc_write(port, TCPC_REG_MASK, - reg & ~TCPC_REG_MASK_BC_LVL); - } - -#ifdef CONFIG_USB_PD_DECODE_SOP - /* - * Only the VCONN Source is allowed to communicate - * with the Cable Plugs. - */ - if (state[port].vconn_enabled) { - if (tcpc_read(port, TCPC_REG_CONTROL1, ®)) - return EC_ERROR_UNKNOWN; - - reg |= (TCPC_REG_CONTROL1_ENSOP1 | TCPC_REG_CONTROL1_ENSOP2); - tcpc_write(port, TCPC_REG_CONTROL1, reg); - } -#endif - - fusb302_auto_goodcrc_enable(port, enable); - - return 0; -} - -/* Return true if our Rx FIFO is empty */ -static int fusb302_rx_fifo_is_empty(int port) -{ - int reg; - - return (!tcpc_read(port, TCPC_REG_STATUS1, ®)) && - (reg & TCPC_REG_STATUS1_RX_EMPTY); -} - -static int fusb302_tcpm_get_message_raw(int port, uint32_t *payload, int *head) -{ - /* - * This is the buffer that will get the burst-read data - * from the fusb302. - * - * It's re-used in a couple different spots, the worst of which - * is the PD packet (not header) and CRC. - * maximum size necessary = 28 + 4 = 32 - */ - uint8_t buf[32]; - int rv, len; - - /* Read until we have a non-GoodCRC packet or an empty FIFO */ - do { - buf[0] = TCPC_REG_FIFOS; - tcpc_lock(port, 1); - - /* - * PART 1 OF BURST READ: Write in register address. - * Issue a START, no STOP. - */ - rv = tcpc_xfer_unlocked(port, buf, 1, 0, 0, I2C_XFER_START); - - /* - * PART 2 OF BURST READ: Read up to the header. - * Issue a repeated START, no STOP. - * only grab three bytes so we can get the header - * and determine how many more bytes we need to read. - * TODO: Check token to ensure valid packet. - */ - rv |= tcpc_xfer_unlocked(port, 0, 0, buf, 3, I2C_XFER_START); - - /* Grab the header */ - *head = (buf[1] & 0xFF); - *head |= ((buf[2] << 8) & 0xFF00); - - /* figure out packet length, subtract header bytes */ - len = get_num_bytes(*head) - 2; - - /* - * PART 3 OF BURST READ: Read everything else. - * No START, but do issue a STOP at the end. - * add 4 to len to read CRC out - */ - rv |= tcpc_xfer_unlocked(port, 0, 0, buf, len+4, I2C_XFER_STOP); - - tcpc_lock(port, 0); - } while (!rv && PACKET_IS_GOOD_CRC(*head) && - !fusb302_rx_fifo_is_empty(port)); - - if (!rv) { - /* Discard GoodCRC packets */ - if (PACKET_IS_GOOD_CRC(*head)) - rv = EC_ERROR_UNKNOWN; - else - memcpy(payload, buf, len); - } - -#ifdef CONFIG_USB_PD_DECODE_SOP - { - int reg; - - if (tcpc_read(port, TCPC_REG_STATUS1, ®)) - return EC_ERROR_UNKNOWN; - - if (reg & TCPC_REG_STATUS1_RXSOP1) - *head |= PD_HEADER_SOP(PD_MSG_SOPP); - else if (reg & TCPC_REG_STATUS1_RXSOP2) - *head |= PD_HEADER_SOP(PD_MSG_SOPPP); - } -#endif - - return rv; -} - -static int fusb302_tcpm_transmit(int port, enum tcpm_transmit_type type, - uint16_t header, const uint32_t *data) -{ - /* - * this is the buffer that will be burst-written into the fusb302 - * maximum size necessary = - * 1: FIFO register address - * 4: SOP* tokens - * 1: Token that signifies "next X bytes are not tokens" - * 30: 2 for header and up to 7*4 = 28 for rest of message - * 1: "Insert CRC" Token - * 1: EOP Token - * 1: "Turn transmitter off" token - * 1: "Star Transmission" Command - * - - * 40: 40 bytes worst-case - */ - uint8_t buf[40]; - int buf_pos = 0; - - int reg; - - /* Flush the TXFIFO */ - fusb302_flush_tx_fifo(port); - - switch (type) { - case TCPC_TX_SOP: - - /* put register address first for of burst tcpc write */ - buf[buf_pos++] = TCPC_REG_FIFOS; - - /* Write the SOP Ordered Set into TX FIFO */ - buf[buf_pos++] = FUSB302_TKN_SYNC1; - buf[buf_pos++] = FUSB302_TKN_SYNC1; - buf[buf_pos++] = FUSB302_TKN_SYNC1; - buf[buf_pos++] = FUSB302_TKN_SYNC2; - - return fusb302_send_message(port, header, data, buf, buf_pos); - case TCPC_TX_HARD_RESET: - /* Simply hit the SEND_HARD_RESET bit */ - tcpc_read(port, TCPC_REG_CONTROL3, ®); - reg |= TCPC_REG_CONTROL3_SEND_HARDRESET; - tcpc_write(port, TCPC_REG_CONTROL3, reg); - - break; - case TCPC_TX_BIST_MODE_2: - /* Hit the BIST_MODE2 bit and start TX */ - tcpc_read(port, TCPC_REG_CONTROL1, ®); - reg |= TCPC_REG_CONTROL1_BIST_MODE2; - tcpc_write(port, TCPC_REG_CONTROL1, reg); - - tcpc_read(port, TCPC_REG_CONTROL0, ®); - reg |= TCPC_REG_CONTROL0_TX_START; - tcpc_write(port, TCPC_REG_CONTROL0, reg); - - task_wait_event(PD_T_BIST_TRANSMIT); - - /* Clear BIST mode bit, TX_START is self-clearing */ - tcpc_read(port, TCPC_REG_CONTROL1, ®); - reg &= ~TCPC_REG_CONTROL1_BIST_MODE2; - tcpc_write(port, TCPC_REG_CONTROL1, reg); - - break; - default: - return EC_ERROR_UNIMPLEMENTED; - } - - return 0; -} - -#ifdef CONFIG_USB_PD_VBUS_DETECT_TCPC -static int fusb302_tcpm_get_vbus_level(int port) -{ - int reg; - - /* Read status register */ - tcpc_read(port, TCPC_REG_STATUS0, ®); - - return (reg & TCPC_REG_STATUS0_VBUSOK) ? 1 : 0; -} -#endif - -void fusb302_tcpc_alert(int port) -{ - /* interrupt has been received */ - int interrupt; - int interrupta; - int interruptb; - - /* reading interrupt registers clears them */ - - tcpc_read(port, TCPC_REG_INTERRUPT, &interrupt); - tcpc_read(port, TCPC_REG_INTERRUPTA, &interrupta); - tcpc_read(port, TCPC_REG_INTERRUPTB, &interruptb); - - /* - * Ignore BC_LVL changes when transmitting / receiving PD, - * since CC level will constantly change. - */ - if (state[port].rx_enable) - interrupt &= ~TCPC_REG_INTERRUPT_BC_LVL; - - if (interrupt & TCPC_REG_INTERRUPT_BC_LVL) { - /* CC Status change */ - task_set_event(PD_PORT_TO_TASK_ID(port), PD_EVENT_CC, 0); - } - - if (interrupt & TCPC_REG_INTERRUPT_COLLISION) { - /* packet sending collided */ - pd_transmit_complete(port, TCPC_TX_COMPLETE_FAILED); - } - -#ifdef CONFIG_USB_PD_VBUS_DETECT_TCPC - if (interrupt & TCPC_REG_INTERRUPT_VBUSOK) { - /* VBUS crossed threshold */ -#ifdef CONFIG_USB_CHARGER - usb_charger_vbus_change(port, - fusb302_tcpm_get_vbus_level(port)); -#else - if (!fusb302_tcpm_get_vbus_level(port)) - pd_vbus_low(port); -#endif - task_wake(PD_PORT_TO_TASK_ID(port)); - hook_notify(HOOK_AC_CHANGE); - } -#endif - - /* GoodCRC was received, our FIFO is now non-empty */ - if (interrupta & TCPC_REG_INTERRUPTA_TX_SUCCESS) { - pd_transmit_complete(port, TCPC_TX_COMPLETE_SUCCESS); - } - - if (interrupta & TCPC_REG_INTERRUPTA_RETRYFAIL) { - /* all retries have failed to get a GoodCRC */ - pd_transmit_complete(port, TCPC_TX_COMPLETE_FAILED); - } - - if (interrupta & TCPC_REG_INTERRUPTA_HARDSENT) { - /* hard reset has been sent */ - - /* bring FUSB302 out of reset */ - fusb302_pd_reset(port); - - pd_transmit_complete(port, TCPC_TX_COMPLETE_SUCCESS); - } - - if (interrupta & TCPC_REG_INTERRUPTA_HARDRESET) { - /* hard reset has been received */ - - /* bring FUSB302 out of reset */ - fusb302_pd_reset(port); - - pd_execute_hard_reset(port); - - task_wake(PD_PORT_TO_TASK_ID(port)); - } - - if (interruptb & TCPC_REG_INTERRUPTB_GCRCSENT) { - /* Packet received and GoodCRC sent */ - /* (this interrupt fires after the GoodCRC finishes) */ - if (state[port].rx_enable) { - /* Pull all RX messages from TCPC into EC memory */ - while (!fusb302_rx_fifo_is_empty(port)) - tcpm_enqueue_message(port); - } else { - /* flush rx fifo if rx isn't enabled */ - fusb302_flush_rx_fifo(port); - } - } - -} - -/* For BIST receiving */ -void tcpm_set_bist_test_data(int port) -{ - int reg; - - /* Read control3 register */ - tcpc_read(port, TCPC_REG_CONTROL3, ®); - - /* Set the BIST_TMODE bit (Clears on Hard Reset) */ - reg |= TCPC_REG_CONTROL3_BIST_TMODE; - - /* Write the updated value */ - tcpc_write(port, TCPC_REG_CONTROL3, reg); -} - -#ifdef CONFIG_USB_PD_TCPC_LOW_POWER -static int fusb302_tcpm_enter_low_power_mode(int port) -{ - return tcpc_write(port, TCPC_REG_POWER, TCPC_REG_POWER_PWR_LOW); -} -#endif - -const struct tcpm_drv fusb302_tcpm_drv = { - .init = &fusb302_tcpm_init, - .release = &fusb302_tcpm_release, - .get_cc = &fusb302_tcpm_get_cc, -#ifdef CONFIG_USB_PD_VBUS_DETECT_TCPC - .get_vbus_level = &fusb302_tcpm_get_vbus_level, -#endif - .select_rp_value = &fusb302_tcpm_select_rp_value, - .set_cc = &fusb302_tcpm_set_cc, - .set_polarity = &fusb302_tcpm_set_polarity, - .set_vconn = &fusb302_tcpm_set_vconn, - .set_msg_header = &fusb302_tcpm_set_msg_header, - .set_rx_enable = &fusb302_tcpm_set_rx_enable, - .get_message_raw = &fusb302_tcpm_get_message_raw, - .transmit = &fusb302_tcpm_transmit, - .tcpc_alert = &fusb302_tcpc_alert, -#ifdef CONFIG_USB_PD_TCPC_LOW_POWER - .enter_low_power_mode = &fusb302_tcpm_enter_low_power_mode, -#endif -}; diff --git a/driver/tcpm/fusb302.h b/driver/tcpm/fusb302.h deleted file mode 100644 index ec418407f7..0000000000 --- a/driver/tcpm/fusb302.h +++ /dev/null @@ -1,213 +0,0 @@ -/* Copyright 2015 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. - * - * Author: Gabe Noblesmith - */ - -/* USB Power delivery port management */ -/* For Fairchild FUSB302 */ -#ifndef __CROS_EC_DRIVER_TCPM_FUSB302_H -#define __CROS_EC_DRIVER_TCPM_FUSB302_H - -/* Chip Device ID - 302A or 302B */ -#define FUSB302_DEVID_302A 0x08 -#define FUSB302_DEVID_302B 0x09 - -/* I2C slave address varies by part number */ -/* FUSB302BUCX / FUSB302BMPX */ -#define FUSB302_I2C_SLAVE_ADDR_FLAGS 0x22 -/* FUSB302B01MPX */ -#define FUSB302_I2C_SLAVE_ADDR_B01_FLAGS 0x23 -/* FUSB302B10MPX */ -#define FUSB302_I2C_SLAVE_ADDR_B10_FLAGS 0x24 -/* FUSB302B11MPX */ -#define FUSB302_I2C_SLAVE_ADDR_B11_FLAGS 0x25 - -/* Default retry count for transmitting */ -#define PD_RETRY_COUNT 3 - -#define TCPC_REG_DEVICE_ID 0x01 - -#define TCPC_REG_SWITCHES0 0x02 -#define TCPC_REG_SWITCHES0_CC2_PU_EN (1<<7) -#define TCPC_REG_SWITCHES0_CC1_PU_EN (1<<6) -#define TCPC_REG_SWITCHES0_VCONN_CC2 (1<<5) -#define TCPC_REG_SWITCHES0_VCONN_CC1 (1<<4) -#define TCPC_REG_SWITCHES0_MEAS_CC2 (1<<3) -#define TCPC_REG_SWITCHES0_MEAS_CC1 (1<<2) -#define TCPC_REG_SWITCHES0_CC2_PD_EN (1<<1) -#define TCPC_REG_SWITCHES0_CC1_PD_EN (1<<0) - -#define TCPC_REG_SWITCHES1 0x03 -#define TCPC_REG_SWITCHES1_POWERROLE (1<<7) -#define TCPC_REG_SWITCHES1_SPECREV1 (1<<6) -#define TCPC_REG_SWITCHES1_SPECREV0 (1<<5) -#define TCPC_REG_SWITCHES1_DATAROLE (1<<4) -#define TCPC_REG_SWITCHES1_AUTO_GCRC (1<<2) -#define TCPC_REG_SWITCHES1_TXCC2_EN (1<<1) -#define TCPC_REG_SWITCHES1_TXCC1_EN (1<<0) - -#define TCPC_REG_MEASURE 0x04 -#define TCPC_REG_MEASURE_VBUS (1<<6) -/* - * MDAC reference voltage step size is 42 mV. Round our thresholds to reduce - * maximum error, which also matches suggested thresholds in datasheet - * (Table 3. Host Interrupt Summary). - */ -#define TCPC_REG_MEASURE_MDAC_MV(mv) (DIV_ROUND_NEAREST((mv), 42) & 0x3f) - -#define TCPC_REG_CONTROL0 0x06 -#define TCPC_REG_CONTROL0_TX_FLUSH (1<<6) -#define TCPC_REG_CONTROL0_INT_MASK (1<<5) -#define TCPC_REG_CONTROL0_HOST_CUR_MASK (3<<2) -#define TCPC_REG_CONTROL0_HOST_CUR_3A0 (3<<2) -#define TCPC_REG_CONTROL0_HOST_CUR_1A5 (2<<2) -#define TCPC_REG_CONTROL0_HOST_CUR_USB (1<<2) -#define TCPC_REG_CONTROL0_TX_START (1<<0) - -#define TCPC_REG_CONTROL1 0x07 -#define TCPC_REG_CONTROL1_ENSOP2DB (1<<6) -#define TCPC_REG_CONTROL1_ENSOP1DB (1<<5) -#define TCPC_REG_CONTROL1_BIST_MODE2 (1<<4) -#define TCPC_REG_CONTROL1_RX_FLUSH (1<<2) -#define TCPC_REG_CONTROL1_ENSOP2 (1<<1) -#define TCPC_REG_CONTROL1_ENSOP1 (1<<0) - -#define TCPC_REG_CONTROL2 0x08 -/* two-bit field, valid values below */ -#define TCPC_REG_CONTROL2_MODE (1<<1) -#define TCPC_REG_CONTROL2_MODE_DFP (0x3) -#define TCPC_REG_CONTROL2_MODE_UFP (0x2) -#define TCPC_REG_CONTROL2_MODE_DRP (0x1) -#define TCPC_REG_CONTROL2_MODE_POS (1) -#define TCPC_REG_CONTROL2_TOGGLE (1<<0) - -#define TCPC_REG_CONTROL3 0x09 -#define TCPC_REG_CONTROL3_SEND_HARDRESET (1<<6) -#define TCPC_REG_CONTROL3_BIST_TMODE (1<<5) /* 302B Only */ -#define TCPC_REG_CONTROL3_AUTO_HARDRESET (1<<4) -#define TCPC_REG_CONTROL3_AUTO_SOFTRESET (1<<3) -/* two-bit field */ -#define TCPC_REG_CONTROL3_N_RETRIES (1<<1) -#define TCPC_REG_CONTROL3_N_RETRIES_POS (1) -#define TCPC_REG_CONTROL3_N_RETRIES_SIZE (2) -#define TCPC_REG_CONTROL3_AUTO_RETRY (1<<0) - -#define TCPC_REG_MASK 0x0A -#define TCPC_REG_MASK_VBUSOK (1<<7) -#define TCPC_REG_MASK_ACTIVITY (1<<6) -#define TCPC_REG_MASK_COMP_CHNG (1<<5) -#define TCPC_REG_MASK_CRC_CHK (1<<4) -#define TCPC_REG_MASK_ALERT (1<<3) -#define TCPC_REG_MASK_WAKE (1<<2) -#define TCPC_REG_MASK_COLLISION (1<<1) -#define TCPC_REG_MASK_BC_LVL (1<<0) - -#define TCPC_REG_POWER 0x0B -#define TCPC_REG_POWER_PWR (1<<0) /* four-bit field */ -#define TCPC_REG_POWER_PWR_LOW 0x1 /* Bandgap + Wake circuitry */ -#define TCPC_REG_POWER_PWR_MEDIUM 0x3 /* LOW + Receiver + Current refs */ -#define TCPC_REG_POWER_PWR_HIGH 0x7 /* MEDIUM + Measure block */ -#define TCPC_REG_POWER_PWR_ALL 0xF /* HIGH + Internal Oscillator */ - -#define TCPC_REG_RESET 0x0C -#define TCPC_REG_RESET_PD_RESET (1<<1) -#define TCPC_REG_RESET_SW_RESET (1<<0) - -#define TCPC_REG_MASKA 0x0E -#define TCPC_REG_MASKA_OCP_TEMP (1<<7) -#define TCPC_REG_MASKA_TOGDONE (1<<6) -#define TCPC_REG_MASKA_SOFTFAIL (1<<5) -#define TCPC_REG_MASKA_RETRYFAIL (1<<4) -#define TCPC_REG_MASKA_HARDSENT (1<<3) -#define TCPC_REG_MASKA_TX_SUCCESS (1<<2) -#define TCPC_REG_MASKA_SOFTRESET (1<<1) -#define TCPC_REG_MASKA_HARDRESET (1<<0) - -#define TCPC_REG_MASKB 0x0F -#define TCPC_REG_MASKB_GCRCSENT (1<<0) - -#define TCPC_REG_STATUS0A 0x3C -#define TCPC_REG_STATUS0A_SOFTFAIL (1<<5) -#define TCPC_REG_STATUS0A_RETRYFAIL (1<<4) -#define TCPC_REG_STATUS0A_POWER (1<<2) /* two-bit field */ -#define TCPC_REG_STATUS0A_RX_SOFT_RESET (1<<1) -#define TCPC_REG_STATUS0A_RX_HARD_RESEt (1<<0) - -#define TCPC_REG_STATUS1A 0x3D -/* three-bit field, valid values below */ -#define TCPC_REG_STATUS1A_TOGSS (1<<3) -#define TCPC_REG_STATUS1A_TOGSS_RUNNING 0x0 -#define TCPC_REG_STATUS1A_TOGSS_SRC1 0x1 -#define TCPC_REG_STATUS1A_TOGSS_SRC2 0x2 -#define TCPC_REG_STATUS1A_TOGSS_SNK1 0x5 -#define TCPC_REG_STATUS1A_TOGSS_SNK2 0x6 -#define TCPC_REG_STATUS1A_TOGSS_AA 0x7 -#define TCPC_REG_STATUS1A_TOGSS_POS (3) -#define TCPC_REG_STATUS1A_TOGSS_MASK (0x7) - -#define TCPC_REG_STATUS1A_RXSOP2DB (1<<2) -#define TCPC_REG_STATUS1A_RXSOP1DB (1<<1) -#define TCPC_REG_STATUS1A_RXSOP (1<<0) - -#define TCPC_REG_INTERRUPTA 0x3E -#define TCPC_REG_INTERRUPTA_OCP_TEMP (1<<7) -#define TCPC_REG_INTERRUPTA_TOGDONE (1<<6) -#define TCPC_REG_INTERRUPTA_SOFTFAIL (1<<5) -#define TCPC_REG_INTERRUPTA_RETRYFAIL (1<<4) -#define TCPC_REG_INTERRUPTA_HARDSENT (1<<3) -#define TCPC_REG_INTERRUPTA_TX_SUCCESS (1<<2) -#define TCPC_REG_INTERRUPTA_SOFTRESET (1<<1) -#define TCPC_REG_INTERRUPTA_HARDRESET (1<<0) - -#define TCPC_REG_INTERRUPTB 0x3F -#define TCPC_REG_INTERRUPTB_GCRCSENT (1<<0) - -#define TCPC_REG_STATUS0 0x40 -#define TCPC_REG_STATUS0_VBUSOK (1<<7) -#define TCPC_REG_STATUS0_ACTIVITY (1<<6) -#define TCPC_REG_STATUS0_COMP (1<<5) -#define TCPC_REG_STATUS0_CRC_CHK (1<<4) -#define TCPC_REG_STATUS0_ALERT (1<<3) -#define TCPC_REG_STATUS0_WAKE (1<<2) -#define TCPC_REG_STATUS0_BC_LVL1 (1<<1) /* two-bit field */ -#define TCPC_REG_STATUS0_BC_LVL0 (1<<0) /* two-bit field */ - -#define TCPC_REG_STATUS1 0x41 -#define TCPC_REG_STATUS1_RXSOP2 (1<<7) -#define TCPC_REG_STATUS1_RXSOP1 (1<<6) -#define TCPC_REG_STATUS1_RX_EMPTY (1<<5) -#define TCPC_REG_STATUS1_RX_FULL (1<<4) -#define TCPC_REG_STATUS1_TX_EMPTY (1<<3) -#define TCPC_REG_STATUS1_TX_FULL (1<<2) - -#define TCPC_REG_INTERRUPT 0x42 -#define TCPC_REG_INTERRUPT_VBUSOK (1<<7) -#define TCPC_REG_INTERRUPT_ACTIVITY (1<<6) -#define TCPC_REG_INTERRUPT_COMP_CHNG (1<<5) -#define TCPC_REG_INTERRUPT_CRC_CHK (1<<4) -#define TCPC_REG_INTERRUPT_ALERT (1<<3) -#define TCPC_REG_INTERRUPT_WAKE (1<<2) -#define TCPC_REG_INTERRUPT_COLLISION (1<<1) -#define TCPC_REG_INTERRUPT_BC_LVL (1<<0) - -#define TCPC_REG_FIFOS 0x43 - -/* Tokens defined for the FUSB302 TX FIFO */ -enum fusb302_txfifo_tokens { - FUSB302_TKN_TXON = 0xA1, - FUSB302_TKN_SYNC1 = 0x12, - FUSB302_TKN_SYNC2 = 0x13, - FUSB302_TKN_SYNC3 = 0x1B, - FUSB302_TKN_RST1 = 0x15, - FUSB302_TKN_RST2 = 0x16, - FUSB302_TKN_PACKSYM = 0x80, - FUSB302_TKN_JAMCRC = 0xFF, - FUSB302_TKN_EOP = 0x14, - FUSB302_TKN_TXOFF = 0xFE, -}; - -extern const struct tcpm_drv fusb302_tcpm_drv; - -#endif /* __CROS_EC_DRIVER_TCPM_FUSB302_H */ diff --git a/driver/tcpm/it83xx.c b/driver/tcpm/it83xx.c deleted file mode 100644 index 14e7571dc6..0000000000 --- a/driver/tcpm/it83xx.c +++ /dev/null @@ -1,644 +0,0 @@ -/* Copyright 2016 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. - */ - -/* TCPM for MCU also running TCPC */ - -#include "common.h" -#include "config.h" -#include "console.h" -#include "it83xx_pd.h" -#include "registers.h" -#include "system.h" -#include "task.h" -#include "timer.h" -#include "util.h" -#include "usb_pd.h" -#include "usb_pd_tcpm.h" -#include "hooks.h" - -#if defined(CONFIG_USB_PD_DUAL_ROLE_AUTO_TOGGLE) || \ - defined(CONFIG_USB_PD_VBUS_DETECT_TCPC) || \ - defined(CONFIG_USB_PD_TCPC_LOW_POWER) || \ - defined(CONFIG_USB_PD_DISCHARGE_TCPC) -#error "Unsupported config options of IT83xx PD driver" -#endif - -/* Wait time for vconn power switch to turn off. */ -#ifndef PD_IT83XX_VCONN_TURN_OFF_DELAY_US -#define PD_IT83XX_VCONN_TURN_OFF_DELAY_US 500 -#endif - -const struct usbpd_ctrl_t usbpd_ctrl_regs[] = { - {&IT83XX_GPIO_GPCRF4, &IT83XX_GPIO_GPCRF5, IT83XX_IRQ_USBPD0}, - {&IT83XX_GPIO_GPCRH1, &IT83XX_GPIO_GPCRH2, IT83XX_IRQ_USBPD1}, -}; -BUILD_ASSERT(ARRAY_SIZE(usbpd_ctrl_regs) == USBPD_PORT_COUNT); - -/* - * This function disables integrated pd module and enables 5.1K resistor for - * dead battery. A EC reset or calling _init() is able to re-active pd module. - */ -void it83xx_disable_pd_module(int port) -{ - /* This only apply to PD port. */ - if (*usbpd_ctrl_regs[port].cc1 == IT83XX_USBPD_CC_PIN_CONFIG && - *usbpd_ctrl_regs[port].cc2 == IT83XX_USBPD_CC_PIN_CONFIG) { - /* Disable PD PHY */ - IT83XX_USBPD_GCR(port) &= ~(BIT(0) | BIT(4)); - /* Power down CC1/CC2 */ - IT83XX_USBPD_CCGCR(port) |= 0x1f; - /* Disable CC1/CC2 voltage detector */ - IT83XX_USBPD_CCCSR(port) = 0xff; - /* Connect 5.1K resistor to CC1/CC2 for dead battery. */ - IT83XX_USBPD_CCPSR(port) = 0x33; - } -} - -static enum tcpc_cc_voltage_status it83xx_get_cc( - enum usbpd_port port, - enum usbpd_cc_pin cc_pin) -{ - enum usbpd_ufp_volt_status ufp_volt; - enum usbpd_dfp_volt_status dfp_volt; - enum tcpc_cc_voltage_status cc_state = TYPEC_CC_VOLT_OPEN; - int pull; - - pull = (cc_pin == USBPD_CC_PIN_1) ? - USBPD_GET_CC1_PULL_REGISTER_SELECTION(port) : - USBPD_GET_CC2_PULL_REGISTER_SELECTION(port); - - /* select Rp */ - if (pull) - CLEAR_MASK(cc_state, BIT(2)); - /* select Rd */ - else - SET_MASK(cc_state, BIT(2)); - - /* sink */ - if (USBPD_GET_POWER_ROLE(port) == USBPD_POWER_ROLE_CONSUMER) { - if (cc_pin == USBPD_CC_PIN_1) - ufp_volt = IT83XX_USBPD_UFPVDR(port) & 0x7; - else - ufp_volt = (IT83XX_USBPD_UFPVDR(port) >> 4) & 0x7; - - switch (ufp_volt) { - case USBPD_UFP_STATE_SNK_DEF: - cc_state |= (TYPEC_CC_VOLT_RP_DEF & 3); - break; - case USBPD_UFP_STATE_SNK_1_5: - cc_state |= (TYPEC_CC_VOLT_RP_1_5 & 3); - break; - case USBPD_UFP_STATE_SNK_3_0: - cc_state |= (TYPEC_CC_VOLT_RP_3_0 & 3); - break; - case USBPD_UFP_STATE_SNK_OPEN: - cc_state = TYPEC_CC_VOLT_OPEN; - break; - default: - cc_state = TYPEC_CC_VOLT_OPEN; - break; - } - /* source */ - } else { - if (cc_pin == USBPD_CC_PIN_1) - dfp_volt = IT83XX_USBPD_DFPVDR(port) & 0xf; - else - dfp_volt = (IT83XX_USBPD_DFPVDR(port) >> 4) & 0xf; - - switch (dfp_volt) { - case USBPD_DFP_STATE_SRC_RA: - cc_state |= TYPEC_CC_VOLT_RA; - break; - case USBPD_DFP_STATE_SRC_RD: - cc_state |= TYPEC_CC_VOLT_RD; - break; - case USBPD_DFP_STATE_SRC_OPEN: - cc_state = TYPEC_CC_VOLT_OPEN; - break; - default: - cc_state = TYPEC_CC_VOLT_OPEN; - break; - } - } - - return cc_state; -} - -static int it83xx_tcpm_get_message_raw(int port, uint32_t *buf, int *head) -{ - int cnt = PD_HEADER_CNT(IT83XX_USBPD_RMH(port)); - - if (!USBPD_IS_RX_DONE(port)) - return EC_ERROR_UNKNOWN; - - /* store header */ - *head = IT83XX_USBPD_RMH(port); - /* check data message */ - if (cnt) - memcpy(buf, (uint32_t *)&IT83XX_USBPD_RDO0(port), cnt * 4); - /* - * Note: clear RX done interrupt after get the data. - * If clear this bit, USBPD receives next packet - */ - IT83XX_USBPD_MRSR(port) = USBPD_REG_MASK_RX_MSG_VALID; - - return EC_SUCCESS; -} - -static enum tcpc_transmit_complete it83xx_tx_data( - enum usbpd_port port, - enum tcpm_transmit_type type, - uint16_t header, - const uint32_t *buf) -{ - int r; - uint32_t evt; - uint8_t length = PD_HEADER_CNT(header); - - /* set message header */ - IT83XX_USBPD_TMHLR(port) = (uint8_t)header; - IT83XX_USBPD_TMHHR(port) = (header >> 8); - - /* - * SOP type bit[6~4]: - * on bx version and before: - * x00b=SOP, x01b=SOP', x10b=SOP", bit[6] is reserved. - * on dx version: - * 000b=SOP, 001b=SOP', 010b=SOP", 011b=Debug SOP', 100b=Debug SOP''. - */ - IT83XX_USBPD_MTSR1(port) = - (IT83XX_USBPD_MTSR1(port) & ~0x70) | ((type & 0x7) << 4); - /* bit7: transmit message is send to cable or not */ - if (TCPC_TX_SOP == type) - IT83XX_USBPD_MTSR0(port) &= ~USBPD_REG_MASK_CABLE_ENABLE; - else - IT83XX_USBPD_MTSR0(port) |= USBPD_REG_MASK_CABLE_ENABLE; - /* clear msg length */ - IT83XX_USBPD_MTSR1(port) &= (~0x7); - /* Limited by PD_HEADER_CNT() */ - ASSERT(length <= 0x7); - - if (length) { - /* set data bit */ - IT83XX_USBPD_MTSR0(port) |= BIT(4); - /* set data length setting */ - IT83XX_USBPD_MTSR1(port) |= length; - /* set data */ - memcpy((uint32_t *)&IT83XX_USBPD_TDO(port), buf, length * 4); - } - - for (r = 0; r <= PD_RETRY_COUNT; r++) { - /* Start TX */ - USBPD_KICK_TX_START(port); - evt = task_wait_event_mask(TASK_EVENT_PHY_TX_DONE, - PD_T_TCPC_TX_TIMEOUT); - /* check TX status */ - if (USBPD_IS_TX_ERR(port) || (evt & TASK_EVENT_TIMER)) { - /* - * If discard, means HW doesn't send the msg and resend. - */ - if (USBPD_IS_TX_DISCARD(port)) - continue; - /* - * Or port partner doesn't respond GoodCRC - */ - else - return TCPC_TX_COMPLETE_FAILED; - } else { - break; - } - } - - if (r > PD_RETRY_COUNT) - return TCPC_TX_COMPLETE_DISCARDED; - - return TCPC_TX_COMPLETE_SUCCESS; -} - -static enum tcpc_transmit_complete it83xx_send_hw_reset(enum usbpd_port port, - enum tcpm_transmit_type reset_type) -{ - if (reset_type == TCPC_TX_CABLE_RESET) - IT83XX_USBPD_MTSR0(port) |= USBPD_REG_MASK_CABLE_ENABLE; - else - IT83XX_USBPD_MTSR0(port) &= ~USBPD_REG_MASK_CABLE_ENABLE; - - /* send hard reset */ - USBPD_SEND_HARD_RESET(port); - usleep(MSEC); - - if (IT83XX_USBPD_MTSR0(port) & USBPD_REG_MASK_SEND_HW_RESET) - return TCPC_TX_COMPLETE_FAILED; - - return TCPC_TX_COMPLETE_SUCCESS; -} - -static void it83xx_send_bist_mode2_pattern(enum usbpd_port port) -{ - USBPD_ENABLE_SEND_BIST_MODE_2(port); - usleep(PD_T_BIST_TRANSMIT); - USBPD_DISABLE_SEND_BIST_MODE_2(port); -} - -static void it83xx_enable_vconn(enum usbpd_port port, int enabled) -{ - enum usbpd_cc_pin cc_pin; - - if (USBPD_GET_PULL_CC_SELECTION(port)) - cc_pin = USBPD_CC_PIN_1; - else - cc_pin = USBPD_CC_PIN_2; - - if (enabled) { - /* Disable unused CC to become VCONN */ - if (cc_pin == USBPD_CC_PIN_1) { - IT83XX_USBPD_CCCSR(port) = USBPD_CC2_DISCONNECTED(port); - IT83XX_USBPD_CCPSR(port) = (IT83XX_USBPD_CCPSR(port) - & ~USBPD_REG_MASK_DISCONNECT_POWER_CC2) - | USBPD_REG_MASK_DISCONNECT_POWER_CC1; - } else { - IT83XX_USBPD_CCCSR(port) = USBPD_CC1_DISCONNECTED(port); - IT83XX_USBPD_CCPSR(port) = (IT83XX_USBPD_CCPSR(port) - & ~USBPD_REG_MASK_DISCONNECT_POWER_CC1) - | USBPD_REG_MASK_DISCONNECT_POWER_CC2; - } - } else { - /* Enable cc1 and cc2 */ - IT83XX_USBPD_CCCSR(port) &= ~0xaa; - IT83XX_USBPD_CCPSR(port) |= - (USBPD_REG_MASK_DISCONNECT_POWER_CC1 | - USBPD_REG_MASK_DISCONNECT_POWER_CC2); - } -} - -static void it83xx_enable_cc(enum usbpd_port port, int enable) -{ - if (enable) - CLEAR_MASK(IT83XX_USBPD_CCGCR(port), BIT(4)); - else - SET_MASK(IT83XX_USBPD_CCGCR(port), BIT(4)); -} - -static void it83xx_set_power_role(enum usbpd_port port, int power_role) -{ - /* PD_ROLE_SINK 0, PD_ROLE_SOURCE 1 */ - if (power_role == PD_ROLE_SOURCE) { - /* - * bit[2,3] BMC Rx threshold setting - * 00b: power neutral - * 01b: sinking power => - * High to low Y3Rx threshold = 0.38, - * Low to high Y3Rx threshold = 0.54. - * 10b: sourcing power => - * High to low Y3Rx threshold = 0.64, - * Low to high Y3Rx threshold = 0.79. - */ - IT83XX_USBPD_CCADCR(port) = 0x08; - /* bit0: source */ - SET_MASK(IT83XX_USBPD_PDMSR(port), BIT(0)); - /* bit1: CC1 select Rp */ - SET_MASK(IT83XX_USBPD_CCGCR(port), BIT(1)); - /* bit3: CC2 select Rp */ - SET_MASK(IT83XX_USBPD_BMCSR(port), BIT(3)); - } else { - /* - * bit[2,3] BMC Rx threshold setting - * 00b: power neutral - * 01b: sinking power => - * High to low Y3Rx threshold = 0.38, - * Low to high Y3Rx threshold = 0.54 - * 10b: sourcing power => - * High to low Y3Rx threshold = 0.64, - * Low to high Y3Rx threshold = 0.79 - */ - IT83XX_USBPD_CCADCR(port) = 0x04; - /* bit0: sink */ - CLEAR_MASK(IT83XX_USBPD_PDMSR(port), BIT(0)); - /* bit1: CC1 select Rd */ - CLEAR_MASK(IT83XX_USBPD_CCGCR(port), BIT(1)); - /* bit3: CC2 select Rd */ - CLEAR_MASK(IT83XX_USBPD_BMCSR(port), BIT(3)); - } -} - -static void it83xx_set_data_role(enum usbpd_port port, int pd_role) -{ - /* 0: PD_ROLE_UFP 1: PD_ROLE_DFP */ - IT83XX_USBPD_PDMSR(port) = - (IT83XX_USBPD_PDMSR(port) & ~0xc) | ((pd_role & 0x1) << 2); -} - -static void it83xx_init(enum usbpd_port port, int role) -{ -#ifdef IT83XX_USBPD_CC_PARAMETER_RELOAD - /* bit7: Reload CC parameter setting. */ - IT83XX_USBPD_CCPSR0(port) |= BIT(7); -#endif - /* reset and disable HW auto generate message header */ - IT83XX_USBPD_GCR(port) = BIT(5); - USBPD_SW_RESET(port); - /* set SOP: receive SOP message only. - * bit[7]: SOP" support enable. - * bit[6]: SOP' support enable. - * bit[5]: SOP support enable. - */ - IT83XX_USBPD_PDMSR(port) = USBPD_REG_MASK_SOP_ENABLE; - /* W/C status */ - IT83XX_USBPD_ISR(port) = 0xff; - /* enable cc, select cc1 and Rd. */ - IT83XX_USBPD_CCGCR(port) = 0xd; - /* change data role as the same power role */ - it83xx_set_data_role(port, role); - /* set power role */ - it83xx_set_power_role(port, role); - /* disable all interrupts */ - IT83XX_USBPD_IMR(port) = 0xff; - /* enable tx done and reset detect interrupt */ - IT83XX_USBPD_IMR(port) &= ~(USBPD_REG_MASK_MSG_TX_DONE | - USBPD_REG_MASK_HARD_RESET_DETECT); -#ifdef IT83XX_INTC_PLUG_IN_SUPPORT - /* - * when tcpc detect type-c plug in (cc lines voltage change), it will - * interrupt fw to wake pd task, so task can react immediately. - * - * w/c status and unmask TCDCR (detect type-c plug in interrupt default - * is enable). - */ - IT83XX_USBPD_TCDCR(port) = USBPD_REG_PLUG_IN_OUT_DETECT_STAT; -#endif //IT83XX_INTC_PLUG_IN_SUPPORT - IT83XX_USBPD_CCPSR(port) = 0xff; - /* cc connect */ - IT83XX_USBPD_CCCSR(port) = 0; - /* disable vconn */ - it83xx_enable_vconn(port, 0); - /* TX start from high */ - IT83XX_USBPD_CCADCR(port) |= BIT(6); - /* enable cc1/cc2 */ - *usbpd_ctrl_regs[port].cc1 = IT83XX_USBPD_CC_PIN_CONFIG; - *usbpd_ctrl_regs[port].cc2 = IT83XX_USBPD_CC_PIN_CONFIG; - task_clear_pending_irq(usbpd_ctrl_regs[port].irq); - task_enable_irq(usbpd_ctrl_regs[port].irq); - USBPD_START(port); -} - -static void it83xx_select_polarity(enum usbpd_port port, - enum usbpd_cc_pin cc_pin) -{ - /* cc1/cc2 selection */ - if (cc_pin == USBPD_CC_PIN_1) - SET_MASK(IT83XX_USBPD_CCGCR(port), BIT(0)); - else - CLEAR_MASK(IT83XX_USBPD_CCGCR(port), BIT(0)); -} - -static int it83xx_set_cc(enum usbpd_port port, int pull) -{ - int enable_cc = 1; - - switch (pull) { - case TYPEC_CC_RD: - it83xx_set_power_role(port, PD_ROLE_SINK); - break; - case TYPEC_CC_RP: - it83xx_set_power_role(port, PD_ROLE_SOURCE); - break; - case TYPEC_CC_OPEN: - /* Power-down CC1 & CC2 to remove Rp/Rd */ - enable_cc = 0; - break; - default: - return EC_ERROR_UNIMPLEMENTED; - } - - it83xx_enable_cc(port, enable_cc); - return EC_SUCCESS; -} - -static int it83xx_tcpm_init(int port) -{ - /* Initialize physical layer */ - it83xx_init(port, PD_ROLE_DEFAULT(port)); - - return EC_SUCCESS; -} - -static int it83xx_tcpm_release(int port) -{ - return EC_ERROR_UNIMPLEMENTED; -} - -static int it83xx_tcpm_get_cc(int port, enum tcpc_cc_voltage_status *cc1, - enum tcpc_cc_voltage_status *cc2) -{ - *cc2 = it83xx_get_cc(port, USBPD_CC_PIN_2); - *cc1 = it83xx_get_cc(port, USBPD_CC_PIN_1); - - return EC_SUCCESS; -} - -static int it83xx_tcpm_select_rp_value(int port, int rp_sel) -{ - uint8_t rp; - /* - * bit[3-2]: CC output current (when Rp selected) - * 00: reserved - * 01: 330uA outpt (3.0A) - * 10: 180uA outpt (1.5A) - * 11: 80uA outpt (USB default) - */ - switch (rp_sel) { - case TYPEC_RP_1A5: - rp = 2 << 2; - break; - case TYPEC_RP_3A0: - rp = BIT(2); - break; - case TYPEC_RP_USB: - default: - rp = 3 << 2; - break; - } - IT83XX_USBPD_CCGCR(port) = (IT83XX_USBPD_CCGCR(port) & ~(3 << 2)) | rp; - - return EC_SUCCESS; -} - -static int it83xx_tcpm_set_cc(int port, int pull) -{ - return it83xx_set_cc(port, pull); -} - -static int it83xx_tcpm_set_polarity(int port, int polarity) -{ - it83xx_select_polarity(port, polarity); - - return EC_SUCCESS; -} - -static int it83xx_tcpm_set_vconn(int port, int enable) -{ - /* - * IT83XX doesn't have integrated circuit to source CC lines for VCONN. - * An external device like PPC or Power Switch has to source the VCONN. - */ - if (IS_ENABLED(CONFIG_USBC_VCONN)) { - if (enable) { - /* - * Unused cc will become Vconn SRC, disable cc analog - * module (ex.UP/RD/DET/Tx/Rx) and enable 5v tolerant. - */ - it83xx_enable_vconn(port, enable); - if (IS_ENABLED(CONFIG_USB_PD_DECODE_SOP)) - /* Enable tcpc receive SOP' packet */ - IT83XX_USBPD_PDMSR(port) |= - USBPD_REG_MASK_SOPP_ENABLE; - } - - /* Turn on/off vconn power switch. */ - board_pd_vconn_ctrl(port, - USBPD_GET_PULL_CC_SELECTION(port) ? - USBPD_CC_PIN_2 : USBPD_CC_PIN_1, enable); - - if (!enable) { - /* Disable tcpc receive SOP' packet */ - if (IS_ENABLED(CONFIG_USB_PD_DECODE_SOP)) - IT83XX_USBPD_PDMSR(port) &= - ~USBPD_REG_MASK_SOPP_ENABLE; - /* - * We need to make sure cc voltage detector is enabled - * after vconn is turned off to avoid the potential risk - * of voltage fed back into Vcore. - */ - usleep(PD_IT83XX_VCONN_TURN_OFF_DELAY_US); - /* - * Since our cc are not Vconn SRC, enable cc analog - * module (ex.UP/RD/DET/Tx/Rx) and disable 5v tolerant. - */ - it83xx_enable_vconn(port, enable); - } - } - - return EC_SUCCESS; -} - -static int it83xx_tcpm_set_msg_header(int port, int power_role, int data_role) -{ - /* PD_ROLE_SINK 0, PD_ROLE_SOURCE 1 */ - if (power_role == PD_ROLE_SOURCE) - /* bit0: source */ - SET_MASK(IT83XX_USBPD_PDMSR(port), BIT(0)); - else - /* bit0: sink */ - CLEAR_MASK(IT83XX_USBPD_PDMSR(port), BIT(0)); - - it83xx_set_data_role(port, data_role); - - return EC_SUCCESS; -} - -static int it83xx_tcpm_set_rx_enable(int port, int enable) -{ - int i; - - if (enable) { - IT83XX_USBPD_IMR(port) &= ~USBPD_REG_MASK_MSG_RX_DONE; - USBPD_ENABLE_BMC_PHY(port); - } else { - IT83XX_USBPD_IMR(port) |= USBPD_REG_MASK_MSG_RX_DONE; - USBPD_DISABLE_BMC_PHY(port); - } - - /* If any PD port is connected, then disable deep sleep */ - for (i = 0; i < board_get_usb_pd_port_count(); ++i) - if (IT83XX_USBPD_GCR(i) | USBPD_REG_MASK_BMC_PHY) - break; - - if (i == board_get_usb_pd_port_count()) - enable_sleep(SLEEP_MASK_USB_PD); - else - disable_sleep(SLEEP_MASK_USB_PD); - - return EC_SUCCESS; -} - -static int it83xx_tcpm_transmit(int port, - enum tcpm_transmit_type type, - uint16_t header, - const uint32_t *data) -{ - int status = TCPC_TX_COMPLETE_FAILED; - - switch (type) { - case TCPC_TX_SOP: - case TCPC_TX_SOP_PRIME: - case TCPC_TX_SOP_PRIME_PRIME: - case TCPC_TX_SOP_DEBUG_PRIME: - case TCPC_TX_SOP_DEBUG_PRIME_PRIME: - status = it83xx_tx_data(port, - type, - header, - data); - break; - case TCPC_TX_BIST_MODE_2: - it83xx_send_bist_mode2_pattern(port); - status = TCPC_TX_COMPLETE_SUCCESS; - break; - case TCPC_TX_HARD_RESET: - case TCPC_TX_CABLE_RESET: - status = it83xx_send_hw_reset(port, type); - break; - default: - status = TCPC_TX_COMPLETE_FAILED; - break; - } - pd_transmit_complete(port, status); - - return EC_SUCCESS; -} - -static int it83xx_tcpm_get_chip_info(int port, int live, - struct ec_response_pd_chip_info_v1 **chip_info) -{ - static struct ec_response_pd_chip_info_v1 i; - - *chip_info = &i; - i.vendor_id = USB_VID_ITE; - i.product_id = (IT83XX_GCTRL_CHIPID1 << 8) | IT83XX_GCTRL_CHIPID2; - i.device_id = IT83XX_GCTRL_CHIPVER & 0xf; - i.fw_version_number = 0xEC; - - return EC_SUCCESS; -} - -static void it83xx_tcpm_sw_reset(void) -{ - int port = TASK_ID_TO_PD_PORT(task_get_current()); -#ifdef IT83XX_INTC_PLUG_IN_SUPPORT - /* - * Enable detect type-c plug in interrupt, since the pd task has - * detected a type-c physical disconnected. - */ - IT83XX_USBPD_TCDCR(port) &= ~USBPD_REG_PLUG_IN_OUT_DETECT_DISABLE; -#endif //IT83XX_INTC_PLUG_IN_SUPPORT - /* exit BIST test data mode */ - USBPD_SW_RESET(port); -} - -DECLARE_HOOK(HOOK_USB_PD_DISCONNECT, it83xx_tcpm_sw_reset, HOOK_PRIO_DEFAULT); - -const struct tcpm_drv it83xx_tcpm_drv = { - .init = &it83xx_tcpm_init, - .release = &it83xx_tcpm_release, - .get_cc = &it83xx_tcpm_get_cc, - .select_rp_value = &it83xx_tcpm_select_rp_value, - .set_cc = &it83xx_tcpm_set_cc, - .set_polarity = &it83xx_tcpm_set_polarity, - .set_vconn = &it83xx_tcpm_set_vconn, - .set_msg_header = &it83xx_tcpm_set_msg_header, - .set_rx_enable = &it83xx_tcpm_set_rx_enable, - .get_message_raw = &it83xx_tcpm_get_message_raw, - .transmit = &it83xx_tcpm_transmit, - .get_chip_info = &it83xx_tcpm_get_chip_info, -}; diff --git a/driver/tcpm/it83xx_pd.h b/driver/tcpm/it83xx_pd.h deleted file mode 100644 index 9e8bff1342..0000000000 --- a/driver/tcpm/it83xx_pd.h +++ /dev/null @@ -1,109 +0,0 @@ -/* Copyright 2016 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. - */ - -/* USB Power delivery port management */ -#ifndef __CROS_EC_DRIVER_TCPM_IT83XX_H -#define __CROS_EC_DRIVER_TCPM_IT83XX_H - -/* - * Dedicated setting for CC pin. - * This setting will connect CC pin to internal PD module directly without - * applying any GPIO/ALT configuration. - */ -#define IT83XX_USBPD_CC_PIN_CONFIG 0x86 - -#define TASK_EVENT_PHY_TX_DONE TASK_EVENT_CUSTOM_BIT(PD_EVENT_FIRST_FREE_BIT) - -#define SET_MASK(reg, bit_mask) ((reg) |= (bit_mask)) -#define CLEAR_MASK(reg, bit_mask) ((reg) &= (~(bit_mask))) -#define IS_MASK_SET(reg, bit_mask) (((reg) & (bit_mask)) != 0) -#define IS_MASK_CLEAR(reg, bit_mask) (((reg) & (bit_mask)) == 0) - -/* macros for set */ -#define USBPD_KICK_TX_START(port) \ - SET_MASK(IT83XX_USBPD_MTCR(port), \ - USBPD_REG_MASK_TX_START) -#define USBPD_SEND_HARD_RESET(port) \ - SET_MASK(IT83XX_USBPD_MTSR0(port), \ - USBPD_REG_MASK_SEND_HW_RESET) -#define USBPD_SW_RESET(port) \ - SET_MASK(IT83XX_USBPD_GCR(port), \ - USBPD_REG_MASK_SW_RESET_BIT) -#define USBPD_ENABLE_BMC_PHY(port) \ - SET_MASK(IT83XX_USBPD_GCR(port), \ - USBPD_REG_MASK_BMC_PHY) -#define USBPD_DISABLE_BMC_PHY(port) \ - CLEAR_MASK(IT83XX_USBPD_GCR(port), \ - USBPD_REG_MASK_BMC_PHY) -#define USBPD_START(port) \ - CLEAR_MASK(IT83XX_USBPD_CCGCR(port), \ - USBPD_REG_MASK_DISABLE_CC) -#define USBPD_ENABLE_SEND_BIST_MODE_2(port) \ - SET_MASK(IT83XX_USBPD_MTSR0(port), \ - USBPD_REG_MASK_SEND_BIST_MODE_2) -#define USBPD_DISABLE_SEND_BIST_MODE_2(port) \ - CLEAR_MASK(IT83XX_USBPD_MTSR0(port), \ - USBPD_REG_MASK_SEND_BIST_MODE_2) - -/* macros for get */ -#define USBPD_GET_POWER_ROLE(port) \ - (IT83XX_USBPD_PDMSR(port) & 1) -#define USBPD_GET_CC1_PULL_REGISTER_SELECTION(port) \ - (IT83XX_USBPD_CCGCR(port) & BIT(1)) -#define USBPD_GET_CC2_PULL_REGISTER_SELECTION(port) \ - (IT83XX_USBPD_BMCSR(port) & BIT(3)) -#define USBPD_GET_PULL_CC_SELECTION(port) \ - (IT83XX_USBPD_CCGCR(port) & 1) - -/* macros for check */ -#define USBPD_IS_TX_ERR(port) \ - IS_MASK_SET(IT83XX_USBPD_MTCR(port), USBPD_REG_MASK_TX_ERR_STAT) -#define USBPD_IS_TX_DISCARD(port) \ - IS_MASK_SET(IT83XX_USBPD_MTCR(port), USBPD_REG_MASK_TX_DISCARD_STAT) - -/* macros for PD ISR */ -#define USBPD_IS_HARD_RESET_DETECT(port) \ - IS_MASK_SET(IT83XX_USBPD_ISR(port), USBPD_REG_MASK_HARD_RESET_DETECT) -#define USBPD_IS_TX_DONE(port) \ - IS_MASK_SET(IT83XX_USBPD_ISR(port), USBPD_REG_MASK_MSG_TX_DONE) -#define USBPD_IS_RX_DONE(port) \ - IS_MASK_SET(IT83XX_USBPD_ISR(port), USBPD_REG_MASK_MSG_RX_DONE) -#ifdef IT83XX_INTC_PLUG_IN_SUPPORT -#define USBPD_IS_PLUG_IN_OUT_DETECT(port)\ - IS_MASK_SET(IT83XX_USBPD_TCDCR(port), USBPD_REG_PLUG_IN_OUT_DETECT_STAT) -#endif //IT83XX_INTC_PLUG_IN_SUPPORT - -enum usbpd_ufp_volt_status { - USBPD_UFP_STATE_SNK_OPEN = 0, - USBPD_UFP_STATE_SNK_DEF = 1, - USBPD_UFP_STATE_SNK_1_5 = 3, - USBPD_UFP_STATE_SNK_3_0 = 7, -}; - -enum usbpd_dfp_volt_status { - USBPD_DFP_STATE_SRC_RA = 0, - USBPD_DFP_STATE_SRC_RD = 1, - USBPD_DFP_STATE_SRC_OPEN = 3, -}; - -enum usbpd_power_role { - USBPD_POWER_ROLE_CONSUMER, - USBPD_POWER_ROLE_PROVIDER, - USBPD_POWER_ROLE_CONSUMER_PROVIDER, - USBPD_POWER_ROLE_PROVIDER_CONSUMER, -}; - -struct usbpd_ctrl_t { - volatile uint8_t *cc1; - volatile uint8_t *cc2; - uint8_t irq; -}; - -extern const struct usbpd_ctrl_t usbpd_ctrl_regs[]; -extern const struct tcpm_drv it83xx_tcpm_drv; -/* Disable integrated pd module */ -void it83xx_disable_pd_module(int port); - -#endif /* __CROS_EC_DRIVER_TCPM_IT83XX_H */ diff --git a/driver/tcpm/mt6370.c b/driver/tcpm/mt6370.c deleted file mode 100644 index 8a50b480f6..0000000000 --- a/driver/tcpm/mt6370.c +++ /dev/null @@ -1,218 +0,0 @@ -/* Copyright 2018 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. - * - * MT6370 TCPC Driver - */ - -#include "console.h" -#include "hooks.h" -#include "mt6370.h" -#include "task.h" -#include "tcpci.h" -#include "tcpm.h" -#include "timer.h" -#include "usb_mux.h" -#include "usb_pd.h" -#include "util.h" - -#define CPRINTS(format, args...) cprints(CC_USBCHARGE, format, ## args) -#define CPRINTF(format, args...) cprintf(CC_USBCHARGE, format, ## args) - -static int mt6370_polarity; - -/* i2c_write function which won't wake TCPC from low power mode. */ -static int mt6370_i2c_write8(int port, int reg, int val) -{ - return i2c_write8(tcpc_config[port].i2c_info.port, - tcpc_config[port].i2c_info.addr_flags, reg, val); -} - -static int mt6370_init(int port) -{ - int rv, val; - - rv = tcpc_read(port, MT6370_REG_IDLE_CTRL, &val); - - /* Only do soft-reset in shipping mode. (b:122017882) */ - if (!(val & MT6370_REG_SHIPPING_OFF)) { - - /* Software reset. */ - rv = tcpc_write(port, MT6370_REG_SWRESET, 1); - if (rv) - return rv; - - /* Need 1 ms for software reset. */ - msleep(1); - } - - /* The earliest point that we can do generic init. */ - rv = tcpci_tcpm_init(port); - - if (rv) - return rv; - - /* - * AUTO IDLE off, shipping off, select CK_300K from BICIO_320K, - * PD3.0 ext-msg on. - */ - rv = tcpc_write(port, MT6370_REG_IDLE_CTRL, - MT6370_REG_IDLE_SET(0, 1, 0, 0)); - /* CC Detect Debounce 5 */ - rv |= tcpc_write(port, MT6370_REG_TTCPC_FILTER, 5); - /* DRP Duty */ - rv |= tcpc_write(port, MT6370_REG_DRP_TOGGLE_CYCLE, 4); - rv |= tcpc_write16(port, MT6370_REG_DRP_DUTY_CTRL, 400); - /* Vconn OC on */ - rv |= tcpc_write(port, MT6370_REG_VCONN_CLIMITEN, 1); - /* PHY control */ - rv |= tcpc_write(port, MT6370_REG_PHY_CTRL1, - MT6370_REG_PHY_CTRL1_SET(0, 7, 0, 1)); - rv |= tcpc_write(port, MT6370_REG_PHY_CTRL3, 0x82); - - return rv; -} - -static inline int mt6370_init_cc_params(int port, int cc_res) -{ - int rv, en, sel; - - if (cc_res == TYPEC_CC_VOLT_RP_DEF) { /* RXCC threshold : 0.55V */ - en = 1; - sel = MT6370_OCCTRL_600MA | MT6370_MASK_BMCIO_RXDZSEL; - } else { /* RD threshold : 0.4V & RP threshold : 0.7V */ - en = 0; - sel = MT6370_OCCTRL_600MA; - } - rv = tcpc_write(port, MT6370_REG_BMCIO_RXDZEN, en); - if (!rv) - rv = tcpc_write(port, MT6370_REG_BMCIO_RXDZSEL, sel); - return rv; -} - -static int mt6370_get_cc(int port, enum tcpc_cc_voltage_status *cc1, - enum tcpc_cc_voltage_status *cc2) -{ - int status; - int rv; - int role, is_snk; - - rv = tcpc_read(port, TCPC_REG_CC_STATUS, &status); - - /* If tcpc read fails, return error and CC as open */ - if (rv) { - *cc1 = TYPEC_CC_VOLT_OPEN; - *cc2 = TYPEC_CC_VOLT_OPEN; - return rv; - } - - *cc1 = TCPC_REG_CC_STATUS_CC1(status); - *cc2 = TCPC_REG_CC_STATUS_CC2(status); - - /* - * If status is not open, then OR in termination to convert to - * enum tcpc_cc_voltage_status. - * - * MT6370 TCPC follows USB PD 1.0 protocol. When DRP not auto-toggling, - * it will not update the DRP_RESULT bits in TCPC_REG_CC_STATUS, - * instead, we should check CC1/CC2 bits in TCPC_REG_ROLE_CTRL. - */ - rv = tcpc_read(port, TCPC_REG_ROLE_CTRL, &role); - - if (TCPC_REG_ROLE_CTRL_DRP(role)) - is_snk = TCPC_REG_CC_STATUS_TERM(status); - else - /* CC1/CC2 states are the same, checking one-side is enough. */ - is_snk = TCPC_REG_CC_STATUS_CC1(role) == TYPEC_CC_RD; - - if (is_snk) { - if (*cc1 != TYPEC_CC_VOLT_OPEN) - *cc1 |= 0x04; - if (*cc2 != TYPEC_CC_VOLT_OPEN) - *cc2 |= 0x04; - } - - rv = mt6370_init_cc_params(port, (int)mt6370_polarity ? *cc1 : *cc2); - return rv; -} - -static int mt6370_set_cc(int port, int pull) -{ - if (pull == TYPEC_CC_RD) - mt6370_init_cc_params(port, TYPEC_CC_VOLT_RP_DEF); - return tcpci_tcpm_set_cc(port, pull); -} - -#ifdef CONFIG_USB_PD_TCPC_LOW_POWER -static int mt6370_enter_low_power_mode(int port) -{ - int rv; - - /* VBUS_DET_EN for detecting charger plug. */ - rv = tcpc_write(port, MT6370_REG_BMC_CTRL, - MT6370_REG_BMCIO_LPEN | MT6370_REG_VBUS_DET_EN); - - if (rv) - return rv; - - return tcpci_enter_low_power_mode(port); -} -#endif - -static int mt6370_set_polarity(int port, int polarity) -{ - enum tcpc_cc_voltage_status cc1, cc2; - - mt6370_polarity = polarity; - mt6370_get_cc(port, &cc1, &cc2); - return tcpci_tcpm_set_polarity(port, polarity); -} - -int mt6370_vconn_discharge(int port) -{ - /* - * Write to mt6370 in low-power mode may return fail, but it is - * actually written. So we just ignore its return value. - */ - mt6370_i2c_write8(port, MT6370_REG_OVP_FLAG_SEL, - MT6370_REG_DISCHARGE_LVL); - /* Set MT6370_REG_DISCHARGE_EN bit and also the rest default value. */ - mt6370_i2c_write8(port, MT6370_REG_BMC_CTRL, - MT6370_REG_DISCHARGE_EN | - MT6370_REG_BMC_CTRL_DEFAULT); - - return EC_SUCCESS; -} - -/* MT6370 is a TCPCI compatible port controller */ -const struct tcpm_drv mt6370_tcpm_drv = { - .init = &mt6370_init, - .release = &tcpci_tcpm_release, - .get_cc = &mt6370_get_cc, -#ifdef CONFIG_USB_PD_VBUS_DETECT_TCPC - .get_vbus_level = &tcpci_tcpm_get_vbus_level, -#endif - .select_rp_value = &tcpci_tcpm_select_rp_value, - .set_cc = &mt6370_set_cc, - .set_polarity = &mt6370_set_polarity, - .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_USBC_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 = &mt6370_enter_low_power_mode, -#endif -}; diff --git a/driver/tcpm/mt6370.h b/driver/tcpm/mt6370.h deleted file mode 100644 index cdc3112a3e..0000000000 --- a/driver/tcpm/mt6370.h +++ /dev/null @@ -1,200 +0,0 @@ -/* Copyright 2018 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. - * - * MT6370 TCPC Driver - */ - -#ifndef __CROS_EC_USB_PD_TCPM_MT6370_H -#define __CROS_EC_USB_PD_TCPM_MT6370_H - -/* MT6370 Private RegMap */ - -#define MT6370_REG_PHY_CTRL1 0x80 -#define MT6370_REG_PHY_CTRL2 0x81 -#define MT6370_REG_PHY_CTRL3 0x82 -#define MT6370_REG_PHY_CTRL6 0x85 - -#define MT6370_REG_CLK_CTRL2 0x87 -#define MT6370_REG_CLK_CTRL3 0x88 - -#define MT6370_REG_RUST_STATUS 0x8A -#define MT6370_REG_RUST_INT_EVENT 0x8B -#define MT6370_REG_RUST_MASK 0x8C -#define MT6370_REG_BMC_CTRL 0x90 -#define MT6370_REG_BMCIO_RXDZSEL 0x93 -#define MT6370_REG_VCONN_CLIMITEN 0x95 - -#define MT6370_REG_OVP_FLAG_SEL 0x96 - -#define MT6370_REG_RT_STATUS 0x97 -#define MT6370_REG_RT_INT 0x98 -#define MT6370_REG_RT_MASK 0x99 -#define RT5081_REG_BMCIO_RXDZEN 0x9A -#define MT6370_REG_IDLE_CTRL 0x9B -#define MT6370_REG_INTRST_CTRL 0x9C -#define MT6370_REG_WATCHDOG_CTRL 0x9D -#define MT6370_REG_I2CRST_CTRL 0X9E - -#define MT6370_REG_SWRESET 0xA0 -#define MT6370_REG_TTCPC_FILTER 0xA1 -#define MT6370_REG_DRP_TOGGLE_CYCLE 0xA2 -#define MT6370_REG_DRP_DUTY_CTRL 0xA3 -#define MT6370_REG_RUST_DETECTION 0xAD -#define MT6370_REG_RUST_CONTROL 0xAE -#define MT6370_REG_BMCIO_RXDZEN 0xAF -#define MT6370_REG_DRP_RUST 0xB9 - -#define MT6370_REG_UNLOCK_PW2 0xF0 -#define MT6370_REG_UNLOCK_PW1 0xF1 - -#define MT6370_TCPC_I2C_ADDR_FLAGS 0x4E - -/* - * MT6370_REG_PHY_CTRL1 0x80 - */ - -#define MT6370_REG_PHY_CTRL1_SET(retry_discard, toggle_cnt, bus_idle_cnt, \ - rx_filter) \ - ((retry_discard << 7) | (toggle_cnt << 4) | (bus_idle_cnt << 2) | \ - (rx_filter & 0x03)) - -/* - * MT6370_REG_CLK_CTRL2 0x87 - */ - -#define MT6370_REG_CLK_DIV_600K_EN BIT(7) -#define MT6370_REG_CLK_BCLK2_EN BIT(6) -#define MT6370_REG_CLK_BCLK2_TG_EN BIT(5) -#define MT6370_REG_CLK_DIV_300K_EN BIT(3) -#define MT6370_REG_CLK_CK_300K_EN BIT(2) -#define MT6370_REG_CLK_BCLK_EN BIT(1) -#define MT6370_REG_CLK_BCLK_TH_EN BIT(0) - -/* - * MT6370_REG_CLK_CTRL3 0x88 - */ - -#define MT6370_REG_CLK_OSCMUX_RG_EN BIT(7) -#define MT6370_REG_CLK_CK_24M_EN BIT(6) -#define MT6370_REG_CLK_OSC_RG_EN BIT(5) -#define MT6370_REG_CLK_DIV_2P4M_EN BIT(4) -#define MT6370_REG_CLK_CK_2P4M_EN BIT(3) -#define MT6370_REG_CLK_PCLK_EN BIT(2) -#define MT6370_REG_CLK_PCLK_RG_EN BIT(1) -#define MT6370_REG_CLK_PCLK_TG_EN BIT(0) - -/* - * MT6370_REG_RX_TX_DBG 0x8b - */ - -#define MT6370_REG_RX_TX_DBG_RX_BUSY BIT(7) -#define MT6370_REG_RX_TX_DBG_TX_BUSY BIT(6) - -/* - * MT6370_REG_BMC_CTRL 0x90 - */ - -#define MT6370_REG_IDLE_EN BIT(6) -#define MT6370_REG_DISCHARGE_EN BIT(5) -#define MT6370_REG_BMCIO_LPRPRD BIT(4) -#define MT6370_REG_BMCIO_LPEN BIT(3) -#define MT6370_REG_BMCIO_BG_EN BIT(2) -#define MT6370_REG_VBUS_DET_EN BIT(1) -#define MT6370_REG_BMCIO_OSC_EN BIT(0) -#define MT6370_REG_BMC_CTRL_DEFAULT \ - (MT6370_REG_BMCIO_BG_EN | MT6370_REG_VBUS_DET_EN | \ - MT6370_REG_BMCIO_OSC_EN) - -/* - * MT6370_REG_BMCIO_RXDZSEL 0x93 - */ - -#define MT6370_MASK_OCCTRL_SEL 0xE0 -#define MT6370_OCCTRL_600MA 0x80 -#define MT6370_MASK_BMCIO_RXDZSEL BIT(0) - -/* - * MT6370_REG_OVP_FLAG_SEL 0x96 - */ - -#define MT6370_MASK_DISCHARGE_LVL 0x03 -#define MT6370_REG_DISCHARGE_LVL BIT(0) - -/* - * MT6370_REG_RT_STATUS 0x97 - */ - -#define MT6370_REG_RA_DETACH BIT(5) -#define MT6370_REG_VBUS_80 BIT(1) - -/* - * MT6370_REG_RT_INT 0x98 - */ - -#define MT6370_REG_INT_RA_DETACH BIT(5) -#define MT6370_REG_INT_WATCHDOG BIT(2) -#define MT6370_REG_INT_VBUS_80 BIT(1) -#define MT6370_REG_INT_WAKEUP BIT(0) - -/* - * MT6370_REG_RT_MASK 0x99 - */ - -#define MT6370_REG_M_RA_DETACH BIT(5) -#define MT6370_REG_M_WATCHDOG BIT(2) -#define MT6370_REG_M_VBUS_80 BIT(1) -#define MT6370_REG_M_WAKEUP BIT(0) - -/* - * MT6370_REG_IDLE_CTRL 0x9B - */ - -#define MT6370_REG_CK_300K_SEL BIT(7) -#define MT6370_REG_SHIPPING_OFF BIT(5) -#define MT6370_REG_ENEXTMSG BIT(4) -#define MT6370_REG_AUTOIDLE_EN BIT(3) - -/* timeout = (tout*2+1) * 6.4ms */ -#ifdef CONFIG_USB_PD_REV30 -#define MT6370_REG_IDLE_SET(ck300, ship_dis, auto_idle, tout) \ - ((ck300 << 7) | (ship_dis << 5) | (auto_idle << 3) | (tout & 0x07) | \ - MT6370_REG_ENEXTMSG) -#else -#define MT6370_REG_IDLE_SET(ck300, ship_dis, auto_idle, tout) \ - ((ck300 << 7) | (ship_dis << 5) | (auto_idle << 3) | (tout & 0x07)) -#endif - -/* - * MT6370_REG_INTRST_CTRL 0x9C - */ - -#define MT6370_REG_INTRST_EN BIT(7) - -/* timeout = (tout+1) * 0.2sec */ -#define MT6370_REG_INTRST_SET(en, tout) ((en << 7) | (tout & 0x03)) - -/* - * MT6370_REG_WATCHDOG_CTRL 0x9D - */ - -#define MT6370_REG_WATCHDOG_EN BIT(7) - -/* timeout = (tout+1) * 0.4sec */ -#define MT6370_REG_WATCHDOG_CTRL_SET(en, tout) ((en << 7) | (tout & 0x07)) - -/* - * MT6370_REG_I2CRST_CTRL 0x9E - */ - -#define MT6370_REG_I2CRST_EN BIT(7) - -/* timeout = (tout+1) * 12.5ms */ -#define MT6370_REG_I2CRST_SET(en, tout) ((en << 7) | (tout & 0x0f)) - -extern const struct tcpm_drv mt6370_tcpm_drv; - -/* Enable VCONN discharge. */ -int mt6370_vconn_discharge(int port); - -#endif /* __CROS_EC_USB_PD_TCPM_MT6370_H */ diff --git a/driver/tcpm/nct38xx.c b/driver/tcpm/nct38xx.c deleted file mode 100644 index 9d91c21b30..0000000000 --- a/driver/tcpm/nct38xx.c +++ /dev/null @@ -1,384 +0,0 @@ -/* - * 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. - */ - -/* Type-C port manager for Nuvoton NCT38XX. */ - -#include "common.h" -#include "console.h" -#include "ioexpander_nct38xx.h" -#include "nct38xx.h" -#include "tcpci.h" - -#if !defined(CONFIG_USB_PD_TCPM_TCPCI) -#error "NCT38XX is using part of standard TCPCI control" -#error "Please upgrade your board configuration" -#endif - -#define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args) -#define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args) - -#define POLARITY_NORMAL 0 -#define POLARITY_FLIPPED 1 -#define POLARITY_NONE 3 - -static int cable_polarity[CONFIG_USB_PD_PORT_MAX_COUNT]; -static unsigned char txBuf[33]; -static unsigned char rxBuf[33]; -/* Save the selected rp value */ -static int selected_rp[CONFIG_USB_PD_PORT_MAX_COUNT]; - -static int nct38xx_tcpm_init(int port) -{ - int rv = 0; - int reg; - - cable_polarity[port] = POLARITY_NONE; - - rv = tcpci_tcpm_init(port); - if (rv) - return rv; - - /* - * Write to the CONTROL_OUT_EN register to enable: - * [6] - CONNDIREN : Connector direction indication output enable - * [2] - SNKEN : VBUS sink enable output enable - * [0] - SRCEN : VBUS source voltage enable output enable - */ - reg = NCT38XX_REG_CTRL_OUT_EN_SRCEN | - NCT38XX_REG_CTRL_OUT_EN_SNKEN | - NCT38XX_REG_CTRL_OUT_EN_CONNDIREN; - - rv = tcpc_write(port, NCT38XX_REG_CTRL_OUT_EN, reg); - if (rv) - return rv; - - /* Disable OVP */ - rv = tcpc_read(port, TCPC_REG_FAULT_CTRL, ®); - if (rv) - return rv; - reg = reg | TCPC_REG_FAULT_CTRL_VBUS_OVP_FAULT_DIS; - rv = tcpc_write(port, TCPC_REG_FAULT_CTRL, reg); - if (rv) - return rv; - - /* Enable VBus monitor and Disable FRS */ - rv = tcpc_read(port, TCPC_REG_POWER_CTRL, ®); - if (rv) - return rv; - reg = reg & ~(TCPC_REG_POWER_CTRL_VBUS_VOL_MONITOR_DIS | - TCPC_REG_POWER_CTRL_FRS_ENABLE); - rv = tcpc_write(port, TCPC_REG_POWER_CTRL, reg); - if (rv) - return rv; - - /* Set FRS direction for SNK detect, if FRS is enabled */ - if (IS_ENABLED(CONFIG_USB_TYPEC_PD_FAST_ROLE_SWAP)) { - reg = TCPC_REG_DEV_CAP_2_SNK_FR_SWAP; - rv = tcpc_write(port, TCPC_REG_DEV_CAP_2, reg); - if (rv) - return rv; - - reg = TCPC_REG_CONFIG_EXT_1_FR_SWAP_SNK_DIR; - rv = tcpc_write(port, TCPC_REG_CONFIG_EXT_1, reg); - if (rv) - return rv; - } - - /* Start VBus monitor */ - rv = tcpc_write(port, TCPC_REG_COMMAND, - TCPC_REG_COMMAND_ENABLE_VBUS_DETECT); - - /* - * Enable the Vendor Define alert event only when the IO expander - * feature is defined - */ - if (IS_ENABLED(CONFIG_IO_EXPANDER_NCT38XX)) { - int mask; - - rv |= tcpc_read16(port, TCPC_REG_ALERT_MASK, &mask); - mask |= TCPC_REG_ALERT_VENDOR_DEF; - rv |= tcpc_write16(port, TCPC_REG_ALERT_MASK, mask); - } - return rv; -} - -static int tcpci_nct38xx_select_rp_value(int port, int rp) -{ - selected_rp[port] = rp; - return EC_SUCCESS; -} - -static int auto_discharge_disconnect(int port, int enable) -{ - int reg, rv; - - rv = tcpc_read(port, TCPC_REG_POWER_CTRL, ®); - if (rv) - return rv; - - if (enable) - reg = reg | TCPC_REG_POWER_CTRL_AUTO_DISCHARGE_DISCONNECT; - else - reg = reg & ~TCPC_REG_POWER_CTRL_AUTO_DISCHARGE_DISCONNECT; - rv = tcpc_write(port, TCPC_REG_POWER_CTRL, reg); - return rv; - -} - -static int tcpci_nct38xx_check_cable_polarity(int port) -{ - int cc, rv; - - /* Try to check the polarity */ - rv = tcpc_read(port, TCPC_REG_CC_STATUS, &cc); - if (rv) - return rv; - - if (TCPC_REG_CC_STATUS_TERM(cc)) { - /* TCPC is presenting RD (Sink mode) */ - if ((TCPC_REG_CC_STATUS_CC1(cc) != TYPEC_CC_VOLT_OPEN) && - (TCPC_REG_CC_STATUS_CC2(cc) == TYPEC_CC_VOLT_OPEN)) { - /* CC1 active && CC2 open */ - cable_polarity[port] = POLARITY_NORMAL; - } - if ((TCPC_REG_CC_STATUS_CC1(cc) == TYPEC_CC_VOLT_OPEN) && - (TCPC_REG_CC_STATUS_CC2(cc) != TYPEC_CC_VOLT_OPEN)) { - /* CC1 open && CC2 active */ - cable_polarity[port] = POLARITY_FLIPPED; - } - } else { - /* TCPC is presenting RP (Source mode) */ - if ((TCPC_REG_CC_STATUS_CC1(cc) == TYPEC_CC_VOLT_RD) && - (TCPC_REG_CC_STATUS_CC2(cc) != TYPEC_CC_VOLT_RD)) { - /* CC1 active && CC2 open */ - cable_polarity[port] = POLARITY_NORMAL; - } - if ((TCPC_REG_CC_STATUS_CC1(cc) != TYPEC_CC_VOLT_RD) && - (TCPC_REG_CC_STATUS_CC2(cc) == TYPEC_CC_VOLT_RD)) { - /* CC1 open && CC2 active */ - cable_polarity[port] = POLARITY_FLIPPED; - } - } - return rv; -} - - /* - * TODO(crbug.com/951681): This code can be simplified once that bug is fixed. - */ -static int tcpci_nct38xx_set_cc(int port, int pull) -{ - - int rv; - - if (cable_polarity[port] == POLARITY_NONE) { - rv = tcpci_nct38xx_check_cable_polarity(port); - if (rv) - return rv; - } - - if (cable_polarity[port] == POLARITY_NORMAL) { - rv = tcpc_write(port, TCPC_REG_ROLE_CTRL, - TCPC_REG_ROLE_CTRL_SET(0, selected_rp[port], - pull, TYPEC_CC_OPEN)); - } else if (cable_polarity[port] == POLARITY_FLIPPED) { - rv = tcpc_write(port, TCPC_REG_ROLE_CTRL, - TCPC_REG_ROLE_CTRL_SET(0, selected_rp[port], - TYPEC_CC_OPEN, pull)); - } else { - return -1; - } - - return rv; -} - -static int tcpci_nct38xx_get_cc(int port, enum tcpc_cc_voltage_status *cc1, - enum tcpc_cc_voltage_status *cc2) -{ - int rv; - int rc; - - rv = tcpc_read(port, TCPC_REG_ROLE_CTRL, &rc); - if (rv) - return rv; - - rv = tcpci_tcpm_get_cc(port, cc1, cc2); - if (rv) - return rv; - - if (!TCPC_REG_ROLE_CTRL_DRP(rc)) { - if ((*cc1 != TYPEC_CC_VOLT_OPEN) && - (TCPC_REG_ROLE_CTRL_CC1(rc) == TYPEC_CC_RD)) - *cc1 |= 0x4; - if ((*cc2 != TYPEC_CC_VOLT_OPEN) && - (TCPC_REG_ROLE_CTRL_CC2(rc) == TYPEC_CC_RD)) - *cc2 |= 0x04; - } - - return rv; -} - -int tcpci_nct38xx_drp_toggle(int port) -{ - int rv; - - cable_polarity[port] = POLARITY_NONE; - - /* - * The port was disconnected so it is probably a good place to set - * auto-discharge-disconnect to '0' - * - * TODO(crbug.com/951683: this should be removed when common code adds - * auto discharge. - */ - rv = auto_discharge_disconnect(port, 0); - if (rv) - return rv; - - return tcpci_tcpc_drp_toggle(port); - -} - -int tcpci_nct38xx_set_polarity(int port, int polarity) -{ - int rv, reg; - - rv = tcpc_read(port, TCPC_REG_TCPC_CTRL, ®); - if (rv) - return rv; - - reg = polarity ? (reg | TCPC_REG_TCPC_CTRL_SET(1)) : - (reg & ~TCPC_REG_TCPC_CTRL_SET(1)); - - rv = tcpc_write(port, TCPC_REG_TCPC_CTRL, reg); - if (rv) - return rv; - - /* - * Polarity is set after connection so it is probably a good time to set - * auto-discharge-disconnect to '1' - */ - rv = auto_discharge_disconnect(port, 1); - return rv; -} - -int tcpci_nct38xx_transmit(int port, enum tcpm_transmit_type type, - uint16_t header, const uint32_t *data) -{ - int rv, num_obj_byte; - - num_obj_byte = PD_HEADER_CNT(header) * 4; - - txBuf[0] = num_obj_byte + 2; - - txBuf[1] = (unsigned char)(header & 0xFF); - txBuf[2] = (unsigned char)((header >> 8) & 0xFF); - - if (num_obj_byte) { - uint32_t *buf_ptr; - - buf_ptr = (uint32_t *)&txBuf[3]; - memcpy(buf_ptr, data, num_obj_byte); - } - - /* total write size = size header (1 byte) + message size */ - rv = tcpc_write_block(port, TCPC_REG_TX_BYTE_CNT, - (const uint8_t *)txBuf, txBuf[0] + 1); - - rv = tcpc_write(port, TCPC_REG_TRANSMIT, - TCPC_REG_TRANSMIT_SET_WITH_RETRY(type)); - return rv; -} - -static int tcpci_nct38xx_get_message_raw(int port, uint32_t *payload, int *head) -{ - int rv, cnt, num_obj_byte; - - rv = tcpc_read(port, TCPC_REG_RX_BYTE_CNT, &cnt); - - if (rv != EC_SUCCESS || cnt < 3) { - rv = EC_ERROR_UNKNOWN; - goto clear; - } - - rv = tcpc_read_block(port, TCPC_REG_RX_BYTE_CNT, rxBuf, cnt + 1); - if (rv != EC_SUCCESS) - goto clear; - - *head = *(int *)&rxBuf[2]; - num_obj_byte = PD_HEADER_CNT(*head) * 4; - - if (num_obj_byte) { - uint32_t *buf_ptr; - - buf_ptr = (uint32_t *)&rxBuf[4]; - memcpy(payload, buf_ptr, num_obj_byte); - } - -clear: - /* Read complete, clear RX status alert bit */ - tcpc_write16(port, TCPC_REG_ALERT, TCPC_REG_ALERT_RX_STATUS); - - return rv; -} - -static void nct38xx_tcpc_alert(int port) -{ - int alert, rv; - - /* - * If IO expander feature is defined, read the ALERT register first to - * keep the status of Vendor Define bit. Otherwise, the status of ALERT - * register will be cleared after tcpci_tcpc_alert() is executed. - */ - if (IS_ENABLED(CONFIG_IO_EXPANDER_NCT38XX)) - rv = tcpc_read16(port, TCPC_REG_ALERT, &alert); - - /* Process normal TCPC ALERT event and clear status */ - tcpci_tcpc_alert(port); - - /* - * If IO expander feature is defined, check the Vendor Define bit to - * handle the IOEX IO's interrupt event - */ - if (IS_ENABLED(CONFIG_IO_EXPANDER_NCT38XX)) - if (!rv && (alert & TCPC_REG_ALERT_VENDOR_DEF)) - nct38xx_ioex_event_handler(port); - -} -const struct tcpm_drv nct38xx_tcpm_drv = { - .init = &nct38xx_tcpm_init, - .release = &tcpci_tcpm_release, - .get_cc = &tcpci_nct38xx_get_cc, -#ifdef CONFIG_USB_PD_VBUS_DETECT_TCPC - .get_vbus_level = &tcpci_tcpm_get_vbus_level, -#endif - .select_rp_value = &tcpci_nct38xx_select_rp_value, - .set_cc = &tcpci_nct38xx_set_cc, - .set_polarity = &tcpci_nct38xx_set_polarity, - .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_nct38xx_get_message_raw, - .transmit = &tcpci_nct38xx_transmit, - .tcpc_alert = &nct38xx_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_nct38xx_drp_toggle, -#endif -#ifdef CONFIG_USBC_PPC - .set_snk_ctrl = &tcpci_tcpm_set_snk_ctrl, - .set_src_ctrl = &tcpci_tcpm_set_src_ctrl, -#endif - .get_chip_info = &tcpci_get_chip_info, -#ifdef CONFIG_USB_PD_TCPC_LOW_POWER - .enter_low_power_mode = &tcpci_enter_low_power_mode, -#endif -#ifdef CONFIG_USB_TYPEC_PD_FAST_ROLE_SWAP - .set_frs_enable = &tcpci_tcpc_fast_role_swap_enable, -#endif -}; diff --git a/driver/tcpm/nct38xx.h b/driver/tcpm/nct38xx.h deleted file mode 100644 index 970c1c8c85..0000000000 --- a/driver/tcpm/nct38xx.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * 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. - */ - -/* Nuvoton Type-C port controller */ - -#ifndef __CROS_EC_USB_PD_TCPM_NCT38XX_H -#define __CROS_EC_USB_PD_TCPM_NCT38XX_H - -/* Chip variant ID (Part number) */ -#define NCT38XX_VARIANT_MASK 0x1C -#define NCT38XX_VARIANT_3807 0x0 -#define NCT38XX_VARIANT_3808 0x2 - -/* There are two IO ports in NCT3807 */ -#define NCT38XX_NCT3807_MAX_IO_PORT 2 -/* There is only one IO port in NCT3808 */ -#define NCT38XX_NCT3808_MAX_IO_PORT 1 - -#define NCT38XX_SUPPORT_GPIO_FLAGS (GPIO_OPEN_DRAIN | GPIO_INPUT | \ - GPIO_OUTPUT | GPIO_LOW | GPIO_HIGH | GPIO_INT_F_RISING | \ - GPIO_INT_F_FALLING | GPIO_INT_F_HIGH | GPIO_INT_F_LOW) - -/* I2C interface */ -#define NCT38XX_I2C_ADDR1_1_FLAGS 0x70 -#define NCT38XX_I2C_ADDR1_2_FLAGS 0x71 -#define NCT38XX_I2C_ADDR1_3_FLAGS 0x72 -#define NCT38XX_I2C_ADDR1_4_FLAGS 0x73 - -#define NCT38XX_I2C_ADDR2_1_FLAGS 0x74 -#define NCT38XX_I2C_ADDR2_2_FLAGS 0x75 -#define NCT38XX_I2C_ADDR2_3_FLAGS 0x76 -#define NCT38XX_I2C_ADDR2_4_FLAGS 0x77 - -#define NCT38XX_REG_VENDOR_ID_L 0x00 -#define NCT38XX_REG_VENDOR_ID_H 0x01 -#define NCT38XX_VENDOR_ID 0x0416 - -#define NCT38XX_PRODUCT_ID 0xC301 - -#define NCT38XX_REG_GPIO_DATA_IN(n) (0xC0 + ((n) * 8)) -#define NCT38XX_REG_GPIO_DATA_OUT(n) (0xC1 + ((n) * 8)) -#define NCT38XX_REG_GPIO_DIR(n) (0xC2 + ((n) * 8)) -#define NCT38XX_REG_GPIO_OD_SEL(n) (0xC3 + ((n) * 8)) -#define NCT38XX_REG_GPIO_ALERT_RISE(n) (0xC4 + ((n) * 8)) -#define NCT38XX_REG_GPIO_ALERT_FALL(n) (0xC5 + ((n) * 8)) -#define NCT38XX_REG_GPIO_ALERT_LEVEL(n) (0xC6 + ((n) * 8)) -#define NCT38XX_REG_GPIO_ALERT_MASK(n) (0xC7 + ((n) * 8)) -#define NCT38XX_REG_MUX_CONTROL 0xD0 -#define NCT38XX_REG_GPIO_ALERT_STAT(n) (0xD4 + (n)) - -/* NCT3808 only supports GPIO 2/3/4/6/7 */ -#define NCT38XXX_3808_VALID_GPIO_MASK 0xDC - -#define NCT38XX_REG_CTRL_OUT_EN 0xD2 -#define NCT38XX_REG_CTRL_OUT_EN_SRCEN (1 << 0) -#define NCT38XX_REG_CTRL_OUT_EN_FASTEN (1 << 1) -#define NCT38XX_REG_CTRL_OUT_EN_SNKEN (1 << 2) -#define NCT38XX_REG_CTRL_OUT_EN_CONNDIREN (1 << 6) - -#define NCT38XX_RESET_HOLD_DELAY_MS 1 -#define NCT38XX_RESET_POST_DELAY_MS 0 - -extern const struct tcpm_drv nct38xx_tcpm_drv; - -#endif /* defined(__CROS_EC_USB_PD_TCPM_NCT38XX_H) */ diff --git a/driver/tcpm/ps8xxx.c b/driver/tcpm/ps8xxx.c deleted file mode 100644 index 81117a5af1..0000000000 --- a/driver/tcpm/ps8xxx.c +++ /dev/null @@ -1,321 +0,0 @@ -/* 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. - */ - -/* - * Type-C port manager for Parade PS8XXX with integrated superspeed muxes. - * - * Supported TCPCs: - * - PS8751 - * - PS8805 - */ - -#include "common.h" -#include "ps8xxx.h" -#include "tcpci.h" -#include "tcpm.h" -#include "timer.h" -#include "usb_pd.h" - -#if !defined(CONFIG_USB_PD_TCPM_PS8751) && \ - !defined(CONFIG_USB_PD_TCPM_PS8805) -#error "Unsupported PS8xxx TCPC." -#endif - -#if !defined(CONFIG_USB_PD_TCPM_TCPCI) || \ - !defined(CONFIG_USB_PD_TCPM_MUX) || \ - !defined(CONFIG_USBC_SS_MUX) - -#error "PS8XXX is using a standard TCPCI interface with integrated mux control" -#error "Please upgrade your board configuration" - -#endif - -/* - * timestamp of the next possible toggle to ensure the 2-ms spacing - * between IRQ_HPD. - */ -static uint64_t hpd_deadline[CONFIG_USB_PD_PORT_MAX_COUNT]; - -static int dp_set_hpd(int port, int enable) -{ - int reg; - int rv; - - rv = mux_read(port, MUX_IN_HPD_ASSERTION_REG, ®); - if (rv) - return rv; - if (enable) - reg |= IN_HPD; - else - reg &= ~IN_HPD; - return mux_write(port, MUX_IN_HPD_ASSERTION_REG, reg); -} - -static int dp_set_irq(int port, int enable) -{ - - int reg; - int rv; - - rv = mux_read(port, MUX_IN_HPD_ASSERTION_REG, ®); - if (rv) - return rv; - if (enable) - reg |= HPD_IRQ; - else - reg &= ~HPD_IRQ; - return mux_write(port, MUX_IN_HPD_ASSERTION_REG, reg); -} - -void ps8xxx_tcpc_update_hpd_status(int port, int hpd_lvl, int hpd_irq) -{ - dp_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_deadline[port]) - usleep(hpd_deadline[port] - now); - - dp_set_irq(port, 0); - usleep(HPD_DSTREAM_DEBOUNCE_IRQ); - dp_set_irq(port, hpd_irq); - } - /* enforce 2-ms delay between HPD pulses */ - hpd_deadline[port] = get_time().val + HPD_USTREAM_DEBOUNCE_LVL; -} - -static int ps8xxx_tcpc_bist_mode_2(int port) -{ - int rv; - - /* Generate BIST for 50ms. */ - rv = tcpc_write(port, - PS8XXX_REG_BIST_CONT_MODE_BYTE0, PS8751_BIST_COUNTER_BYTE0); - rv |= tcpc_write(port, - PS8XXX_REG_BIST_CONT_MODE_BYTE1, PS8751_BIST_COUNTER_BYTE1); - rv |= tcpc_write(port, - PS8XXX_REG_BIST_CONT_MODE_BYTE2, PS8751_BIST_COUNTER_BYTE2); - - /* Auto stop */ - rv |= tcpc_write(port, PS8XXX_REG_BIST_CONT_MODE_CTR, 0); - - /* Start BIST MODE 2 */ - rv |= tcpc_write(port, TCPC_REG_TRANSMIT, TCPC_TX_BIST_MODE_2); - - return rv; -} - -static int ps8xxx_tcpm_transmit(int port, enum tcpm_transmit_type type, - uint16_t header, const uint32_t *data) -{ - if (type == TCPC_TX_BIST_MODE_2) - return ps8xxx_tcpc_bist_mode_2(port); - else - return tcpci_tcpm_transmit(port, type, header, data); -} - -static int ps8xxx_tcpm_release(int port) -{ - int version; - int status; - - status = tcpc_read(port, FW_VER_REG, &version); - if (status != 0) { - /* wait for chip to wake up */ - msleep(10); - } - - return tcpci_tcpm_release(port); -} - -static int ps8xxx_get_chip_info(int port, int live, - struct ec_response_pd_chip_info_v1 **chip_info) -{ - int val; - int rv = tcpci_get_chip_info(port, live, chip_info); - - if (rv) - return rv; - - if (!live) { - (*chip_info)->vendor_id = PS8XXX_VENDOR_ID; - (*chip_info)->product_id = PS8XXX_PRODUCT_ID; - } - - if ((*chip_info)->fw_version_number == 0 || - (*chip_info)->fw_version_number == -1 || live) { - rv = tcpc_read(port, FW_VER_REG, &val); - - if (rv) - return rv; - - (*chip_info)->fw_version_number = val; - } - -#if defined(CONFIG_USB_PD_TCPM_PS8751) && \ - defined(CONFIG_USB_PD_VBUS_DETECT_TCPC) - /* - * Min firmware version of PS8751 to ensure that it can detect Vbus - * properly. See b/109769787#comment7 - */ - (*chip_info)->min_req_fw_version_number = 0x39; -#endif - - return rv; -} - -#ifdef CONFIG_USB_PD_TCPC_LOW_POWER -static int ps8xxx_enter_low_power_mode(int port) -{ - return EC_SUCCESS; -} -#endif - -/* - * DCI is enabled by default and burns about 40 mW when the port is in - * USB2 mode or when a C-to-A dongle is attached, so force it off. - */ - -static int ps8xxx_addr_dci_disable(int port, int i2c_addr, int i2c_reg) -{ - int status; - int dci; - - status = tcpc_addr_read(port, i2c_addr, i2c_reg, &dci); - if (status != EC_SUCCESS) - return status; - if ((dci & PS8XXX_REG_MUX_USB_DCI_CFG_MODE_MASK) != - PS8XXX_REG_MUX_USB_DCI_CFG_MODE_OFF) { - dci &= ~PS8XXX_REG_MUX_USB_DCI_CFG_MODE_MASK; - dci |= PS8XXX_REG_MUX_USB_DCI_CFG_MODE_OFF; - if (tcpc_addr_write(port, i2c_addr, i2c_reg, dci) != EC_SUCCESS) - return status; - } - return EC_SUCCESS; -} - -#ifdef CONFIG_USB_PD_TCPM_PS8805 -static int ps8xxx_dci_disable(int port) -{ - int status, e; - int p1_addr; - - status = tcpc_write(port, PS8XXX_REG_I2C_DEBUGGING_ENABLE, - PS8XXX_REG_I2C_DEBUGGING_ENABLE_ON); - if (status != EC_SUCCESS) - return status; - - p1_addr = tcpc_config[port].i2c_info.addr_flags - - (PS8751_I2C_ADDR1_FLAGS - PS8751_I2C_ADDR1_P1_FLAGS); - status = ps8xxx_addr_dci_disable(port, p1_addr, - PS8805_P1_REG_MUX_USB_DCI_CFG); - - e = tcpc_write(port, PS8XXX_REG_I2C_DEBUGGING_ENABLE, - PS8XXX_REG_I2C_DEBUGGING_ENABLE_OFF); - if (e != EC_SUCCESS) { - if (status == EC_SUCCESS) - status = e; - } - - return status; -} -#endif /* CONFIG_USB_PD_TCPM_PS8805 */ - -#ifdef CONFIG_USB_PD_TCPM_PS8751 -static int ps8xxx_dci_disable(int port) -{ - int p3_addr; - - p3_addr = tcpc_config[port].i2c_info.addr_flags; - return ps8xxx_addr_dci_disable(port, p3_addr, - PS8751_REG_MUX_USB_DCI_CFG); -} -#endif /* CONFIG_USB_PD_TCPM_PS8751 */ - -static int ps8xxx_tcpm_init(int port) -{ - int status; - - status = tcpci_tcpm_init(port); - if (status != EC_SUCCESS) - return status; - - return ps8xxx_dci_disable(port); -} - -const struct tcpm_drv ps8xxx_tcpm_drv = { - .init = &ps8xxx_tcpm_init, - .release = &ps8xxx_tcpm_release, - .get_cc = &tcpci_tcpm_get_cc, -#ifdef CONFIG_USB_PD_VBUS_DETECT_TCPC - .get_vbus_level = &tcpci_tcpm_get_vbus_level, -#endif - .select_rp_value = &tcpci_tcpm_select_rp_value, - .set_cc = &tcpci_tcpm_set_cc, - .set_polarity = &tcpci_tcpm_set_polarity, - .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 = &ps8xxx_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 -#ifdef CONFIG_USBC_PPC - .set_snk_ctrl = &tcpci_tcpm_set_snk_ctrl, - .set_src_ctrl = &tcpci_tcpm_set_src_ctrl, -#endif - .get_chip_info = &ps8xxx_get_chip_info, -#ifdef CONFIG_USB_PD_TCPC_LOW_POWER - .enter_low_power_mode = &ps8xxx_enter_low_power_mode, -#endif -}; - -#ifdef CONFIG_CMD_I2C_STRESS_TEST_TCPC -struct i2c_stress_test_dev ps8xxx_i2c_stress_test_dev = { - .reg_info = { - .read_reg = PS8XXX_REG_VENDOR_ID_L, - .read_val = PS8XXX_VENDOR_ID & 0xFF, - .write_reg = MUX_IN_HPD_ASSERTION_REG, - }, - .i2c_read = &tcpc_i2c_read, - .i2c_write = &tcpc_i2c_write, -}; -#endif /* CONFIG_CMD_I2C_STRESS_TEST_TCPC */ - -static int ps8xxx_mux_init(int port) -{ - tcpci_tcpm_mux_init(port); - - /* If this MUX is also the TCPC, then skip init */ - if (!(usb_muxes[port].flags & USB_MUX_FLAG_NOT_TCPC)) - return EC_SUCCESS; - - /* We always want to be a sink when this device is only being used as a mux - * to support external peripherals better. - */ - return mux_write(port, TCPC_REG_ROLE_CTRL, - TCPC_REG_ROLE_CTRL_SET(0, 1, TYPEC_CC_RD, TYPEC_CC_RD)); -} - -static int ps8xxx_mux_enter_low_power_mode(int port) -{ - mux_write(port, TCPC_REG_ROLE_CTRL, - TCPC_REG_ROLE_CTRL_SET(0, 0, TYPEC_CC_RP, TYPEC_CC_RP)); - return tcpci_tcpm_mux_enter_low_power(port); -} - -/* This is meant for mux-only applications */ -const struct usb_mux_driver ps8xxx_usb_mux_driver = { - .init = &ps8xxx_mux_init, - .set = &tcpci_tcpm_mux_set, - .get = &tcpci_tcpm_mux_get, - .enter_low_power_mode = &ps8xxx_mux_enter_low_power_mode, -}; diff --git a/driver/tcpm/ps8xxx.h b/driver/tcpm/ps8xxx.h deleted file mode 100644 index e2927c8531..0000000000 --- a/driver/tcpm/ps8xxx.h +++ /dev/null @@ -1,81 +0,0 @@ -/* 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. - */ - -/* Parade Tech Type-C port controller */ - -#ifndef __CROS_EC_USB_PD_TCPM_PS8XXX_H -#define __CROS_EC_USB_PD_TCPM_PS8XXX_H - -/* I2C interface */ -#define PS8751_I2C_ADDR1_P1_FLAGS 0x09 -#define PS8751_I2C_ADDR1_FLAGS 0x0B -#define PS8751_I2C_ADDR2_FLAGS 0x1B -#define PS8751_I2C_ADDR3_FLAGS 0x2B -#define PS8751_I2C_ADDR4_FLAGS 0x4B - -/* Minimum Delay for reset assertion */ -#define PS8XXX_RESET_DELAY_MS 1 - -#define PS8751_BIST_TIMER_FREQ 15000000 -#define PS8751_BIST_DELAY_MS 50 - -#define PS8751_BIST_COUNTER (PS8751_BIST_TIMER_FREQ / MSEC \ - * PS8751_BIST_DELAY_MS) - -#define PS8751_BIST_COUNTER_BYTE0 (PS8751_BIST_COUNTER & 0xff) -#define PS8751_BIST_COUNTER_BYTE1 ((PS8751_BIST_COUNTER >> 8) & 0xff) -#define PS8751_BIST_COUNTER_BYTE2 ((PS8751_BIST_COUNTER >> 16) & 0xff) - -#define PS8XXX_VENDOR_ID 0x1DA0 -#define PS8XXX_REG_I2C_DEBUGGING_ENABLE 0xA0 -#define PS8XXX_REG_I2C_DEBUGGING_ENABLE_ON 0x30 -#define PS8XXX_REG_I2C_DEBUGGING_ENABLE_OFF 0x31 /* default */ -#define PS8XXX_REG_BIST_CONT_MODE_BYTE0 0xBC -#define PS8XXX_REG_BIST_CONT_MODE_BYTE1 0xBD -#define PS8XXX_REG_BIST_CONT_MODE_BYTE2 0xBE -#define PS8XXX_REG_BIST_CONT_MODE_CTR 0xBF -#define PS8XXX_REG_DET_CTRL0 0x08 - -#define PS8XXX_REG_MUX_USB_DCI_CFG_MODE_MASK 0xC0 -#define PS8XXX_REG_MUX_USB_DCI_CFG_MODE_OFF 0x80 - -#if defined(CONFIG_USB_PD_TCPM_PS8751) -/* Vendor defined registers */ -#define PS8XXX_PRODUCT_ID 0x8751 - -#define FW_VER_REG 0x90 -#define PS8XXX_REG_VENDOR_ID_L 0x00 -#define PS8XXX_REG_VENDOR_ID_H 0x01 -#define MUX_IN_HPD_ASSERTION_REG 0xD0 -#define IN_HPD BIT(0) -#define HPD_IRQ BIT(1) -#define PS8XXX_REG_MUX_DP_EQ_CONFIGURATION 0xD3 -#define PS8XXX_REG_MUX_DP_OUTPUT_CONFIGURATION 0xD4 -#define PS8XXX_REG_MUX_USB_C2SS_EQ 0xE7 -#define PS8XXX_REG_MUX_USB_C2SS_HS_THRESHOLD 0xE8 -#define PS8751_REG_MUX_USB_DCI_CFG 0xED - -#elif defined(CONFIG_USB_PD_TCPM_PS8805) -/* Vendor defined registers */ -#define PS8XXX_PRODUCT_ID 0x8805 - -#define PS8805_P1_REG_MUX_USB_DCI_CFG 0x4B -#define FW_VER_REG 0x82 -#define MUX_IN_HPD_ASSERTION_REG 0xD0 -#define IN_HPD BIT(0) -#define HPD_IRQ BIT(1) - -#endif - -extern const struct tcpm_drv ps8xxx_tcpm_drv; -void ps8xxx_tcpc_update_hpd_status(int port, int hpd_lvl, int hpd_irq); - -#ifdef CONFIG_CMD_I2C_STRESS_TEST_TCPC -extern struct i2c_stress_test_dev ps8xxx_i2c_stress_test_dev; -#endif /* defined(CONFIG_CMD_I2C_STRESS_TEST_TCPC) */ - -extern const struct usb_mux_driver ps8xxx_usb_mux_driver; - -#endif /* defined(__CROS_EC_USB_PD_TCPM_PS8XXX_H) */ diff --git a/driver/tcpm/stub.c b/driver/tcpm/stub.c deleted file mode 100644 index 0ebe8af999..0000000000 --- a/driver/tcpm/stub.c +++ /dev/null @@ -1,155 +0,0 @@ -/* Copyright 2015 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. - */ - -/* TCPM for MCU also running TCPC */ - -#include "task.h" -#include "tcpci.h" -#include "tcpm.h" -#include "usb_pd.h" -#include "usb_pd_tcpc.h" -#include "usb_pd_tcpm.h" - -static int init_alert_mask(int port) -{ - uint16_t mask; - int rv; - - /* - * Create mask of alert events that will cause the TCPC to - * signal the TCPM via the Alert# gpio line. - */ - mask = TCPC_REG_ALERT_TX_SUCCESS | TCPC_REG_ALERT_TX_FAILED | - TCPC_REG_ALERT_TX_DISCARDED | TCPC_REG_ALERT_RX_STATUS | - TCPC_REG_ALERT_RX_HARD_RST | TCPC_REG_ALERT_CC_STATUS; - /* Set the alert mask in TCPC */ - rv = tcpc_alert_mask_set(port, mask); - - return rv; -} - -static int init_power_status_mask(int port) -{ - return tcpc_set_power_status_mask(port, 0); -} - -int tcpm_init(int port) -{ - int rv; - - tcpc_init(port); - rv = init_alert_mask(port); - if (rv) - return rv; - - return init_power_status_mask(port); -} - -int tcpm_get_cc(int port, enum tcpc_cc_voltage_status *cc1, - enum tcpc_cc_voltage_status *cc2) -{ - return tcpc_get_cc(port, cc1, cc2); -} - -int tcpm_select_rp_value(int port, int rp) -{ - return tcpc_select_rp_value(port, rp); -} - -int tcpm_set_cc(int port, int pull) -{ - return tcpc_set_cc(port, pull); -} - -int tcpm_set_polarity(int port, int polarity) -{ - return tcpc_set_polarity(port, polarity); -} - -int tcpm_set_vconn(int port, int enable) -{ - return tcpc_set_vconn(port, enable); -} - -int tcpm_set_msg_header(int port, int power_role, int data_role) -{ - return tcpc_set_msg_header(port, power_role, data_role); -} - -static int tcpm_alert_status(int port, int *alert) -{ - /* Read TCPC Alert register */ - return tcpc_alert_status(port, alert); -} - -int tcpm_set_rx_enable(int port, int enable) -{ - return tcpc_set_rx_enable(port, enable); -} - -int tcpm_has_pending_message(int port) -{ - return !rx_buf_is_empty(port); -} - -int tcpm_dequeue_message(int port, uint32_t *payload, int *head) -{ - int ret = tcpc_get_message(port, payload, head); - - /* Read complete, clear RX status alert bit */ - tcpc_alert_status_clear(port, TCPC_REG_ALERT_RX_STATUS); - - return ret; -} - -void tcpm_clear_pending_messages(int port) -{ - rx_buf_clear(port); -} - -int tcpm_transmit(int port, enum tcpm_transmit_type type, uint16_t header, - const uint32_t *data) -{ - return tcpc_transmit(port, type, header, data); -} - -void tcpc_alert(int port) -{ - int status; - - /* Read the Alert register from the TCPC */ - tcpm_alert_status(port, &status); - - /* - * Clear alert status for everything except RX_STATUS, which shouldn't - * be cleared until we have successfully retrieved message. - */ - if (status & ~TCPC_REG_ALERT_RX_STATUS) - tcpc_alert_status_clear(port, - status & ~TCPC_REG_ALERT_RX_STATUS); - - if (status & TCPC_REG_ALERT_CC_STATUS) { - /* CC status changed, wake task */ - task_set_event(PD_PORT_TO_TASK_ID(port), PD_EVENT_CC, 0); - } - if (status & TCPC_REG_ALERT_RX_STATUS) { - /* - * message received. since TCPC is compiled in, we - * already woke the PD task up from the phy layer via - * pd_rx_event(), so we don't need to wake it again. - */ - } - if (status & TCPC_REG_ALERT_RX_HARD_RST) { - /* hard reset received */ - pd_execute_hard_reset(port); - task_wake(PD_PORT_TO_TASK_ID(port)); - } - if (status & TCPC_REG_ALERT_TX_COMPLETE) { - /* transmit complete */ - pd_transmit_complete(port, status & TCPC_REG_ALERT_TX_SUCCESS ? - TCPC_TX_COMPLETE_SUCCESS : - TCPC_TX_COMPLETE_FAILED); - } -} diff --git a/driver/tcpm/tcpci.c b/driver/tcpm/tcpci.c deleted file mode 100644 index 001a7ee579..0000000000 --- a/driver/tcpm/tcpci.c +++ /dev/null @@ -1,1014 +0,0 @@ -/* Copyright 2015 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. - */ - -/* Type-C port manager */ - -#include "atomic.h" -#include "anx74xx.h" -#include "compile_time_macros.h" -#include "console.h" -#include "ec_commands.h" -#include "ps8xxx.h" -#include "task.h" -#include "tcpci.h" -#include "tcpm.h" -#include "timer.h" -#include "usb_charge.h" -#include "usb_mux.h" -#include "usb_pd.h" -#include "usb_pd_tcpc.h" -#include "util.h" - -#define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args) -#define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args) - -#ifdef CONFIG_USB_PD_DECODE_SOP -static int vconn_en[CONFIG_USB_PD_PORT_MAX_COUNT]; -static int rx_en[CONFIG_USB_PD_PORT_MAX_COUNT]; -#endif -static int tcpc_vbus[CONFIG_USB_PD_PORT_MAX_COUNT]; - -/* Save the selected rp value */ -static int selected_rp[CONFIG_USB_PD_PORT_MAX_COUNT]; - - -#ifdef CONFIG_USB_PD_TCPC_LOW_POWER -int tcpc_addr_write(int port, int i2c_addr, int reg, int val) -{ - int rv; - - pd_wait_exit_low_power(port); - - rv = i2c_write8(tcpc_config[port].i2c_info.port, - i2c_addr, reg, val); - - pd_device_accessed(port); - return rv; -} - -int tcpc_write16(int port, int reg, int val) -{ - int rv; - - pd_wait_exit_low_power(port); - - rv = i2c_write16(tcpc_config[port].i2c_info.port, - tcpc_config[port].i2c_info.addr_flags, - reg, val); - - pd_device_accessed(port); - return rv; -} - -int tcpc_addr_read(int port, int i2c_addr, int reg, int *val) -{ - int rv; - - pd_wait_exit_low_power(port); - - rv = i2c_read8(tcpc_config[port].i2c_info.port, - i2c_addr, reg, val); - - pd_device_accessed(port); - return rv; -} - -int tcpc_read16(int port, int reg, int *val) -{ - int rv; - - pd_wait_exit_low_power(port); - - rv = i2c_read16(tcpc_config[port].i2c_info.port, - tcpc_config[port].i2c_info.addr_flags, - reg, val); - - pd_device_accessed(port); - return rv; -} - -int tcpc_read_block(int port, int reg, uint8_t *in, int size) -{ - int rv; - - pd_wait_exit_low_power(port); - - rv = i2c_read_block(tcpc_config[port].i2c_info.port, - tcpc_config[port].i2c_info.addr_flags, - reg, in, size); - - pd_device_accessed(port); - return rv; -} - -int tcpc_write_block(int port, int reg, const uint8_t *out, int size) -{ - int rv; - - pd_wait_exit_low_power(port); - - rv = i2c_write_block(tcpc_config[port].i2c_info.port, - tcpc_config[port].i2c_info.addr_flags, - reg, out, size); - - pd_device_accessed(port); - return rv; -} - -int tcpc_xfer(int port, const uint8_t *out, int out_size, - uint8_t *in, int in_size) -{ - int rv; - /* Dispatching to tcpc_xfer_unlocked reduces code size growth. */ - tcpc_lock(port, 1); - rv = tcpc_xfer_unlocked(port, out, out_size, in, in_size, - I2C_XFER_SINGLE); - tcpc_lock(port, 0); - return rv; -} - -int tcpc_xfer_unlocked(int port, const uint8_t *out, int out_size, - uint8_t *in, int in_size, int flags) -{ - int rv; - - pd_wait_exit_low_power(port); - - rv = i2c_xfer_unlocked(tcpc_config[port].i2c_info.port, - tcpc_config[port].i2c_info.addr_flags, - out, out_size, in, in_size, flags); - - pd_device_accessed(port); - return rv; -} -#endif /* CONFIG_USB_PD_TCPC_LOW_POWER */ - -static int init_alert_mask(int port) -{ - int rv; - uint16_t mask; - - /* - * Create mask of alert events that will cause the TCPC to - * signal the TCPM via the Alert# gpio line. - */ - mask = TCPC_REG_ALERT_TX_SUCCESS | TCPC_REG_ALERT_TX_FAILED | - TCPC_REG_ALERT_TX_DISCARDED | TCPC_REG_ALERT_RX_STATUS | - TCPC_REG_ALERT_RX_HARD_RST | TCPC_REG_ALERT_CC_STATUS -#ifdef CONFIG_USB_PD_VBUS_DETECT_TCPC - | TCPC_REG_ALERT_POWER_STATUS -#endif - ; - /* Set the alert mask in TCPC */ - rv = tcpc_write16(port, TCPC_REG_ALERT_MASK, mask); - - if (IS_ENABLED(CONFIG_USB_TYPEC_PD_FAST_ROLE_SWAP)) { - if (rv) - return rv; - - /* Sink FRS allowed */ - mask = TCPC_REG_ALERT_EXT_SNK_FRS; - rv = tcpc_write(port, TCPC_REG_ALERT_EXT, mask); - } - return rv; -} - -static int clear_alert_mask(int port) -{ - return tcpc_write16(port, TCPC_REG_ALERT_MASK, 0); -} - -static int init_power_status_mask(int port) -{ - uint8_t mask; - int rv; - -#ifdef CONFIG_USB_PD_VBUS_DETECT_TCPC - mask = TCPC_REG_POWER_STATUS_VBUS_PRES; -#else - mask = 0; -#endif - rv = tcpc_write(port, TCPC_REG_POWER_STATUS_MASK , mask); - - return rv; -} - -static int clear_power_status_mask(int port) -{ - return tcpc_write(port, TCPC_REG_POWER_STATUS_MASK, 0); -} - -int tcpci_tcpm_get_cc(int port, enum tcpc_cc_voltage_status *cc1, - enum tcpc_cc_voltage_status *cc2) -{ - int status; - int rv; - - rv = tcpc_read(port, TCPC_REG_CC_STATUS, &status); - - /* If tcpc read fails, return error and CC as open */ - if (rv) { - *cc1 = TYPEC_CC_VOLT_OPEN; - *cc2 = TYPEC_CC_VOLT_OPEN; - return rv; - } - - *cc1 = TCPC_REG_CC_STATUS_CC1(status); - *cc2 = TCPC_REG_CC_STATUS_CC2(status); - - /* - * If status is not open, then OR in termination to convert to - * enum tcpc_cc_voltage_status. - */ - if (*cc1 != TYPEC_CC_VOLT_OPEN) - *cc1 |= TCPC_REG_CC_STATUS_TERM(status) << 2; - if (*cc2 != TYPEC_CC_VOLT_OPEN) - *cc2 |= TCPC_REG_CC_STATUS_TERM(status) << 2; - - return rv; -} - -static int tcpci_tcpm_get_power_status(int port, int *status) -{ - return tcpc_read(port, TCPC_REG_POWER_STATUS, status); -} - -int tcpci_tcpm_select_rp_value(int port, int rp) -{ - selected_rp[port] = rp; - return EC_SUCCESS; -} - -#ifdef CONFIG_USB_PD_DISCHARGE_TCPC -void tcpci_tcpc_discharge_vbus(int port, int enable) -{ - int reg; - - if (tcpc_read(port, TCPC_REG_POWER_CTRL, ®)) - return; - - if (enable) - reg |= TCPC_REG_POWER_CTRL_FORCE_DISCHARGE; - else - reg &= ~TCPC_REG_POWER_CTRL_FORCE_DISCHARGE; - - tcpc_write(port, TCPC_REG_POWER_CTRL, reg); -} -#endif - -static int set_role_ctrl(int port, int toggle, int rp, int pull) -{ - return tcpc_write(port, TCPC_REG_ROLE_CTRL, - TCPC_REG_ROLE_CTRL_SET(toggle, rp, pull, pull)); -} - -int tcpci_tcpm_set_cc(int port, int pull) -{ - /* Set manual control, and set both CC lines to the same pull */ - return set_role_ctrl(port, 0, selected_rp[port], pull); -} - -#ifdef CONFIG_USB_PD_DUAL_ROLE_AUTO_TOGGLE -int tcpci_tcpc_drp_toggle(int port) -{ - int rv; - - /* Set auto drp toggle */ - rv = set_role_ctrl(port, 1, TYPEC_RP_USB, TYPEC_CC_RD); - - /* Set Look4Connection command */ - rv |= tcpc_write(port, TCPC_REG_COMMAND, - TCPC_REG_COMMAND_LOOK4CONNECTION); - - return rv; -} -#endif - -#ifdef CONFIG_USB_PD_TCPC_LOW_POWER -int tcpci_enter_low_power_mode(int port) -{ - return tcpc_write(port, TCPC_REG_COMMAND, TCPC_REG_COMMAND_I2CIDLE); -} -#endif - -int tcpci_tcpm_set_polarity(int port, int polarity) -{ - return tcpc_write(port, TCPC_REG_TCPC_CTRL, - TCPC_REG_TCPC_CTRL_SET(polarity)); -} - -#ifdef CONFIG_USBC_PPC -int tcpci_tcpm_set_snk_ctrl(int port, int enable) -{ - int cmd = enable ? TCPC_REG_COMMAND_SNK_CTRL_HIGH : - TCPC_REG_COMMAND_SNK_CTRL_LOW; - - return tcpc_write(port, TCPC_REG_COMMAND, cmd); -} - -int tcpci_tcpm_set_src_ctrl(int port, int enable) -{ - int cmd = enable ? TCPC_REG_COMMAND_SRC_CTRL_HIGH : - TCPC_REG_COMMAND_SRC_CTRL_LOW; - - return tcpc_write(port, TCPC_REG_COMMAND, cmd); -} -#endif - -int tcpci_tcpm_set_vconn(int port, int enable) -{ - int reg, rv; - - rv = tcpc_read(port, TCPC_REG_POWER_CTRL, ®); - if (rv) - return rv; - -#ifdef CONFIG_USB_PD_DECODE_SOP - /* save vconn */ - vconn_en[port] = enable; - - if (rx_en[port]) { - int detect_sop_en = TCPC_REG_RX_DETECT_SOP_HRST_MASK; - - if (enable) { - detect_sop_en = - TCPC_REG_RX_DETECT_SOP_SOPP_SOPPP_HRST_MASK; - } - - tcpc_write(port, TCPC_REG_RX_DETECT, detect_sop_en); - } -#endif - reg &= ~TCPC_REG_POWER_CTRL_VCONN(1); - reg |= TCPC_REG_POWER_CTRL_VCONN(enable); - return tcpc_write(port, TCPC_REG_POWER_CTRL, reg); -} - -int tcpci_tcpm_set_msg_header(int port, int power_role, int data_role) -{ - return tcpc_write(port, TCPC_REG_MSG_HDR_INFO, - TCPC_REG_MSG_HDR_INFO_SET(data_role, power_role)); -} - -static int tcpm_alert_status(int port, int *alert) -{ - /* Read TCPC Alert register */ - return tcpc_read16(port, TCPC_REG_ALERT, alert); -} - -static int tcpm_alert_ext_status(int port, int *alert_ext) -{ - /* Read TCPC Extended Alert register */ - return tcpc_read(port, TCPC_REG_ALERT_EXT, alert_ext); -} - -int tcpci_tcpm_set_rx_enable(int port, int enable) -{ - int detect_sop_en = 0; - - if (enable) { - detect_sop_en = TCPC_REG_RX_DETECT_SOP_HRST_MASK; - -#ifdef CONFIG_USB_PD_DECODE_SOP - /* save rx_on */ - rx_en[port] = enable; - - /* - * Only the VCONN Source is allowed to communicate - * with the Cable Plugs. - */ - - if (vconn_en[port]) - detect_sop_en = - TCPC_REG_RX_DETECT_SOP_SOPP_SOPPP_HRST_MASK; -#endif - } - - /* If enable, then set RX detect for SOP and HRST */ - return tcpc_write(port, TCPC_REG_RX_DETECT, detect_sop_en); -} - -#ifdef CONFIG_USB_TYPEC_PD_FAST_ROLE_SWAP -void tcpci_tcpc_fast_role_swap_enable(int port, int enable) -{ - int reg; - - if (tcpc_read(port, TCPC_REG_POWER_CTRL, ®)) - return; - - if (enable) - reg |= TCPC_REG_POWER_CTRL_FRS_ENABLE; - else - reg &= ~TCPC_REG_POWER_CTRL_FRS_ENABLE; - - tcpc_write(port, TCPC_REG_POWER_CTRL, reg); - - board_tcpc_fast_role_swap_enable(port, enable); -} -#endif - -#ifdef CONFIG_USB_PD_VBUS_DETECT_TCPC -int tcpci_tcpm_get_vbus_level(int port) -{ - return tcpc_vbus[port]; -} -#endif - -struct cached_tcpm_message { - uint32_t header; - uint32_t payload[7]; -}; - -int tcpci_tcpm_get_message_raw(int port, uint32_t *payload, int *head) -{ - int rv, cnt, reg = TCPC_REG_RX_DATA; -#ifdef CONFIG_USB_PD_DECODE_SOP - int frm; -#endif - - rv = tcpc_read(port, TCPC_REG_RX_BYTE_CNT, &cnt); - - /* RX_BYTE_CNT includes 3 bytes for frame type and header */ - if (rv != EC_SUCCESS || cnt < 3) { - rv = EC_ERROR_UNKNOWN; - goto clear; - } - cnt -= 3; - if (cnt > member_size(struct cached_tcpm_message, payload)) { - rv = EC_ERROR_UNKNOWN; - goto clear; - } - -#ifdef CONFIG_USB_PD_DECODE_SOP - rv = tcpc_read(port, TCPC_REG_RX_BUF_FRAME_TYPE, &frm); - if (rv != EC_SUCCESS) { - rv = EC_ERROR_UNKNOWN; - goto clear; - } -#endif - - rv = tcpc_read16(port, TCPC_REG_RX_HDR, (int *)head); - -#ifdef CONFIG_USB_PD_DECODE_SOP - /* Encode message address in bits 31 to 28 */ - *head &= 0x0000ffff; - *head |= PD_HEADER_SOP(frm & 7); -#endif - if (rv == EC_SUCCESS && cnt > 0) { - tcpc_read_block(port, reg, (uint8_t *)payload, cnt); - } - -clear: - /* Read complete, clear RX status alert bit */ - tcpc_write16(port, TCPC_REG_ALERT, TCPC_REG_ALERT_RX_STATUS); - - return rv; -} - -/* Cache depth needs to be power of 2 */ -#define CACHE_DEPTH BIT(2) -#define CACHE_DEPTH_MASK (CACHE_DEPTH - 1) - -struct queue { - /* - * Head points to the index of the first empty slot to put a new RX - * message. Must be masked before used in lookup. - */ - uint32_t head; - /* - * Tail points to the index of the first message for the PD task to - * consume. Must be masked before used in lookup. - */ - uint32_t tail; - struct cached_tcpm_message buffer[CACHE_DEPTH]; -}; -static struct queue cached_messages[CONFIG_USB_PD_PORT_MAX_COUNT]; - -/* Note this method can be called from an interrupt context. */ -int tcpm_enqueue_message(const int port) -{ - int rv; - struct queue *const q = &cached_messages[port]; - struct cached_tcpm_message *const head = - &q->buffer[q->head & CACHE_DEPTH_MASK]; - - if (q->head - q->tail == CACHE_DEPTH) { - CPRINTS("C%d RX EC Buffer full!", port); - return EC_ERROR_OVERFLOW; - } - - /* Blank any old message, just in case. */ - memset(head, 0, sizeof(*head)); - /* Call the raw driver without caching */ - rv = tcpc_config[port].drv->get_message_raw(port, head->payload, - &head->header); - if (rv) { - CPRINTS("C%d: Could not retrieve RX message (%d)", port, rv); - return rv; - } - - /* Increment atomically to ensure get_message_raw happens-before */ - atomic_add(&q->head, 1); - - /* Wake PD task up so it can process incoming RX messages */ - task_set_event(PD_PORT_TO_TASK_ID(port), TASK_EVENT_WAKE, 0); - - return EC_SUCCESS; -} - -int tcpm_has_pending_message(const int port) -{ - const struct queue *const q = &cached_messages[port]; - - return q->head != q->tail; -} - -int tcpm_dequeue_message(const int port, uint32_t *const payload, - int *const header) -{ - struct queue *const q = &cached_messages[port]; - struct cached_tcpm_message *const tail = - &q->buffer[q->tail & CACHE_DEPTH_MASK]; - - if (!tcpm_has_pending_message(port)) { - CPRINTS("C%d No message in RX buffer!", port); - return EC_ERROR_BUSY; - } - - /* Copy cache data in to parameters */ - *header = tail->header; - memcpy(payload, tail->payload, sizeof(tail->payload)); - - /* Increment atomically to ensure memcpy happens-before */ - atomic_add(&q->tail, 1); - - return EC_SUCCESS; -} - -void tcpm_clear_pending_messages(int port) -{ - struct queue *const q = &cached_messages[port]; - - q->tail = q->head; -} - -int tcpci_tcpm_transmit(int port, enum tcpm_transmit_type type, - uint16_t header, const uint32_t *data) -{ - int reg = TCPC_REG_TX_DATA; - int rv, cnt = 4*PD_HEADER_CNT(header); - - /* If not SOP* transmission, just write to the transmit register */ - if (type >= NUM_SOP_STAR_TYPES) { - /* - * Per TCPCI spec, do not specify retry (although the TCPC - * should ignore retry field for these 3 types). - */ - return tcpc_write(port, TCPC_REG_TRANSMIT, - TCPC_REG_TRANSMIT_SET_WITHOUT_RETRY(type)); - } - - /* TX_BYTE_CNT includes extra bytes for message header */ - rv = tcpc_write(port, TCPC_REG_TX_BYTE_CNT, cnt + sizeof(header)); - - rv |= tcpc_write16(port, TCPC_REG_TX_HDR, header); - - /* If tcpc read fails, return error */ - if (rv) - return rv; - - if (cnt > 0) { - rv = tcpc_write_block(port, reg, (const uint8_t *)data, cnt); - - /* If tcpc read fails, return error */ - if (rv) - return rv; - } - - /* - * On receiving a received message on SOP, protocol layer - * discards the pending SOP messages queued for transmission. - * But it doesn't do the same for SOP' message. So retry is - * assigned to 0 to avoid multiple transmission. - */ - return tcpc_write(port, TCPC_REG_TRANSMIT, - (type == TCPC_TX_SOP_PRIME) ? - TCPC_REG_TRANSMIT_SET_WITHOUT_RETRY(type) : - TCPC_REG_TRANSMIT_SET_WITH_RETRY(type)); -} - -#ifndef CONFIG_USB_PD_TCPC_LOW_POWER -/* - * Returns true if TCPC has reset based on reading mask registers. Only need to - * check this if the TCPC low power mode (LPM) code isn't compiled in because - * LPM will automatically reset the device when the TCPC exits LPM. - */ -static int register_mask_reset(int port) -{ - int mask; - - mask = 0; - tcpc_read16(port, TCPC_REG_ALERT_MASK, &mask); - if (mask == TCPC_REG_ALERT_MASK_ALL) - return 1; - - mask = 0; - tcpc_read(port, TCPC_REG_POWER_STATUS_MASK, &mask); - if (mask == TCPC_REG_POWER_STATUS_MASK_ALL) - return 1; - - return 0; -} -#endif - -/* - * Don't let the TCPC try to pull from the RX buffer forever. We typical only - * have 1 or 2 messages waiting. - */ -#define MAX_ALLOW_FAILED_RX_READS 10 - -void tcpci_tcpc_alert(int port) -{ - int status = 0; - int alert_ext = 0; - int failed_attempts; - uint32_t pd_event = 0; - - /* Read the Alert register from the TCPC */ - tcpm_alert_status(port, &status); - - /* Get Extended Alert register if needed */ - if (status & TCPC_REG_ALERT_ALERT_EXT) - tcpm_alert_ext_status(port, &alert_ext); - - /* Clear any pending faults */ - if (status & TCPC_REG_ALERT_FAULT) { - int fault; - int fault_rv; - - fault_rv = tcpc_read(port, TCPC_REG_FAULT_STATUS, &fault); - if (!fault_rv) { - CPRINTS("C%d FAULT=0x%02X", port, fault); - - /* Clear any faults that are set */ - fault_rv = tcpc_write(port, - TCPC_REG_FAULT_STATUS, - fault); - if (fault_rv) - CPRINTS("C%d Writing FAULT failed, rv=%d", - port, fault_rv); - } else { - CPRINTS("C%d Reading FAULT failed, rv=%d", - port, fault_rv); - } - } - - /* - * Check for TX complete first b/c PD state machine waits on TX - * completion events. This will send an event to the PD tasks - * immediately - */ - if (status & TCPC_REG_ALERT_TX_COMPLETE) - pd_transmit_complete(port, status & TCPC_REG_ALERT_TX_SUCCESS ? - TCPC_TX_COMPLETE_SUCCESS : - TCPC_TX_COMPLETE_FAILED); - - /* Pull all RX messages from TCPC into EC memory */ - failed_attempts = 0; - while (status & TCPC_REG_ALERT_RX_STATUS) { - if (tcpm_enqueue_message(port)) - ++failed_attempts; - if (tcpm_alert_status(port, &status)) - ++failed_attempts; - - /* Ensure we don't loop endlessly */ - if (failed_attempts >= MAX_ALLOW_FAILED_RX_READS) { - CPRINTS("C%d Cannot consume RX buffer after %d failed attempts!", - port, failed_attempts); - /* - * The port is in a bad state, we don't want to consume - * all EC resources so suspend the port for a little - * while. - */ - pd_set_suspend(port, 1); - pd_deferred_resume(port); - return; - } - } - - /* Clear all pending alert bits */ - if (status) - tcpc_write16(port, TCPC_REG_ALERT, status); - - if (status & TCPC_REG_ALERT_CC_STATUS) { - /* CC status changed, wake task */ - pd_event |= PD_EVENT_CC; - } - if (status & TCPC_REG_ALERT_POWER_STATUS) { - int reg = 0; - /* Read Power Status register */ - tcpci_tcpm_get_power_status(port, ®); - /* Update VBUS status */ - tcpc_vbus[port] = reg & - TCPC_REG_POWER_STATUS_VBUS_PRES ? 1 : 0; -#if defined(CONFIG_USB_PD_VBUS_DETECT_TCPC) && defined(CONFIG_USB_CHARGER) - /* Update charge manager with new VBUS state */ - usb_charger_vbus_change(port, tcpc_vbus[port]); - pd_event |= TASK_EVENT_WAKE; -#endif /* CONFIG_USB_PD_VBUS_DETECT_TCPC && CONFIG_USB_CHARGER */ - } - if (status & TCPC_REG_ALERT_RX_HARD_RST) { - /* hard reset received */ - pd_execute_hard_reset(port); - pd_event |= TASK_EVENT_WAKE; - } - - if (IS_ENABLED(CONFIG_USB_TYPEC_PD_FAST_ROLE_SWAP) - && (alert_ext & TCPC_REG_ALERT_EXT_SNK_FRS)) - pd_got_frs_signal(port); - -#ifndef CONFIG_USB_PD_TCPC_LOW_POWER - /* - * Check registers to see if we can tell that the TCPC has reset. If - * so, perform a tcpc_init. This only needs to happen for devices that - * don't support low power mode as the transition from low power mode - * will automatically reset the device. - */ - if (register_mask_reset(port)) - pd_event |= PD_EVENT_TCPC_RESET; -#endif - - /* - * Wait until all possible TCPC accesses in this function are complete - * prior to setting events and/or waking the pd task. When the PD - * task is woken and runs (which will happen during I2C transactions in - * this function), the pd task may put the TCPC into low power mode and - * the next I2C transaction to the TCPC will cause it to wake again. - */ - if (pd_event) - task_set_event(PD_PORT_TO_TASK_ID(port), pd_event, 0); -} - -/* - * This call will wake up the TCPC if it is in low power mode upon accessing the - * i2c bus (but the pd state machine should put it back into low power mode). - * - * Once it's called, the chip info will be stored in cache, which can be - * accessed by tcpm_get_chip_info without worrying about chip states. - */ -int tcpci_get_chip_info(int port, int live, - struct ec_response_pd_chip_info_v1 **chip_info) -{ - static struct ec_response_pd_chip_info_v1 - info[CONFIG_USB_PD_PORT_MAX_COUNT]; - struct ec_response_pd_chip_info_v1 *i; - int error; - int val; - - if (port >= board_get_usb_pd_port_count()) - return EC_ERROR_INVAL; - - i = &info[port]; - - /* If chip_info is NULL, chip info will be stored in cache and can be - * read later by another call. */ - if (chip_info) - *chip_info = i; - - /* If already cached && live data is not asked, return cached value */ - if (i->vendor_id && !live) - return EC_SUCCESS; - - error = tcpc_read16(port, TCPC_REG_VENDOR_ID, &val); - if (error) - return error; - i->vendor_id = val; - - error = tcpc_read16(port, TCPC_REG_PRODUCT_ID, &val); - if (error) - return error; - i->product_id = val; - - error = tcpc_read16(port, TCPC_REG_BCD_DEV, &val); - if (error) - return error; - i->device_id = val; - - /* - * This varies chip to chip; more specific driver code is expected to - * override this value if it can. - */ - i->fw_version_number = -1; - - return EC_SUCCESS; -} - -/* - * Dissociate from the TCPC. - */ - -int tcpci_tcpm_release(int port) -{ - int error; - - error = clear_alert_mask(port); - if (error) - return error; - error = clear_power_status_mask(port); - if (error) - return error; - /* Clear pending interrupts */ - error = tcpc_write16(port, TCPC_REG_ALERT, 0xffff); - if (error) - return error; - - return EC_SUCCESS; -} - -/* - * On TCPC i2c failure, make 30 tries (at least 300ms) before giving up - * in order to allow the TCPC time to boot / reset. - */ -#define TCPM_INIT_TRIES 30 - -int tcpci_tcpm_init(int port) -{ - int error; - int power_status; - int tries = TCPM_INIT_TRIES; - - if (port >= board_get_usb_pd_port_count()) - return EC_ERROR_INVAL; - - while (1) { - error = tcpc_read(port, TCPC_REG_POWER_STATUS, &power_status); - /* - * If read succeeds and the uninitialized bit is clear, then - * initialization is complete, clear all alert bits and write - * the initial alert mask. - */ - if (!error && !(power_status & TCPC_REG_POWER_STATUS_UNINIT)) - break; - if (--tries <= 0) - return error ? error : EC_ERROR_TIMEOUT; - msleep(10); - } - - tcpc_write16(port, TCPC_REG_ALERT, 0xffff); - /* Initialize power_status_mask */ - init_power_status_mask(port); - /* Update VBUS status */ - tcpc_vbus[port] = power_status & - TCPC_REG_POWER_STATUS_VBUS_PRES ? 1 : 0; -#if defined(CONFIG_USB_PD_VBUS_DETECT_TCPC) && defined(CONFIG_USB_CHARGER) - /* - * Set Vbus change now in case the TCPC doesn't send a power status - * changed interrupt for it later. - */ - usb_charger_vbus_change(port, tcpc_vbus[port]); -#endif - error = init_alert_mask(port); - if (error) - return error; - - /* Read chip info here when we know the chip is awake. */ - tcpm_get_chip_info(port, 1, NULL); - - return EC_SUCCESS; -} - -#ifdef CONFIG_USB_PD_TCPM_MUX - -/* - * When the TCPC/MUX device is only used for the MUX, we need to initialize it - * via mux init because tcpc_init won't run for the device. This is borrowed - * from tcpc_init. - */ -int tcpci_tcpm_mux_init(int port) -{ - int error; - int power_status; - int tries = TCPM_INIT_TRIES; - - /* If this MUX is also the TCPC, then skip init */ - if (!(usb_muxes[port].flags & USB_MUX_FLAG_NOT_TCPC)) - return EC_SUCCESS; - - /* Wait for the device to exit low power state */ - while (1) { - error = mux_read(port, TCPC_REG_POWER_STATUS, &power_status); - /* - * If read succeeds and the uninitialized bit is clear, then - * initialization is complete. - */ - if (!error && !(power_status & TCPC_REG_POWER_STATUS_UNINIT)) - break; - if (--tries <= 0) - return error ? error : EC_ERROR_TIMEOUT; - msleep(10); - } - - /* Turn off all alerts and acknowledge any pending IRQ */ - error = mux_write16(port, TCPC_REG_ALERT_MASK, 0); - error |= mux_write16(port, TCPC_REG_ALERT, 0xffff); - - return error ? EC_ERROR_UNKNOWN : EC_SUCCESS; -} - -int tcpci_tcpm_mux_enter_low_power(int port) -{ - /* If this MUX is also the TCPC, then skip low power */ - if (!(usb_muxes[port].flags & USB_MUX_FLAG_NOT_TCPC)) - return EC_SUCCESS; - - return mux_write(port, TCPC_REG_COMMAND, TCPC_REG_COMMAND_I2CIDLE); -} - -int tcpci_tcpm_mux_set(int port, mux_state_t mux_state) -{ - int reg = 0; - int rv; - - /* Parameter is port only */ - rv = mux_read(port, TCPC_REG_CONFIG_STD_OUTPUT, ®); - if (rv != EC_SUCCESS) - return rv; - - reg &= ~(TCPC_REG_CONFIG_STD_OUTPUT_MUX_MASK | - TCPC_REG_CONFIG_STD_OUTPUT_CONNECTOR_FLIPPED); - if (mux_state & MUX_USB_ENABLED) - reg |= TCPC_REG_CONFIG_STD_OUTPUT_MUX_USB; - if (mux_state & MUX_DP_ENABLED) - reg |= TCPC_REG_CONFIG_STD_OUTPUT_MUX_DP; - if (mux_state & MUX_POLARITY_INVERTED) - reg |= TCPC_REG_CONFIG_STD_OUTPUT_CONNECTOR_FLIPPED; - - /* Parameter is port only */ - return mux_write(port, TCPC_REG_CONFIG_STD_OUTPUT, reg); -} - -/* Reads control register and updates mux_state accordingly */ -int tcpci_tcpm_mux_get(int port, mux_state_t *mux_state) -{ - int reg = 0; - int rv; - - *mux_state = 0; - - /* Parameter is port only */ - rv = mux_read(port, TCPC_REG_CONFIG_STD_OUTPUT, ®); - - if (rv != EC_SUCCESS) - return rv; - - if (reg & TCPC_REG_CONFIG_STD_OUTPUT_MUX_USB) - *mux_state |= MUX_USB_ENABLED; - if (reg & TCPC_REG_CONFIG_STD_OUTPUT_MUX_DP) - *mux_state |= MUX_DP_ENABLED; - if (reg & TCPC_REG_CONFIG_STD_OUTPUT_CONNECTOR_FLIPPED) - *mux_state |= MUX_POLARITY_INVERTED; - - return EC_SUCCESS; -} - -const struct usb_mux_driver tcpci_tcpm_usb_mux_driver = { - .init = &tcpci_tcpm_mux_init, - .set = &tcpci_tcpm_mux_set, - .get = &tcpci_tcpm_mux_get, - .enter_low_power_mode = &tcpci_tcpm_mux_enter_low_power, -}; - -#endif /* CONFIG_USB_PD_TCPM_MUX */ - -const struct tcpm_drv tcpci_tcpm_drv = { - .init = &tcpci_tcpm_init, - .release = &tcpci_tcpm_release, - .get_cc = &tcpci_tcpm_get_cc, -#ifdef CONFIG_USB_PD_VBUS_DETECT_TCPC - .get_vbus_level = &tcpci_tcpm_get_vbus_level, -#endif - .select_rp_value = &tcpci_tcpm_select_rp_value, - .set_cc = &tcpci_tcpm_set_cc, - .set_polarity = &tcpci_tcpm_set_polarity, - .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_USBC_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 -}; diff --git a/driver/tcpm/tcpci.h b/driver/tcpm/tcpci.h deleted file mode 100644 index 930bfd6d70..0000000000 --- a/driver/tcpm/tcpci.h +++ /dev/null @@ -1,191 +0,0 @@ -/* Copyright 2015 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. - */ - -/* USB Power delivery port management */ - -#ifndef __CROS_EC_USB_PD_TCPM_TCPCI_H -#define __CROS_EC_USB_PD_TCPM_TCPCI_H - -#include "tcpm.h" -#include "usb_mux.h" -#include "usb_pd_tcpm.h" - -#define TCPC_REG_VENDOR_ID 0x0 -#define TCPC_REG_PRODUCT_ID 0x2 -#define TCPC_REG_BCD_DEV 0x4 -#define TCPC_REG_TC_REV 0x6 -#define TCPC_REG_PD_REV 0x8 -#define TCPC_REG_PD_INT_REV 0xa - -#define TCPC_REG_ALERT 0x10 -#define TCPC_REG_ALERT_MASK_ALL 0xffff -#define TCPC_REG_ALERT_VENDOR_DEF BIT(15) -#define TCPC_REG_ALERT_ALERT_EXT BIT(14) -#define TCPC_REG_ALERT_VBUS_DISCNCT BIT(11) -#define TCPC_REG_ALERT_RX_BUF_OVF BIT(10) -#define TCPC_REG_ALERT_FAULT BIT(9) -#define TCPC_REG_ALERT_V_ALARM_LO BIT(8) -#define TCPC_REG_ALERT_V_ALARM_HI BIT(7) -#define TCPC_REG_ALERT_TX_SUCCESS BIT(6) -#define TCPC_REG_ALERT_TX_DISCARDED BIT(5) -#define TCPC_REG_ALERT_TX_FAILED BIT(4) -#define TCPC_REG_ALERT_RX_HARD_RST BIT(3) -#define TCPC_REG_ALERT_RX_STATUS BIT(2) -#define TCPC_REG_ALERT_POWER_STATUS BIT(1) -#define TCPC_REG_ALERT_CC_STATUS BIT(0) -#define TCPC_REG_ALERT_TX_COMPLETE (TCPC_REG_ALERT_TX_SUCCESS | \ - TCPC_REG_ALERT_TX_DISCARDED | \ - TCPC_REG_ALERT_TX_FAILED) - -#define TCPC_REG_ALERT_MASK 0x12 -#define TCPC_REG_POWER_STATUS_MASK 0x14 -#define TCPC_REG_FAULT_STATUS_MASK 0x15 - -#define TCPC_REG_CONFIG_STD_OUTPUT 0x18 -#define TCPC_REG_CONFIG_STD_OUTPUT_MUX_MASK (3 << 2) -#define TCPC_REG_CONFIG_STD_OUTPUT_MUX_NONE (0 << 2) -#define TCPC_REG_CONFIG_STD_OUTPUT_MUX_USB BIT(2) -#define TCPC_REG_CONFIG_STD_OUTPUT_MUX_DP (2 << 2) -#define TCPC_REG_CONFIG_STD_OUTPUT_CONNECTOR_FLIPPED BIT(0) - -#define TCPC_REG_TCPC_CTRL 0x19 -#define TCPC_REG_TCPC_CTRL_SET(polarity) (polarity) -#define TCPC_REG_TCPC_CTRL_POLARITY(reg) ((reg) & 0x1) - -#define TCPC_REG_ROLE_CTRL 0x1a -#define TCPC_REG_ROLE_CTRL_SET(drp, rp, cc1, cc2) \ - ((drp) << 6 | (rp) << 4 | (cc2) << 2 | (cc1)) -#define TCPC_REG_ROLE_CTRL_DRP(reg) (((reg) & 0x40) >> 6) -#define TCPC_REG_ROLE_CTRL_RP_MASK 0x30 -#define TCPC_REG_ROLE_CTRL_RP(reg) (((reg) & TCPC_REG_ROLE_CTRL_RP_MASK) >> 4) -#define TCPC_REG_ROLE_CTRL_CC2(reg) (((reg) & 0xc) >> 2) -#define TCPC_REG_ROLE_CTRL_CC1(reg) ((reg) & 0x3) - -#define TCPC_REG_FAULT_CTRL 0x1b -#define TCPC_REG_FAULT_CTRL_VBUS_OVP_FAULT_DIS BIT(1) - -#define TCPC_REG_POWER_CTRL 0x1c -#define TCPC_REG_POWER_CTRL_FRS_ENABLE BIT(7) -#define TCPC_REG_POWER_CTRL_VBUS_VOL_MONITOR_DIS BIT(6) -#define TCPC_REG_POWER_CTRL_AUTO_DISCHARGE_DISCONNECT BIT(4) -#define TCPC_REG_POWER_CTRL_FORCE_DISCHARGE BIT(2) -#define TCPC_REG_POWER_CTRL_SET(vconn) (vconn) -#define TCPC_REG_POWER_CTRL_VCONN(reg) ((reg) & 0x1) - -#define TCPC_REG_CC_STATUS 0x1d -#define TCPC_REG_CC_STATUS_LOOK4CONNECTION(reg) ((reg & 0x20) >> 5) -#define TCPC_REG_CC_STATUS_SET(term, cc1, cc2) \ - ((term) << 4 | ((cc2) & 0x3) << 2 | ((cc1) & 0x3)) -#define TCPC_REG_CC_STATUS_TERM(reg) (((reg) & 0x10) >> 4) -#define TCPC_REG_CC_STATUS_CC2(reg) (((reg) & 0xc) >> 2) -#define TCPC_REG_CC_STATUS_CC1(reg) ((reg) & 0x3) - -#define TCPC_REG_POWER_STATUS 0x1e -#define TCPC_REG_POWER_STATUS_MASK_ALL 0xff -#define TCPC_REG_POWER_STATUS_UNINIT BIT(6) -#define TCPC_REG_POWER_STATUS_VBUS_DET BIT(3) -#define TCPC_REG_POWER_STATUS_VBUS_PRES BIT(2) - -#define TCPC_REG_FAULT_STATUS 0x1f - -#define TCPC_REG_ALERT_EXT 0x21 -#define TCPC_REG_ALERT_EXT_TIMER_EXPIRED BIT(2) -#define TCPC_REG_ALERT_EXT_SRC_FRS BIT(1) -#define TCPC_REG_ALERT_EXT_SNK_FRS BIT(0) - -#define TCPC_REG_COMMAND 0x23 -#define TCPC_REG_COMMAND_ENABLE_VBUS_DETECT 0x33 -#define TCPC_REG_COMMAND_SNK_CTRL_LOW 0x44 -#define TCPC_REG_COMMAND_SNK_CTRL_HIGH 0x55 -#define TCPC_REG_COMMAND_SRC_CTRL_LOW 0x66 -#define TCPC_REG_COMMAND_SRC_CTRL_HIGH 0x77 -#define TCPC_REG_COMMAND_LOOK4CONNECTION 0x99 -#define TCPC_REG_COMMAND_I2CIDLE 0xFF - -#define TCPC_REG_DEV_CAP_1 0x24 - -#define TCPC_REG_DEV_CAP_2 0x26 -#define TCPC_REG_DEV_CAP_2_SNK_FR_SWAP BIT(9) - -#define TCPC_REG_STD_INPUT_CAP 0x28 -#define TCPC_REG_STD_OUTPUT_CAP 0x29 - -#define TCPC_REG_CONFIG_EXT_1 0x2A -#define TCPC_REG_CONFIG_EXT_1_FR_SWAP_SNK_DIR BIT(1) - -#define TCPC_REG_MSG_HDR_INFO 0x2e -#define TCPC_REG_MSG_HDR_INFO_SET(drole, prole) \ - ((drole) << 3 | (PD_REV20 << 1) | (prole)) -#define TCPC_REG_MSG_HDR_INFO_DROLE(reg) (((reg) & 0x8) >> 3) -#define TCPC_REG_MSG_HDR_INFO_PROLE(reg) ((reg) & 0x1) - -#define TCPC_REG_RX_DETECT 0x2f -#define TCPC_REG_RX_DETECT_SOP_HRST_MASK 0x21 -#define TCPC_REG_RX_DETECT_SOP_SOPP_SOPPP_HRST_MASK 0x27 -#define TCPC_REG_RX_BYTE_CNT 0x30 -#define TCPC_REG_RX_BUF_FRAME_TYPE 0x31 - -#define TCPC_REG_RX_HDR 0x32 -#define TCPC_REG_RX_DATA 0x34 /* through 0x4f */ - -#define TCPC_REG_TRANSMIT 0x50 -#define TCPC_REG_TRANSMIT_SET_WITH_RETRY(type) \ - (PD_RETRY_COUNT << 4 | (type)) -#define TCPC_REG_TRANSMIT_SET_WITHOUT_RETRY(type) (type) -#define TCPC_REG_TRANSMIT_RETRY(reg) (((reg) & 0x30) >> 4) -#define TCPC_REG_TRANSMIT_TYPE(reg) ((reg) & 0x7) - -#define TCPC_REG_TX_BYTE_CNT 0x51 -#define TCPC_REG_TX_HDR 0x52 -#define TCPC_REG_TX_DATA 0x54 /* through 0x6f */ - -#define TCPC_REG_VBUS_VOLTAGE 0x70 -#define TCPC_REG_VBUS_SINK_DISCONNECT_THRESH 0x72 -#define TCPC_REG_VBUS_STOP_DISCHARGE_THRESH 0x74 -#define TCPC_REG_VBUS_VOLTAGE_ALARM_HI_CFG 0x76 -#define TCPC_REG_VBUS_VOLTAGE_ALARM_LO_CFG 0x78 - -extern const struct tcpm_drv tcpci_tcpm_drv; -extern const struct usb_mux_driver tcpci_tcpm_usb_mux_driver; - -void tcpci_tcpc_alert(int port); -int tcpci_tcpm_init(int port); -int tcpci_tcpm_get_cc(int port, enum tcpc_cc_voltage_status *cc1, - enum tcpc_cc_voltage_status *cc2); -int tcpci_tcpm_get_vbus_level(int port); -int tcpci_tcpm_select_rp_value(int port, int rp); -int tcpci_tcpm_set_cc(int port, int pull); -int tcpci_tcpm_set_polarity(int port, int polarity); -int tcpci_tcpm_set_vconn(int port, int enable); -int tcpci_tcpm_set_msg_header(int port, int power_role, int data_role); -int tcpci_tcpm_set_rx_enable(int port, int enable); -int tcpci_tcpm_get_message_raw(int port, uint32_t *payload, int *head); -int tcpci_tcpm_transmit(int port, enum tcpm_transmit_type type, - uint16_t header, const uint32_t *data); -int tcpci_tcpm_release(int port); -#ifdef CONFIG_USB_PD_DUAL_ROLE_AUTO_TOGGLE -int tcpci_tcpc_drp_toggle(int port); -#endif -#ifdef CONFIG_USB_PD_TCPC_LOW_POWER -int tcpci_enter_low_power_mode(int port); -#endif -#ifdef CONFIG_USB_PD_DISCHARGE_TCPC -void tcpci_tcpc_discharge_vbus(int port, int enable); -#endif - -int tcpci_tcpm_mux_init(int i2c_addr); -int tcpci_tcpm_mux_set(int i2c_addr, mux_state_t mux_state); -int tcpci_tcpm_mux_get(int i2c_addr, mux_state_t *mux_state); -int tcpci_tcpm_mux_enter_low_power(int port); -int tcpci_get_chip_info(int port, int live, - struct ec_response_pd_chip_info_v1 **chip_info); -#ifdef CONFIG_USBC_PPC -int tcpci_tcpm_set_snk_ctrl(int port, int enable); -int tcpci_tcpm_set_src_ctrl(int port, int enable); -#endif - -void tcpci_tcpc_fast_role_swap_enable(int port, int enable); - -#endif /* __CROS_EC_USB_PD_TCPM_TCPCI_H */ diff --git a/driver/tcpm/tcpm.h b/driver/tcpm/tcpm.h deleted file mode 100644 index 51b315fb77..0000000000 --- a/driver/tcpm/tcpm.h +++ /dev/null @@ -1,418 +0,0 @@ -/* Copyright 2015 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. - */ - -/* USB Power delivery port management - common header for TCPM drivers */ - -#ifndef __CROS_EC_USB_PD_TCPM_TCPM_H -#define __CROS_EC_USB_PD_TCPM_TCPM_H - -#include "common.h" -#include "ec_commands.h" -#include "gpio.h" -#include "i2c.h" -#include "usb_pd_tcpm.h" -#include "util.h" - -#if defined(CONFIG_USB_PD_DUAL_ROLE_AUTO_TOGGLE) && \ - !defined(CONFIG_USB_PD_DUAL_ROLE) -#error "DRP auto toggle requires board to have DRP support" -#error "Please upgrade your board configuration" -#endif - -#ifndef CONFIG_USB_PD_TCPC - -/* I2C wrapper functions - get I2C port / slave addr from config struct. */ -#ifndef CONFIG_USB_PD_TCPC_LOW_POWER -static inline int tcpc_addr_write(int port, int i2c_addr, int reg, int val) -{ - return i2c_write8(tcpc_config[port].i2c_info.port, - i2c_addr, reg, val); -} - -static inline int tcpc_write16(int port, int reg, int val) -{ - return i2c_write16(tcpc_config[port].i2c_info.port, - tcpc_config[port].i2c_info.addr_flags, - reg, val); -} - -static inline int tcpc_addr_read(int port, int i2c_addr, int reg, int *val) -{ - return i2c_read8(tcpc_config[port].i2c_info.port, - i2c_addr, reg, val); -} - -static inline int tcpc_read16(int port, int reg, int *val) -{ - return i2c_read16(tcpc_config[port].i2c_info.port, - tcpc_config[port].i2c_info.addr_flags, - reg, val); -} - -static inline int tcpc_xfer(int port, const uint8_t *out, int out_size, - uint8_t *in, int in_size) -{ - return i2c_xfer(tcpc_config[port].i2c_info.port, - tcpc_config[port].i2c_info.addr_flags, - out, out_size, in, in_size); -} - -static inline int tcpc_xfer_unlocked(int port, const uint8_t *out, int out_size, - uint8_t *in, int in_size, int flags) -{ - return i2c_xfer_unlocked(tcpc_config[port].i2c_info.port, - tcpc_config[port].i2c_info.addr_flags, - out, out_size, in, in_size, flags); -} - -static inline int tcpc_read_block(int port, int reg, uint8_t *in, int size) -{ - return i2c_read_block(tcpc_config[port].i2c_info.port, - tcpc_config[port].i2c_info.addr_flags, - reg, in, size); -} - -static inline int tcpc_write_block(int port, int reg, - const uint8_t *out, int size) -{ - return i2c_write_block(tcpc_config[port].i2c_info.port, - tcpc_config[port].i2c_info.addr_flags, - reg, out, size); -} - -#else /* !CONFIG_USB_PD_TCPC_LOW_POWER */ -int tcpc_addr_write(int port, int i2c_addr, int reg, int val); -int tcpc_write16(int port, int reg, int val); -int tcpc_addr_read(int port, int i2c_addr, int reg, int *val); -int tcpc_read16(int port, int reg, int *val); -int tcpc_read_block(int port, int reg, uint8_t *in, int size); -int tcpc_write_block(int port, int reg, const uint8_t *out, int size); -int tcpc_xfer(int port, const uint8_t *out, int out_size, - uint8_t *in, int in_size); -int tcpc_xfer_unlocked(int port, const uint8_t *out, int out_size, - uint8_t *in, int in_size, int flags); - -#endif /* CONFIG_USB_PD_TCPC_LOW_POWER */ - -static inline int tcpc_write(int port, int reg, int val) -{ - return tcpc_addr_write(port, - tcpc_config[port].i2c_info.addr_flags, reg, val); -} - -static inline int tcpc_read(int port, int reg, int *val) -{ - return tcpc_addr_read(port, - tcpc_config[port].i2c_info.addr_flags, reg, val); -} - -static inline void tcpc_lock(int port, int lock) -{ - i2c_lock(tcpc_config[port].i2c_info.port, lock); -} - -/* TCPM driver wrapper function */ -static inline int tcpm_init(int port) -{ - int rv; - - rv = tcpc_config[port].drv->init(port); - if (rv) - return rv; - - /* Board specific post TCPC init */ - if (board_tcpc_post_init) - rv = board_tcpc_post_init(port); - - return rv; -} - -static inline int tcpm_release(int port) -{ - return tcpc_config[port].drv->release(port); -} - -static inline int tcpm_get_cc(int port, enum tcpc_cc_voltage_status *cc1, - enum tcpc_cc_voltage_status *cc2) -{ - return tcpc_config[port].drv->get_cc(port, cc1, cc2); -} - -static inline int tcpm_get_vbus_level(int port) -{ - return tcpc_config[port].drv->get_vbus_level(port); -} - -static inline int tcpm_select_rp_value(int port, int rp) -{ - return tcpc_config[port].drv->select_rp_value(port, rp); -} - -static inline int tcpm_set_cc(int port, int pull) -{ - return tcpc_config[port].drv->set_cc(port, pull); -} - -static inline int tcpm_set_polarity(int port, int polarity) -{ - return tcpc_config[port].drv->set_polarity(port, polarity); -} - -static inline int tcpm_set_vconn(int port, int enable) -{ - return tcpc_config[port].drv->set_vconn(port, enable); -} - -static inline int tcpm_set_msg_header(int port, int power_role, int data_role) -{ - return tcpc_config[port].drv->set_msg_header(port, power_role, - data_role); -} - -static inline int tcpm_set_rx_enable(int port, int enable) -{ - return tcpc_config[port].drv->set_rx_enable(port, enable); -} - -/** - * Reads a message using get_message_raw driver method and puts it into EC's - * cache. - */ -int tcpm_enqueue_message(int port); - -static inline int tcpm_transmit(int port, enum tcpm_transmit_type type, - uint16_t header, const uint32_t *data) -{ - return tcpc_config[port].drv->transmit(port, type, header, data); -} - -#ifdef CONFIG_USBC_PPC -static inline int tcpm_set_snk_ctrl(int port, int enable) -{ - if (tcpc_config[port].drv->set_snk_ctrl != NULL) - return tcpc_config[port].drv->set_snk_ctrl(port, enable); - else - return EC_ERROR_UNIMPLEMENTED; -} - -static inline int tcpm_set_src_ctrl(int port, int enable) -{ - if (tcpc_config[port].drv->set_src_ctrl != NULL) - return tcpc_config[port].drv->set_src_ctrl(port, enable); - else - return EC_ERROR_UNIMPLEMENTED; -} -#endif - -static inline void tcpc_alert(int port) -{ - tcpc_config[port].drv->tcpc_alert(port); -} - -static inline void tcpc_discharge_vbus(int port, int enable) -{ - tcpc_config[port].drv->tcpc_discharge_vbus(port, enable); -} - -#ifdef CONFIG_USB_PD_DUAL_ROLE_AUTO_TOGGLE -static inline int tcpm_auto_toggle_supported(int port) -{ - return !!tcpc_config[port].drv->drp_toggle; -} - -static inline int tcpm_enable_drp_toggle(int port) -{ - return tcpc_config[port].drv->drp_toggle(port); -} -#endif - -#ifdef CONFIG_USB_PD_TCPC_LOW_POWER -static inline int tcpm_enter_low_power_mode(int port) -{ - return tcpc_config[port].drv->enter_low_power_mode(port); -} -#endif - -#ifdef CONFIG_CMD_I2C_STRESS_TEST_TCPC -static inline int tcpc_i2c_read(const int port, const uint16_t addr_flags, - const int reg, int *data) -{ - return tcpc_read(port, reg, data); -} - -static inline int tcpc_i2c_write(const int port, const uint16_t addr_flags, - const int reg, int data) -{ - return tcpc_write(port, reg, data); -} -#endif - -static inline int tcpm_get_chip_info(int port, int live, - struct ec_response_pd_chip_info_v1 **info) -{ - if (tcpc_config[port].drv->get_chip_info) - return tcpc_config[port].drv->get_chip_info(port, live, info); - return EC_ERROR_UNIMPLEMENTED; -} - -#else - -/** - * Initialize TCPM driver and wait for TCPC readiness. - * - * @param port Type-C port number - * - * @return EC_SUCCESS or error - */ -int tcpm_init(int port); - -/** - * Read the CC line status. - * - * @param port Type-C port number - * @param cc1 pointer to CC status for CC1 - * @param cc2 pointer to CC status for CC2 - * - * @return EC_SUCCESS or error - */ -int tcpm_get_cc(int port, enum tcpc_cc_voltage_status *cc1, - enum tcpc_cc_voltage_status *cc2); - -/** - * Read VBUS - * - * @param port Type-C port number - * - * @return 0 => VBUS not detected, 1 => VBUS detected - */ -int tcpm_get_vbus_level(int port); - -/** - * Set the value of the CC pull-up used when we are a source. - * - * @param port Type-C port number - * @param rp One of enum tcpc_rp_value - * - * @return EC_SUCCESS or error - */ -int tcpm_select_rp_value(int port, int rp); - -/** - * Set the CC pull resistor. This sets our role as either source or sink. - * - * @param port Type-C port number - * @param pull One of enum tcpc_cc_pull - * - * @return EC_SUCCESS or error - */ -int tcpm_set_cc(int port, int pull); - -/** - * Set polarity - * - * @param port Type-C port number - * @param polarity 0=> transmit on CC1, 1=> transmit on CC2 - * - * @return EC_SUCCESS or error - */ -int tcpm_set_polarity(int port, int polarity); - -/** - * Set Vconn. - * - * @param port Type-C port number - * @param polarity Polarity of the CC line to read - * - * @return EC_SUCCESS or error - */ -int tcpm_set_vconn(int port, int enable); - -/** - * Set PD message header to use for goodCRC - * - * @param port Type-C port number - * @param power_role Power role to use in header - * @param data_role Data role to use in header - * - * @return EC_SUCCESS or error - */ -int tcpm_set_msg_header(int port, int power_role, int data_role); - -/** - * Set RX enable flag - * - * @param port Type-C port number - * @enable true for enable, false for disable - * - * @return EC_SUCCESS or error - */ -int tcpm_set_rx_enable(int port, int enable); - -/** - * Transmit PD message - * - * @param port Type-C port number - * @param type Transmit type - * @param header Packet header - * @param cnt Number of bytes in payload - * @param data Payload - * - * @return EC_SUCCESS or error - */ -int tcpm_transmit(int port, enum tcpm_transmit_type type, uint16_t header, - const uint32_t *data); - -/** - * TCPC is asserting alert - * - * @param port Type-C port number - */ -void tcpc_alert(int port); - -#endif - -/** - * Gets the next waiting RX message. - * - * @param port Type-C port number - * @param payload Pointer to location to copy payload of PD message - * @param header The header of PD message - * - * @return EC_SUCCESS or error - */ -int tcpm_dequeue_message(int port, uint32_t *payload, int *header); - -/** - * Returns true if the tcpm has RX messages waiting to be consumed. - */ -int tcpm_has_pending_message(int port); - -/** - * Clear any pending messages in the RX queue. This function must be - * called from the same context as the caller of tcpm_dequeue_message to avoid - * race conditions. - */ -void tcpm_clear_pending_messages(int port); - -/** - * Enable/Disable TCPC Fast Role Swap detection - * - * @param port Type-C port number - * @param enable FRS enable (true) disable (false) - */ -static inline void tcpm_set_frs_enable(int port, int enable) -{ - const struct tcpm_drv *tcpc; - - /* - * set_frs_enable will be set to tcpci_tcp_fast_role_swap_enable - * if it is handled by the tcpci for the tcpc chipset - */ - tcpc = tcpc_config[port].drv; - if (tcpc->set_frs_enable) - tcpc->set_frs_enable(port, enable); -} - -#endif diff --git a/driver/tcpm/tusb422.c b/driver/tcpm/tusb422.c deleted file mode 100644 index 0e6a6c51d5..0000000000 --- a/driver/tcpm/tusb422.c +++ /dev/null @@ -1,66 +0,0 @@ -/* Copyright 2018 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. - */ - -/* Type-C port manager for TI TUSB422 Port Controller */ - -#include "common.h" -#include "tusb422.h" -#include "tcpci.h" -#include "tcpm.h" -#include "timer.h" -#include "usb_pd.h" - -#ifndef CONFIG_USB_PD_TCPM_TCPCI -#error "TUSB422 is using a standard TCPCI interface" -#error "Please upgrade your board configuration" - -#endif - -int tusb422_tcpci_tcpn_init(int port) -{ - int rv = tcpci_tcpm_init(port); - - if (rv) - return rv; - - /* - * VBUS detection is supposed to be enabled by default, however the - * TUSB422 has this disabled following reset. - */ - /* Enable VBUS detection */ - return tcpc_write16(port, TCPC_REG_COMMAND, 0x33); -} - -const struct tcpm_drv tusb422_tcpm_drv = { - .init = &tusb422_tcpci_tcpn_init, - .release = &tcpci_tcpm_release, - .get_cc = &tcpci_tcpm_get_cc, -#ifdef CONFIG_USB_PD_VBUS_DETECT_TCPC - .get_vbus_level = &tcpci_tcpm_get_vbus_level, -#endif - .select_rp_value = &tcpci_tcpm_select_rp_value, - .set_cc = &tcpci_tcpm_set_cc, - .set_polarity = &tcpci_tcpm_set_polarity, - .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 -#ifdef CONFIG_USBC_PPC - .set_snk_ctrl = &tcpci_tcpm_set_snk_ctrl, - .set_src_ctrl = &tcpci_tcpm_set_src_ctrl, -#endif - .get_chip_info = &tcpci_get_chip_info, -#ifdef CONFIG_USB_PD_TCPC_LOW_POWER - .enter_low_power_mode = &tcpci_enter_low_power_mode, -#endif -}; diff --git a/driver/tcpm/tusb422.h b/driver/tcpm/tusb422.h deleted file mode 100644 index 52d0a079d6..0000000000 --- a/driver/tcpm/tusb422.h +++ /dev/null @@ -1,16 +0,0 @@ -/* Copyright 2018 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. - */ - -/* TI TUSB422 Type-C port controller */ - -#ifndef __CROS_EC_USB_PD_TCPM_TUSB422_H -#define __CROS_EC_USB_PD_TCPM_TUSB422_H - -/* I2C interface */ -#define TUSB422_I2C_ADDR_FLAGS 0x20 - -extern const struct tcpm_drv tusb422_tcpm_drv; - -#endif /* defined(__CROS_EC_USB_PD_TCPM_TUSB422_H) */ |