Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

serial: stm32: add support for RS485 hardware control mode

Implement Driver Enable signal (DE) to activate the transmission mode
of the external transceiver.

Signed-off-by: Yves Coppeaux <yves.coppeaux@st.com>
Signed-off-by: Bich Hemon <bich.hemon@st.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Bich HEMON and committed by
Greg Kroah-Hartman
1bcda09d 241672cb

+132 -1
+129 -1
drivers/tty/serial/stm32-usart.c
··· 62 62 writel_relaxed(val, port->membase + reg); 63 63 } 64 64 65 + static void stm32_config_reg_rs485(u32 *cr1, u32 *cr3, u32 delay_ADE, 66 + u32 delay_DDE, u32 baud) 67 + { 68 + u32 rs485_deat_dedt; 69 + u32 rs485_deat_dedt_max = (USART_CR1_DEAT_MASK >> USART_CR1_DEAT_SHIFT); 70 + bool over8; 71 + 72 + *cr3 |= USART_CR3_DEM; 73 + over8 = *cr1 & USART_CR1_OVER8; 74 + 75 + if (over8) 76 + rs485_deat_dedt = delay_ADE * baud * 8; 77 + else 78 + rs485_deat_dedt = delay_ADE * baud * 16; 79 + 80 + rs485_deat_dedt = DIV_ROUND_CLOSEST(rs485_deat_dedt, 1000); 81 + rs485_deat_dedt = rs485_deat_dedt > rs485_deat_dedt_max ? 82 + rs485_deat_dedt_max : rs485_deat_dedt; 83 + rs485_deat_dedt = (rs485_deat_dedt << USART_CR1_DEAT_SHIFT) & 84 + USART_CR1_DEAT_MASK; 85 + *cr1 |= rs485_deat_dedt; 86 + 87 + if (over8) 88 + rs485_deat_dedt = delay_DDE * baud * 8; 89 + else 90 + rs485_deat_dedt = delay_DDE * baud * 16; 91 + 92 + rs485_deat_dedt = DIV_ROUND_CLOSEST(rs485_deat_dedt, 1000); 93 + rs485_deat_dedt = rs485_deat_dedt > rs485_deat_dedt_max ? 94 + rs485_deat_dedt_max : rs485_deat_dedt; 95 + rs485_deat_dedt = (rs485_deat_dedt << USART_CR1_DEDT_SHIFT) & 96 + USART_CR1_DEDT_MASK; 97 + *cr1 |= rs485_deat_dedt; 98 + } 99 + 100 + static int stm32_config_rs485(struct uart_port *port, 101 + struct serial_rs485 *rs485conf) 102 + { 103 + struct stm32_port *stm32_port = to_stm32_port(port); 104 + struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; 105 + struct stm32_usart_config *cfg = &stm32_port->info->cfg; 106 + u32 usartdiv, baud, cr1, cr3; 107 + bool over8; 108 + unsigned long flags; 109 + 110 + spin_lock_irqsave(&port->lock, flags); 111 + stm32_clr_bits(port, ofs->cr1, BIT(cfg->uart_enable_bit)); 112 + 113 + port->rs485 = *rs485conf; 114 + 115 + rs485conf->flags |= SER_RS485_RX_DURING_TX; 116 + 117 + if (rs485conf->flags & SER_RS485_ENABLED) { 118 + cr1 = readl_relaxed(port->membase + ofs->cr1); 119 + cr3 = readl_relaxed(port->membase + ofs->cr3); 120 + usartdiv = readl_relaxed(port->membase + ofs->brr); 121 + usartdiv = usartdiv & GENMASK(15, 0); 122 + over8 = cr1 & USART_CR1_OVER8; 123 + 124 + if (over8) 125 + usartdiv = usartdiv | (usartdiv & GENMASK(4, 0)) 126 + << USART_BRR_04_R_SHIFT; 127 + 128 + baud = DIV_ROUND_CLOSEST(port->uartclk, usartdiv); 129 + stm32_config_reg_rs485(&cr1, &cr3, 130 + rs485conf->delay_rts_before_send, 131 + rs485conf->delay_rts_after_send, baud); 132 + 133 + if (rs485conf->flags & SER_RS485_RTS_ON_SEND) { 134 + cr3 &= ~USART_CR3_DEP; 135 + rs485conf->flags &= ~SER_RS485_RTS_AFTER_SEND; 136 + } else { 137 + cr3 |= USART_CR3_DEP; 138 + rs485conf->flags |= SER_RS485_RTS_AFTER_SEND; 139 + } 140 + 141 + writel_relaxed(cr3, port->membase + ofs->cr3); 142 + writel_relaxed(cr1, port->membase + ofs->cr1); 143 + } else { 144 + stm32_clr_bits(port, ofs->cr3, USART_CR3_DEM | USART_CR3_DEP); 145 + stm32_clr_bits(port, ofs->cr1, 146 + USART_CR1_DEDT_MASK | USART_CR1_DEAT_MASK); 147 + } 148 + 149 + stm32_set_bits(port, ofs->cr1, BIT(cfg->uart_enable_bit)); 150 + spin_unlock_irqrestore(&port->lock, flags); 151 + 152 + return 0; 153 + } 154 + 155 + static int stm32_init_rs485(struct uart_port *port, 156 + struct platform_device *pdev) 157 + { 158 + struct serial_rs485 *rs485conf = &port->rs485; 159 + 160 + rs485conf->flags = 0; 161 + rs485conf->delay_rts_before_send = 0; 162 + rs485conf->delay_rts_after_send = 0; 163 + 164 + if (!pdev->dev.of_node) 165 + return -ENODEV; 166 + 167 + uart_get_rs485_mode(&pdev->dev, rs485conf); 168 + 169 + return 0; 170 + } 171 + 65 172 static int stm32_pending_rx(struct uart_port *port, u32 *sr, int *last_res, 66 173 bool threaded) 67 174 { ··· 605 498 struct stm32_port *stm32_port = to_stm32_port(port); 606 499 struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; 607 500 struct stm32_usart_config *cfg = &stm32_port->info->cfg; 501 + struct serial_rs485 *rs485conf = &port->rs485; 608 502 unsigned int baud; 609 503 u32 usartdiv, mantissa, fraction, oversampling; 610 504 tcflag_t cflag = termios->c_cflag; ··· 623 515 writel_relaxed(0, port->membase + ofs->cr1); 624 516 625 517 cr1 = USART_CR1_TE | USART_CR1_RE | USART_CR1_RXNEIE; 626 - cr1 |= BIT(cfg->uart_enable_bit); 518 + 627 519 if (stm32_port->fifoen) 628 520 cr1 |= USART_CR1_FIFOEN; 629 521 cr2 = 0; ··· 661 553 */ 662 554 if (usartdiv < 16) { 663 555 oversampling = 8; 556 + cr1 |= USART_CR1_OVER8; 664 557 stm32_set_bits(port, ofs->cr1, USART_CR1_OVER8); 665 558 } else { 666 559 oversampling = 16; 560 + cr1 &= ~USART_CR1_OVER8; 667 561 stm32_clr_bits(port, ofs->cr1, USART_CR1_OVER8); 668 562 } 669 563 ··· 702 592 if (stm32_port->rx_ch) 703 593 cr3 |= USART_CR3_DMAR; 704 594 595 + if (rs485conf->flags & SER_RS485_ENABLED) { 596 + stm32_config_reg_rs485(&cr1, &cr3, 597 + rs485conf->delay_rts_before_send, 598 + rs485conf->delay_rts_after_send, baud); 599 + if (rs485conf->flags & SER_RS485_RTS_ON_SEND) { 600 + cr3 &= ~USART_CR3_DEP; 601 + rs485conf->flags &= ~SER_RS485_RTS_AFTER_SEND; 602 + } else { 603 + cr3 |= USART_CR3_DEP; 604 + rs485conf->flags |= SER_RS485_RTS_AFTER_SEND; 605 + } 606 + 607 + } else { 608 + cr3 &= ~(USART_CR3_DEM | USART_CR3_DEP); 609 + cr1 &= ~(USART_CR1_DEDT_MASK | USART_CR1_DEAT_MASK); 610 + } 611 + 705 612 writel_relaxed(cr3, port->membase + ofs->cr3); 706 613 writel_relaxed(cr2, port->membase + ofs->cr2); 707 614 writel_relaxed(cr1, port->membase + ofs->cr1); 708 615 616 + stm32_set_bits(port, ofs->cr1, BIT(cfg->uart_enable_bit)); 709 617 spin_unlock_irqrestore(&port->lock, flags); 710 618 } 711 619
+3
drivers/tty/serial/stm32-usart.h
··· 135 135 #define USART_BRR_DIV_F_MASK GENMASK(3, 0) 136 136 #define USART_BRR_DIV_M_MASK GENMASK(15, 4) 137 137 #define USART_BRR_DIV_M_SHIFT 4 138 + #define USART_BRR_04_R_SHIFT 1 138 139 139 140 /* USART_CR1 */ 140 141 #define USART_CR1_SBK BIT(0) ··· 163 162 #define USART_CR1_M1 BIT(28) /* F7 */ 164 163 #define USART_CR1_IE_MASK (GENMASK(8, 4) | BIT(14) | BIT(26) | BIT(27)) 165 164 #define USART_CR1_FIFOEN BIT(29) /* H7 */ 165 + #define USART_CR1_DEAT_SHIFT 21 166 + #define USART_CR1_DEDT_SHIFT 16 166 167 167 168 /* USART_CR2 */ 168 169 #define USART_CR2_ADD_MASK GENMASK(3, 0) /* F4 */