diff --git a/common/usb_pd_tcpc.c b/common/usb_pd_tcpc.c index 88d4996844..73a0447fae 100644 --- a/common/usb_pd_tcpc.c +++ b/common/usb_pd_tcpc.c @@ -10,6 +10,7 @@ #include "crc.h" #include "ec_commands.h" #include "gpio.h" +#include "hooks.h" #include "host_command.h" #include "registers.h" #include "task.h" @@ -207,8 +208,6 @@ enum pd_tx_errors { #define RX_BUFFER_SIZE 2 #endif -#define TCPC_FLAGS_INITIALIZED (1 << 0) /* TCPC is initialized */ - static struct pd_port_controller { /* current port power role (SOURCE or SINK) */ uint8_t power_role; @@ -225,8 +224,6 @@ static struct pd_port_controller { uint16_t alert_mask; /* RX enabled */ uint8_t rx_enabled; - /* TCPC flags */ - uint8_t flags; /* Power status */ uint8_t power_status; uint8_t power_status_mask; @@ -838,7 +835,7 @@ void pd_task(void) tcpc_init(port); /* we are now initialized */ - pd[port].flags |= TCPC_FLAGS_INITIALIZED; + pd[port].power_status &= ~TCPC_REG_POWER_STATUS_UNINIT; while (1) { /* wait for next event/packet or timeout expiration */ @@ -947,12 +944,12 @@ static int tcpc_set_power_status(int port, int vbus_present) { /* Update VBUS present bit */ if (vbus_present) - pd[port].power_status |= TCPC_REG_POWER_VBUS_PRES; + pd[port].power_status |= TCPC_REG_POWER_STATUS_VBUS_PRES; else - pd[port].power_status &= ~TCPC_REG_POWER_VBUS_PRES; + pd[port].power_status &= ~TCPC_REG_POWER_STATUS_VBUS_PRES; /* Set bit Port Power Status bit in Alert register */ - if (pd[port].power_status_mask & TCPC_REG_POWER_VBUS_PRES) + if (pd[port].power_status_mask & TCPC_REG_POWER_STATUS_VBUS_PRES) alert(port, TCPC_REG_ALERT_POWER_STATUS); return EC_SUCCESS; @@ -1018,6 +1015,18 @@ int tcpc_get_message(int port, uint32_t *payload, int *head) return EC_SUCCESS; } +void tcpc_pre_init(void) +{ + int i; + + /* Mark as uninitialized */ + for (i = 0; i < CONFIG_USB_PD_PORT_COUNT; i++) + pd[i].power_status |= TCPC_REG_POWER_STATUS_UNINIT | + TCPC_REG_POWER_STATUS_VBUS_DET; +} +/* Must be prioritized above i2c init */ +DECLARE_HOOK(HOOK_INIT, tcpc_pre_init, HOOK_PRIO_INIT_I2C - 1); + void tcpc_init(int port) { int i; @@ -1074,10 +1083,12 @@ static void tcpc_i2c_write(int port, int reg, int len, uint8_t *payload) tcpc_set_cc(port, TCPC_REG_ROLE_CTRL_CC1(payload[1])); break; case TCPC_REG_POWER_CTRL: - tcpc_set_polarity(port, - TCPC_REG_POWER_CTRL_POLARITY(payload[1])); tcpc_set_vconn(port, TCPC_REG_POWER_CTRL_VCONN(payload[1])); break; + case TCPC_REG_TCPC_CTRL: + tcpc_set_polarity(port, + TCPC_REG_TCPC_CTRL_POLARITY(payload[1])); + break; case TCPC_REG_MSG_HDR_INFO: tcpc_set_msg_header(port, TCPC_REG_MSG_HDR_INFO_PROLE(payload[1]), @@ -1123,10 +1134,6 @@ static int tcpc_i2c_read(int port, int reg, uint8_t *payload) case TCPC_REG_VENDOR_ID: *(uint16_t *)payload = USB_VID_GOOGLE; return 2; - case TCPC_REG_ERROR_STATUS: - payload[0] = (pd[port].flags & TCPC_FLAGS_INITIALIZED) ? - 0 : TCPC_REG_ERROR_STATUS_UNINIT; - return 1; case TCPC_REG_CC_STATUS: tcpc_get_cc(port, &cc1, &cc2); payload[0] = TCPC_REG_CC_STATUS_SET( @@ -1138,8 +1145,8 @@ static int tcpc_i2c_read(int port, int reg, uint8_t *payload) pd[port].cc_pull, pd[port].cc_pull); return 1; - case TCPC_REG_POWER_CTRL: - payload[0] = TCPC_REG_POWER_CTRL_SET(pd[port].polarity, 0); + case TCPC_REG_TCPC_CTRL: + payload[0] = TCPC_REG_TCPC_CTRL_SET(pd[port].polarity); return 1; case TCPC_REG_MSG_HDR_INFO: payload[0] = TCPC_REG_MSG_HDR_INFO_SET(pd[port].data_role, diff --git a/driver/tcpm/tcpci.c b/driver/tcpm/tcpci.c index 926a1dda1b..149e7c9f5e 100644 --- a/driver/tcpm/tcpci.c +++ b/driver/tcpm/tcpci.c @@ -18,7 +18,7 @@ /* Convert port number to tcpc i2c address */ #define I2C_ADDR_TCPC(p) (CONFIG_TCPC_I2C_BASE_ADDR + 2*(p)) -static int tcpc_polarity, tcpc_vconn, tcpc_vbus[CONFIG_USB_PD_PORT_COUNT]; +static int tcpc_vbus[CONFIG_USB_PD_PORT_COUNT]; static int init_alert_mask(int port) { @@ -48,7 +48,7 @@ static int init_power_status_mask(int port) uint8_t mask; int rv; - mask = TCPC_REG_POWER_VBUS_PRES; + mask = TCPC_REG_POWER_STATUS_VBUS_PRES; rv = tcpm_set_power_status_mask(port, mask); return rv; @@ -102,20 +102,16 @@ int tcpm_set_cc(int port, int pull) int tcpm_set_polarity(int port, int polarity) { - /* Write new polarity, leave vconn enable flag untouched */ - tcpc_polarity = polarity; return i2c_write8(I2C_PORT_TCPC, I2C_ADDR_TCPC(port), - TCPC_REG_POWER_CTRL, - TCPC_REG_POWER_CTRL_SET(tcpc_polarity, tcpc_vconn)); + TCPC_REG_TCPC_CTRL, + TCPC_REG_TCPC_CTRL_SET(polarity)); } int tcpm_set_vconn(int port, int enable) { - /* Write new vconn enable flag, leave polarity untouched */ - tcpc_vconn = enable; return i2c_write8(I2C_PORT_TCPC, I2C_ADDR_TCPC(port), TCPC_REG_POWER_CTRL, - TCPC_REG_POWER_CTRL_SET(tcpc_polarity, tcpc_vconn)); + TCPC_REG_POWER_CTRL_SET(enable)); } int tcpm_set_msg_header(int port, int power_role, int data_role) @@ -246,7 +242,7 @@ void tcpc_alert(int port) tcpm_get_power_status(port, &power_status); /* Update VBUS status */ tcpc_vbus[port] = power_status & - TCPC_REG_POWER_VBUS_PRES ? 1 : 0; + TCPC_REG_POWER_STATUS_VBUS_PRES ? 1 : 0; #if defined(CONFIG_USB_PD_TCPM_VBUS) && defined(CONFIG_USB_CHARGER) /* Update charge manager with new VBUS state */ usb_charger_vbus_change(port, tcpc_vbus[port]); @@ -272,30 +268,27 @@ void tcpc_alert(int port) int tcpm_init(int port) { - int rv, err = 0; -#ifdef CONFIG_USB_PD_TCPM_VBUS + int rv; int power_status; -#endif while (1) { - rv = i2c_read16(I2C_PORT_TCPC, I2C_ADDR_TCPC(port), - TCPC_REG_ERROR_STATUS, &err); + rv = i2c_read8(I2C_PORT_TCPC, I2C_ADDR_TCPC(port), + TCPC_REG_POWER_STATUS, &power_status); /* * If i2c succeeds and the uninitialized bit is clear, then * initalization is complete, clear all alert bits and write * the initial alert mask. */ - if (rv == EC_SUCCESS && !(err & TCPC_REG_ERROR_STATUS_UNINIT)) { + if (rv == EC_SUCCESS && + !(power_status & TCPC_REG_POWER_STATUS_UNINIT)) { i2c_write16(I2C_PORT_TCPC, I2C_ADDR_TCPC(port), - TCPC_REG_ALERT, 0xff); + TCPC_REG_ALERT, 0xffff); #ifdef CONFIG_USB_PD_TCPM_VBUS /* Initialize power_status_mask */ init_power_status_mask(port); - /* Read Power Status register */ - tcpm_get_power_status(port, &power_status); /* Update VBUS status */ tcpc_vbus[port] = power_status & - TCPC_REG_POWER_VBUS_PRES ? 1 : 0; + TCPC_REG_POWER_STATUS_VBUS_PRES ? 1 : 0; #endif return init_alert_mask(port); } diff --git a/driver/tcpm/tcpci.h b/driver/tcpm/tcpci.h index cbfac0380c..da6e412669 100644 --- a/driver/tcpm/tcpci.h +++ b/driver/tcpm/tcpci.h @@ -14,16 +14,13 @@ #define TCPC_REG_TC_REV 0x6 #define TCPC_REG_PD_REV 0x8 #define TCPC_REG_PD_INT_REV 0xa -#define TCPC_REG_DEV_CAP_1 0xc -#define TCPC_REG_DEV_CAP_2 0xd -#define TCPC_REG_DEV_CAP_3 0xe -#define TCPC_REG_DEV_CAP_4 0xf #define TCPC_REG_ALERT 0x10 -#define TCPC_REG_ALERT_INTRFACE_ERR (1<<11) -#define TCPC_REG_ALERT_GPIO_CHANGE (1<<10) -#define TCPC_REG_ALERT_V_ALARM_LO (1<<9) -#define TCPC_REG_ALERT_V_ALARM_HI (1<<8) -#define TCPC_REG_ALERT_SLEEP_EXITED (1<<7) + +#define TCPC_REG_ALERT_VBUS_DISCNCT (1<<11) +#define TCPC_REG_ALERT_RX_BUF_OVF (1<<10) +#define TCPC_REG_ALERT_FAULT (1<<9) +#define TCPC_REG_ALERT_V_ALARM_LO (1<<8) +#define TCPC_REG_ALERT_V_ALARM_HI (1<<7) #define TCPC_REG_ALERT_TX_SUCCESS (1<<6) #define TCPC_REG_ALERT_TX_DISCARDED (1<<5) #define TCPC_REG_ALERT_TX_FAILED (1<<4) @@ -37,31 +34,42 @@ #define TCPC_REG_ALERT_MASK 0x12 #define TCPC_REG_POWER_STATUS_MASK 0x14 -#define TCPC_REG_CC_STATUS 0x18 +#define TCPC_REG_FAULT_STATUS_MASK 0x15 +#define TCPC_REG_CONFIG_STD_OUTPUT 0x18 +#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_CC2(reg) (((reg) & 0xc) >> 2) +#define TCPC_REG_ROLE_CTRL_CC1(reg) ((reg) & 0x3) + +#define TCPC_REG_FAULT_CTRL 0x1b +#define TCPC_REG_POWER_CTRL 0x1c +#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_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 0x19 -#define TCPC_REG_POWER_VBUS_PRES (1<<5) -#define TCPC_REG_ERROR_STATUS 0x1a -#define TCPC_REG_ERROR_STATUS_UNINIT (1<<7) -#define TCPC_REG_ROLE_CTRL 0x1b -#define TCPC_REG_ROLE_CTRL_SET(drp, rp, cc1, cc2) \ - ((drp) << 6 | (rp) << 4 | (cc2) << 2 | (cc1)) -#define TCPC_REG_ROLE_CTRL_CC2(reg) (((reg) & 0xc) >> 2) -#define TCPC_REG_ROLE_CTRL_CC1(reg) ((reg) & 0x3) - -#define TCPC_REG_POWER_PATH_CTRL 0x1c -#define TCPC_REG_POWER_CTRL 0x1d -#define TCPC_REG_POWER_CTRL_SET(polarity, vconn) \ - ((polarity) << 4 | (vconn)) -#define TCPC_REG_POWER_CTRL_POLARITY(reg) (((reg) & 0x10) >> 4) -#define TCPC_REG_POWER_CTRL_VCONN(reg) ((reg) & 0x1) +#define TCPC_REG_POWER_STATUS 0x1e +#define TCPC_REG_POWER_STATUS_VBUS_PRES (1<<2) +#define TCPC_REG_POWER_STATUS_VBUS_DET (1<<3) +#define TCPC_REG_POWER_STATUS_UNINIT (1<<6) +#define TCPC_REG_FAULT_STATUS 0x1f #define TCPC_REG_COMMAND 0x23 +#define TCPC_REG_DEV_CAP_1 0x24 +#define TCPC_REG_DEV_CAP_2 0x26 +#define TCPC_REG_STD_INPUT_CAP 0x28 +#define TCPC_REG_STD_OUTPUT_CAP 0x29 + #define TCPC_REG_MSG_HDR_INFO 0x2e #define TCPC_REG_MSG_HDR_INFO_SET(drole, prole) \ ((drole) << 3 | (PD_REV20 << 1) | (prole)) @@ -86,4 +94,10 @@ #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 + #endif /* __CROS_EC_USB_PD_TCPM_TCPCI_H */