diff options
Diffstat (limited to 'driver')
-rw-r--r-- | driver/build.mk | 1 | ||||
-rw-r--r-- | driver/tcpm/it83xx_pd.h | 20 | ||||
-rw-r--r-- | driver/tcpm/it8xxx2.c | 21 | ||||
-rw-r--r-- | driver/tcpm/ite_pd_intc.c | 87 | ||||
-rw-r--r-- | driver/tcpm/ite_pd_intc.h | 22 |
5 files changed, 135 insertions, 16 deletions
diff --git a/driver/build.mk b/driver/build.mk index 3df8ecc102..3efe9cd467 100644 --- a/driver/build.mk +++ b/driver/build.mk @@ -142,6 +142,7 @@ driver-$(CONFIG_USB_PD_TCPM_TCPCI)+=tcpm/tcpci.o driver-$(CONFIG_USB_PD_TCPM_FUSB302)+=tcpm/fusb302.o driver-$(CONFIG_USB_PD_TCPM_MT6370)+=tcpm/mt6370.o ifdef CONFIG_USB_PD_TCPM_ITE_ON_CHIP +driver-y +=tcpm/ite_pd_intc.o driver-$(CONFIG_USB_PD_TCPM_DRIVER_IT83XX)+=tcpm/it83xx.o driver-$(CONFIG_USB_PD_TCPM_DRIVER_IT8XXX2)+=tcpm/it8xxx2.o endif diff --git a/driver/tcpm/it83xx_pd.h b/driver/tcpm/it83xx_pd.h index c3efb7e150..ff7c231f23 100644 --- a/driver/tcpm/it83xx_pd.h +++ b/driver/tcpm/it83xx_pd.h @@ -379,6 +379,26 @@ IS_MASK_SET(IT83XX_USBPD_IFS(port), USBPD_REG_FAST_SWAP_DETECT_STAT) #endif +#if defined(CONFIG_USB_PD_TCPM_ITE_ON_CHIP) && defined(CONFIG_ZEPHYR) +/* Use the Zephyr names here. When upstreaming we can update this */ +#include <dt-bindings/interrupt-controller/ite-intc.h> + +#define IT83XX_GPIO_GPCRF4 GPCRF4 +#define IT83XX_GPIO_GPCRF5 GPCRF5 +#define IT83XX_GPIO_GPCRH1 GPCRH1 +#define IT83XX_GPIO_GPCRH2 GPCRH2 +#define IT83XX_GPIO_GPCRP0 IT8XXX2_GPIO_GPCRP0 +#define IT83XX_GPIO_GPCRP1 IT8XXX2_GPIO_GPCRP1 +#define IT83XX_IRQ_USBPD0 IT8XXX2_IRQ_USBPD0 +#define IT83XX_IRQ_USBPD1 IT8XXX2_IRQ_USBPD1 +#define IT83XX_IRQ_USBPD2 IT8XXX2_IRQ_USBPD2 +#define USB_VID_ITE 0x048d + +/* ITE chip supports PD features */ +#define IT83XX_INTC_FAST_SWAP_SUPPORT +#define IT83XX_INTC_PLUG_IN_OUT_SUPPORT +#endif + enum usbpd_port { USBPD_PORT_A, USBPD_PORT_B, diff --git a/driver/tcpm/it8xxx2.c b/driver/tcpm/it8xxx2.c index b2ff476d63..246075207f 100644 --- a/driver/tcpm/it8xxx2.c +++ b/driver/tcpm/it8xxx2.c @@ -9,6 +9,7 @@ #include "config.h" #include "console.h" #include "it83xx_pd.h" +#include "ite_pd_intc.h" #include "registers.h" #include "system.h" #include "task.h" @@ -37,22 +38,6 @@ #define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args) -#ifdef CONFIG_ZEPHYR -/* Use the Zephyr names here. When upstreaming we can update this */ -#include <dt-bindings/interrupt-controller/ite-intc.h> - -#define IT83XX_GPIO_GPCRF4 GPCRF4 -#define IT83XX_GPIO_GPCRF5 GPCRF5 -#define IT83XX_GPIO_GPCRH1 GPCRH1 -#define IT83XX_GPIO_GPCRH2 GPCRH2 -#define IT83XX_GPIO_GPCRP0 IT8XXX2_GPIO_GPCRP0 -#define IT83XX_GPIO_GPCRP1 IT8XXX2_GPIO_GPCRP1 -#define IT83XX_IRQ_USBPD0 IT8XXX2_IRQ_USBPD0 -#define IT83XX_IRQ_USBPD1 IT8XXX2_IRQ_USBPD1 -#define IT83XX_IRQ_USBPD2 IT8XXX2_IRQ_USBPD2 -#define USB_VID_ITE 0x048d -#endif - bool rx_en[IT83XX_USBPD_PHY_PORT_COUNT]; STATIC_IF(CONFIG_USB_PD_DECODE_SOP) bool sop_prime_en[IT83XX_USBPD_PHY_PORT_COUNT]; @@ -827,6 +812,10 @@ static void it8xxx2_init(enum usbpd_port port, int role) *usbpd_ctrl_regs[port].cc1 = cc_config; *usbpd_ctrl_regs[port].cc2 = cc_config; task_clear_pending_irq(usbpd_ctrl_regs[port].irq); +#ifdef CONFIG_ZEPHYR + irq_connect_dynamic(usbpd_ctrl_regs[port].irq, 0, + (void (*)(const void *))chip_pd_irq, (void *)port, 0); +#endif task_enable_irq(usbpd_ctrl_regs[port].irq); USBPD_START(port); /* diff --git a/driver/tcpm/ite_pd_intc.c b/driver/tcpm/ite_pd_intc.c new file mode 100644 index 0000000000..2b5a391dfe --- /dev/null +++ b/driver/tcpm/ite_pd_intc.c @@ -0,0 +1,87 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "common.h" +#include "it83xx_pd.h" +#include "ite_pd_intc.h" +#include "task.h" +#include "tcpm/tcpm.h" +#include "usb_pd.h" + +void chip_pd_irq(enum usbpd_port port) +{ + task_clear_pending_irq(usbpd_ctrl_regs[port].irq); + + /* check status */ + if (IS_ENABLED(IT83XX_INTC_FAST_SWAP_SUPPORT) && + IS_ENABLED(CONFIG_USB_PD_FRS_TCPC) && + IS_ENABLED(CONFIG_USB_PD_REV30)) { + /* + * FRS detection must handle first, because we need to short + * the interrupt -> board_frs_handler latency-critical time. + */ + if (USBPD_IS_FAST_SWAP_DETECT(port)) { + /* clear detect FRS signal (cc to GND) status */ + USBPD_CLEAR_FRS_DETECT_STATUS(port); + if (board_frs_handler) + board_frs_handler(port); + /* inform TCPMv2 to change state */ + pd_got_frs_signal(port); + } + } + + if (USBPD_IS_HARD_RESET_DETECT(port)) { + /* clear interrupt */ + IT83XX_USBPD_ISR(port) = USBPD_REG_MASK_HARD_RESET_DETECT; + USBPD_SW_RESET(port); + task_set_event(PD_PORT_TO_TASK_ID(port), + PD_EVENT_RX_HARD_RESET); + } + + if (USBPD_IS_RX_DONE(port)) { + tcpm_enqueue_message(port); + /* clear RX done interrupt */ + IT83XX_USBPD_ISR(port) = USBPD_REG_MASK_MSG_RX_DONE; + } + + if (USBPD_IS_TX_DONE(port)) { +#ifdef CONFIG_USB_PD_TCPM_DRIVER_IT8XXX2 + it8xxx2_clear_tx_error_status(port); + /* check TX status, clear by TX_DONE status too */ + if (USBPD_IS_TX_ERR(port)) + it8xxx2_get_tx_error_status(port); +#endif + /* clear TX done interrupt */ + IT83XX_USBPD_ISR(port) = USBPD_REG_MASK_MSG_TX_DONE; + task_set_event(PD_PORT_TO_TASK_ID(port), + TASK_EVENT_PHY_TX_DONE); + } + + if (IS_ENABLED(IT83XX_INTC_PLUG_IN_OUT_SUPPORT)) { + if (USBPD_IS_PLUG_IN_OUT_DETECT(port)) { + if (USBPD_IS_PLUG_IN(port)) + /* + * When tcpc detect type-c plug in: + * 1)If we are sink, disable detect interrupt, + * messages on cc line won't trigger interrupt. + * 2)If we are source, then set plug out + * detection. + */ + switch_plug_out_type(port); + else + /* + * When tcpc detect type-c plug out: + * switch to detect plug in. + */ + IT83XX_USBPD_TCDCR(port) &= + ~USBPD_REG_PLUG_OUT_SELECT; + + /* clear type-c device plug in/out detect interrupt */ + IT83XX_USBPD_TCDCR(port) |= + USBPD_REG_PLUG_IN_OUT_DETECT_STAT; + task_set_event(PD_PORT_TO_TASK_ID(port), PD_EVENT_CC); + } + } +} diff --git a/driver/tcpm/ite_pd_intc.h b/driver/tcpm/ite_pd_intc.h new file mode 100644 index 0000000000..8123e1a233 --- /dev/null +++ b/driver/tcpm/ite_pd_intc.h @@ -0,0 +1,22 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* ITE PD INTC control module */ + +#ifndef __CROS_EC_ITE_PD_INTC_H +#define __CROS_EC_ITE_PD_INTC_H + +/** + * ITE embedded PD interrupt routine + * + * NOTE: Enable ITE embedded PD that it requires CONFIG_USB_PD_TCPM_ITE_ON_CHIP + * + * @param port Type-C port number + * + * @return none + */ +void chip_pd_irq(enum usbpd_port port); + +#endif /* __CROS_EC_ITE_PD_INTC_H */ |