forked from Minki/linux
serial: stm32: Add RS485 RTS GPIO control again
While the STM32 does support RS485 drive-enable control within the
UART IP itself, some systems have the drive-enable line connected
to a pin which cannot be pinmuxed as RTS. Add support for toggling
the RTS GPIO line using the modem control GPIOs to provide at least
some sort of emulation.
Fixes: 7df5081cbf
("serial: stm32: Add RS485 RTS GPIO control")
Signed-off-by: Marek Vasut <marex@denx.de>
Cc: Alexandre Torgue <alexandre.torgue@st.com>
Cc: Andy Shevchenko <andy.shevchenko@gmail.com>
Cc: Manivannan Sadhasivam <mani@kernel.org>
Cc: Fabrice Gasnier <fabrice.gasnier@st.com>
Cc: linux-stm32@st-md-mailman.stormreply.com
Link: https://lore.kernel.org/r/20200831171045.205691-1-marex@denx.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
0fb9342d06
commit
ad0c274805
@ -129,13 +129,9 @@ static int stm32_config_rs485(struct uart_port *port,
|
||||
if (rs485conf->flags & SER_RS485_RTS_ON_SEND) {
|
||||
cr3 &= ~USART_CR3_DEP;
|
||||
rs485conf->flags &= ~SER_RS485_RTS_AFTER_SEND;
|
||||
mctrl_gpio_set(stm32_port->gpios,
|
||||
stm32_port->port.mctrl & ~TIOCM_RTS);
|
||||
} else {
|
||||
cr3 |= USART_CR3_DEP;
|
||||
rs485conf->flags |= SER_RS485_RTS_AFTER_SEND;
|
||||
mctrl_gpio_set(stm32_port->gpios,
|
||||
stm32_port->port.mctrl | TIOCM_RTS);
|
||||
}
|
||||
|
||||
writel_relaxed(cr3, port->membase + ofs->cr3);
|
||||
@ -541,17 +537,42 @@ static void stm32_disable_ms(struct uart_port *port)
|
||||
/* Transmit stop */
|
||||
static void stm32_stop_tx(struct uart_port *port)
|
||||
{
|
||||
struct stm32_port *stm32_port = to_stm32_port(port);
|
||||
struct serial_rs485 *rs485conf = &port->rs485;
|
||||
|
||||
stm32_tx_interrupt_disable(port);
|
||||
|
||||
if (rs485conf->flags & SER_RS485_ENABLED) {
|
||||
if (rs485conf->flags & SER_RS485_RTS_ON_SEND) {
|
||||
mctrl_gpio_set(stm32_port->gpios,
|
||||
stm32_port->port.mctrl & ~TIOCM_RTS);
|
||||
} else {
|
||||
mctrl_gpio_set(stm32_port->gpios,
|
||||
stm32_port->port.mctrl | TIOCM_RTS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* There are probably characters waiting to be transmitted. */
|
||||
static void stm32_start_tx(struct uart_port *port)
|
||||
{
|
||||
struct stm32_port *stm32_port = to_stm32_port(port);
|
||||
struct serial_rs485 *rs485conf = &port->rs485;
|
||||
struct circ_buf *xmit = &port->state->xmit;
|
||||
|
||||
if (uart_circ_empty(xmit))
|
||||
return;
|
||||
|
||||
if (rs485conf->flags & SER_RS485_ENABLED) {
|
||||
if (rs485conf->flags & SER_RS485_RTS_ON_SEND) {
|
||||
mctrl_gpio_set(stm32_port->gpios,
|
||||
stm32_port->port.mctrl | TIOCM_RTS);
|
||||
} else {
|
||||
mctrl_gpio_set(stm32_port->gpios,
|
||||
stm32_port->port.mctrl & ~TIOCM_RTS);
|
||||
}
|
||||
}
|
||||
|
||||
stm32_transmit_chars(port);
|
||||
}
|
||||
|
||||
@ -851,13 +872,9 @@ static void stm32_set_termios(struct uart_port *port, struct ktermios *termios,
|
||||
if (rs485conf->flags & SER_RS485_RTS_ON_SEND) {
|
||||
cr3 &= ~USART_CR3_DEP;
|
||||
rs485conf->flags &= ~SER_RS485_RTS_AFTER_SEND;
|
||||
mctrl_gpio_set(stm32_port->gpios,
|
||||
stm32_port->port.mctrl & ~TIOCM_RTS);
|
||||
} else {
|
||||
cr3 |= USART_CR3_DEP;
|
||||
rs485conf->flags |= SER_RS485_RTS_AFTER_SEND;
|
||||
mctrl_gpio_set(stm32_port->gpios,
|
||||
stm32_port->port.mctrl | TIOCM_RTS);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
Loading…
Reference in New Issue
Block a user