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 ...
随机推荐
- 关于python中的类方法(classmethod)和静态方法(staticmethod)
首先明确两点: a)python在创建类的时候,self指向的是类的实例而不是类属性! b)我们所创建的类的方法有两种作用,一种是改变类的属性,一种是改变实例的属性,这点一定要分清! c)我们在调用类 ...
- UML和模式应用3:迭代和进化式分析和设计案例研究
1.前言 如何进行迭代和进化式分析和设计?将采用案例研究的方式贯穿始终.案例研究所包含的内容: UI元素 核心应用逻辑层 数据库访问 与外部软硬构件的协作 本章关于OOA/D主要介绍核心应用逻辑层 2 ...
- Linux电源管理【转】
转自:http://www.cnblogs.com/sky-zhang/archive/2012/06/05/2536807.html PM notifier机制: 应用场景: There are s ...
- 『转载』hadoop 1.X到2.X的变化
表1新旧hadoop脚本/变量/位置变化表 改变项 原框架中 新框架中(Yarn) 备注 配置文件位置 ${hadoop_home_dir}/conf ${hadoop_home_dir}/etc/h ...
- asp.net core 2.0 api ajax跨域问题
API配置: services.AddCors(options => { options.AddPolicy("any", builder => { builder.W ...
- vue-router两种模式,到底什么情况下用hash,什么情况下用history模式呢?
转:https://segmentfault.com/q/1010000010340823/a-1020000010598395 为什么要有 hash 和 history 对于 Vue 这类渐进式前端 ...
- SQL代码整理
--SQL代码整理: create database mingzi--创建数据库go--连接符(可省略)create table biao--创建表( lieming1 int not null,-- ...
- TCP连接的3次握手和4次挥手
TCP连接的3次握手和4次挥手笔记 三次握手 TCP(Transmission Control Protocol) 传输控制协议 TCP是主机对主机层的传输控制协议,提供可靠的连接服务,采用三次握手确 ...
- python3的unittest中使用test suite(测试套件)执行指定测试用例
示例代码 module.py class baidumodule(): def __init__(self,driver,): self.dr = driver #不能在类中再次导入webdriver ...
- 基于TCPCopy的仿真压测方案
一.tcpcopy工具介绍 tcpcopy 是一个分布式在线压力测试工具,可以将线上流量拷贝到测试机器,实时的模拟线上环境,达到在程序不上线的情况下实时承担线上流量的效果,尽早发现 bug,增加上线信 ...