summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXin Ji <xji@analogixsemi.com>2020-03-19 15:33:41 +0800
committerCommit Bot <commit-bot@chromium.org>2020-04-02 23:44:08 +0000
commit32e49e5e3b7724fa302f13893e7154ef319c9daf (patch)
treee05591970a523c93482f91e68b7c40be26e39a63
parent697b49ae69ae35e1df9188e2c6f4df07b0cdc2cc (diff)
downloadchrome-ec-stabilize-sylas-13019.B-master.tar.gz
tcpm/anx7447.c: use chip internal timer to generate HPD IRQstabilize-sylas-13019.B-master
Anx7447 has 2 ways to generate HPD IRQ: 1): internal timer delay ~750ms. 2): outside timer delay(configured by EC anx7447.c). Some board didn't have accurate timer cause method #2 cannot be used, this patch change the default policy to method #1. BRANCH=none BUG=b:151696902 TEST=tested on STM32 board Change-Id: Ifcccacc484f82e4ed047d4caa7d86318f60d0192 Signed-off-by: Xin Ji <xji@analogixsemi.com> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2112312 Tested-by: Devin Lu <Devin.Lu@quantatw.com> Reviewed-by: Jett Rink <jettrink@chromium.org> Commit-Queue: Jett Rink <jettrink@chromium.org>
-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