diff options
Diffstat (limited to 'driver/tcpm/tcpci.c')
-rw-r--r-- | driver/tcpm/tcpci.c | 73 |
1 files changed, 60 insertions, 13 deletions
diff --git a/driver/tcpm/tcpci.c b/driver/tcpm/tcpci.c index 606b84e31c..939ab9ccf2 100644 --- a/driver/tcpm/tcpci.c +++ b/driver/tcpm/tcpci.c @@ -9,6 +9,7 @@ #include "task.h" #include "tcpci.h" #include "timer.h" +#include "usb_charge.h" #include "usb_pd.h" #include "usb_pd_tcpc.h" #include "usb_pd_tcpm.h" @@ -17,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; +static int tcpc_polarity, tcpc_vconn, tcpc_vbus[CONFIG_USB_PD_PORT_COUNT]; static int init_alert_mask(int port) { @@ -30,13 +31,30 @@ static int init_alert_mask(int port) */ 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; + TCPC_REG_ALERT_RX_HARD_RST | TCPC_REG_ALERT_CC_STATUS +#ifdef CONFIG_USB_PD_TCPM_VBUS + | TCPC_REG_ALERT_POWER_STATUS +#endif + ; /* Set the alert mask in TCPC */ rv = tcpm_alert_mask_set(port, mask); return rv; } +#ifdef CONFIG_USB_PD_TCPM_VBUS +static int init_power_status_mask(int port) +{ + uint8_t mask; + int rv; + + mask = TCPC_REG_POWER_VBUS_PRES; + rv = tcpm_set_power_status_mask(port, mask); + + return rv; +} +#endif + int tcpm_init(int port) { int rv, err = 0; @@ -52,6 +70,10 @@ int tcpm_init(int port) if (rv == EC_SUCCESS && !(err & TCPC_REG_ERROR_STATUS_UNINIT)) { i2c_write16(I2C_PORT_TCPC, I2C_ADDR_TCPC(port), TCPC_REG_ALERT, 0xff); +#ifdef CONFIG_USB_PD_TCPM_VBUS + /* Initialize power_status_mask */ + init_power_status_mask(port); +#endif return init_alert_mask(port); } msleep(10); @@ -85,6 +107,12 @@ int tcpm_get_cc(int port, int *cc1, int *cc2) return rv; } +int tcpm_get_power_status(int port, int *status) +{ + return i2c_read8(I2C_PORT_TCPC, I2C_ADDR_TCPC(port), + TCPC_REG_POWER_STATUS, status); +} + int tcpm_set_cc(int port, int pull) { /* @@ -124,11 +152,9 @@ int tcpm_set_msg_header(int port, int power_role, int data_role) int tcpm_alert_status(int port, int *alert) { - int rv; /* Read TCPC Alert register */ - rv = i2c_read16(I2C_PORT_TCPC, I2C_ADDR_TCPC(port), - TCPC_REG_ALERT, alert); - return rv; + return i2c_read16(I2C_PORT_TCPC, I2C_ADDR_TCPC(port), + TCPC_REG_ALERT, alert); } int tcpm_set_rx_enable(int port, int enable) @@ -139,18 +165,26 @@ int tcpm_set_rx_enable(int port, int enable) enable ? TCPC_REG_RX_DETECT_SOP_HRST_MASK : 0); } -int tcpm_alert_mask_set(int port, uint16_t mask) +int tcpm_set_power_status_mask(int port, uint8_t mask) { - int rv; /* write to the Alert Mask register */ - rv = i2c_write16(I2C_PORT_TCPC, I2C_ADDR_TCPC(port), - TCPC_REG_ALERT_MASK, mask); + return i2c_write8(I2C_PORT_TCPC, I2C_ADDR_TCPC(port), + TCPC_REG_POWER_STATUS_MASK , mask); +} - if (rv) - return rv; +int tcpm_alert_mask_set(int port, uint16_t mask) +{ + /* write to the Alert Mask register */ + return i2c_write16(I2C_PORT_TCPC, I2C_ADDR_TCPC(port), + TCPC_REG_ALERT_MASK, mask); +} - return rv; +#ifdef CONFIG_USB_PD_TCPM_VBUS +int tcpm_get_vbus_level(int port) +{ + return tcpc_vbus[port]; } +#endif int tcpm_get_message(int port, uint32_t *payload, int *head) { @@ -215,6 +249,7 @@ int tcpm_transmit(int port, enum tcpm_transmit_type type, uint16_t header, void tcpc_alert(int port) { int status; + int power_status; /* Read the Alert register from the TCPC */ tcpm_alert_status(port, &status); @@ -231,6 +266,18 @@ void tcpc_alert(int port) /* CC status changed, wake task */ task_set_event(PD_PORT_TO_TASK_ID(port), PD_EVENT_CC, 0); } + if (status & TCPC_REG_ALERT_POWER_STATUS) { + /* 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; +#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]); +#endif /* CONFIG_USB_PD_TCPM_VBUS && CONFIG_USB_CHARGER */ + task_wake(PD_PORT_TO_TASK_ID(port)); + } if (status & TCPC_REG_ALERT_RX_STATUS) { /* message received */ task_set_event(PD_PORT_TO_TASK_ID(port), PD_EVENT_RX, 0); |