Re: [PATCH 1/2] serial: imx: Fix the RTS GPIO polarity in RS485 mode

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, Jan 30, 2017 at 09:12:11AM -0200, Fabio Estevam 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
> 

Tested-by: Clemens Gruber <clemens.gruber@xxxxxxxxxxxx>

Regards,
Clemens
--
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



[Index of Archives]     [Kernel Newbies]     [Security]     [Netfilter]     [Bugtraq]     [Linux PPP]     [Linux FS]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Linmodem]     [Device Mapper]     [Linux Kernel for ARM]

  Powered by Linux