联系管理员

开通文章发布权限

扫码 添加微信
微信图片
电话: QQ:1602036736

RK3566 android13 kernel5.10 485串口收发

设备树

/* 485串口 */
&uart0 {
	status = "okay";
	pinctrl-names = "default";
	pinctrl-0 = <&uart0_xfer>;
    485_ctrl_gpio = <&gpio3 RK_PC3 GPIO_ACTIVE_HIGH>;
};

 

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

 

评论

快捷导航

把好文章收藏到微信

打开微信,扫码查看

关闭

还没有账号?立即注册