linux驱动子系统之输入子系统(3)

时间:2021-10-19 23:35:03

linux驱动子系统之输入子系统(3)

3.设备驱动层

3.1 概述

负责与底层输入设备通信,实现具体硬件设备驱动,获取硬件产生的事件信息报给上层。本层是要我们实现的,内核也提供了很多设备驱动。

 

3.2 数据结构和函数

l  input_dev,子系统中用此结构体来描述一个输入设备

struct input_dev{

         /* 导出到用户空间的相关信息,在sys文件可以看到*/

         const char *name;

         const char *phys;

         const char *uniq;

         struct input_id id;       

 

         unsigned longevbit[BITS_TO_LONGS(EV_CNT)];  /*输入设备的事件支持位图*/

         unsigned longkeybit[BITS_TO_LONGS(KEY_CNT)];/*按键设备支持的事件代码位图*/

 

         int (*open)(struct input_dev *dev);

         void (*close)(struct input_dev *dev);

         int (*flush)(struct input_dev *dev,struct file *file);

         int (*event)(struct input_dev *dev,unsigned int type, unsigned int code, int value);

 

         struct device dev;   /* 应用于设备驱动模型 */

 

         struct list_head        h_list;  /* 与输入设备相关的输入处理列表 */

         struct list_head        node;  /* 用于把input_dev链接到全局的Input_dev_list链表 */

         ……

}

 

l  注册函数,将输入设备注册到核心层中,注册前需要输入设备需要调用input_allocate_device来分配,然后设置设备处理能力

intinput_register_device(struct input_dev *dev)

{

error = device_add(&dev->dev);   /* 注册一个设备,设备驱动模型思想 */

 

list_add_tail(&dev->node,&input_dev_list);

 

list_for_each_entry(handler,&input_handler_list, node)

         input_attach_handler(dev,handler);

 

}

1.List_add_tail函数把输入设备添加到全局变量Input_dev_list中;

2.List_for_each_entry函数遍历Input_handler_list(全局链表,连接所有的input_handler)上的handler,并调用Input_attach_handler来进行输入设备和处理方法的关联。

 

l  Input_match_handler函数,主要由input_match_device和handler->connect函数来实现

static intinput_attach_handler(struct input_dev *dev, struct input_handler *handler)

{

         id = input_match_device(handler, dev);

         if (!id)

                   return -ENODEV;

 

         error = handler->connect(handler,dev, id);

        

}

Input_match_device(依照事件处理层实现Input_device_id信息来匹配)匹配成功后,会调用到事件处理层实现handler->connect的函数来完成注册handle和创建处理层设备(evdev, mousedev, keybdev and so on)相应工作。