From 38f549d78aa83ee574a65e14f45e5363e44b68cf Mon Sep 17 00:00:00 2001 From: Peter van der Perk Date: Tue, 7 May 2024 21:44:40 +0200 Subject: [PATCH] lpuart: IMXRT/S32K3XX implement TIOCSSINGLEWIREDUPLEX --- arch/arm/src/imxrt/imxrt_serial.c | 28 ++++++++++++++++++++++++++- arch/arm/src/s32k3xx/s32k3xx_serial.c | 26 +++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/arch/arm/src/imxrt/imxrt_serial.c b/arch/arm/src/imxrt/imxrt_serial.c index f91be50d254bc..30cbcd2ab4e50 100644 --- a/arch/arm/src/imxrt/imxrt_serial.c +++ b/arch/arm/src/imxrt/imxrt_serial.c @@ -2629,7 +2629,7 @@ static int imxrt_ioctl(struct file *filep, int cmd, unsigned long arg) if ((arg & SER_SINGLEWIRE_ENABLED) != 0) { - uint32_t gpio_val = IOMUX_OPENDRAIN; + uint32_t gpio_val = 0; gpio_val |= (arg & SER_SINGLEWIRE_PULL_MASK) == SER_SINGLEWIRE_PULLUP ? IOMUX_PULL_UP : IOMUX_PULL_NONE; @@ -2653,6 +2653,32 @@ static int imxrt_ioctl(struct file *filep, int cmd, unsigned long arg) spin_unlock_irqrestore(NULL, flags); } break; + + case TIOCSSINGLEWIREDUPLEX: + { + uint32_t regval; + irqstate_t flags; + struct imxrt_uart_s *priv = (struct imxrt_uart_s *)dev; + + flags = spin_lock_irqsave(NULL); + regval = imxrt_serialin(priv, IMXRT_LPUART_CTRL_OFFSET); + + if ((arg & SER_SINGLEWIRE_DUPLEX_TX) != 0) + { + regval &= ~(LPUART_CTRL_RSRC); + regval |= (LPUART_CTRL_TXDIR); + } + else /* RX Mode */ + { + regval |= LPUART_CTRL_RSRC; + regval &= ~(LPUART_CTRL_TXDIR); + } + + imxrt_serialout(priv, IMXRT_LPUART_CTRL_OFFSET, regval); + + spin_unlock_irqrestore(NULL, flags); + } + break; #endif #ifdef CONFIG_IMXRT_LPUART_INVERT diff --git a/arch/arm/src/s32k3xx/s32k3xx_serial.c b/arch/arm/src/s32k3xx/s32k3xx_serial.c index e64152e4a2461..b4b520f4de2b3 100644 --- a/arch/arm/src/s32k3xx/s32k3xx_serial.c +++ b/arch/arm/src/s32k3xx/s32k3xx_serial.c @@ -3529,6 +3529,32 @@ static int s32k3xx_ioctl(struct file *filep, int cmd, unsigned long arg) spin_unlock_irqrestore(NULL, flags); } break; + + case TIOCSSINGLEWIREDUPLEX: + { + uint32_t regval; + irqstate_t flags; + struct s32k3xx_uart_s *priv = (struct s32k3xx_uart_s *)dev->priv; + + flags = spin_lock_irqsave(NULL); + regval = s32k3xx_serialin(priv, S32K3XX_LPUART_CTRL_OFFSET); + + if ((arg & SER_SINGLEWIRE_DUPLEX_TX) != 0) + { + regval &= ~(LPUART_CTRL_RSRC); + regval |= (LPUART_CTRL_TXDIR); + } + else /* RX Mode */ + { + regval |= LPUART_CTRL_RSRC; + regval &= ~(LPUART_CTRL_TXDIR); + } + + s32k3xx_serialout(priv, S32K3XX_LPUART_CTRL_OFFSET, regval); + + spin_unlock_irqrestore(NULL, flags); + } + break; #endif #ifdef CONFIG_S32K3XX_LPUART_INVERT