From 430990ee3fd72fe37560d249e6686a7c630b24ca Mon Sep 17 00:00:00 2001 From: Sam Hurst Date: Wed, 8 Mar 2023 07:16:52 -0800 Subject: [PATCH] usb-c: tcpc: Disable Dead Battery after system starts The Dead Battery resistors interfere with port partner detection. So, Dead Battery is disabled after the system starts and sets the Rd or Rp resistors on the CC lines. Tested on b_g474e_dpow1 with JP5 set to USBC. Tested on stm32g081b_eval with JP17 set to D5V. Signed-off-by: Sam Hurst --- drivers/usb_c/tcpc/ucpd_stm32.c | 53 ++++++++++++++++++++++------ drivers/usb_c/tcpc/ucpd_stm32_priv.h | 3 ++ 2 files changed, 46 insertions(+), 10 deletions(-) diff --git a/drivers/usb_c/tcpc/ucpd_stm32.c b/drivers/usb_c/tcpc/ucpd_stm32.c index 45c514e7bf8..812ddfaa7a1 100644 --- a/drivers/usb_c/tcpc/ucpd_stm32.c +++ b/drivers/usb_c/tcpc/ucpd_stm32.c @@ -360,6 +360,37 @@ static int ucpd_get_rp_value(const struct device *dev, enum tc_rp_value *rp) return 0; } +/** + * @brief Enable or disable Dead Battery resistors + */ +static void dead_battery(const struct device *dev, bool en) +{ + struct tcpc_data *data = dev->data; + +#ifdef CONFIG_SOC_SERIES_STM32G0X + const struct tcpc_config *const config = dev->config; + uint32_t cr; + + cr = LL_UCPD_ReadReg(config->ucpd_port, CR); + + if (en) { + cr |= UCPD_CR_DBATTEN; + } else { + cr &= ~UCPD_CR_DBATTEN; + } + + LL_UCPD_WriteReg(config->ucpd_port, CR, cr); + update_stm32g0x_cc_line(config->ucpd_port); +#else + if (en) { + CLEAR_BIT(PWR->CR3, PWR_CR3_UCPD_DBDIS); + } else { + SET_BIT(PWR->CR3, PWR_CR3_UCPD_DBDIS); + } +#endif + data->dead_battery_active = en; +} + /** * @brief Set the CC pull up or pull down resistors * @@ -373,6 +404,11 @@ static int ucpd_set_cc(const struct device *dev, struct tcpc_data *data = dev->data; uint32_t cr; + /* Disable dead battery if it's active */ + if (data->dead_battery_active) { + dead_battery(dev, false); + } + cr = LL_UCPD_ReadReg(config->ucpd_port, CR); /* @@ -1384,16 +1420,13 @@ static int ucpd_init(const struct device *dev) /* Enable Dead Battery Support */ if (config->ucpd_dead_battery) { -#ifdef CONFIG_SOC_SERIES_STM32G0X - uint32_t cr; - - cr = LL_UCPD_ReadReg(config->ucpd_port, CR); - cr |= UCPD_CR_DBATTEN; - LL_UCPD_WriteReg(config->ucpd_port, CR, cr); - update_stm32g0x_cc_line(config->ucpd_port); -#else - CLEAR_BIT(PWR->CR3, PWR_CR3_UCPD_DBDIS); -#endif + dead_battery(dev, true); + } else { + /* + * Some devices have dead battery enabled by default + * after power up, so disable it + */ + dead_battery(dev, false); } /* Initialize the isr */ diff --git a/drivers/usb_c/tcpc/ucpd_stm32_priv.h b/drivers/usb_c/tcpc/ucpd_stm32_priv.h index 727524c1519..67eda58a000 100644 --- a/drivers/usb_c/tcpc/ucpd_stm32_priv.h +++ b/drivers/usb_c/tcpc/ucpd_stm32_priv.h @@ -322,6 +322,9 @@ struct tcpc_data { /* Track CC line that VCONN was active on */ enum tc_cc_polarity ucpd_vconn_cc; + /* Dead Battery active */ + bool dead_battery_active; + /* Timer for amount of time to wait for receiving a GoodCRC */ struct k_timer goodcrc_rx_timer; };