Chinaunix首页 | 论坛 | 博客
  • 博客访问: 95225
  • 博文数量: 38
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 384
  • 用 户 组: 普通用户
  • 注册时间: 2014-04-06 16:52
文章分类

全部博文(38)

文章存档

2014年(38)

我的朋友

分类: 嵌入式

2014-05-12 17:27:03

目的:把usb鼠标当作按键使用,左键相当按键l,右键相当按键s,中键相当enter

代码如下

点击(此处)折叠或打开

  1. /*
  2.  * 参考drivers\hid\usbhid\usbmouse.c
  3.  */

  4. #include <linux/kernel.h>
  5. #include <linux/slab.h>
  6. #include <linux/module.h>
  7. #include <linux/init.h>
  8. #include <linux/usb/input.h>
  9. #include <linux/hid.h>

  10. static struct input_dev *uk_dev;
  11. static char *usb_buf;
  12. static dma_addr_t usb_buf_phys;
  13. static int len;
  14. static struct urb *uk_urb;

  15. static struct usb_device_id usbmouse_as_key_id_table [] = {
  16.     { USB_INTERFACE_INFO(USB_INTERFACE_CLASS_HID, USB_INTERFACE_SUBCLASS_BOOT,USB_INTERFACE_PROTOCOL_MOUSE) },
  17.     //只要USB设备的接口描述符里的类是HID,子类是BOOT,协议是MOUSE,那就支持该设备
  18.         
  19.     //{USB_DEVICE(0x1234,0x5678)},
  20.     //只支持某个厂家生产的某个产品,厂家编号0x1234,设备编号0x5678
  21.     
  22.     { }    /* Terminating entry */
  23. };

  24. static void usbmouse_as_key_irq(struct urb *urb)
  25. {
  26.     static unsigned char pre_val;

  27.     /* USB鼠标数据含义
  28.      * data[0]: bit0-左键, 1-按下, 0-松开
  29.      * bit1-右键, 1-按下, 0-松开
  30.      * bit2-中键, 1-按下, 0-松开
  31.      */
  32.     if ((pre_val & (1<<0)) != (usb_buf[0] & (1<<0)))
  33.     {
  34.         /* 左键发生了变化 */
  35.         input_event(uk_dev, EV_KEY, KEY_L, (usb_buf[0] & (1<<0)) ? 1 : 0);
  36.         input_sync(uk_dev);
  37.     }

  38.     if ((pre_val & (1<<1)) != (usb_buf[0] & (1<<1)))
  39.     {
  40.         /* 右键发生了变化 */
  41.         input_event(uk_dev, EV_KEY, KEY_S, (usb_buf[0] & (1<<1)) ? 1 : 0);
  42.         input_sync(uk_dev);
  43.     }

  44.     if ((pre_val & (1<<2)) != (usb_buf[0] & (1<<2)))
  45.     {
  46.         /* 中键发生了变化 */
  47.         input_event(uk_dev, EV_KEY, KEY_ENTER, (usb_buf[0] & (1<<2)) ? 1 : 0);
  48.         input_sync(uk_dev);
  49.     }
  50.     
  51.     pre_val = usb_buf[0];

  52.     /* 重新提交urb */
  53.     usb_submit_urb(uk_urb, GFP_KERNEL);
  54. }

  55. static int usbmouse_as_key_probe(struct usb_interface *intf, const struct usb_device_id *id)
  56. {    
  57.     struct usb_device *dev = interface_to_usbdev(intf);
  58.     struct usb_host_interface *interface;
  59.     struct usb_endpoint_descriptor *endpoint;
  60.     int pipe;
  61.     
  62.     printk("find usbmouse!\n");    

  63.     printk("bcdUSB = %x\n", dev->descriptor.bcdUSB);
  64.     printk("VID = 0x%x\n", dev->descriptor.idVendor);
  65.     printk("PID = 0x%x\n", dev->descriptor.idProduct);
  66.     
  67.     interface = intf->cur_altsetting;
  68.     endpoint = &interface->endpoint[0].desc;

  69.     /* a. 分配一个input_dev */
  70.     uk_dev = input_allocate_device();
  71.     
  72.     /* b. 设置 */
  73.     /* b.1 能产生哪类事件 */
  74.     set_bit(EV_KEY, uk_dev->evbit);//按键类事件
  75.     set_bit(EV_REP, uk_dev->evbit);//重复类事件
  76.     
  77.     /* b.2 能产生哪些事件 */
  78.     set_bit(KEY_L, uk_dev->keybit);//左键作为按键L
  79.     set_bit(KEY_S, uk_dev->keybit);//右键作为按键S
  80.     set_bit(KEY_ENTER, uk_dev->keybit);//中键作为按键ENTER
  81.     
  82.     /* c. 注册 */
  83.     if( input_register_device(uk_dev) )
  84.         return -EFAULT;
  85.     
  86.     /* d. 硬件相关操作 */
  87.     /* 数据传输3要素:,目的,长度 */
  88.     /*: USB设备的某个端点 */
  89.     pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);

  90.     /* 长度: */
  91.     len = endpoint->wMaxPacketSize;

  92.     /* 目的: */
  93.     usb_buf = usb_alloc_coherent(dev, len, GFP_ATOMIC, &usb_buf_phys);

  94.     /* 使用"3要素" */
  95.     /* 分配usb request block */
  96.     uk_urb = usb_alloc_urb(0, GFP_KERNEL);
  97.     /* 使用"3要素设置urb" */
  98.     usb_fill_int_urb(uk_urb, dev, pipe, usb_buf, len, usbmouse_as_key_irq, NULL, endpoint->bInterval);
  99.     uk_urb->transfer_dma = usb_buf_phys;
  100.     uk_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;

  101.     /* 使用URB */
  102.     usb_submit_urb(uk_urb, GFP_KERNEL);
  103.     
  104.     return 0;
  105. }

  106. static void usbmouse_as_key_disconnect(struct usb_interface *intf)
  107. {
  108.     printk("disconnect usbmouse!\n");
  109. }

  110. /* 1. 分配/设置usb_driver */
  111. static struct usb_driver usbmouse_as_key_driver = {
  112.     .name        = "usbmouse_as_key",
  113.     .probe        = usbmouse_as_key_probe,
  114.     .disconnect    = usbmouse_as_key_disconnect,
  115.     .id_table    = usbmouse_as_key_id_table,
  116. };


  117. static int usbmouse_as_key_init(void)
  118. {
  119.     /* 2. 注册 */
  120.     usb_register(&usbmouse_as_key_driver);
  121.     return 0;
  122. }

  123. static void usbmouse_as_key_exit(void)
  124. {
  125.     usb_deregister(&usbmouse_as_key_driver);    
  126. }

  127. module_init(usbmouse_as_key_init);
  128. module_exit(usbmouse_as_key_exit);

  129. MODULE_LICENSE("GPL");

阅读(1094) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~