Linux输入子系统

  1. Linux输入子系统  
  2.   
  3. 按键与触摸屏的设备驱动,在Linux系统中实现这类设备驱动的方法是利用input子系统。  
  4.   
  5. Linux系统提供了input子系统,按键、触摸屏、键盘、鼠标等输入都可以利用input接口函数来实现设备驱动,按键和触摸屏设备驱动都可以作为input设备驱动而实现。  
  6.   
  7. 在Linux内核中,input设备用input_dev结构体描述,使用input子系统实现输入设备驱动的时候,驱动的核心工作是向系统报告按键、触摸屏、键盘、鼠标等输入事件(event,通过input_event结构体描述),不再需要关心文件操作接口,因为input子系统已经完成了文件操作接口。驱动报告的事件经过InputCore和 Eventhandler最终到达用户空间。  
  8.   
  9. 输入子系统支持的事件类型在文件  
  10. kernel/include/linux/input.h 中定义:  
  11.   
  12.  event 还定义了标准按键的编码等  
  13.   
  14.   
  15.    
  16.   
  17.    
  18.   
  19. 通过input子系统,具体的输入设备驱动只需要完成如下工作。  
  20.   
  21. l 在模块加载函数中告知input子系统它可以报告的事件。  
  22.   
  23. 设备驱动通过set_bit()告诉input子系统它支持哪些事件,如下所示:  
  24.   
  25. set_bit(EV_KEY, button_dev.evbit);  
  26.   
  27. l 在模块加载函数中注册输入设备。  
  28.   
  29. 注册输入设备的函数为:  
  30.   
  31. int input_register_device(struct input_dev *dev);  
  32.   
  33. l 在键被按下/抬起、触摸屏被触摸/抬起/移动、鼠标被移动/单击/抬起时通过input_ report_xxx()报告发生的事件及对应的键值/坐标等状态。  
  34.   
  35. 主要的事件类型包括EV_KEY(按键事件)、EV_REL(相对值,如光标移动,报告的是相对最后一次位置的偏移)和EV_ABS(绝对值,如触摸屏和操纵杆,它们工作在绝对坐标系统)。  
  36.   
  37. 用于报告EV_KEY、EV_REL和EV_ABS事件的函数分别为:  
  38.   
  39. void input_report_key(struct input_dev *dev, unsigned int code, int value);  
  40.   
  41. void input_report_rel(struct input_dev *dev, unsigned int code, int value);  
  42.   
  43. void input_report_abs(struct input_dev *dev, unsigned int code, int value);  
  44.   
  45. input_sync()用于事件同步,它告知事件的接收者驱动已经发出了一个完整的报告。  
  46.   
  47. 例如,在触摸屏设备驱动中,一次坐标及按下状态的整个报告过程如下:  
  48.   
  49. input_report_abs(input_dev, ABS_X, x);  //X坐标   
  50.   
  51. input_report_abs(input_dev, ABS_Y, y);   //Y坐标   
  52.   
  53. input_report_abs(input_dev, ABS_PRESSURE, pres); //压力   
  54.   
  55. input_sync(input_dev);  //同步   
  56.   
  57. 在模块卸载函数中注销输入设备。注销输入设备的函数为:  
  58.   
  59. void input_unregister_device(struct input_dev *dev);  
  60.   
  61. 代码清单12.28给出了一个最简单的使用input接口实现按键设备驱动的范例,它在中断服务程序中向系统报告按键及同步事件。  
  62.   
  63. input设备驱动  
  64.   
  65. 1  /*在按键中断中报告事件*/  
  66.   
  67. 2  static void button_interrupt(int irq, void *dummy, struct pt_regs *fp)  
  68.   
  69. 3  {  
  70.   
  71. 4    input_report_key(&button_dev, BTN_1, inb(BUTTON_PORT) &1);  
  72.   
  73. 5    input_sync(&button_dev);  
  74.   
  75. 6  }  
  76.   
  77. 7   
  78.   
  79. 8  static int _ _init button_init(void)  
  80.   
  81. 9  {  
  82.   
  83. 10   /*申请中断*/  
  84.   
  85. 11   if (request_irq(BUTTON_IRQ, button_interrupt, 0, "button", NULL))  
  86.   
  87. 12   {  
  88.   
  89. 13     printk(KERN_ERR "button.c: Can't allocate irq %d/n", button_irq);  
  90.   
  91. 14     return  - EBUSY;  
  92.   
  93. 15   }  
  94.   
  95. 16  
  96.   
  97. 17   button_dev.evbit[0] = BIT(EV_KEY);    //支持EV_KEY事件   
  98.   
  99. 18   button_dev.keybit[LONG(BTN_0)] = BIT(BTN_0);  
  100.   
  101. 19  
  102.   
  103. 20   input_register_device(&button_dev);   //注册input设备   
  104.   
  105. 21 }  
  106.   
  107. 22  
  108.   
  109. 23 static void _ _exit button_exit(void)  
  110.   
  111. 24 {  
  112.   
  113. 25   input_unregister_device(&button_dev);   //注销input设备   
  114.   
  115. 26   free_irq(BUTTON_IRQ, button_interrupt); //释放中断   
  116.   
  117. 27 }  
  118.   
  119.    
  120.   
  121. 触摸屏的注册  
  122.   
  123.  ts->input_dev = input_allocate_device();  
  124.  ts->input_dev->name = "synaptics-rmi-touchscreen";  
  125.  set_bit(EV_SYN, ts->input_dev->evbit);  
  126.  set_bit(EV_KEY, ts->input_dev->evbit);  
  127.  set_bit(BTN_TOUCH, ts->input_dev->keybit);  
  128.  set_bit(BTN_2, ts->input_dev->keybit);  
  129.  set_bit(EV_ABS, ts->input_dev->evbit);  
  130.   
  131.  /* ts->input_dev->name = ts->keypad_info->name; */  
  132.  ret = input_register_device(ts->input_dev);  
  133.   
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值