鼠标作为按键输入之完整程序
1 /*参考/drivers/hid/usbhid/usbmouse.c*/ 2 3 #include <linux/kernel.h> 4 #include <linux/slab.h> 5 #include <linux/module.h> 6 #include <linux/init.h> 7 #include <linux/usb/input.h> 8 #include <linux/hid.h> 9 10 static struct urb *mouse_urb; 11 static int len; 12 static char *buf; 13 static dma_addr_t mouse_dma; 14 15 static struct input_dev *mouse_dev; 16 static struct timer_list mouse_timer; 17 18 static const struct usb_device_id mouse_table[] = { 19 { USB_INTERFACE_INFO(USB_INTERFACE_CLASS_HID, USB_INTERFACE_SUBCLASS_BOOT, 20 USB_INTERFACE_PROTOCOL_MOUSE) }, /* mouse */ 21 { }/* Terminating entry */ 22 }; 23 24 MODULE_DEVICE_TABLE (usb, mouse_table); 25 26 static void usb_mouse_irq(struct urb *urb) 27 { 28 mod_timer(&mouse_timer,jiffies + HZ/100); 29 } 30 31 static void mouse_time_function(unsigned long data) 32 { 33 static char pre_val; 34 35 if((pre_val & (1<<0)) != (buf[0] & (1<<0))){ 36 input_event(mouse_dev,EV_KEY,KEY_L,buf[0] & (1<<0) ? 1 : 0); 37 input_sync(mouse_dev); 38 } 39 if((pre_val & (1<<1)) != (buf[0] & (1<<1))){ 40 input_event(mouse_dev,EV_KEY,KEY_S,buf[0] & (1<<1) ? 1 : 0); 41 input_sync(mouse_dev); 42 } 43 if((pre_val & (1<<2)) != (buf[0] & (1<<2))){ 44 input_event(mouse_dev,EV_KEY,KEY_ENTER,buf[0] & (1<<2) ? 1 : 0); 45 input_sync(mouse_dev); 46 } 47 48 pre_val = buf[0]; 49 usb_submit_urb(mouse_urb, GFP_KERNEL); 50 } 51 52 static int mouse_probe(struct usb_interface *intf, 53 const struct usb_device_id *id) 54 { 55 int pipe; 56 int res; 57 struct usb_device *mdev = interface_to_usbdev(intf); //设备 58 struct usb_endpoint_descriptor *endpoint; 59 struct usb_host_interface *interface; 60 61 mouse_dev = input_allocate_device(); 62 /*设置事件*/ 63 set_bit(EV_KEY,mouse_dev->evbit); 64 set_bit(EV_REP,mouse_dev->evbit); 65 66 set_bit(KEY_L,mouse_dev->keybit); 67 set_bit(KEY_S,mouse_dev->keybit); 68 set_bit(KEY_ENTER,mouse_dev->keybit); 69 70 res = input_register_device(mouse_dev); 71 if(res){ 72 printk("input_register_device failed!\n"); 73 return -1; 74 } 75 /*时间函数*/ 76 77 init_timer(&mouse_timer); 78 mouse_timer.function = mouse_time_function; 79 add_timer(&mouse_timer); 80 81 interface = intf->cur_altsetting; //接口 82 if (interface->desc.bNumEndpoints != 1) 83 return -ENODEV; 84 85 endpoint = &interface->endpoint[0].desc; //端点 86 if (!usb_endpoint_is_int_in(endpoint)) 87 return -ENODEV; 88 89 len = endpoint->wMaxPacketSize; //长度(多少字节) 90 91 buf = usb_alloc_coherent(mdev, len, GFP_ATOMIC, &mouse_dma); //传输buffer,目的 92 93 pipe=usb_rcvintpipe(mdev,endpoint->bEndpointAddress); //源 94 95 mouse_urb = usb_alloc_urb(0, GFP_KERNEL); 96 97 usb_fill_int_urb(mouse_urb,mdev,pipe,buf,len,usb_mouse_irq, NULL, endpoint->bInterval); //初始化中断型urb结构体 98 mouse_urb->transfer_dma = mouse_dma; 99 mouse_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; 100 101 usb_submit_urb(mouse_urb, GFP_KERNEL); 102 103 return 0; 104 } 105 106 static void mouse_disconnect(struct usb_interface *intf) 107 { 108 struct usb_device *mdev = interface_to_usbdev(intf); //设备 109 usb_kill_urb(mouse_urb); 110 usb_free_urb(mouse_urb); 111 usb_free_coherent(mdev, len, buf, mouse_dma); 112 del_timer(&mouse_timer); 113 input_unregister_device(mouse_dev); 114 input_free_device(mouse_dev); 115 116 } 117 118 static struct usb_driver usb_driver = { 119 .name = "mouse", 120 .probe = mouse_probe, 121 .disconnect = mouse_disconnect, 122 .id_table = mouse_table, 123 }; 124 125 static int usb_drv_init(void) 126 { 127 usb_register(&usb_driver); 128 return 0; 129 } 130 131 static void usb_drv_exit(void) 132 { 133 usb_deregister(&usb_driver); 134 } 135 136 module_init(usb_drv_init); 137 module_exit(usb_drv_exit); 138 //module_usb_driver(usb_driver); 139 140 MODULE_LICENSE("GPL"); 141 MODULE_AUTHOR("1653699780@qq.com");