summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/usb_pd_protocol.c7
-rw-r--r--common/usb_pd_tcpc.c9
-rw-r--r--common/usb_pd_tcpm.c18
-rw-r--r--common/usb_pd_tcpm_stub.c6
-rw-r--r--include/usb_pd_tcpm.h9
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