summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--driver/tcpm/anx7447.c38
-rw-r--r--driver/tcpm/anx7447.h3
2 files changed, 31 insertions, 10 deletions
diff --git a/driver/tcpm/anx7447.c b/driver/tcpm/anx7447.c
index e83ca32d9b..fa614f5454 100644
--- a/driver/tcpm/anx7447.c
+++ b/driver/tcpm/anx7447.c
@@ -93,7 +93,7 @@ static inline int anx7447_reg_read(int port, int reg, int *val)
return rv;
}
-void anx7447_hpd_mode_en(int port)
+void anx7447_hpd_mode_init(int port)
{
int reg, rv;
@@ -101,7 +101,13 @@ void anx7447_hpd_mode_en(int port)
if (rv)
return;
- reg |= ANX7447_REG_HPD_MODE;
+ /*
+ * Set ANX7447_REG_HPD_MODE bit as 0, then the TCPC will generate the
+ * HPD pulse from internal timer (by using ANX7447_REG_HPD_IRQ0)
+ * instead of using the ANX7447_REG_HPD_OUT to set the HPD IRQ signal.
+ */
+ reg &= ~(ANX7447_REG_HPD_MODE | ANX7447_REG_HPD_PLUG |
+ ANX7447_REG_HPD_UNPLUG);
anx7447_reg_write(port, ANX7447_REG_HPD_CTRL_0, reg);
}
@@ -125,10 +131,18 @@ void anx7447_set_hpd_level(int port, int hpd_lvl)
if (rv)
return;
- if (hpd_lvl)
- reg |= ANX7447_REG_HPD_OUT;
- else
- reg &= ~ANX7447_REG_HPD_OUT;
+ /*
+ * When ANX7447_REG_HPD_MODE is 1, use ANX7447_REG_HPD_OUT
+ * to generate HPD event, otherwise use ANX7447_REG_HPD_UNPLUG
+ * and ANX7447_REG_HPD_PLUG.
+ */
+ if (hpd_lvl) {
+ reg &= ~ANX7447_REG_HPD_UNPLUG;
+ reg |= ANX7447_REG_HPD_PLUG;
+ } else {
+ reg &= ~ANX7447_REG_HPD_PLUG;
+ reg |= ANX7447_REG_HPD_UNPLUG;
+ }
anx7447_reg_write(port, ANX7447_REG_HPD_CTRL_0, reg);
}
@@ -483,11 +497,15 @@ void anx7447_tcpc_update_hpd_status(const struct usb_mux *me,
if (now < hpd_deadline[port])
usleep(hpd_deadline[port] - now);
+ /*
+ * For generate hardware HPD IRQ, need clear bit
+ * ANX7447_REG_HPD_IRQ0 first, then set it. This bit is not
+ * write clear.
+ */
anx7447_reg_read(port, ANX7447_REG_HPD_CTRL_0, &reg);
- reg &= ~ANX7447_REG_HPD_OUT;
+ reg &= ~ANX7447_REG_HPD_IRQ0;
anx7447_reg_write(port, ANX7447_REG_HPD_CTRL_0, reg);
- usleep(HPD_DSTREAM_DEBOUNCE_IRQ);
- reg |= ANX7447_REG_HPD_OUT;
+ reg |= ANX7447_REG_HPD_IRQ0;
anx7447_reg_write(port, ANX7447_REG_HPD_CTRL_0, reg);
}
/* enforce 2-ms delay between HPD pulses */
@@ -510,7 +528,7 @@ static int anx7447_mux_init(const struct usb_mux *me)
memset(&mux[port], 0, sizeof(struct anx_usb_mux));
/* init hpd status */
- anx7447_hpd_mode_en(port);
+ anx7447_hpd_mode_init(port);
anx7447_set_hpd_level(port, 0);
anx7447_hpd_output_en(port);
diff --git a/driver/tcpm/anx7447.h b/driver/tcpm/anx7447.h
index 049b82d4bb..b1d571c7c8 100644
--- a/driver/tcpm/anx7447.h
+++ b/driver/tcpm/anx7447.h
@@ -27,6 +27,9 @@
#define ANX7447_REG_HPD_CTRL_0 0x7E
#define ANX7447_REG_HPD_MODE 0x01
#define ANX7447_REG_HPD_OUT 0x02
+#define ANX7447_REG_HPD_IRQ0 0x04
+#define ANX7447_REG_HPD_PLUG 0x08
+#define ANX7447_REG_HPD_UNPLUG 0x10
#define ANX7447_REG_HPD_DEGLITCH_H 0x80
#define ANX7447_REG_HPD_OEN 0x40