基于Linux内核的input子系统驱动
2014-02-20 10:41
435 查看
#include <linux/init.h> #include <linux/module.h> #include <linux/input.h> #include <linux/irq.h> #include <linux/interrupt.h> #include <asm/gpio.h> #include <plat/gpio-cfg.h> /*1.硬件私有结构体*/ struct button_resource { unsigned long gpio; int irq; char *name; int code; }; //初始化按键信息 static struct button_resource btn_info[] = { [0] = { .gpio = S5PV210_GPH0(0), .irq = IRQ_EINT(0), .name = "KEY_L", .code = KEY_L }, [1] = { .gpio = S5PV210_GPH0(1), .irq = IRQ_EINT(1), .name = "KEY_S", .code = KEY_S }, [2] = { .gpio = S5PV210_GPH0(2), .irq = IRQ_EINT(2), .name = "KEY_ENTER", .code = KEY_ENTER }, }; //定义一个struct input_dev指针 static struct input_dev *btn_dev; //中断处理函数 static irqreturn_t button_isr(int irq, void *dev_id) { /*1.获取每个按键的按键信息*/ struct button_resource *pbtn = (struct button_resource *)dev_id; unsigned int pinstatus; /*2.获取按键状态*/ pinstatus = gpio_get_value(pbtn->gpio); /*3.上报按键信息*/ /*3.1 唤醒休眠的进程*/ /*3.2 将数据信息上报给核心层*/ if (pinstatus == 1) { //松开 input_event(btn_dev, EV_KEY, pbtn->code, 0); input_sync(btn_dev); } else { //按下 input_event(btn_dev, EV_KEY, pbtn->code, 1); input_sync(btn_dev); } return IRQ_HANDLED; } static int button_init(void) { int i; /*1.分配input_dev*/ btn_dev = input_allocate_device(); /*2.初始化input_dev*/ /*2.1指定一个名称*/ btn_dev->name = "tarena_button"; /*2.2指定上报哪类事件*/ set_bit(EV_KEY, btn_dev->evbit); //按键类事件 set_bit(EV_REP, btn_dev->evbit); //重复类事件 /*2.3指定按键类事件的哪些事件*/ for (i = 0; i < ARRAY_SIZE(btn_info); i++) { set_bit(btn_info[i].code, btn_dev->keybit); } /*3.注册input_dev*/ input_register_device(btn_dev); /*4.申请GPIO和注册中断*/ for (i = 0; i < ARRAY_SIZE(btn_info); i++) { gpio_request(btn_info[i].gpio, btn_info[i].name); request_irq(btn_info[i].irq, button_isr, IRQF_TRIGGER_FALLING|IRQF_TRIGGER_RISING, btn_info[i].name, &btn_info[i]); } return 0; } static void button_exit(void) { int i; /*1.释放GPIO和中断*/ for (i = 0; i < ARRAY_SIZE(btn_info); i++) { free_irq(btn_info[i].irq, &btn_info[i]); gpio_free(btn_info[i].gpio); } /*2.卸载input_dev*/ input_unregister_device(btn_dev); /*3.释放input_dev*/ input_free_device(btn_dev); } module_init(button_init); module_exit(button_exit); MODULE_LICENSE("GPL v2"); ******************************************************************************* 测试代码: ******************************************************************************* #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <linux/input.h> int main(int argc, char *argv[]) { //定义用户和驱动交互的数据元 struct input_event button; int fd; fd = open(argv[1], O_RDWR); if (fd < 0) { printf("open failed.\n"); return -1; } while(1) { read(fd, &button, sizeof(button)); printf("type = %#x, code = %#x, value = %#x\n", button.type, button.code, button.value); } close(fd); }
相关文章推荐
- 基于input输入子系统的按键驱动(2.6.22内核)
- Linux内核驱动之input子系统介绍
- 利用linux 内核所提供的input子系统编写字符设备驱动的步骤
- 实例:触摸屏驱动-2.用input子系统报告事件 分类: linux_内核_input模型 2013-07-10 09:39 327人阅读 评论(0) 收藏
- 详解Linux2.6内核中基于platform机制的驱动模型
- 基于Linux内核的1-wair总线驱动(…
- 基于S3C2440的嵌入式Linux驱动——SPI子系统解读(四)
- 详解Linux2.6内核中基于platform机制的驱动模型
- Linux芯片级移植与底层驱动(基于3.7.4内核)
- 详解Linux2.6内核中基于platform机制的驱动模型
- Android驱动之 Linux Input子系统之TP——A/B(Slot)协议【转】
- Linux驱动编程--基于I2C子系统的I2C驱动
- 基于linux-2.6.38.8内核的SDIO/wifi驱动分析
- Linux驱动编程--基于I2C子系统的I2C驱动的Makefile
- Linux芯片级移植与底层驱动(基于3.7.4内核) --中断控制器 推荐
- linux驱动—input输入子系统—The simplest example(一个最简单的实例)分析(1)
- 基于tiny4412的Linux内核移植 -- PWM子系统学习
- linux input输入子系统分析《三》:S3C2440的触摸屏驱动实例
- Linux内核驱动之GPIO子系统(一)GPIO的使用
- Android驱动之 Linux Input子系统之TP——A/B(Slot)协议