The LPUART can loop the RX and TX signal. Add support for it. Please note, this was only tested on the 32 bit version of the LPUART. Signed-off-by: Michael Walle <michael@xxxxxxxx> --- drivers/tty/serial/fsl_lpuart.c | 36 +++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index 19714047d571..5e66f628e895 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -1403,22 +1403,54 @@ static int lpuart32_config_rs485(struct uart_port *port, static unsigned int lpuart_get_mctrl(struct uart_port *port) { - return 0; + unsigned int mctrl = 0; + u8 reg; + + reg = readb(port->membase + UARTCR1); + if (reg & UARTCR1_LOOPS) + mctrl |= TIOCM_LOOP; + + return mctrl; } static unsigned int lpuart32_get_mctrl(struct uart_port *port) { - return 0; + unsigned int mctrl = 0; + u32 reg; + + reg = lpuart32_read(port, UARTCTRL); + if (reg & UARTCTRL_LOOPS) + mctrl |= TIOCM_LOOP; + + return mctrl; } static void lpuart_set_mctrl(struct uart_port *port, unsigned int mctrl) { + u8 reg; + + reg = readb(port->membase + UARTCR1); + + /* for internal loopback we need LOOPS=1 and RSRC=0 */ + reg &= ~(UARTCR1_LOOPS | UARTCR1_RSRC); + if (mctrl & TIOCM_LOOP) + reg |= UARTCR1_LOOPS; + writeb(reg, port->membase + UARTCR1); } static void lpuart32_set_mctrl(struct uart_port *port, unsigned int mctrl) { + u32 reg; + + reg = lpuart32_read(port, UARTCTRL); + + /* for internal loopback we need LOOPS=1 and RSRC=0 */ + reg &= ~(UARTCTRL_LOOPS | UARTCTRL_RSRC); + if (mctrl & TIOCM_LOOP) + reg |= UARTCTRL_LOOPS; + lpuart32_write(port, reg, UARTCTRL); } static void lpuart_break_ctl(struct uart_port *port, int break_state) -- 2.20.1