diff options
-rw-r--r-- | baseboard/zork/baseboard.c | 10 | ||||
-rw-r--r-- | driver/ioexpander_nct38xx.c | 344 | ||||
-rw-r--r-- | driver/ioexpander_nct38xx.h | 16 | ||||
-rw-r--r-- | driver/tcpm/nct38xx.c | 39 | ||||
-rw-r--r-- | driver/tcpm/nct38xx.h | 39 | ||||
-rw-r--r-- | driver/tcpm/tcpci.h | 1 | ||||
-rw-r--r-- | include/ioexpander.h | 5 |
7 files changed, 389 insertions, 65 deletions
diff --git a/baseboard/zork/baseboard.c b/baseboard/zork/baseboard.c index e160c7b38d..1505405071 100644 --- a/baseboard/zork/baseboard.c +++ b/baseboard/zork/baseboard.c @@ -315,7 +315,7 @@ const struct tcpc_config_t tcpc_config[] = { .bus_type = EC_BUS_TYPE_I2C, .i2c_info = { .port = I2C_PORT_TCPC0, - .addr_flags = NCT38xx_I2C_ADDR1_1_FLAGS, + .addr_flags = NCT38XX_I2C_ADDR1_1_FLAGS, }, .drv = &nct38xx_tcpm_drv, }, @@ -323,7 +323,7 @@ const struct tcpc_config_t tcpc_config[] = { .bus_type = EC_BUS_TYPE_I2C, .i2c_info = { .port = I2C_PORT_TCPC1, - .addr_flags = NCT38xx_I2C_ADDR1_1_FLAGS, + .addr_flags = NCT38XX_I2C_ADDR1_1_FLAGS, }, .drv = &nct38xx_tcpm_drv, }, @@ -453,14 +453,12 @@ BUILD_ASSERT(ARRAY_SIZE(usb_muxes) == USBC_PORT_COUNT); struct ioexpander_config_t ioex_config[] = { [USBC_PORT_C0] = { .i2c_host_port = I2C_PORT_TCPC0, - .i2c_slave_addr = NCT38xx_I2C_ADDR1_1_FLAGS, - .chip_info = -1, + .i2c_slave_addr = NCT38XX_I2C_ADDR1_1_FLAGS, .drv = &nct38xx_ioexpander_drv, }, [USBC_PORT_C1] = { .i2c_host_port = I2C_PORT_TCPC1, - .i2c_slave_addr = NCT38xx_I2C_ADDR1_1_FLAGS, - .chip_info = -1, + .i2c_slave_addr = NCT38XX_I2C_ADDR1_1_FLAGS, .drv = &nct38xx_ioexpander_drv, }, }; diff --git a/driver/ioexpander_nct38xx.c b/driver/ioexpander_nct38xx.c index 3baca77ddf..e7fe3d9453 100644 --- a/driver/ioexpander_nct38xx.c +++ b/driver/ioexpander_nct38xx.c @@ -16,9 +16,22 @@ #define CPRINTF(format, args...) cprintf(CC_GPIO, format, ## args) #define CPRINTS(format, args...) cprints(CC_GPIO, format, ## args) -static int nct38xx_ioex_check_is_valid(int chip_info, int port, int mask) +/* + * Store the GPIO_ALERT_MASK_0/1 and chip ID registers locally. In this way, + * we don't have to read it via I2C transaction everytime. + */ +struct nct38xx_chip_data { + uint8_t int_mask[2]; + int chip_id; +}; + +static struct nct38xx_chip_data chip_data[CONFIG_IO_EXPANDER_PORT_COUNT] = { + [0 ... (CONFIG_IO_EXPANDER_PORT_COUNT - 1)] = { {0, 0}, -1 } +}; + +static int nct38xx_ioex_check_is_valid(int ioex, int port, int mask) { - if (chip_info == NCT38XX_VARIANT_3808) { + if (chip_data[ioex].chip_id == NCT38XX_VARIANT_3808) { if (port == 1) { CPRINTF("Port 1 is not support in NCT3808\n"); return EC_ERROR_INVAL; @@ -32,7 +45,6 @@ static int nct38xx_ioex_check_is_valid(int chip_info, int port, int mask) } return EC_SUCCESS; - } static int nct38xx_ioex_init(int ioex) @@ -48,54 +60,73 @@ static int nct38xx_ioex_init(int ioex) rv = i2c_read8(ioex_p->i2c_host_port, ioex_p->i2c_slave_addr, TCPC_REG_BCD_DEV, &val); - if (rv) + if (rv != EC_SUCCESS) { CPRINTF("Failed to read NCT38XX DEV ID for IOexpander %d\n", ioex); - else - ioex_p->chip_info = - ((uint8_t)val & NCT38XX_VARIANT_MASK) >> 2; + return rv; + } - return rv; + chip_data[ioex].chip_id = ((uint8_t)val & NCT38XX_VARIANT_MASK) >> 2; + + /* + * NCT38XX uses the Vendor Define bit in the ALERT event to indicate + * that an IOEX IO's interrupt is triggered. + * Normally, The ALERT MASK for Vendor Define event should be set by + * the NCT38XX TCPCI driver's init function. + * However, it should be also set here if we want to test the interrupt + * function of IOEX when the NCT38XX TCPCI driver is not included. + */ + if (!IS_ENABLED(CONFIG_USB_PD_TCPM_NCT38XX)) { + rv = i2c_write16(ioex_p->i2c_host_port, + ioex_p->i2c_slave_addr, TCPC_REG_ALERT_MASK, + TCPC_REG_ALERT_VENDOR_DEF); + if (rv != EC_SUCCESS) + return rv; + } + return EC_SUCCESS; } static int nct38xx_ioex_get_level(int ioex, int port, int mask, int *val) { int rv, reg; - struct ioexpander_config_t *ioex_p = &ioex_config[ioex]; - rv = nct38xx_ioex_check_is_valid(ioex_p->chip_info, port, mask); + rv = nct38xx_ioex_check_is_valid(ioex, port, mask); if (rv != EC_SUCCESS) return rv; - reg = NCT38XXX_REG_GPIO_DATA_IN(port); + reg = NCT38XX_REG_GPIO_DATA_IN(port); rv = i2c_read8(ioex_config[ioex].i2c_host_port, ioex_config[ioex].i2c_slave_addr, reg, val); + if (rv != EC_SUCCESS) + return rv; *val = !!(*val & mask); - return rv; + + return EC_SUCCESS; } static int nct38xx_ioex_set_level(int ioex, int port, int mask, int value) { int rv, reg, val; - struct ioexpander_config_t *ioex_p = &ioex_config[ioex]; - rv = nct38xx_ioex_check_is_valid(ioex_p->chip_info, port, mask); + rv = nct38xx_ioex_check_is_valid(ioex, port, mask); if (rv != EC_SUCCESS) return rv; - reg = NCT38XXX_REG_GPIO_DATA_OUT(port); + reg = NCT38XX_REG_GPIO_DATA_OUT(port); rv = i2c_read8(ioex_config[ioex].i2c_host_port, ioex_config[ioex].i2c_slave_addr, reg, &val); + if (rv != EC_SUCCESS) + return rv; if (value) val |= mask; else val &= ~mask; - rv |= i2c_write8(ioex_config[ioex].i2c_host_port, + + return i2c_write8(ioex_config[ioex].i2c_host_port, ioex_config[ioex].i2c_slave_addr, reg, val); - return rv; } static int nct38xx_ioex_get_flags(int ioex, int port, int mask, int *flags) @@ -106,30 +137,104 @@ static int nct38xx_ioex_get_flags(int ioex, int port, int mask, int *flags) i2c_port = ioex_p->i2c_host_port; i2c_addr = ioex_p->i2c_slave_addr; - rv = nct38xx_ioex_check_is_valid(ioex_p->chip_info, port, mask); + rv = nct38xx_ioex_check_is_valid(ioex, port, mask); if (rv != EC_SUCCESS) return rv; - reg = NCT38XXX_REG_GPIO_DIR(port); + reg = NCT38XX_REG_GPIO_DIR(port); rv = i2c_read8(i2c_port, i2c_addr, reg, &val); + if (rv != EC_SUCCESS) + return rv; + if (val & mask) *flags |= GPIO_OUTPUT; else *flags |= GPIO_INPUT; - reg = NCT38XXX_REG_GPIO_DATA_IN(port); - rv |= i2c_read8(i2c_port, i2c_addr, reg, &val); + reg = NCT38XX_REG_GPIO_DATA_IN(port); + rv = i2c_read8(i2c_port, i2c_addr, reg, &val); + if (rv != EC_SUCCESS) + return rv; + if (val & mask) *flags |= GPIO_HIGH; else *flags |= GPIO_LOW; - reg = NCT38XXX_REG_GPIO_OD_SEL(port); - rv |= i2c_read8(i2c_port, i2c_addr, reg, &val); + reg = NCT38XX_REG_GPIO_OD_SEL(port); + rv = i2c_read8(i2c_port, i2c_addr, reg, &val); + if (rv != EC_SUCCESS) + return rv; + if (val & mask) *flags |= GPIO_OPEN_DRAIN; - return rv; + return EC_SUCCESS; +} + +static int nct38xx_ioex_sel_int_type(int i2c_port, int i2c_addr, int port, + int mask, int flags) +{ + int rv; + int reg_rising, reg_falling; + int rising, falling; + + reg_rising = NCT38XX_REG_GPIO_ALERT_RISE(port); + rv = i2c_read8(i2c_port, i2c_addr, reg_rising, &rising); + if (rv != EC_SUCCESS) + return rv; + + reg_falling = NCT38XX_REG_GPIO_ALERT_FALL(port); + rv = i2c_read8(i2c_port, i2c_addr, reg_falling, &falling); + if (rv != EC_SUCCESS) + return rv; + + /* Handle interrupt for level trigger */ + if ((flags & GPIO_INT_F_HIGH) || (flags & GPIO_INT_F_LOW)) { + int reg_level, level; + + reg_level = NCT38XX_REG_GPIO_ALERT_LEVEL(port); + rv = i2c_read8(i2c_port, i2c_addr, reg_level, &level); + if (rv != EC_SUCCESS) + return rv; + /* + * For "level" triggered interrupt, the related bit in + * ALERT_RISE and ALERT_FALL registers must be 0 + */ + rising &= ~mask; + falling &= ~mask; + if (flags & GPIO_INT_F_HIGH) + level |= mask; + else + level &= ~mask; + + rv = i2c_write8(i2c_port, i2c_addr, reg_rising, rising); + if (rv != EC_SUCCESS) + return rv; + rv = i2c_write8(i2c_port, i2c_addr, reg_falling, falling); + if (rv != EC_SUCCESS) + return rv; + rv = i2c_write8(i2c_port, i2c_addr, reg_level, level); + if (rv != EC_SUCCESS) + return rv; + } else if ((flags & GPIO_INT_F_RISING) || + (flags & GPIO_INT_F_FALLING)) { + if (flags & GPIO_INT_F_RISING) + rising |= mask; + else + rising &= ~mask; + if (flags & GPIO_INT_F_FALLING) + falling |= mask; + else + falling &= ~mask; + rv = i2c_write8(i2c_port, i2c_addr, reg_rising, rising); + if (rv != EC_SUCCESS) + return rv; + rv = i2c_write8(i2c_port, i2c_addr, reg_falling, falling); + if (rv != EC_SUCCESS) + return rv; + } + return EC_SUCCESS; } static int nct38xx_ioex_set_flags_by_mask(int ioex, int port, int mask, @@ -141,7 +246,7 @@ static int nct38xx_ioex_set_flags_by_mask(int ioex, int port, int mask, i2c_port = ioex_p->i2c_host_port; i2c_addr = ioex_p->i2c_slave_addr; - rv = nct38xx_ioex_check_is_valid(ioex_p->chip_info, port, mask); + rv = nct38xx_ioex_check_is_valid(ioex, port, mask); if (rv != EC_SUCCESS) return rv; @@ -151,12 +256,17 @@ static int nct38xx_ioex_set_flags_by_mask(int ioex, int port, int mask, */ if (port == 0) { /* GPIO03 in NCT3807 is not muxed with other function. */ - if (!(ioex_p->chip_info == + if (!(chip_data[ioex].chip_id == NCT38XX_VARIANT_3807 && mask & 0x08)) { - reg = NCT38XXX_REG_MUX_CONTROL; - rv |= i2c_read8(i2c_port, i2c_addr, reg, &val); + reg = NCT38XX_REG_MUX_CONTROL; + rv = i2c_read8(i2c_port, i2c_addr, reg, &val); + if (rv != EC_SUCCESS) + return rv; + val = (val | mask); - rv |= i2c_write8(i2c_port, i2c_addr, reg, val); + rv = i2c_write8(i2c_port, i2c_addr, reg, val); + if (rv != EC_SUCCESS) + return rv; } } @@ -167,32 +277,187 @@ static int nct38xx_ioex_set_flags_by_mask(int ioex, int port, int mask, } /* Select open drain 0:push-pull 1:open-drain */ - reg = NCT38XXX_REG_GPIO_OD_SEL(port); - rv |= i2c_read8(i2c_port, i2c_addr, reg, &val); + reg = NCT38XX_REG_GPIO_OD_SEL(port); + rv = i2c_read8(i2c_port, i2c_addr, reg, &val); + if (rv != EC_SUCCESS) + return rv; + if (flags & GPIO_OPEN_DRAIN) val |= mask; else val &= ~mask; - rv |= i2c_write8(i2c_port, i2c_addr, reg, val); + rv = i2c_write8(i2c_port, i2c_addr, reg, val); + if (rv != EC_SUCCESS) + return rv; + + nct38xx_ioex_sel_int_type(i2c_port, i2c_addr, port, mask, flags); /* Configure the output level */ - reg = NCT38XXX_REG_GPIO_DATA_OUT(port); - rv |= i2c_read8(i2c_port, i2c_addr, reg, &val); + reg = NCT38XX_REG_GPIO_DATA_OUT(port); + rv = i2c_read8(i2c_port, i2c_addr, reg, &val); + if (rv != EC_SUCCESS) + return rv; + if (flags & GPIO_HIGH) val |= mask; else if (flags & GPIO_LOW) val &= ~mask; - rv |= i2c_write8(i2c_port, i2c_addr, reg, val); + rv = i2c_write8(i2c_port, i2c_addr, reg, val); + if (rv != EC_SUCCESS) + return rv; + + reg = NCT38XX_REG_GPIO_DIR(port); + rv = i2c_read8(i2c_port, i2c_addr, reg, &val); + if (rv != EC_SUCCESS) + return rv; - reg = NCT38XXX_REG_GPIO_DIR(port); - rv |= i2c_read8(i2c_port, i2c_addr, reg, &val); if (flags & GPIO_OUTPUT) val |= mask; else val &= ~mask; - rv |= i2c_write8(i2c_port, i2c_addr, reg, val); - return rv; + return i2c_write8(i2c_port, i2c_addr, reg, val); +} + +/* + * The following functions are used for IO's interrupt support. + * + * please note that if the system needs to use an IO on NCT38XX to support + * the interrupt, the following two consideration should be taken into account. + * 1. Interrupt latency: + * Because it requires to access the registers of NCT38XX via I2C + * transaction to know the interrupt event, there is some added latency + * for the interrupt handling. If the interrupt requires short latency, + * we do not recommend to connect such a signal to the NCT38XX. + * + * 2. Shared ALERT pin: + * Because the ALERT pin is shared also with the TCPC ALERT, we do not + * recommend to connect any signal that may generate a high rate of + * interrupts so it will not interfere with the normal work of the + * TCPC. + */ +static int nct38xx_ioex_enable_interrupt(int ioex, int port, int mask, + int enable) +{ + int rv, reg, val; + struct ioexpander_config_t *ioex_p = &ioex_config[ioex]; + + rv = nct38xx_ioex_check_is_valid(ioex, port, mask); + if (rv != EC_SUCCESS) + return rv; + + /* Clear the pending bit */ + reg = NCT38XX_REG_GPIO_ALERT_STAT(port); + rv = i2c_read8(ioex_p->i2c_host_port, ioex_p->i2c_slave_addr, + reg, &val); + if (rv != EC_SUCCESS) + return rv; + + val |= mask; + rv = i2c_write8(ioex_p->i2c_host_port, ioex_p->i2c_slave_addr, + reg, val); + if (rv != EC_SUCCESS) + return rv; + + reg = NCT38XX_REG_GPIO_ALERT_MASK(port); + if (enable) { + /* Enable the alert mask */ + chip_data[ioex].int_mask[port] |= mask; + val = chip_data[ioex].int_mask[port]; + } else { + /* Disable the alert mask */ + chip_data[ioex].int_mask[port] &= ~mask; + val = chip_data[ioex].int_mask[port]; + } + + return i2c_write8(ioex_p->i2c_host_port, ioex_p->i2c_slave_addr, + reg, val); +} + +int nct38xx_ioex_event_handler(int ioex) +{ + int reg, int_status, int_mask; + int i, j, total_port; + const struct ioex_info *g; + struct ioexpander_config_t *ioex_p = &ioex_config[ioex]; + int rv = 0; + + int_mask = chip_data[ioex].int_mask[0] | ( + chip_data[ioex].int_mask[1] << 8); + reg = NCT38XX_REG_GPIO_ALERT_STAT(0); + /* + * Read ALERT_STAT_0 and ALERT_STAT_1 register in a single I2C + * transaction to increase efficiency + */ + rv = i2c_read16(ioex_p->i2c_host_port, ioex_p->i2c_slave_addr, + reg, &int_status); + if (rv != EC_SUCCESS) + return rv; + + int_status = int_status & int_mask; + /* + * Clear the changed status bits in ALERT_STAT_0 and ALERT_STAT_1 + * register in a single I2C transaction to increase efficiency + */ + rv = i2c_write16(ioex_p->i2c_host_port, ioex_p->i2c_slave_addr, + reg, int_status); + if (rv != EC_SUCCESS) + return rv; + + /* For NCT3808, only check one port */ + total_port = (chip_data[ioex].chip_id == NCT38XX_VARIANT_3808) ? + NCT38XX_NCT3808_MAX_IO_PORT : + NCT38XX_NCT3807_MAX_IO_PORT; + for (i = 0; i < total_port; i++) { + uint8_t pending; + + pending = int_status >> (i * 8); + + if (!pending) + continue; + + for (j = 0, g = ioex_list; j < ioex_ih_count; j++, g++) { + + if (ioex == g->ioex && i == g->port && + (pending & g->mask)) { + ioex_irq_handlers[j](j); + pending &= ~g->mask; + if (!pending) + break; + } + + } + } + + return EC_SUCCESS; +} + +/* + * Normally, the ALERT MASK for Vendor Define event should be checked by + * the NCT38XX TCPCI driver's tcpc_alert function. + * However, it should be checked here if we want to test the interrupt + * function of IOEX when the NCT38XX TCPCI driver is not included. + */ +void nct38xx_ioex_handle_alert(int ioex) +{ + int rv, status; + struct ioexpander_config_t *ioex_p = &ioex_config[ioex]; + + rv = i2c_read16(ioex_p->i2c_host_port, ioex_p->i2c_slave_addr, + TCPC_REG_ALERT, &status); + if (rv != EC_SUCCESS) + CPRINTF("fail to read ALERT register\n"); + + if (status & TCPC_REG_ALERT_VENDOR_DEF) { + rv = i2c_write16(ioex_p->i2c_host_port, + ioex_p->i2c_slave_addr, TCPC_REG_ALERT, + TCPC_REG_ALERT_VENDOR_DEF); + if (rv != EC_SUCCESS) { + CPRINTF("Fail to clear Vendor Define mask\n"); + return; + } + nct38xx_ioex_event_handler(ioex); + } } const struct ioexpander_drv nct38xx_ioexpander_drv = { @@ -201,4 +466,5 @@ const struct ioexpander_drv nct38xx_ioexpander_drv = { .set_level = &nct38xx_ioex_set_level, .get_flags_by_mask = &nct38xx_ioex_get_flags, .set_flags_by_mask = &nct38xx_ioex_set_flags_by_mask, + .enable_interrupt = &nct38xx_ioex_enable_interrupt, }; diff --git a/driver/ioexpander_nct38xx.h b/driver/ioexpander_nct38xx.h index bbd5d89ac0..56dfe76e04 100644 --- a/driver/ioexpander_nct38xx.h +++ b/driver/ioexpander_nct38xx.h @@ -12,6 +12,22 @@ */ #include "nct38xx.h" +/* + * The interrupt handler to handle Vendor Define ALERT event from IOEX chip. + * + * Normally, the Vendor Define event should be checked by the NCT38XX TCPCI + * driver's tcpc_alert function. + * This function is only included when NCT38XX TCPC driver is not included. + * (i.e. CONFIG_USB_PD_TCPM_NCT38XX is not defined) + */ +void nct38xx_ioex_handle_alert(int ioex); + +/* + * Check which IO's interrupt event is triggered. If any, call its + * registered interrupt handler. + */ +int nct38xx_ioex_event_handler(int ioex); + extern const struct ioexpander_drv nct38xx_ioexpander_drv; #endif /* defined(__CROS_EC_IOEXPANDER_NCT38XX_H) */ diff --git a/driver/tcpm/nct38xx.c b/driver/tcpm/nct38xx.c index ee8aeb58e6..8061f7190c 100644 --- a/driver/tcpm/nct38xx.c +++ b/driver/tcpm/nct38xx.c @@ -8,6 +8,7 @@ #include "common.h" #include "console.h" +#include "ioexpander_nct38xx.h" #include "nct38xx.h" #include "tcpci.h" @@ -75,6 +76,18 @@ static int nct38xx_tcpm_init(int port) /* 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; } @@ -297,6 +310,30 @@ clear: 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, @@ -312,7 +349,7 @@ const struct tcpm_drv nct38xx_tcpm_drv = { .set_rx_enable = &tcpci_tcpm_set_rx_enable, .get_message_raw = &tcpci_nct38xx_get_message_raw, .transmit = &tcpci_nct38xx_transmit, - .tcpc_alert = &tcpci_tcpc_alert, + .tcpc_alert = &nct38xx_tcpc_alert, #ifdef CONFIG_USB_PD_DISCHARGE_TCPC .tcpc_discharge_vbus = &tcpci_tcpc_discharge_vbus, #endif diff --git a/driver/tcpm/nct38xx.h b/driver/tcpm/nct38xx.h index 5d80606018..970c1c8c85 100644 --- a/driver/tcpm/nct38xx.h +++ b/driver/tcpm/nct38xx.h @@ -14,19 +14,25 @@ #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_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_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_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 @@ -34,11 +40,16 @@ #define NCT38XX_PRODUCT_ID 0xC301 -#define NCT38XXX_REG_GPIO_DATA_IN(n) (0xC0 + ((n) * 8)) -#define NCT38XXX_REG_GPIO_DATA_OUT(n) (0xC1 + ((n) * 8)) -#define NCT38XXX_REG_GPIO_DIR(n) (0xC2 + ((n) * 8)) -#define NCT38XXX_REG_GPIO_OD_SEL(n) (0xC3 + ((n) * 8)) -#define NCT38XXX_REG_MUX_CONTROL 0xD0 +#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 diff --git a/driver/tcpm/tcpci.h b/driver/tcpm/tcpci.h index 6db71e4161..d2950b7b1a 100644 --- a/driver/tcpm/tcpci.h +++ b/driver/tcpm/tcpci.h @@ -21,6 +21,7 @@ #define TCPC_REG_ALERT 0x10 #define TCPC_REG_ALERT_MASK_ALL 0xfff +#define TCPC_REG_ALERT_VENDOR_DEF (1<<15) #define TCPC_REG_ALERT_VBUS_DISCNCT (1<<11) #define TCPC_REG_ALERT_RX_BUF_OVF (1<<10) #define TCPC_REG_ALERT_FAULT (1<<9) diff --git a/include/ioexpander.h b/include/ioexpander.h index e8f76d9fbc..150db65750 100644 --- a/include/ioexpander.h +++ b/include/ioexpander.h @@ -51,11 +51,6 @@ struct ioexpander_config_t { /* I2C slave address */ int i2c_slave_addr; /* - * The extra variable used to store information which may be required - * by the IO expander chip. - */ - int chip_info; - /* * Pointer to the specific IO expander chip's ops defined in * the struct ioexpander_drv. */ |