RK3566 android13 kernel5.10 485串口收发
设备树
kernel 目录下的驱动修改:
diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c
index 82a4f6dab59a..447ac24455dc 100644
--- a/drivers/tty/serial/8250/8250_dw.c
+++ b/drivers/tty/serial/8250/8250_dw.c
@@ -35,6 +35,11 @@
#include "8250_dwlib.h"
#endif
+//20251016 liguoyi 485 IO-ctl
+#include <linux/gpio.h>
+#include <linux/of_gpio.h>
+//add endif
+
/* Offsets for the DesignWare specific registers */
#define DW_UART_USR 0x1f /* UART Status Register */
#define DW_UART_RFL 0x21 /* UART Receive Fifo Level Register */
@@ -544,6 +549,18 @@ static int dw8250_probe(struct platform_device *pdev)
data->uart_16550_compatible = device_property_read_bool(dev,
"snps,uart-16550-compatible");
+ //20251016 liguoyi新增
+ uart.port.rs485.rts_gpio = of_get_named_gpio(p->dev->of_node, "485_ctrl_gpio", 0);
+ //116=GPIO3_C4
+ //115=GPIO3_C3
+ if(uart.port.rs485.rts_gpio > 0)
+ {
+ gpio_direction_output(uart.port.rs485.rts_gpio, 0);
+ gpio_set_value(uart.port.rs485.rts_gpio, 0); // defalut low-level
+ }
+ //add endif
+
+
err = device_property_read_u32(dev, "reg-shift", &val);
if (!err)
p->regshift = val;
diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c
index 9e681b375bad..063416d11d3d 100644
--- a/drivers/tty/serial/8250/8250_port.c
+++ b/drivers/tty/serial/8250/8250_port.c
@@ -37,6 +37,11 @@
#include "8250.h"
+
+// 20251016 liguoyi 485 IO-ctl
+#include <linux/of_gpio.h>
+// add endif
+
/* Nuvoton NPCM timeout register */
#define UART_NPCM_TOR 7
#define UART_NPCM_TOIE BIT(7) /* Timeout Interrupt Enable */
@@ -1798,6 +1803,11 @@ void serial8250_tx_chars(struct uart_8250_port *up)
struct circ_buf *xmit = &port->state->xmit;
int count;
+ //20251016 liguoyi 485 IO-ctl
+ int lsr; // 用于获取状态
+ int i; // 用于循环计数
+ //add endif
+
if (port->x_char) {
uart_xchar_out(port, UART_TX);
return;
@@ -1812,6 +1822,20 @@ void serial8250_tx_chars(struct uart_8250_port *up)
}
count = up->tx_loadsz;
+
+
+
+ //20251016 liguoyi 485 IO-ctl
+ //116=GPIO3_C4
+ //115=GPIO3_C3
+ if(up->port.rs485.rts_gpio > 0)
+ {
+ gpio_set_value(up->port.rs485.rts_gpio, 1);
+ udelay(1); // 这个延时好像可以不用
+ }
+ //add endif
+
+
do {
serial_out(up, UART_TX, xmit->buf[xmit->tail]);
if (up->bugs & UART_BUG_TXRACE) {
@@ -1848,7 +1872,27 @@ void serial8250_tx_chars(struct uart_8250_port *up)
* the interrupt and RPM in __stop_tx()
*/
if (uart_circ_empty(xmit) && !(up->capabilities & UART_CAP_RPM))
- __stop_tx(up);
+ { __stop_tx(up);
+
+ //20251016 liguoyi 485 IO-ctl
+ //116=GPIO3_C4
+ //115=GPIO3_C3
+ if(up->port.rs485.rts_gpio > 0)
+ {
+ for(i = 0; i < 200; i++)
+ {
+ mdelay(3);
+ lsr = serial_in(up, UART_LSR);
+ if(UART_LSR_TEMT == (lsr & UART_LSR_TEMT))
+ {
+ printk("[%d] wait finished: %d, lsr: %d\n", i, (lsr & UART_LSR_TEMT) == UART_LSR_TEMT, lsr);
+ break;
+ }
+ }
+ gpio_set_value(up->port.rs485.rts_gpio, 0);
+ }
+ //add endif
+ }
}
EXPORT_SYMBOL_GPL(serial8250_tx_chars);
diff --git a/include/uapi/linux/serial.h b/include/uapi/linux/serial.h
index 93eb3c496ff1..e39f21e3b2fb 100644
--- a/include/uapi/linux/serial.h
+++ b/include/uapi/linux/serial.h
@@ -130,6 +130,8 @@ struct serial_rs485 {
__u32 delay_rts_after_send; /* Delay after send (milliseconds) */
__u32 padding[5]; /* Memory is cheap, new structs
are a royal PITA .. */
+ //20251016 liguoyi 485 IO-ctl
+ __u32 rts_gpio;
};
a


评论