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)相应工作。