瑞芯微Rockchip开发者社区
直播中

风语者199104

12年用户 177经验值
擅长:存储技术
私信 关注
[问答]

RK3568多次insmod触摸驱动后提示中断不匹配

设备树如下,触摸挂在i2c1下面,中断用pinctrl子系统
image.png

驱动如下:

#include <linux/init.h>
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/gpio.h>
#include <linux/gpio/consumer.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
// 定义 ft5x06 设备的 GPIO 描述符
struct gpio_desc *reset_gpio, *irq_gpio;
// ft5x06 中断处理函数
irqreturn_t ft5x06_handler(int irq, void *args)
{
	printk("This is ft5x06 handler\n");
	// 返回中断已处理标志
	return IRQ_RETVAL(IRQ_HANDLED);
}

// ft5x06 设备的探测函数
int ft5x06_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
	int ret;
	printk("This is ft5x06 probe\n");
	// 获取 reset GPIO 描述符
	reset_gpio = devm_gpiod_get_optional(&client->dev, "reset", 0);
	if (!reset_gpio) {
		printk("gpiod_get_optional reset gpio is error\n");
		return -1;
	}
	// 获取 irq GPIO 描述符
	irq_gpio = devm_gpiod_get_optional(&client->dev, "interrupts", 0);
	if (!irq_gpio) {
		printk("gpiod_get_optional irq gpio is error\n");
		return -1;
	}

	// 请求中断,设置为下降沿触发,单次触发
	ret = devm_request_irq(&client->dev, client->irq, ft5x06_handler,
			  IRQ_TYPE_EDGE_FALLING | IRQF_ONESHOT | IRQF_SHARED, client->name,
			  client);
	printk("request irq name:%s\n", client->name);
	if (ret < 0) {
		printk("request irq is error\n");
		return -2;
	}
	return 0;
}
// ft5x06 设备的移除函数
int ft5x06_remove(struct i2c_client *client)
{
	// free_irq(client->irq, client);
	// gpiod_put(reset_gpio);
	// gpiod_put(irq_gpio);
	return 0;
}

// 定义 i2c_device_id 结构体数组,用于标识 ft5x06 设备
static const struct i2c_device_id ft5x06_id[] = { { "my-ft5x06", 0 }, {} };
// 定义 i2c_driver 结构体,描述 ft5x06 设备驱动
static struct i2c_driver ft5x06_driver = {
	.driver = {
		.name = "my-ft5x06",
		.owner = THIS_MODULE,
	},
	.probe = ft5x06_probe,
	.remove = ft5x06_remove,
	.id_table = ft5x06_id,
};
// 驱动初始化函数
static int __init ft5x06_driver_init(void)
{
	int ret;
	// 注册 I2C 设备驱动
	ret = i2c_add_driver(&ft5x06_driver);
	if (ret < 0) {
		printk("i2c_add_driver is error\n");
		return ret;
	}
	return 0;
}
// 驱动退出函数
static void __exit ft5x06_driver_exit(void)
{
	// 注销 I2C 设备驱动
	i2c_del_driver(&ft5x06_driver);
}
module_init(ft5x06_driver_init);
module_exit(ft5x06_driver_exit);
MODULE_LICENSE("GPL");

在第二次insmod的时候就报错

image.png

第一次insmod,触摸屏幕正常产生了中断,中断号也有

image.png
第二次insmod报错
image.png

请教下大佬,这是什么原因导致的啊

回帖(1)

Arvinhw

2024-7-25 17:08:58
从您提供的信息来看,您正在尝试为 RK3568 平台的 ft5x06 触摸驱动编写一个 Linux 内核模块。您遇到了中断不匹配的问题,这可能是由于设备树配置不正确或者中断处理函数实现有问题。

首先,让我们检查设备树配置。确保您的设备树文件(如:`.dts` 或 `.dtsi`)中包含了正确的 i2c 控制器和中断配置。例如:

```
i2c1 {
    compatible = "...";
    #address-cells = <1>;
    #size-cells = <0>;
    status = "okay";

    ft5x06@38 {
        compatible = "...";
        reg = <0x38>; // 确保这里的地址与您的设备地址匹配
        interrupt-parent = <&gpio1>;
        interrupts = ; // 确保这里的 GPIO 引脚和中断类型与您的硬件匹配
        status = "okay";
    };
};
```

接下来,检查您的中断处理函数。您提供的代码片段不完整,但这里有一些关键点需要注意:

1. 确保您已经正确初始化了 `reset_gpio` 和 `irq_gpio`。
2. 在中断处理函数中,您需要检查中断是否来自您的设备。这可以通过检查 `irq` 参数与您设备的中断号是否匹配来实现。
3. 如果中断确实来自您的设备,执行相应的处理逻辑。

以下是一个简化的中断处理函数示例:

```c
irqreturn_t ft5x06_handler(int irq, void *args)
{
    if (irq != gpio_to_irq(irq_gpio->pin)) {
        return IRQ_NONE;
    }

    // 处理中断
    printk("This is ft5x06 interrupt handlern");

    return IRQ_HANDLED;
}
```

最后,确保您的模块正确地注册了中断处理函数。例如:

```c
static int __init ft5x06_init(void)
{
    // 初始化 GPIO 和其他资源

    request_irq(gpio_to_irq(irq_gpio->pin), ft5x06_handler, IRQF_TRIGGER_FALLING, "ft5x06", NULL);

    return 0;
}

static void __exit ft5x06_exit(void)
{
    // 释放资源和注销中断
    free_irq(gpio_to_irq(irq_gpio->pin), NULL);
}

module_init(ft5x06_init);
module_exit(ft5x06_exit);
```

请检查您的代码,确保所有部分都正确实现。如果问题仍然存在,请提供更详细的错误信息和代码,以便进一步分析。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分