serial: imx: Fix the RTS GPIO polarity in RS485 mode
On a board that needs to drive RTS GPIO high in order to enable the transmission of a RS485 transceiver the following description is passed in the devide tree: &uart4 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_uart4>; rts-gpios = <&gpio6 2 GPIO_ACTIVE_HIGH>; status = "okay"; }; and userspace configures the uart port as follows: /* enable RS485 mode: */ rs485conf.flags |= SER_RS485_ENABLED; /* set logical level for RTS pin equal to 1 when sending: */ rs485conf.flags |= SER_RS485_RTS_ON_SEND; /* set logical level for RTS pin equal to 0 after sending: */ rs485conf.flags &= ~(SER_RS485_RTS_AFTER_SEND); However the RTS GPIO polarity observed in the oscilloscope is inverted. When the SER_RS485_RTS_ON_SEND flag is set the imx_port_rts_active() function should be called and following the same logic when SER_RS485_RTS_AFTER_SEND flag is cleared the imx_port_rts_inactive() should be called. Do such logic change so that RS485 communication in half duplex can work successfully when the RTS GPIO pin is passed via device tree. Signed-off-by: Fabio Estevam <fabio.estevam@nxp.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Родитель
aa42db44f6
Коммит
1a613626d2
|
@ -377,9 +377,9 @@ static void imx_stop_tx(struct uart_port *port)
|
|||
readl(port->membase + USR2) & USR2_TXDC) {
|
||||
temp = readl(port->membase + UCR2);
|
||||
if (port->rs485.flags & SER_RS485_RTS_AFTER_SEND)
|
||||
imx_port_rts_inactive(sport, &temp);
|
||||
else
|
||||
imx_port_rts_active(sport, &temp);
|
||||
else
|
||||
imx_port_rts_inactive(sport, &temp);
|
||||
temp |= UCR2_RXEN;
|
||||
writel(temp, port->membase + UCR2);
|
||||
|
||||
|
@ -585,9 +585,9 @@ static void imx_start_tx(struct uart_port *port)
|
|||
if (port->rs485.flags & SER_RS485_ENABLED) {
|
||||
temp = readl(port->membase + UCR2);
|
||||
if (port->rs485.flags & SER_RS485_RTS_ON_SEND)
|
||||
imx_port_rts_inactive(sport, &temp);
|
||||
else
|
||||
imx_port_rts_active(sport, &temp);
|
||||
else
|
||||
imx_port_rts_inactive(sport, &temp);
|
||||
if (!(port->rs485.flags & SER_RS485_RX_DURING_TX))
|
||||
temp &= ~UCR2_RXEN;
|
||||
writel(temp, port->membase + UCR2);
|
||||
|
@ -1477,9 +1477,9 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios,
|
|||
*/
|
||||
if (port->rs485.flags &
|
||||
SER_RS485_RTS_AFTER_SEND)
|
||||
imx_port_rts_inactive(sport, &ucr2);
|
||||
else
|
||||
imx_port_rts_active(sport, &ucr2);
|
||||
else
|
||||
imx_port_rts_inactive(sport, &ucr2);
|
||||
} else {
|
||||
imx_port_rts_auto(sport, &ucr2);
|
||||
}
|
||||
|
@ -1489,9 +1489,9 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios,
|
|||
} else if (port->rs485.flags & SER_RS485_ENABLED) {
|
||||
/* disable transmitter */
|
||||
if (port->rs485.flags & SER_RS485_RTS_AFTER_SEND)
|
||||
imx_port_rts_inactive(sport, &ucr2);
|
||||
else
|
||||
imx_port_rts_active(sport, &ucr2);
|
||||
else
|
||||
imx_port_rts_inactive(sport, &ucr2);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1733,9 +1733,9 @@ static int imx_rs485_config(struct uart_port *port,
|
|||
/* disable transmitter */
|
||||
temp = readl(sport->port.membase + UCR2);
|
||||
if (rs485conf->flags & SER_RS485_RTS_AFTER_SEND)
|
||||
imx_port_rts_inactive(sport, &temp);
|
||||
else
|
||||
imx_port_rts_active(sport, &temp);
|
||||
else
|
||||
imx_port_rts_inactive(sport, &temp);
|
||||
writel(temp, sport->port.membase + UCR2);
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче