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 ...
随机推荐
- 集群下Dubbo负载均衡配置
在集群负载均衡时,Dubbo提供了4种均衡策略,默认为Random(随机调用) 负载均衡策略: 1).Random LoadBalance(随机,按照权重的设置随机概率) 2).RoundRobin ...
- 一文看懂汽车电子ECU bootloader工作原理及开发要点
随着半导体技术的不断进步(按照摩尔定律),MCU内部集成的逻辑功能外设越来越多,存储器也越来越大.消费者对于汽车节能(经济和法规对排放的要求)型.舒适性.互联性.安全性(功能安全和信息安全)的要求越来 ...
- [转]RJ45接口说明
[转]http://blog.csdn.net/dog0138/article/details/7016351 1.前言 常见的RJ45接口有两类: 用于以太网网卡.路由器以太网接口等的DTE类型,可 ...
- 所有Windows7下游戏的全屏问题
Win键+R键,打开运行窗口,输入regedit 回车,这样就打开了注册表编辑器,然后,定位到以下位置:HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\ ...
- mysql系列十一、mysql优化笔记:表设计、sql优化、配置优化
可以从这些方面进行优化: 数据库(表)设计合理 SQL语句优化 数据库配置优化 系统层.硬件层优化 数据库设计 关系数据库三范式 1NF:字段不可分; 2NF:有主键,非主键字段依赖主键; 3NF:非 ...
- HTML学习笔记03-HTML基础
<!DOCTYPE HTML> <html> <head> <title> </title> </head> <body& ...
- Vue.js——理解与创建使用
Vue.js 概念:是一个轻巧.高性能.可组件化的MVVM库,同时拥有非常容易上手的API,作者是尤雨溪是中国人. 优点: 1)易用 已经会了HTML,CSS,JavaScript?即刻阅读指南开始构 ...
- route 的标志位
linux下利用route命令查看当前路由信息时,会打印如下信息: root@root:/# route Kernel IP routing tableDestination Gateway ...
- 一张纸,折多少次和珠穆拉峰一样高(for if 和break)
- Windows Server 2003 R2标准版 SP2 64位 (简体中文)官方原版ISO镜像
Windows Server 2003 R2标准版 SP2 64位 (简体中文)官方原版ISO镜像迅雷下载 软件简介 Windows Server 2003 R2标准版是继Windows Serv ...