diff options
-rw-r--r-- | common/usb_pd_protocol.c | 7 | ||||
-rw-r--r-- | common/usb_pd_tcpc.c | 9 | ||||
-rw-r--r-- | common/usb_pd_tcpm.c | 18 | ||||
-rw-r--r-- | common/usb_pd_tcpm_stub.c | 6 | ||||
-rw-r--r-- | include/usb_pd_tcpm.h | 9 |
5 files changed, 45 insertions, 4 deletions
diff --git a/common/usb_pd_protocol.c b/common/usb_pd_protocol.c index 52b046328a..f87e5010a5 100644 --- a/common/usb_pd_protocol.c +++ b/common/usb_pd_protocol.c @@ -1326,10 +1326,9 @@ void pd_task(void) /* Ensure the power supply is in the default state */ pd_power_supply_reset(port); -#ifdef CONFIG_USB_PD_TCPC - /* Initialize port controller */ - tcpc_init(port); -#endif + /* Initialize TCPM driver and wait for TCPC to be ready */ + tcpm_init(port); + CPRINTF("[%T TCPC p%d ready]\n", port); /* Disable TCPC RX until connection is established */ tcpm_set_rx_enable(port, 0); diff --git a/common/usb_pd_tcpc.c b/common/usb_pd_tcpc.c index 0a5d60d95c..c9cbf03896 100644 --- a/common/usb_pd_tcpc.c +++ b/common/usb_pd_tcpc.c @@ -40,6 +40,9 @@ static struct mutex pd_crc_lock; static const int debug_level; #endif +/* USB Vendor ID, initialized to 0, written to actual VID when TCPC is ready */ +static int tcpc_vid; + /* Encode 5 bits using Biphase Mark Coding */ #define BMC(x) ((x & 1 ? 0x001 : 0x3FF) \ ^ (x & 2 ? 0x004 : 0x3FC) \ @@ -785,6 +788,9 @@ int tcpc_run(int port, int evt) if (pd[port].rx_enabled) pd_rx_enable_monitoring(port); + /* write our TCPC VID to notify TCPM that we are ready */ + tcpc_vid = USB_VID_GOOGLE; + /* TODO: adjust timeout based on how often to sample CC */ return 10*MSEC; } @@ -963,6 +969,9 @@ static int tcpc_i2c_read(int port, int reg, uint8_t *payload) int cc1, cc2; switch (reg) { + case TCPC_REG_VENDOR_ID: + *(uint16_t *)payload = tcpc_vid; + return 2; case TCPC_REG_CC1_STATUS: tcpc_get_cc(port, &cc1, &cc2); payload[0] = TCPC_REG_CC_STATUS_SET( diff --git a/common/usb_pd_tcpm.c b/common/usb_pd_tcpm.c index d24931e692..d7458fabfe 100644 --- a/common/usb_pd_tcpm.c +++ b/common/usb_pd_tcpm.c @@ -6,6 +6,7 @@ /* Type-C port manager */ #include "i2c.h" +#include "timer.h" #include "usb_pd.h" #include "usb_pd_tcpc.h" #include "usb_pd_tcpm.h" @@ -19,6 +20,23 @@ static int tcpc_polarity, tcpc_vconn; +int tcpm_init(int port) +{ + int rv, vid = 0; + + while (1) { + rv = i2c_read16(I2C_PORT_TCPC, I2C_ADDR_TCPC(port), + TCPC_REG_VENDOR_ID, &vid); + /* + * If i2c succeeds and VID is non-zero, then initialization + * is complete + */ + if (rv == EC_SUCCESS && vid) + return rv; + msleep(10); + } +} + int tcpm_get_cc(int port, int *cc1, int *cc2) { int status; diff --git a/common/usb_pd_tcpm_stub.c b/common/usb_pd_tcpm_stub.c index bb8ba57045..dc0843fa10 100644 --- a/common/usb_pd_tcpm_stub.c +++ b/common/usb_pd_tcpm_stub.c @@ -20,6 +20,12 @@ extern int tcpc_get_message(int port, uint32_t *payload, int *head); extern int tcpc_transmit(int port, enum tcpm_transmit_type type, uint16_t header, const uint32_t *data); +int tcpm_init(int port) +{ + tcpc_init(port); + return EC_SUCCESS; +} + int tcpm_get_cc(int port, int *cc1, int *cc2) { return tcpc_get_cc(port, cc1, cc2); diff --git a/include/usb_pd_tcpm.h b/include/usb_pd_tcpm.h index 951de5572f..97624fd34c 100644 --- a/include/usb_pd_tcpm.h +++ b/include/usb_pd_tcpm.h @@ -161,6 +161,15 @@ int tcpm_alert_status(int port, int alert_reg, uint8_t *alert); /** + * 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 |