<按键驱动程序>
#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. Python模块学习 - fnmatch & glob

    介绍 fnmatch 和 glob 模块都是用来做字符串匹配文件名的标准库. fnmatch模块 大部分情况下使用字符串匹配查找特定的文件就能满足需求,如果需要更加灵活的字符串匹配,就没有办法了,这里 ...

  2. 【vim】把当前文件转化为网页

    这会生成一个 HTML 文件来显示文本,并在分开的窗口显示源代码: :%TOhtml (译者注:原文是 :%Tohtml,但在我的电脑上是 :%TOhtml) 转载自:https://linux.cn ...

  3. Delphi中的动态包,有详细建立包的步骤(答案很简单:因为包的功能强大)

    为什么要使用包? 答案很简单:因为包的功能强大.设计期包(design-time package)简化了自定义组件的发布和安装:而运行期包(run-time package)则更是给传统的程序设计注入 ...

  4. Ajax jsonp 跨域请求实例

    跨域请求 JSONP的缺点则是:它只支持GET请求而不支持POST等其它类型的HTTP请求:它只支持跨域HTTP请求这种情况,不能解决不同域的两个页面之间如何进行JavaScript调用的问题. $. ...

  5. grep基础用法

    功能:全面搜索正则表达式并把行打印出来,是一种强大的文本搜索工具. grep  yuan  filename :在文件中搜索yuan 这个字符串,并把含有此字符串的行打印出来,也可以多文件搜索.  g ...

  6. 故障 -> nginx启动失败

    描述:在用saltstack给 minion 安装 nginx 服务 时 提示 nginx 服务下载成功,但是启动失败. ---------- ID: nginx-systemctl Function ...

  7. windows系统实现mysql数据库数据库主从复制

    环境: master mysql服务器 192.168.8.201 slave mysql服务器 192.168.8.89 目标: 实现主从复制 1.将MySQL5.5安装文件分别拷贝到两台机器的c盘 ...

  8. sqlserver数据库系统性能监控步骤

    1.部署好环境JDK+tomcat+数据库 ①修改数据库连接账号密码db.properties ②修改applicationContext.xml文件,开启任务 <bean id="o ...

  9. SPI、IIC、IIS、UART、CAN、SDIO、GPIO、USB总线协议

    SPI.IIC.IIS.UART.CAN.SDIO.GPIO总线协议 SPI(Serial Peripheral Interface:串行外设接口)SPI总线由三条信号线组成:串行时钟(SCLK).串 ...

  10. 作业8_exer1128.txt

    1.规范化理论是关系数据库进行逻辑设计的理论依据,根据这个理论,关系数据库中的关系必须满足:每 一个属性都是(B). A.长度不变的 B.不可分解的 C.互相关联的 D.互不相关的 2.已知关系模式R ...