<按键驱动程序>
#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. Java 集合和映射表

    集合 可以使用集合的三个具体类HashSet.LinkedHashSet.TreeSet来创建集合 HashSet类 负载系数 当元素个数超过了容量与负载系数的乘积,容量就会自动翻倍 HashSet类 ...

  2. Maven整合Spring3.0+Mybatis3.2+Struts2.3+查找坐标+jar包依赖(五)

    依赖传递 只添加了一个struts2-core依赖,发现项目中出现了很多jar,这种情况 叫 依赖传递

  3. ubuntu下安装搜狗输入法以及出现不能输入中文的解决办法

    1. 官网下载安装包 http://pinyin.sogou.com/linux/?r=pinyin 下载你需要的版本,这里选择64位版. 2. 进入软件中心安装 3. 修改ibus为fcitx im ...

  4. Python爬虫-爬取百度贴吧帖子

    这次主要学习了替换各种标签,规范格式的方法.依然参考博主崔庆才的博客. 1.获取url 某一帖子:https://tieba.baidu.com/p/3138733512?see_lz=1&p ...

  5. Linux inotify功能及实现原理【转】

    转自:http://blog.csdn.net/myarrow/article/details/7096460 1. inotify主要功能 它是一个内核用于通知用户空间程序文件系统变化的机制. 众所 ...

  6. 使用RMS API 自定义Office(Word、Excel、PPT)加密策略

    什么是RMS: Microsoft Windows Rights Management 服务 (RMS),是一种与应用程序协作来保护数字内容(不论其何去何从)的安全技术,专为那些需要保护敏感的 Web ...

  7. mysql语句判断是否存在记录,没有则插入新纪录否则不执行

    1 前言 由于项目需要,当某个表如果有记录,就不执行加入语句,否则加入新纪录(测试数据).思路是:判断表的记录是否为空,然后再决定是否插入 2 代码 DROP PROCEDURE IF EXISTS ...

  8. Java编码与乱码问题

    一.为什么要编码? 由于人类的语言太多,因而表示这些语言的符号太多,无法用计算机的一个基本的存储单元----byte来表示,因而必须要经过拆分或一些翻译工作,才能让计算机能理解. byte一个字节即8 ...

  9. raindi python魔法函数(一)之__repr__与__str__

    __repr__和__str__都是python中的特殊方法,都是用来输出实例对象的,如果没有定义这两个方法在打印的时候只会输出实例所在的内存地址 这种方式的输出没有可读性,并不能直观的体现实例.py ...

  10. JS中sort()方法原理及使用

    说明 如果调用该方法时没有使用参数,将按字母顺序对数组中的元素进行排序,说得更精确点,是按照字符编码的顺序进行排序.要实现这一点,首先应把数组的元素都转换成字符串(如有必要),以便进行比较. arra ...