summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuibin Chang <Ruibin.Chang@ite.com.tw>2018-12-17 18:16:29 +0800
committerchrome-bot <chrome-bot@chromium.org>2018-12-18 00:43:03 -0800
commitc7d12adf74c22a1ef538ce9d7faac1a0d7c7ab66 (patch)
tree31504efe882b55984dad7d9429c21e437da8d291
parentf0998e9a4bbd7f77c9574f9e27e7e8b8bcc65a18 (diff)
downloadchrome-ec-c7d12adf74c22a1ef538ce9d7faac1a0d7c7ab66.tar.gz
it83xx/intc:add type-c plug in interrupt
When tcpc detect type-c plug in (cc lines voltage change), it will interrupt fw to wake pd task, so task can react immediately. BRANCH=None BUG=None TEST=GRL USBPD test Change-Id: I194b2fcad1d0c62dde2d3296753abd47af8feea6 Signed-off-by: Ruibin Chang <Ruibin.Chang@ite.com.tw> Reviewed-on: https://chromium-review.googlesource.com/1333207 Reviewed-by: Jett Rink <jettrink@chromium.org>
-rw-r--r--chip/it83xx/config_chip.h2
-rw-r--r--chip/it83xx/intc.c22
-rw-r--r--chip/it83xx/registers.h8
-rw-r--r--driver/tcpm/it83xx.c17
-rw-r--r--driver/tcpm/it83xx_pd.h4
5 files changed, 53 insertions, 0 deletions
diff --git a/chip/it83xx/config_chip.h b/chip/it83xx/config_chip.h
index 26f81f124d..9991d518e7 100644
--- a/chip/it83xx/config_chip.h
+++ b/chip/it83xx/config_chip.h
@@ -114,6 +114,8 @@
#define IT83XX_GPIO_INT_FLEXIBLE
/* Enable interrupts of group 21 and 22. */
#define IT83XX_INTC_GROUP_21_22_SUPPORT
+/* Enable detect type-c plug in interrupt. */
+#define IT83XX_INTC_PLUG_IN_SUPPORT
#else
#error "Unsupported chip variant!"
#endif
diff --git a/chip/it83xx/intc.c b/chip/it83xx/intc.c
index 36a6029f9c..79d738e93c 100644
--- a/chip/it83xx/intc.c
+++ b/chip/it83xx/intc.c
@@ -81,6 +81,28 @@ static void chip_pd_irq(enum usbpd_port port)
task_set_event(PD_PORT_TO_TASK_ID(port),
TASK_EVENT_PHY_TX_DONE, 0);
}
+#ifdef IT83XX_INTC_PLUG_IN_SUPPORT
+ if (USBPD_IS_PLUG_IN_OUT_DETECT(port)) {
+ /*
+ * When tcpc detect type-c plug in, then disable
+ * this interrupt. Because any cc volt changes
+ * (include pd negotiation) would trigger plug in
+ * interrupt, frequently plug in interrupt and wakeup
+ * pd task may cause task starvation or device dead
+ * (ex.transmit lots SRC_Cap).
+ *
+ * When polling disconnect will enable detect type-c
+ * plug in again.
+ *
+ * Clear detect type-c plug in interrupt status.
+ */
+ IT83XX_USBPD_TCDCR(port) |=
+ (USBPD_REG_PLUG_IN_OUT_DETECT_DISABLE |
+ USBPD_REG_PLUG_IN_OUT_DETECT_STAT);
+ task_set_event(PD_PORT_TO_TASK_ID(port),
+ PD_EVENT_CC, 0);
+ }
+#endif //IT83XX_INTC_PLUG_IN_SUPPORT
}
}
#endif
diff --git a/chip/it83xx/registers.h b/chip/it83xx/registers.h
index cd7fcc0c2a..8d2d8016bb 100644
--- a/chip/it83xx/registers.h
+++ b/chip/it83xx/registers.h
@@ -1250,6 +1250,14 @@ enum i2c_channels {
#define IT83XX_USBPD_CCPSR0(p) REG8(IT83XX_USBPD_BASE(p)+0x60)
#define IT83XX_USBPD_BMCSR(p) REG8(IT83XX_USBPD_BASE(p)+0x64)
#define IT83XX_USBPD_PDMHSR(p) REG8(IT83XX_USBPD_BASE(p)+0x65)
+#ifdef IT83XX_INTC_PLUG_IN_SUPPORT
+#define IT83XX_USBPD_TCDCR(p) REG8(IT83XX_USBPD_BASE(p)+0x67)
+#define USBPD_REG_PLUG_OUT_DETECT_TYPE_SELECT (1 << 7)
+#define USBPD_REG_MASK_TYPEC_PLUG_IN_OUT_ISR (1 << 4)
+#define USBPD_REG_PLUG_IN_OUT_SELECT (1 << 3)
+#define USBPD_REG_PLUG_IN_OUT_DETECT_DISABLE (1 << 1)
+#define USBPD_REG_PLUG_IN_OUT_DETECT_STAT (1 << 0)
+#endif //IT83XX_INTC_PLUG_IN_SUPPORT
enum usbpd_port {
USBPD_PORT_A,
diff --git a/driver/tcpm/it83xx.c b/driver/tcpm/it83xx.c
index 447ba7fd1d..3cf554cf76 100644
--- a/driver/tcpm/it83xx.c
+++ b/driver/tcpm/it83xx.c
@@ -361,6 +361,16 @@ static void it83xx_init(enum usbpd_port port, int role)
/* enable tx done and reset detect interrupt */
IT83XX_USBPD_IMR(port) &= ~(USBPD_REG_MASK_MSG_TX_DONE |
USBPD_REG_MASK_HARD_RESET_DETECT);
+#ifdef IT83XX_INTC_PLUG_IN_SUPPORT
+ /*
+ * when tcpc detect type-c plug in (cc lines voltage change), it will
+ * interrupt fw to wake pd task, so task can react immediately.
+ *
+ * w/c status and unmask TCDCR (detect type-c plug in interrupt default
+ * is enable).
+ */
+ IT83XX_USBPD_TCDCR(port) = USBPD_REG_PLUG_IN_OUT_DETECT_STAT;
+#endif //IT83XX_INTC_PLUG_IN_SUPPORT
IT83XX_USBPD_CCPSR(port) = 0xff;
/* cc connect */
IT83XX_USBPD_CCCSR(port) = 0;
@@ -581,6 +591,13 @@ static void it83xx_tcpm_sw_reset(void)
int port = TASK_ID_TO_PD_PORT(task_get_current());
/* Invalidate last received message id variable */
invalidate_last_message_id(port);
+#ifdef IT83XX_INTC_PLUG_IN_SUPPORT
+ /*
+ * Enable detect type-c plug in interrupt, since the pd task has
+ * detected a type-c physical disconnected.
+ */
+ IT83XX_USBPD_TCDCR(port) &= ~USBPD_REG_PLUG_IN_OUT_DETECT_DISABLE;
+#endif //IT83XX_INTC_PLUG_IN_SUPPORT
/* exit BIST test data mode */
USBPD_SW_RESET(port);
}
diff --git a/driver/tcpm/it83xx_pd.h b/driver/tcpm/it83xx_pd.h
index c0714dd9b1..0f6be9b24f 100644
--- a/driver/tcpm/it83xx_pd.h
+++ b/driver/tcpm/it83xx_pd.h
@@ -70,6 +70,10 @@
IS_MASK_SET(IT83XX_USBPD_ISR(port), USBPD_REG_MASK_MSG_TX_DONE)
#define USBPD_IS_RX_DONE(port) \
IS_MASK_SET(IT83XX_USBPD_ISR(port), USBPD_REG_MASK_MSG_RX_DONE)
+#ifdef IT83XX_INTC_PLUG_IN_SUPPORT
+#define USBPD_IS_PLUG_IN_OUT_DETECT(port)\
+ IS_MASK_SET(IT83XX_USBPD_TCDCR(port), USBPD_REG_PLUG_IN_OUT_DETECT_STAT)
+#endif //IT83XX_INTC_PLUG_IN_SUPPORT
enum usbpd_cc_pin {
USBPD_CC_PIN_1,