On Mon, Jan 30, 2017 at 3:12 AM, Fabio Estevam <festevam@xxxxxxxxx> wrote: > From: Fabio Estevam <fabio.estevam@xxxxxxx> > > 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@xxxxxxx> > --- > drivers/tty/serial/imx.c | 20 ++++++++++---------- > 1 file changed, 10 insertions(+), 10 deletions(-) > > diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c > index 33fcc84..29dd57c 100644 > --- a/drivers/tty/serial/imx.c > +++ b/drivers/tty/serial/imx.c > @@ -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); > } > > -- > 2.7.4 > Fabio, Works great for me with respect to TXEN polarity thanks! Something I noticed this time around while testing however is that in some cases I'm not getting the dma_tx_callback telling us the tx dma completed causing the stop_tx to return and the TXEN to not be de-asserted. I hadn't noticed this before. Have you encountered it in your use/testing? Regards, Tim -- To unsubscribe from this list: send the line "unsubscribe linux-serial" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html