Linux 输入子系统驱动程序范例
int key_value = gpio_get_value(S5PV210_GPH2(0));//上报事件给input核心层input_report_key(button_dev, KEY_A, !key_value);//按下为1//告诉input子系统上报已经完成input_sync(button_dev);//printk("[%d][%s], data=[%lu]\r\n", __LINE__, __FUNCTION__, data);
//the value of timeout is decided by the n of "jiffies + n"//timeout = n*(1000/HZ) ms(HZ=256 in this project)//the empirical value of timeout ≈ 10~100msmod_timer(&my_timer, jiffies + 5);//timeout≈5*4=20msreturn IRQ_HANDLED;
int ret;ret = gpio_request(S5PV210_GPH2(0), "key2");
- #include <linux/module.h>
- #include <linux/init.h>
- #include <linux/interrupt.h>
- #include <linux/platform_device.h>
- #include <linux/input.h>
- #include <linux/slab.h>
- #include <mach/regs-gpio.h>
- #include <linux/gpio.h>
- #include <linux/irq.h>
- #define DHOLE2440_KBD "dhole2440kbd"
- #define DHOLE2440_KBD_IRQ_NUM (6)
- #define KBD_NONE (0xff)
- #define KBD_UP (0)
- #define KBD_DOWN (1)
- typedef struct _dhole2440_key{
- unsigned int gpio;/*对应gpio口*/
- unsigned int irq;/*对应中断*/
- int n_key;/*键值*/
- }dhole2440_key;
- struct dhole2440_kbd{
- dhole2440_key keys[DHOLE2440_KBD_IRQ_NUM];
- struct timer_list key_timer; /*按键去抖定时器*/
- unsigned int key_status; /*按键状态*/
- struct input_dev *input;
- };
- struct dhole2440_kbd *p_dhole2440_kbd;
- struct dhole2440_kbd *get_kbd(void)
- {
- printk("get_kbd p_dhole2440_kbd=%x\n", (unsigned int)p_dhole2440_kbd);
- return p_dhole2440_kbd;
- }
- void set_kbd(struct dhole2440_kbd *p_kbd)
- {
- p_dhole2440_kbd = p_kbd;
- printk("set_kbd p_kbd=%x, p_dhole2440_kbd=%x\n",
- (unsigned int)p_kbd, (unsigned int)p_dhole2440_kbd);
- }
- static irqreturn_t dhole2440_kbd_handler(int irq, void *p_date)
- {
- unsigned int n_key = 0;
- struct dhole2440_kbd *p_kbd = p_date;
- unsigned int key_state = 0;
- int i;
- for(i = 0; i < DHOLE2440_KBD_IRQ_NUM; i++)
- {
- if( irq == p_kbd->keys[i].irq )
- {
- key_state = s3c2410_gpio_getpin(p_kbd->keys[i].gpio);
- n_key = p_kbd->keys[i].n_key;
- break;
- }
- }
- printk("dhole2440_kbd_handler n_key=%d, key_state=%d\n", n_key, key_state);
- input_report_key(p_kbd->input, n_key, !key_state);/*1表示按下*/
- input_sync(p_kbd->input);
- return IRQ_HANDLED;
- }
- static void kbd_free_irqs(void)
- {
- struct dhole2440_kbd *p_kbd = get_kbd();
- int i;
- printk("kbd_free_irqs p_kbd=%x\n", (unsigned int)p_kbd);
- for(i = 0; i < DHOLE2440_KBD_IRQ_NUM; i++)
- free_irq(p_kbd->keys[i].irq, p_kbd);
- }
- static int kbd_req_irqs(void)
- {
- int n_ret;
- int i;
- struct dhole2440_kbd *p_kbd = get_kbd();
- printk("kbd_req_irqs p_kbd=%x\n", (unsigned int)p_kbd);
- for(i = 0; i < DHOLE2440_KBD_IRQ_NUM; i++)
- {
- n_ret = request_irq(p_kbd->keys[i].irq, dhole2440_kbd_handler, IRQ_TYPE_EDGE_BOTH, DHOLE2440_KBD, p_kbd);
- if(n_ret)
- {
- printk("%d: could not register interrupt\n", p_kbd->keys[i].irq);
- goto fail;
- }
- }
- return n_ret;
- fail:
- /*因为上面申请失败的那个没有成功,所以也不要释放*/
- for(i--; i >= 0; i--)
- {
- disable_irq(p_kbd->keys[i].irq);
- free_irq(p_kbd->keys[i].irq, p_kbd);
- }
- return n_ret;
- }
- static void dhole2440_init_kbd_data(struct dhole2440_kbd *p_kbd)
- {
- printk("dhole2440_init_kbd_data p_kbd=%x\n", (unsigned int)p_kbd);
- p_kbd->keys[0].gpio = S3C2410_GPG(11);
- p_kbd->keys[1].gpio = S3C2410_GPG(7);
- p_kbd->keys[2].gpio = S3C2410_GPG(6);
- p_kbd->keys[3].gpio = S3C2410_GPG(5);
- p_kbd->keys[4].gpio = S3C2410_GPG(3);
- p_kbd->keys[5].gpio = S3C2410_GPG(0);
- p_kbd->keys[0].irq = IRQ_EINT19;
- p_kbd->keys[1].irq = IRQ_EINT15;
- p_kbd->keys[2].irq = IRQ_EINT14;
- p_kbd->keys[3].irq = IRQ_EINT13;
- p_kbd->keys[4].irq = IRQ_EINT11;
- p_kbd->keys[5].irq = IRQ_EINT8;
- p_kbd->keys[0].n_key = KEY_0;
- p_kbd->keys[1].n_key = KEY_1;
- p_kbd->keys[2].n_key = KEY_2;
- p_kbd->keys[3].n_key = KEY_3;
- p_kbd->keys[4].n_key = KEY_ESC;
- p_kbd->keys[5].n_key = KEY_ENTER;
- }
- static int __devinit dhole2440_keys_probe(struct platform_device *pdev)
- {
- int err = -ENOMEM;
- struct dhole2440_kbd *p_dhole2440_keys = NULL;
- struct input_dev *input_dev = NULL;
- printk("dhole2440_keys_probe entry!\n");
- p_dhole2440_keys = kmalloc(sizeof(struct dhole2440_kbd), GFP_KERNEL);
- if( !p_dhole2440_keys )
- {
- printk("dhole2440_keys_probe kmalloc error!\n");
- return err;
- }
- printk("dhole2440_keys_probe p_dhole2440_keys=%x\n", (unsigned int)p_dhole2440_keys);
- dhole2440_init_kbd_data(p_dhole2440_keys);
- input_dev = input_allocate_device();
- if (!input_dev)
- {
- printk("dhole2440_keys_probe input_allocate_device error!\n");
- goto fail;
- }
- p_dhole2440_keys->input = input_dev;
- platform_set_drvdata(pdev, p_dhole2440_keys);
- input_dev->name = pdev->name;
- input_dev->phys = DHOLE2440_KBD"/input0";
- input_dev->id.bustype = BUS_HOST;
- input_dev->dev.parent = &pdev->dev;
- input_dev->id.vendor = 0x0001;
- input_dev->id.product = 0x0001;
- input_dev->id.version = 0x0100;
- __set_bit(EV_KEY, input_dev->evbit);
- __set_bit(KEY_0, input_dev->keybit);
- __set_bit(KEY_1, input_dev->keybit);
- __set_bit(KEY_2, input_dev->keybit);
- __set_bit(KEY_3, input_dev->keybit);
- __set_bit(KEY_ESC, input_dev->keybit);
- __set_bit(KEY_ENTER, input_dev->keybit);
- input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
- err = input_register_device(input_dev);
- if( err )
- {
- printk("dhole2440_keys_probe input_register_device error!\n");
- goto fail_allocate;
- }
- set_kbd(p_dhole2440_keys);
- err = kbd_req_irqs();
- if( err )
- {
- printk("dhole2440_keys_probe kbd_req_irqs error!\n");
- goto fail_register;
- }
- printk("dhole2440_keys_probe sucess!\n");
- return 0;
- fail_register:
- input_unregister_device(input_dev);
- goto fail;
- fail_allocate:
- input_free_device(input_dev);
- fail:
- kfree(p_dhole2440_keys);
- return err;
- }
- static int __devexit dhole2440_keys_remove(struct platform_device *pdev)
- {
- struct dhole2440_kbd *p_dhole2440_keys = platform_get_drvdata(pdev);
- printk("dhole2440_keys_remove entry!\n");
- kbd_free_irqs();
- input_unregister_device(p_dhole2440_keys->input);
- kfree(p_dhole2440_keys);
- printk("dhole2440_keys_remove sucess!\n");
- return 0;
- }
- static void dhole2440_keys_release(struct device *dev)
- {
- dev = dev;
- }
- static struct platform_driver dhole2440_keys_device_driver = {
- .probe = dhole2440_keys_probe,
- .remove = __devexit_p(dhole2440_keys_remove),
- .driver = {
- .name = DHOLE2440_KBD,
- .owner = THIS_MODULE,
- }
- };
- static struct platform_device dhole2440_device_kbd = {
- .name = DHOLE2440_KBD,
- .id = -1,
- .dev = {
- .release = dhole2440_keys_release,
- }
- };
- static int __init dhole2440_keys_init(void)
- {
- int n_ret;
- n_ret = platform_driver_register(&dhole2440_keys_device_driver);
- printk("dhole2440_keys_init 1 n_ret=%d jiffies=%lu,HZ=%d\n", n_ret, jiffies, HZ);
- if( n_ret )
- return n_ret;
- n_ret = platform_device_register(&dhole2440_device_kbd);
- printk("dhole2440_keys_init 2 n_ret=%d\n", n_ret);
- if( n_ret )
- goto fail;
- return n_ret;
- fail:
- platform_driver_unregister(&dhole2440_keys_device_driver);
- return n_ret;
- }
- static void __exit dhole2440_keys_exit(void)
- {
- printk("dhole2440_keys_exit\n");
- platform_device_unregister(&dhole2440_device_kbd);
- platform_driver_unregister(&dhole2440_keys_device_driver);
- }
- module_init(dhole2440_keys_init);
- module_exit(dhole2440_keys_exit);
- MODULE_DESCRIPTION("dhole2440 keyboard input events driver");
- MODULE_AUTHOR("liuzhiping <lyliuzhiping@yeah.net style="word-wrap: break-word;">");
- MODULE_LICENSE("GPL");
- MODULE_ALIAS("platform:dhole2440 keyboard driver");
<wiz_tmp_tag id="wiz-table-range-border" contenteditable="false" style="display: none;">
Linux 输入子系统驱动程序范例的更多相关文章
- linux输入子系统(input subsystem)之evdev.c事件处理过程
1.代码 input_subsys.drv.c 在linux输入子系统(input subsystem)之按键输入和LED控制的基础上有小改动,input_subsys_test.c不变. input ...
- Linux输入子系统详解
input输入子系统框架 linux输入子系统(linux input subsystem)从上到下由三层实现,分别为:输入子系统事件处理层(EventHandler).输入子系统核心层(Input ...
- linux输入子系统
linux输入子系统(linux input subsystem)从上到下由三层实现,分别为:输入子系统事件处理层(EventHandler).输入子系统核心层(InputCore)和输入子系统设备驱 ...
- linux输入子系统概念介绍
在此文章之前,我们讲解的都是简单的字符驱动,涉及的内容有字符驱动的框架.自动创建设备节点.linux中断.poll机制.异步通知.同步互斥.非阻塞.定时器去抖动. 上一节文章链接:http://blo ...
- 7.Linux 输入子系统分析
为什么要引入输入子系统? 在前面我们写了一些简单的字符设备的驱动程序,我们是怎么样打开一个设备并操作的呢? 一般都是在执行应用程序时,open一个特定的设备文件,如:/dev/buttons .... ...
- Linux输入子系统(转)
Linux输入子系统(Input Subsystem) 1.1.input子系统概述 输入设备(如按键,键盘,触摸屏,鼠标等)是典型的字符设备,其一般的工作机制是低层在按键,触摸等动作发生时产生一个中 ...
- Linux输入子系统(Input Subsystem)
Linux输入子系统(Input Subsystem) http://blog.csdn.net/lbmygf/article/details/7360084 input子系统分析 http://b ...
- Linux输入子系统框架分析(1)
在Linux下的输入设备键盘.触摸屏.鼠标等都能够用输入子系统来实现驱动.输入子系统分为三层,核心层和设备驱动层.事件层.核心层和事件层由Linux输入子系统本身实现,设备驱动层由我们实现.我们在设备 ...
- linux输入子系统简述【转】
本文转载自:http://blog.csdn.net/xubin341719/article/details/7678035 1,linux输入子系统简述 其实驱动这部分大多还是转载别人的,linux ...
随机推荐
- RoIPooling、RoIAlign笔记
一).RoIPooling 这个可以在Faster RCNN中使用以便使生成的候选框region proposal映射产生固定大小的feature map 先贴出一张图,接着通过这图解释RoiPool ...
- Dom4j向XML中增加节点与属性——(四)
先获取到节点,然后在节点山添加Element 添加节点 添加属性 设置开始标签与结束标签的值book.addElement("描述").addAttribute("nam ...
- oracle数据库自增主键重复
select max(t.id) from T_PLAT_ENUM_VALUE tdrop sequence T_PLAT_ENUM_VALUE;create sequence T_PLAT_ENUM ...
- 利用mysqltuner工具对mysql数据库进行优化
mysqltuner工具使用,本工具建议定期运行,发现目前MYSQL数据库存在的问题及修改相关的参数 工具的下载及部署 解决环境依赖,因为工具是perl脚本开发的,需要perl脚本环境 # yun i ...
- centos7 部署 open-falcon 0.2.1
=============================================== 2019/4/28_第1次修改 ccb_warlock 更新 ...
- Python-互斥锁 进程间通讯
3.守护进程(**) 主进程创建守护进程 其一:守护进程会在主进程代码执行结束后就终止 其二:守护进程内无法再开启子进程,否则抛出异常: AssertionError: daemonic proces ...
- __dirname与__filename
(1) __filename变量 node.js中,在任何模块文件内部,可以使用__filename变量获取当前模块文件的带有完整绝对路径的文件名. 在应用程序根目录下新建app.js文件,其中代码如 ...
- CentOS中在/etc/rc.local添加开机自启动项启动失败
应项目要求需要在开机的时候启动自己的Agent程序,想当然的直接就往/etc/rc.local当中添加启动命令,结果重启之后发现什么都没有发生....一开始还以为是Python路径的问题,结果改成绝对 ...
- inoremap nnoremap vnoremap
原贴:https://www.xuebuyuan.com/zh-hant/1116162.html inoremap nnoremap vnoremap i insert 在插入模式有效 n 在 普通 ...
- poj2114 树分治(点分治)
poj1741板子套一套,统计对数的方式改一下,可以在O(n)时间内统计对数 最后不要忘记输出最后的“.” /* 给定一棵边权树,是否存在一条路径使得其长度为恰好为x 把1741的板子改为求点对之间的 ...