diff options
author | Xin Ji <xji@analogixsemi.com> | 2020-03-19 15:33:41 +0800 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2020-04-02 23:44:08 +0000 |
commit | 32e49e5e3b7724fa302f13893e7154ef319c9daf (patch) | |
tree | e05591970a523c93482f91e68b7c40be26e39a63 /driver | |
parent | 697b49ae69ae35e1df9188e2c6f4df07b0cdc2cc (diff) | |
download | chrome-ec-32e49e5e3b7724fa302f13893e7154ef319c9daf.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>
Diffstat (limited to 'driver')
-rw-r--r-- | driver/tcpm/anx7447.c | 38 | ||||
-rw-r--r-- | driver/tcpm/anx7447.h | 3 |
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 &= ~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 |