This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TDA4VM: Linux操作系统上实现GPIO中断

Part Number: TDA4VM


你好,

我们使用的芯片型号是:TDA4VL,对应的Linux版本是:PROCESSOR-SDK-LINUX-J721S2  08_00_04_05,对应的RTOS的版本是:PROCESSOR-SDK-RTOS-J721S2  08_00_04_04。

我们在A72上面运行Linux操作系统,我们想在Linux操作系统上实现GPIO外部中断功能。我使用的GPIO引脚是:GPIO0_5(AD25)。

对于GPIO中断,我们进行了验证,发现request_irq成功返回,我们尝试去触发中断(确保GPIO0_5(AD25)的电平发生了翻转),但是中断服务函数始终无法响应。我们的代码如下:

diff --git a/board-support/linux-5.10.100+gitAUTOINC+7a7a3af903-g7a7a3af903/arch/arm64/boot/dts/ti/k3-j721s2-common-proc-board.dts b/board-support/linux-5.10.100+gitAUTOINC+7a7a3af903-g7a7a3af903/arch/arm64/boot/dts/ti/k3-j721s2-common-proc-board.dts
index 35edbc1..9c75e3f 100755
--- a/board-support/linux-5.10.100+gitAUTOINC+7a7a3af903-g7a7a3af903/arch/arm64/boot/dts/ti/k3-j721s2-common-proc-board.dts
+++ b/board-support/linux-5.10.100+gitAUTOINC+7a7a3af903-g7a7a3af903/arch/arm64/boot/dts/ti/k3-j721s2-common-proc-board.dts
@@ -93,6 +93,13 @@
 			 <3300000 0x1>;
 	};
 
+	gpio_test: gpio_test {
+		compatible = "ti,gpio_test";
+		interrupt-parent = <&main_gpio0>;
+		interrupts = <5 IRQ_TYPE_EDGE_BOTH>;
+	};
+
+
 	transceiver1: can-phy1 {
 		compatible = "ti,tcan1043";
 		#phy-cells = <0>;
@@ -174,6 +181,12 @@
         >;
     };
 
+	test_key_pins_default: test-key-pins-default {
+		pinctrl-single,pins = <
+			J721S2_IOPAD(0x014, PIN_INPUT, 7) /* (AD25) MCAN14_TX.GPIO0_5 */
+		>;
+	};
+
 	main_uart8_pins_default: main-uart8-pins-default {
 		pinctrl-single,pins = <
 			J721S2_IOPAD(0x040, PIN_INPUT, 14) /* (AC28) MCASP0_AXR0.UART8_CTSn */
@@ -229,10 +242,11 @@
 		>;
 	};
 
+	/*更改I2C4 复用的引脚*/
 	main_i2c4_pins_default: main-i2c4-pins-default {
 		pinctrl-single,pins = <
-			J721S2_IOPAD(0x014, PIN_INPUT_PULLUP, 8) /* (AD25) I2C4_SCL */
-			J721S2_IOPAD(0x010, PIN_INPUT_PULLUP, 8) /* (AF28) I2C4_SDA */
+			J721S2_IOPAD(0x084, PIN_INPUT, 13) /* (AA28) MCASP0_AXR5.I2C4_SCL */
+			J721S2_IOPAD(0x010, PIN_INPUT, 8) /* (AF28) MCAN13_RX.I2C4_SDA */
 		>;
 	};
 
@@ -310,6 +324,12 @@
 	};
 };
 
+&main_gpio0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&test_key_pins_default>;
+};
+
+
 &main_gpio2 {
 	status = "disabled";
 };
diff --git a/board-support/linux-5.10.100+gitAUTOINC+7a7a3af903-g7a7a3af903/drivers/gpio/gpio-davinci.c b/board-support/linux-5.10.100+gitAUTOINC+7a7a3af903-g7a7a3af903/drivers/gpio/gpio-davinci.c
old mode 100644
new mode 100755
index 6f21385..d0d49d3
--- a/board-support/linux-5.10.100+gitAUTOINC+7a7a3af903-g7a7a3af903/drivers/gpio/gpio-davinci.c
+++ b/board-support/linux-5.10.100+gitAUTOINC+7a7a3af903-g7a7a3af903/drivers/gpio/gpio-davinci.c
@@ -25,6 +25,13 @@
 
 #include <asm-generic/gpio.h>
 
+#include <linux/interrupt.h>
+#include <linux/of_irq.h>
+#include <linux/of_gpio.h>
+
+int gpio_test_init(void);
+
+
 #define MAX_REGS_BANKS 5
 #define MAX_INT_PER_BANK 32
 
@@ -64,6 +71,38 @@ struct davinci_gpio_controller {
 	int			irqs[MAX_INT_PER_BANK];
 };
 
+static irqreturn_t test_irq(int irq, void *data)
+{
+	pr_info("%s: irq %d, val=%d\n", __func__, irq,
+		gpio_get_value(432));
+	return IRQ_HANDLED;
+}
+
+int gpio_test_init(void)
+{
+	struct device_node *np;
+	int irq;
+	int ret = 0;
+
+	printk("%s %s %d.\n", __FILE__, __func__, __LINE__);
+
+	np = of_find_node_by_name(NULL, "gpio_test");
+
+	if (np) {
+		pr_info("Initializing gpio test\n");
+		irq = irq_of_parse_and_map(np, 0);
+		printk("irq number is %d\n", irq);
+		ret = request_irq(irq, test_irq, //IRQF_TRIGGER_RISING,
+				  IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
+				  "key-gpio", NULL);
+		if (ret)
+			pr_err("request_irq returns %d\n", ret);
+	}
+
+	return ret;
+}
+
+
 static inline u32 __gpio_mask(unsigned gpio)
 {
 	return 1 << (gpio % 32);
@@ -273,6 +312,10 @@ static int davinci_gpio_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
+	if (!strcmp("600000.gpio", pdev->name)) {
+		gpio_test_init();
+	}
+
 	return 0;
 }
 

后面我们猜测会不会是MCU相关部分导致中断无法响应。我们采取了如下操作:

1、屏蔽了MCU相关代码对GPIO0_5(AD25)的使用。(中断函数还是无法响应)

2、我们在启动过程中,不加载任何MCU相关的固件。(中断函数还是无法响应)

注:我们在TDA4VM上面进行了同样的验证,同样的代码逻辑,发现在TDA4VM上面,GPIO中断可以正常响应。