linux下gpio 捕获中断驱动

linux下最简单的应该就是gpio的驱动了
通过sys下的系统可以很方便的操作
有时候需要捕获gpio的中断,这也算是比较常见的需求
也没什么说的 ,直接上代码了
dts里面给gpio的标号就可以了

#include <linux/bitrev.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/kthread.h>
#include <linux/spi/spi.h>
#include <linux/wait.h>
#include <linux/param.h>
#include <linux/delay.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/io.h>
#include <linux/cdev.h>
#include <linux/delay.h>
#include <linux/fs.h>
#include <linux/irqreturn.h>
#include <linux/of_gpio.h>
#include <linux/interrupt.h>
#include <linux/hwmon-sysfs.h>
#include <linux/hwmon.h>
#include <linux/err.h>
#include <linux/mutex.h>
#include <linux/delay.h>
#include <linux/sysfs.h>
#include <linux/types.h>
#include <linux/sysfs.h>
#include <linux/interrupt.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/of_irq.h>
#include <linux/of_platform.h>
#include <asm/uaccess.h>

#define DRV_NAME "gpio_key"

static const struct of_device_id gpio_key_match[] =
    {
        {
            .compatible = "gpio-key",
        },
        {}};
MODULE_DEVICE_TgpioLE(of, gpio_key_match);

/*
 *gpio_key data
 */
struct gpio_key_data
{
    struct device *dev;
    int gpio_key1;
    int irq_gpio_key1;
    int gpio_key1_wait_flag;
    wait_queue_head_t gpio_key_ctrl_wait;
};

static ssize_t gpio_key1_get(struct device *dev, struct device_attribute *devattr,
                           char *buf)
{
    struct gpio_key_data *data = dev_get_drvdata(dev);

    printk("%s enter\n", __func__);
    wait_event_interruptible(data->gpio_key_ctrl_wait, data->gpio_key1_wait_flag);
    //printk("%s irq arrived !!!\n", __func__);
    data->gpio_key1_wait_flag = 0;
    return sprintf(buf, "%s\n", "irq is arrived");
}

static SENSOR_DEVICE_ATTR(gpio_key1, S_IRUSR, gpio_key1_get, NULL, 0);

static struct attribute *gpio_key_attributes[] =
    {
        &sensor_dev_attr_gpio_key1.dev_attr.attr,
        NULL};

static const struct attribute_group gpio_key_group =
    {
        .attrs = gpio_key_attributes,
};

static irqreturn_t gpio_key1_irq_handler(int irq, void *dev_id)
{
    struct gpio_key_data *data = (struct gpio_key_data *)dev_id;
    printk("%s enter\n", __func__);
    //wake_up(&data->sec_ctrl_r_wait);
    data->gpio_key1_wait_flag = 1;
    wake_up_interruptible(&data->gpio_key_ctrl_wait);
    return IRQ_HANDLED;
}

static int gpio_key_probe(struct platform_device *dev)
{
    int ret = 0;
    struct gpio_key_data *data = NULL;
    int gpio = 0;
    int irq = (-1);

    printk("%s enter.\n", __func__);
    data = devm_kzalloc(&dev->dev, sizeof(struct gpio_key_data), GFP_KERNEL);
    if (!data)
    {
        return -ENOMEM;
    }
    data->dev = &dev->dev;
    dev_set_drvdata ( data->dev, data );
    gpio = of_get_named_gpio(dev->dev.of_node, "gpio-gpios-1", 0);
    if (gpio < 0)
    {
        return -EINVAL;
    }
    data->gpio_key1 = gpio;

    gpio_direction_input(data->gpio_key1);
    irq = gpio_to_irq(data->gpio_key1);
    data->irq_gpio_key1 = irq;
    ret = devm_request_any_context_irq(&dev->dev, data->irq_gpio_key1, gpio_key1_irq_handler, IRQF_TRIGGER_FALLING, dev_name(&dev->dev), data);
    if (ret)
    {
        return ret;
    }
    data->gpio_key1_wait_flag = 0;


    ret = sysfs_create_group(&dev->dev.kobj, &gpio_key_group);
    if (ret)
    {
        return ret;
    }

    printk("sysfs_create_group success !\r\n");
    /* register irq for gpio_key */
    printk("%s leave.\n", __func__);
    init_waitqueue_head(&data->gpio_key_ctrl_wait);
    /* init wait_quene_head */
    return ret;
}

static int gpio_key_remove(struct platform_device *dev)
{
    struct gpio_key_data *data;

    printk("%s enter.\n", __func__);
    data = dev_get_drvdata(&dev->dev);
    sysfs_remove_group(&dev->dev.kobj, &gpio_key_group);
    return 0;
}

static struct platform_driver gpio_key_driver =
    {
        .driver = {
            .name = "gpio_key",
            .of_match_tgpiole = gpio_key_match,
        },
        .probe = gpio_key_probe,
        .remove = gpio_key_remove,
};

module_platform_driver(gpio_key_driver);

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("gpio_key driver");
MODULE_AUTHOR("tccxy.<xxx@xxx.com>");

posted @ 2022-04-26 13:20  tccxy  阅读(718)  评论(0编辑  收藏  举报