[Linux]usb驱动程序
[Linux]usb驱动程序
艾恩凝
2021/7/1
usb framework
code
1
2#include <linux/kernel.h>
3#include <linux/slab.h>
4#include <linux/module.h>
5#include <linux/init.h>
6#include <linux/usb/input.h>
7#include <linux/hid.h>
8
9static struct input_dev *uk_dev;
10static char *usb_buf;
11static dma_addr_t usb_buf_phys;
12static int len;
13static struct urb *uk_urb;
14
15
16static struct usb_device_id usb_mouse_as_key_id_table [] = {
17 { USB_INTERFACE_INFO(USB_INTERFACE_CLASS_HID, USB_INTERFACE_SUBCLASS_BOOT,
18 USB_INTERFACE_PROTOCOL_MOUSE) },
19 //{USB_DEVICE(0x1234,0x5678)},
20 { } /* Terminating entry */
21};
22static void usb_mouse_as_key_irq(struct urb *urb)
23{
24 static unsigned char pre_val;
25
26#if 0
27 int i;
28 static int cnt = 0;
29 printk("data cnt %d: ", ++cnt);
30 for (i = 0; i < len; i++)
31 {
32 printk("%02x ", usb_buf[i]);
33 }
34 printk("\n");
35#endif
36 /* USB鼠标数据含义
37 * data[0]: bit0-左键, 1-按下, 0-松开
38 * bit1-右键, 1-按下, 0-松开
39 * bit2-中键, 1-按下, 0-松开
40 *
41 */
42 if ((pre_val & (1<<0)) != (usb_buf[0] & (1<<0)))
43 {
44 /* 左键发生了变化 */
45 input_event(uk_dev, EV_KEY, KEY_L, (usb_buf[0] & (1<<0)) ? 1 : 0);
46 input_sync(uk_dev);
47 }
48
49 if ((pre_val & (1<<1)) != (usb_buf[0] & (1<<1)))
50 {
51 /* 右键发生了变化 */
52 input_event(uk_dev, EV_KEY, KEY_S, (usb_buf[0] & (1<<1)) ? 1 : 0);
53 input_sync(uk_dev);
54 }
55
56 if ((pre_val & (1<<2)) != (usb_buf[0] & (1<<2)))
57 {
58 /* 中键发生了变化 */
59 input_event(uk_dev, EV_KEY, KEY_ENTER, (usb_buf[0] & (1<<2)) ? 1 : 0);
60 input_sync(uk_dev);
61 }
62
63 pre_val = usb_buf[0];
64
65 /* 重新提交urb */
66 usb_submit_urb(uk_urb, GFP_KERNEL);
67
68
69}
70static int usb_mouse_as_key_probe(struct usb_interface *intf, const struct usb_device_id *id)
71{
72 //printk("found usb_mouse!!!\n");
73 struct usb_device *dev = interface_to_usbdev(intf);
74 struct usb_host_interface *interface;
75 struct usb_endpoint_descriptor *endpoint;
76 int pipe;
77
78
79 /* a. 分配一个input_dev */
80 uk_dev = input_allocate_device();
81
82 /* b. 设置 */
83 /* b.1 能产生哪类事件 */
84 set_bit(EV_KEY, uk_dev->evbit);
85 set_bit(EV_REP, uk_dev->evbit);
86
87 /* b.2 能产生哪些事件 */
88 set_bit(KEY_L, uk_dev->keybit);
89 set_bit(KEY_S, uk_dev->keybit);
90 set_bit(KEY_ENTER, uk_dev->keybit);
91
92
93 /* c. 注册 */
94 input_register_device(uk_dev);
95
96 /* d. 硬件相关操作 */
97 /* 数据传输3要素: 源,目的,长度 */
98 /* 源: USB设备的某个端点 */
99 pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
100 /* 长度: */
101 len = endpoint->wMaxPacketSize;
102 /* 目的: */
103 usb_buf = usb_buffer_alloc(dev, len, GFP_ATOMIC, &usb_buf_phys);
104
105 /* 使用"3要素" */
106 /* 分配usb request block */
107 uk_urb = usb_alloc_urb(0, GFP_KERNEL);
108 /* 使用"3要素设置urb" */
109 usb_fill_int_urb(uk_urb, dev, pipe, usb_buf, len, usb_mouse_as_key_irq, NULL, endpoint->bInterval);
110 uk_urb->transfer_dma = usb_buf_phys;
111 uk_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
112
113 /* 使用URB */
114 usb_submit_urb(uk_urb, GFP_KERNEL);
115
116
117
118
119}
120static void usb_mouse_as_key_disconnect(struct usb_interface *intf)
121{
122 struct usb_device *dev = interface_to_usbdev(intf);
123
124 //printk("disconnect usbmouse!\n");
125 usb_kill_urb(uk_urb);
126 usb_free_urb(uk_urb);
127
128 usb_buffer_free(dev, len, usb_buf, usb_buf_phys);
129 input_unregister_device(uk_dev);
130 input_free_device(uk_dev);
131}
132
133/* setting usb driver*/
134static struct usb_driver usb_mouse_as_key_driver = {
135 .name = "usb_mouse_as_key_",
136 .probe = usb_mouse_as_key_probe,
137 .disconnect = usb_mouse_as_key_disconnect,
138 .id_table = usb_mouse_as_key_id_table,
139};
140
141static int usb_mouse_as_key_init(void){
142 usb_register(&usb_mouse_as_key_driver);
143 return 0;
144}
145
146static void usb_mouse_as_key_exit(void){
147 usb_deregister(&usb_mouse_as_key_driver);
148}
149
150
151module_init(usb_mouse_as_key_init);
152module_exit(usb_mouse_as_key_exit);
153MODULE_AUTHOR("https://aeneag.xyz");
154MODULE_VERSION("0.1");
155MODULE_DESCRIPTION("S3C2440 Mouse Driver");
156MODULE_LICENSE("GPL");
end
总的来说就是了解学习usb相关的驱动基本概念,多注重注重理解,这个程序是用了鼠标模拟按键通过usb设备来实现。
艾恩凝
写于大连
2021/7/1
catalogue
[Linux]驱动系列目录
吾心信其可行,
则移山填海之难,
终有成功之日!
——孙文
则移山填海之难,
终有成功之日!
——孙文
评论
0 评论