Input 设备驱动 ---操作硬件获取硬件寄存器中设备输入的数据,并把数据交给核心层;

 

一 、设备驱动的注册步骤:

1、分配一个struct  input_dev :

         struct      input_dev  *input_dev

2、 初始化 input_dev 这个结构体 :

3、 注册这个input_dev 设备:

Input_register_device(dev);

4、 在input设备发生输入操作时,提交所发生的事件及键值、坐标等信息:

Input_report_abs()///报告X,y的坐标值

Input_report_key()///报告触摸屏的状态,是否被按下

Input_sync () ///表示提交一个完整的报告,这样linux内核就知道哪几个数据组合起来代表一个事件

 

二、Linux 中输入事件的类型:

EV_SYN  0X00  同步事件

EV_KEY  0X01  按键事件

EV_REL  0X02  相对坐标

EV_ABS  0X03  绝对坐标

....

 

三、关键程序片段(以USB鼠标为例:drivers\hid\usbhid\usbmouse.c

 

1、 module_usb_driver(usb_mouse_driver);///系统启动时注册usb_mouse_driver (在usb架构中实现)

2、 usb_mouse_probe (设备初始化,usbmouse 属于usb设备,匹配成功后注册input设备)

3、 input_register_device(mouse->dev); 注册设备驱动

4、 input_attach_handler(dev, handler);///遍历所有的input_handler,并与 dev 进行匹配

usbmouse除了可以和evdev_handler 匹配成功,还和mousedev_handler 匹配成功,所以会分别调用evdev_handler的connect 函数创建event 节点和 mousedev_handler 的connect创建mouse节点

5、 input_match_device(handler, dev);///---->handler 和 device 进行真正的匹配(通过id_table 进行匹配)

6、 handler->connect(handler, dev, id);///匹配成功调用handler的connect 函数

7、 evdev_connect()///将创建 event(0、1、2…)节点

8、 mousedev_connect()///将创建 mouse(0、1、2…)节点

9、 mousedev_create()

10、cdev_init(&mousedev->cdev, &mousedev_fops);

11、usb_mouse_irq()///最终的数据在中断里面获取到,并保存到mouse –>data 里面

12input_report_key\ input_report_rel\ input_sync ///报告按键信息

13、input_event

14、input_handle_event(dev, type, code, value)

15、input_pass_values(dev, dev->vals, dev->num_vals);

16 、input_to_handler(handle, vals, count);

17、handler->event(handle, v->type, v->code, v->value);

 

 

                       Linux input子系统学习总结(三)----Input设备驱动

 

 

1 static struct usb_driver usb_mouse_driver = {
2     .name        = "usbmouse",
3     .probe        = usb_mouse_probe,///当有新的usbmouse加入时,系统会进行匹配,匹配成功后则调用probe函数,完成设备的初始化
4     .disconnect    = usb_mouse_disconnect,
5     .id_table    = usb_mouse_id_table,
6 };
7 
8 module_usb_driver(usb_mouse_driver);///系统启动时注册usb_mouse_driver

 

 

 1 static int usb_mouse_probe(struct usb_interface *intf, const struct usb_device_id *id)
 2 {
 3     struct usb_device *dev = interface_to_usbdev(intf);
 4     struct usb_host_interface *interface;
 5     struct usb_endpoint_descriptor *endpoint;
 6     struct usb_mouse *mouse;
 7     struct input_dev *input_dev;
 8     int pipe, maxp;
 9     int error = -ENOMEM;
10 
11     interface = intf->cur_altsetting;
12 
13     if (interface->desc.bNumEndpoints != 1)
14         return -ENODEV;
15 
16     endpoint = &interface->endpoint[0].desc;
17     if (!usb_endpoint_is_int_in(endpoint))
18         return -ENODEV;
19 
20     pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
21     maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
22 
23     mouse = kzalloc(sizeof(struct usb_mouse), GFP_KERNEL);
24     input_dev = input_allocate_device();
25     if (!mouse || !input_dev)
26         goto fail1;
27 
28     mouse->data = usb_alloc_coherent(dev, 8, GFP_ATOMIC, &mouse->data_dma);
29     if (!mouse->data)
30         goto fail1;
31 
32     mouse->irq = usb_alloc_urb(0, GFP_KERNEL);
33     if (!mouse->irq)
34         goto fail2;
35 
36     mouse->usbdev = dev;
37     mouse->dev = input_dev;
38 
39     if (dev->manufacturer)
40         strlcpy(mouse->name, dev->manufacturer, sizeof(mouse->name));
41 
42     if (dev->product) {
43         if (dev->manufacturer)
44             strlcat(mouse->name, " ", sizeof(mouse->name));
45         strlcat(mouse->name, dev->product, sizeof(mouse->name));
46     }
47 
48     if (!strlen(mouse->name))
49         snprintf(mouse->name, sizeof(mouse->name),
50              "USB HIDBP Mouse %04x:%04x",
51              le16_to_cpu(dev->descriptor.idVendor),
52              le16_to_cpu(dev->descriptor.idProduct));
53 
54     usb_make_path(dev, mouse->phys, sizeof(mouse->phys));
55     strlcat(mouse->phys, "/input0", sizeof(mouse->phys));
56 
57     input_dev->name = mouse->name;
58     input_dev->phys = mouse->phys;
59     usb_to_input_id(dev, &input_dev->id);
60     input_dev->dev.parent = &intf->dev;
61 
62     ////evbit 关于设备支持事件类型的 bitmap 
63     input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); ///BIT_MASK 找到参数值所在的 bit位
64     input_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) | ///鼠标支持左键、右键、中键三个按键
65         BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE);
66     input_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y); ///REL_X REL_Y 表示鼠标的位置信息
67     input_dev->keybit[BIT_WORD(BTN_MOUSE)] |= BIT_MASK(BTN_SIDE) | ///在已有按键的基础上加上一个边键和一个而外的键
68         BIT_MASK(BTN_EXTRA);
69     input_dev->relbit[0] |= BIT_MASK(REL_WHEEL);///给相对事件加上滚轮的事件
70 
71     input_set_drvdata(input_dev, mouse);
72 
73     input_dev->open = usb_mouse_open;
74     input_dev->close = usb_mouse_close;
75 
76     usb_fill_int_urb(mouse->irq, dev, pipe, mouse->data,
77              (maxp > 8 ? 8 : maxp),
78              usb_mouse_irq, mouse, endpoint->bInterval);
79     mouse->irq->transfer_dma = mouse->data_dma;
80     mouse->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
81 
82     error = input_register_device(mouse->dev);
83     if (error)
84         goto fail3;
85 
86     usb_set_intfdata(intf, mouse);
87     return 0;
88 
89 fail3:    
90     usb_free_urb(mouse->irq);
91 fail2:    
92     usb_free_coherent(dev, 8, mouse->data, mouse->data_dma);
93 fail1:    
94     input_free_device(input_dev);
95     kfree(mouse);
96     return error;
97 }
View Code

相关文章: