GPIO驱动实例代码

设备树

		gpio1: gpio@fec20000 {
			compatible = "rockchip,gpio-bank";
			reg = <0x0 0xfec20000 0x0 0x100>;
			interrupts = <GIC_SPI 278 IRQ_TYPE_LEVEL_HIGH>;
			clocks = <&cru PCLK_GPIO1>, <&cru DBCLK_GPIO1>;

			gpio-controller;
			#gpio-cells = <2>;
			gpio-ranges = <&pinctrl 0 32 32>;
			interrupt-controller;
			#interrupt-cells = <2>;
		};
	gpio-int {
		compatible = "gpio-int-demo";
		interrupt-gpio = <&gpio1 RK_PC6 IRQ_TYPE_EDGE_RISING>;
		status = "okay";
	};

MAKEFILE

obj-y                    += gpio-int-demo.o

驱动

#include <linux/module.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/gpio.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/platform_device.h>
#include <linux/kernel.h>
#include <linux/interrupt.h>
#include <linux/cpumask.h>

struct gpio_int_data {
    int irq_num;
    int gpio;
};

static irqreturn_t gpio_irq_handler(int irq, void *dev_id)
{
	{
		//jimmy
		static ktime_t start = 0;
		ktime_t end = 0;
		s64 duration_us = 0;
		static u32 counter = 0;
		static u32 delay_counter = 0;
		static u32 print_counter = 0;

		//printk("gpio_keys_gpio_isr: irq %d\n", irq);
		if (irq == 135)
		{
			end = ktime_get();
			if (start == 0)
			{
				start = ktime_get();
			}
			else
			{
				duration_us = ktime_to_us(ktime_sub(end, start));
				start = end;
				counter++;
				if (duration_us > 135)
				{
					delay_counter++;		
				}

				{
					if (print_counter > 5000)
					{
						printk("gpio_soft usec_diff = %lld [%d/%d] virq %d\n", duration_us, delay_counter, counter, irq);
						print_counter = 0;
					}
					else
					{
						print_counter++;
					}
				}
			}
		}
	}

    // 可以在这里添加去抖、状态读取等逻辑
    return IRQ_HANDLED;
}

static int gpio_int_probe(struct platform_device *pdev)
{
    struct device *dev = &pdev->dev;
    struct gpio_int_data *data;
    enum of_gpio_flags flags;
    int ret;
	struct cpumask mask;

	printk("gpio_int_probe ok\n");

    data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
    if (!data)
        return -ENOMEM;

    /* 获取GPIO和中断标志 */
    data->gpio = of_get_named_gpio_flags(dev->of_node, "interrupt-gpio", 0, &flags);
    if (!gpio_is_valid(data->gpio)) {
        dev_err(dev, "Invalid GPIO\n");
        return -EINVAL;
    }

    data->irq_num = gpio_to_irq(data->gpio);

    /* 请求GPIO */
    ret = devm_gpio_request_one(dev, data->gpio, GPIOF_IN, "gpio_int");
    if (ret) {
        dev_err(dev, "Failed to request GPIO %d\n", data->gpio);
        return ret;
    }

    /* 请求中断 */
    ret = devm_request_irq(dev, data->irq_num, gpio_irq_handler, flags, dev_name(dev), NULL);
    if (ret) {
        dev_err(dev, "Failed to request IRQ %d\n", data->irq_num);
        return ret;
    }

    printk("GPIO %d (IRQ %d) registered successfully.\n", data->gpio, data->irq_num);

    platform_set_drvdata(pdev, data);

    return 0;
}

static int gpio_int_remove(struct platform_device *pdev)
{
    pr_info("GPIO interrupt driver removed.\n");
    return 0;
}

static const struct of_device_id gpio_int_of_match[] = {
    { .compatible = "gpio-int-demo" },
    {}
};
MODULE_DEVICE_TABLE(of, gpio_int_of_match);

static struct platform_driver gpio_int_driver = {
    .probe = gpio_int_probe,
    .remove = gpio_int_remove,
    .driver = {
        .name = "gpio-int-demo",
        .of_match_table = gpio_int_of_match,
    },
};

module_platform_driver(gpio_int_driver);

MODULE_AUTHOR("Jimmy.V");
MODULE_DESCRIPTION("GPIO Interrupt Demo Driver for RK3588");
MODULE_LICENSE("GPL v2");

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值