<按键驱动程序>
#include <stdio.h>
#include <fcntl.h>
#include <linux/input.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc, char** argv)
{
   int fd;
   int count;
   int i = 0;
   int j = 0;
   struct input_event key2;
   //在根文件系统用cat /proc/bus/input/devices查看是event几
   fd = open("/dev/event1", O_RDWR);
 
   if (fd < 0)
   {
       perror("open");
       return -1;
   }
   while (1)
   {
       lseek(fd, 0, SEEK_SET);
       count = read(fd, &key2, sizeof(struct input_event)); 
       if(count != sizeof(struct input_event))
       {
           perror("read");
       }
       if(EV_KEY == key2.type)
       {
           printf("\r\ni = %d, type:%d, code:%d, value:%d\r\n", i, key2.type,                key2.code, key2.value);
           if (key2.value)
           {
               i++;
               printf("***********the k2 down %d times***********\r\n", i);    
           }
       else
       {
           printf("****************the k2 up*****************\r\n"); 
       }
   } 
 
   if(EV_SYN == key2.type)
   {
       printf("syn event\r\n");
       if (++j == 2)
       {
           j = 0;
           printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r\n\n");
       }
   }
}
   close(fd);
   return 0;
}
 
驱动程序:inputk2_drv.c
#include <linux/module.h>
#include <linux/init.h>
#include <linux/input.h>
#include <linux/interrupt.h>
#include <asm/gpio.h>
#include <linux/timer.h>
 
static struct input_dev *button_dev;//定义输入设备
struct timer_list my_timer;//定义定时器结构体timer_list
//定义定时器超时处理函数
void timer_func(unsigned long data)
{
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);
}
static irqreturn_t button_interrupt(int irq, void *dev_id)
{
//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~100ms
mod_timer(&my_timer, jiffies + 5);//timeout≈5*4=20ms
return IRQ_HANDLED;
}
static int __init button_init(void)
{
int ret;
ret = gpio_request(S5PV210_GPH2(0), "key2");
   if (ret)
   {
       printk(KERN_ERR "gpio_request Failed to register device\r\n");
       goto error1;
   }
 
   //为新输入设备分配内存并初始化
   button_dev = input_allocate_device();
   if (!button_dev) 
   {
       printk(KERN_ERR "can't allocate input mem!\r\n");
       goto error2;
   }
 
   button_dev->name = "gec_input";
   button_dev->id.bustype = 0x1;
   button_dev->id.product = 0x2;
   button_dev->id.vendor = 0x3;
   button_dev->id.version = 0x4;
   button_dev->evbit[BIT_WORD(EV_KEY)] = BIT_MASK(EV_KEY);//set_bit(EV_KEY,button_dev-    >evbit[BIT_WORD(EV_KEY)])
   button_dev->keybit[BIT_WORD(KEY_A)] = BIT_MASK(KEY_A);//set_bit(KEY_A, button_dev-      >keybit[BIT_WORD(KEY_A)])
   //注册一个输入设备
   ret = input_register_device(button_dev);
   if (ret) 
   {
       printk(KERN_ERR "Failed to register device\r\n");
       goto error3;
   }
   //申请中断注册中断处理函数
   ret = request_irq(IRQ_EINT(16), button_interrupt,\
   IRQF_TRIGGER_FALLING |IRQF_TRIGGER_RISING | IRQF_DISABLED, "button", NULL);
   if (ret) 
   {
       printk(KERN_ERR "Can't request irq %d\r\n", IRQ_EINT(16));
       goto error4;
   }
 
   //定时器
   init_timer(&my_timer);//初始化定时器
   my_timer.function = timer_func;//注册定时器超时处理函数
   return 0;
   error4:
   free_irq(IRQ_EINT(16), NULL);//释放分配给已定中断的内存
   input_unregister_device(button_dev);
   error3:
   input_free_device(button_dev);
   error2:
   ret = -ENOMEM;
   error1:
   gpio_free(S5PV210_GPH2(0));
 
   return ret;
}
 
static void __exit button_exit(void)
{
   gpio_free(S5PV210_GPH2(0)); 
   free_irq(IRQ_EINT(16), NULL);
   input_unregister_device(button_dev);
   del_timer(&my_timer);//删除内核定时器
}
module_init(button_init);
module_exit(button_exit);
MODULE_LICENSE("Dual BSD/GPL");
MODULE_LICENSE("GPL");
Makefile:
obj-m += inputk2_drv.o
PWD ?= shell pwd
KDIR := /opt/03.kernel_transplant/android-kernel-samsung-dev
all:
make -C $(KDIR) M=$(PWD) modules
cp ./inputk2_drv.ko /mini_rootfs/modules
cp ./inputk2_app /mini_rootfs/modules
rm -rf ./*.o
rm -rf ./*.order
rm -rf ./*.symvers
rm -rf ./*.mod.c
rm -rf ./.*.cmd 
rm -rf ./.*.tmp* 
rm -rf ./.tmp_versions
 
<键盘驱动程序>
  1. #include <linux/module.h>
  2. #include <linux/init.h>
  3. #include <linux/interrupt.h>
  4. #include <linux/platform_device.h>
  5. #include <linux/input.h>
  6. #include <linux/slab.h>
  7. #include <mach/regs-gpio.h>
  8. #include <linux/gpio.h>
  9. #include <linux/irq.h>
  10. #define DHOLE2440_KBD "dhole2440kbd"
  11. #define DHOLE2440_KBD_IRQ_NUM (6)
  12. #define KBD_NONE (0xff)
  13. #define KBD_UP (0)
  14. #define KBD_DOWN (1)
  15. typedef struct _dhole2440_key{
  16. unsigned int gpio;/*对应gpio口*/
  17. unsigned int irq;/*对应中断*/
  18. int n_key;/*键值*/
  19. }dhole2440_key;
  20. struct dhole2440_kbd{
  21. dhole2440_key keys[DHOLE2440_KBD_IRQ_NUM];
  22. struct timer_list key_timer; /*按键去抖定时器*/
  23. unsigned int key_status; /*按键状态*/
  24. struct input_dev *input;
  25. };
  26. struct dhole2440_kbd *p_dhole2440_kbd;
  27. struct dhole2440_kbd *get_kbd(void)
  28. {
  29. printk("get_kbd p_dhole2440_kbd=%x\n", (unsigned int)p_dhole2440_kbd);
  30. return p_dhole2440_kbd;
  31. }
  32. void set_kbd(struct dhole2440_kbd *p_kbd)
  33. {
  34. p_dhole2440_kbd = p_kbd;
  35. printk("set_kbd p_kbd=%x, p_dhole2440_kbd=%x\n",
  36. (unsigned int)p_kbd, (unsigned int)p_dhole2440_kbd);
  37. }
  38. static irqreturn_t dhole2440_kbd_handler(int irq, void *p_date)
  39. {
  40. unsigned int n_key = 0;
  41. struct dhole2440_kbd *p_kbd = p_date;
  42. unsigned int key_state = 0;
  43. int i;
  44. for(i = 0; i < DHOLE2440_KBD_IRQ_NUM; i++)
  45. {
  46. if( irq == p_kbd->keys[i].irq )
  47. {
  48. key_state = s3c2410_gpio_getpin(p_kbd->keys[i].gpio);
  49. n_key = p_kbd->keys[i].n_key;
  50. break;
  51. }
  52. }
  53. printk("dhole2440_kbd_handler n_key=%d, key_state=%d\n", n_key, key_state);
  54. input_report_key(p_kbd->input, n_key, !key_state);/*1表示按下*/
  55. input_sync(p_kbd->input);
  56. return IRQ_HANDLED;
  57. }
  58. static void kbd_free_irqs(void)
  59. {
  60. struct dhole2440_kbd *p_kbd = get_kbd();
  61. int i;
  62. printk("kbd_free_irqs p_kbd=%x\n", (unsigned int)p_kbd);
  63. for(i = 0; i < DHOLE2440_KBD_IRQ_NUM; i++)
  64. free_irq(p_kbd->keys[i].irq, p_kbd);
  65. }
  66. static int kbd_req_irqs(void)
  67. {
  68. int n_ret;
  69. int i;
  70. struct dhole2440_kbd *p_kbd = get_kbd();
  71. printk("kbd_req_irqs p_kbd=%x\n", (unsigned int)p_kbd);
  72. for(i = 0; i < DHOLE2440_KBD_IRQ_NUM; i++)
  73. {
  74. n_ret = request_irq(p_kbd->keys[i].irq, dhole2440_kbd_handler, IRQ_TYPE_EDGE_BOTH, DHOLE2440_KBD, p_kbd);
  75. if(n_ret)
  76. {
  77. printk("%d: could not register interrupt\n", p_kbd->keys[i].irq);
  78. goto fail;
  79. }
  80. }
  81. return n_ret;
  82. fail:
  83. /*因为上面申请失败的那个没有成功,所以也不要释放*/
  84. for(i--; i >= 0; i--)
  85. {
  86. disable_irq(p_kbd->keys[i].irq);
  87. free_irq(p_kbd->keys[i].irq, p_kbd);
  88. }
  89. return n_ret;
  90. }
  91. static void dhole2440_init_kbd_data(struct dhole2440_kbd *p_kbd)
  92. {
  93. printk("dhole2440_init_kbd_data p_kbd=%x\n", (unsigned int)p_kbd);
  94. p_kbd->keys[0].gpio = S3C2410_GPG(11);
  95. p_kbd->keys[1].gpio = S3C2410_GPG(7);
  96. p_kbd->keys[2].gpio = S3C2410_GPG(6);
  97. p_kbd->keys[3].gpio = S3C2410_GPG(5);
  98. p_kbd->keys[4].gpio = S3C2410_GPG(3);
  99. p_kbd->keys[5].gpio = S3C2410_GPG(0);
  100. p_kbd->keys[0].irq = IRQ_EINT19;
  101. p_kbd->keys[1].irq = IRQ_EINT15;
  102. p_kbd->keys[2].irq = IRQ_EINT14;
  103. p_kbd->keys[3].irq = IRQ_EINT13;
  104. p_kbd->keys[4].irq = IRQ_EINT11;
  105. p_kbd->keys[5].irq = IRQ_EINT8;
  106. p_kbd->keys[0].n_key = KEY_0;
  107. p_kbd->keys[1].n_key = KEY_1;
  108. p_kbd->keys[2].n_key = KEY_2;
  109. p_kbd->keys[3].n_key = KEY_3;
  110. p_kbd->keys[4].n_key = KEY_ESC;
  111. p_kbd->keys[5].n_key = KEY_ENTER;
  112. }
  113. static int __devinit dhole2440_keys_probe(struct platform_device *pdev)
  114. {
  115. int err = -ENOMEM;
  116. struct dhole2440_kbd *p_dhole2440_keys = NULL;
  117. struct input_dev *input_dev = NULL;
  118. printk("dhole2440_keys_probe entry!\n");
  119. p_dhole2440_keys = kmalloc(sizeof(struct dhole2440_kbd), GFP_KERNEL);
  120. if( !p_dhole2440_keys )
  121. {
  122. printk("dhole2440_keys_probe kmalloc error!\n");
  123. return err;
  124. }
  125. printk("dhole2440_keys_probe p_dhole2440_keys=%x\n", (unsigned int)p_dhole2440_keys);
  126. dhole2440_init_kbd_data(p_dhole2440_keys);
  127. input_dev = input_allocate_device();
  128. if (!input_dev)
  129. {
  130. printk("dhole2440_keys_probe input_allocate_device error!\n");
  131. goto fail;
  132. }
  133. p_dhole2440_keys->input = input_dev;
  134. platform_set_drvdata(pdev, p_dhole2440_keys);
  135. input_dev->name = pdev->name;
  136. input_dev->phys = DHOLE2440_KBD"/input0";
  137. input_dev->id.bustype = BUS_HOST;
  138. input_dev->dev.parent = &pdev->dev;
  139. input_dev->id.vendor = 0x0001;
  140. input_dev->id.product = 0x0001;
  141. input_dev->id.version = 0x0100;
  142. __set_bit(EV_KEY, input_dev->evbit);
  143. __set_bit(KEY_0, input_dev->keybit);
  144. __set_bit(KEY_1, input_dev->keybit);
  145. __set_bit(KEY_2, input_dev->keybit);
  146. __set_bit(KEY_3, input_dev->keybit);
  147. __set_bit(KEY_ESC, input_dev->keybit);
  148. __set_bit(KEY_ENTER, input_dev->keybit);
  149. input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
  150. err = input_register_device(input_dev);
  151. if( err )
  152. {
  153. printk("dhole2440_keys_probe input_register_device error!\n");
  154. goto fail_allocate;
  155. }
  156. set_kbd(p_dhole2440_keys);
  157. err = kbd_req_irqs();
  158. if( err )
  159. {
  160. printk("dhole2440_keys_probe kbd_req_irqs error!\n");
  161. goto fail_register;
  162. }
  163. printk("dhole2440_keys_probe sucess!\n");
  164. return 0;
  165. fail_register:
  166. input_unregister_device(input_dev);
  167. goto fail;
  168. fail_allocate:
  169. input_free_device(input_dev);
  170. fail:
  171. kfree(p_dhole2440_keys);
  172. return err;
  173. }
  174. static int __devexit dhole2440_keys_remove(struct platform_device *pdev)
  175. {
  176. struct dhole2440_kbd *p_dhole2440_keys = platform_get_drvdata(pdev);
  177. printk("dhole2440_keys_remove entry!\n");
  178. kbd_free_irqs();
  179. input_unregister_device(p_dhole2440_keys->input);
  180. kfree(p_dhole2440_keys);
  181. printk("dhole2440_keys_remove sucess!\n");
  182. return 0;
  183. }
  184. static void dhole2440_keys_release(struct device *dev)
  185. {
  186. dev = dev;
  187. }
  188. static struct platform_driver dhole2440_keys_device_driver = {
  189. .probe = dhole2440_keys_probe,
  190. .remove = __devexit_p(dhole2440_keys_remove),
  191. .driver = {
  192. .name = DHOLE2440_KBD,
  193. .owner = THIS_MODULE,
  194. }
  195. };
  196. static struct platform_device dhole2440_device_kbd = {
  197. .name = DHOLE2440_KBD,
  198. .id = -1,
  199. .dev = {
  200. .release = dhole2440_keys_release,
  201. }
  202. };
  203. static int __init dhole2440_keys_init(void)
  204. {
  205. int n_ret;
  206. n_ret = platform_driver_register(&dhole2440_keys_device_driver);
  207. printk("dhole2440_keys_init 1 n_ret=%d jiffies=%lu,HZ=%d\n", n_ret, jiffies, HZ);
  208. if( n_ret )
  209. return n_ret;
  210. n_ret = platform_device_register(&dhole2440_device_kbd);
  211. printk("dhole2440_keys_init 2 n_ret=%d\n", n_ret);
  212. if( n_ret )
  213. goto fail;
  214. return n_ret;
  215. fail:
  216. platform_driver_unregister(&dhole2440_keys_device_driver);
  217. return n_ret;
  218. }
  219. static void __exit dhole2440_keys_exit(void)
  220. {
  221. printk("dhole2440_keys_exit\n");
  222. platform_device_unregister(&dhole2440_device_kbd);
  223. platform_driver_unregister(&dhole2440_keys_device_driver);
  224. }
  225. module_init(dhole2440_keys_init);
  226. module_exit(dhole2440_keys_exit);
  227. MODULE_DESCRIPTION("dhole2440 keyboard input events driver");
  228. MODULE_AUTHOR("liuzhiping <lyliuzhiping@yeah.net style="word-wrap: break-word;">");
  229. MODULE_LICENSE("GPL");
  230. MODULE_ALIAS("platform:dhole2440 keyboard driver");
 

<wiz_tmp_tag id="wiz-table-range-border" contenteditable="false" style="display: none;">

 
 
 
 

Linux 输入子系统驱动程序范例的更多相关文章

  1. linux输入子系统(input subsystem)之evdev.c事件处理过程

    1.代码 input_subsys.drv.c 在linux输入子系统(input subsystem)之按键输入和LED控制的基础上有小改动,input_subsys_test.c不变. input ...

  2. Linux输入子系统详解

    input输入子系统框架  linux输入子系统(linux input subsystem)从上到下由三层实现,分别为:输入子系统事件处理层(EventHandler).输入子系统核心层(Input ...

  3. linux输入子系统

    linux输入子系统(linux input subsystem)从上到下由三层实现,分别为:输入子系统事件处理层(EventHandler).输入子系统核心层(InputCore)和输入子系统设备驱 ...

  4. linux输入子系统概念介绍

    在此文章之前,我们讲解的都是简单的字符驱动,涉及的内容有字符驱动的框架.自动创建设备节点.linux中断.poll机制.异步通知.同步互斥.非阻塞.定时器去抖动. 上一节文章链接:http://blo ...

  5. 7.Linux 输入子系统分析

    为什么要引入输入子系统? 在前面我们写了一些简单的字符设备的驱动程序,我们是怎么样打开一个设备并操作的呢? 一般都是在执行应用程序时,open一个特定的设备文件,如:/dev/buttons .... ...

  6. Linux输入子系统(转)

    Linux输入子系统(Input Subsystem) 1.1.input子系统概述 输入设备(如按键,键盘,触摸屏,鼠标等)是典型的字符设备,其一般的工作机制是低层在按键,触摸等动作发生时产生一个中 ...

  7. Linux输入子系统(Input Subsystem)

    Linux输入子系统(Input Subsystem) http://blog.csdn.net/lbmygf/article/details/7360084 input子系统分析  http://b ...

  8. Linux输入子系统框架分析(1)

    在Linux下的输入设备键盘.触摸屏.鼠标等都能够用输入子系统来实现驱动.输入子系统分为三层,核心层和设备驱动层.事件层.核心层和事件层由Linux输入子系统本身实现,设备驱动层由我们实现.我们在设备 ...

  9. linux输入子系统简述【转】

    本文转载自:http://blog.csdn.net/xubin341719/article/details/7678035 1,linux输入子系统简述 其实驱动这部分大多还是转载别人的,linux ...

随机推荐

  1. 集群下Dubbo负载均衡配置

    在集群负载均衡时,Dubbo提供了4种均衡策略,默认为Random(随机调用) 负载均衡策略: 1).Random LoadBalance(随机,按照权重的设置随机概率) 2).RoundRobin  ...

  2. 一文看懂汽车电子ECU bootloader工作原理及开发要点

    随着半导体技术的不断进步(按照摩尔定律),MCU内部集成的逻辑功能外设越来越多,存储器也越来越大.消费者对于汽车节能(经济和法规对排放的要求)型.舒适性.互联性.安全性(功能安全和信息安全)的要求越来 ...

  3. [转]RJ45接口说明

    [转]http://blog.csdn.net/dog0138/article/details/7016351 1.前言 常见的RJ45接口有两类: 用于以太网网卡.路由器以太网接口等的DTE类型,可 ...

  4. 所有Windows7下游戏的全屏问题

    Win键+R键,打开运行窗口,输入regedit 回车,这样就打开了注册表编辑器,然后,定位到以下位置:HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\ ...

  5. mysql系列十一、mysql优化笔记:表设计、sql优化、配置优化

    可以从这些方面进行优化: 数据库(表)设计合理 SQL语句优化 数据库配置优化 系统层.硬件层优化 数据库设计 关系数据库三范式 1NF:字段不可分; 2NF:有主键,非主键字段依赖主键; 3NF:非 ...

  6. HTML学习笔记03-HTML基础

    <!DOCTYPE HTML> <html> <head> <title> </title> </head> <body& ...

  7. Vue.js——理解与创建使用

    Vue.js 概念:是一个轻巧.高性能.可组件化的MVVM库,同时拥有非常容易上手的API,作者是尤雨溪是中国人. 优点: 1)易用 已经会了HTML,CSS,JavaScript?即刻阅读指南开始构 ...

  8. route 的标志位

    linux下利用route命令查看当前路由信息时,会打印如下信息: root@root:/# route Kernel IP routing tableDestination     Gateway  ...

  9. 一张纸,折多少次和珠穆拉峰一样高(for if 和break)

  10. Windows Server 2003 R2标准版 SP2 64位 (简体中文)官方原版ISO镜像

    Windows Server 2003 R2标准版 SP2 64位 (简体中文)官方原版ISO镜像迅雷下载   软件简介 Windows Server 2003 R2标准版是继Windows Serv ...