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>");