input子系统三
参考资料:
正点原子Linux设备驱动
韦东山第二期
图来源于100ask:
一个设备链表,一个handler链表,左边是设备层,右侧是handler处理层,用来处理各种事件。handler处理层内核已经做好了。驱动一个Input设备只需要构造一个input_dev,核心层来注册input_dev和注册input_handler就可以了。核心层提供各种函数,如input_register_device来注册一个input_dev输入设备,构造好一个handler之后调用input_register_handler就可以了。
struct input_dev表示一个设备:
// include/linux/input.h struct input_dev { const char *name; const char *phys; const char *uniq; struct input_id id; unsigned long propbit[BITS_TO_LONGS(INPUT_PROP_CNT)]; unsigned long evbit[BITS_TO_LONGS(EV_CNT)]; // 支持哪类事件?ABS绝对位移事件,KEY按键类事件,REL相对位移事件 unsigned long keybit[BITS_TO_LONGS(KEY_CNT)]; // 支持按键类事件的话,支持哪些按键 unsigned long relbit[BITS_TO_LONGS(REL_CNT)]; // 支持相对位移事件的话,支持哪些 unsigned long absbit[BITS_TO_LONGS(ABS_CNT)]; // 支持绝对位移事件的话,支持哪些,例如x方向,y方向,压力方向 unsigned long mscbit[BITS_TO_LONGS(MSC_CNT)]; unsigned long ledbit[BITS_TO_LONGS(LED_CNT)]; unsigned long sndbit[BITS_TO_LONGS(SND_CNT)]; unsigned long ffbit[BITS_TO_LONGS(FF_CNT)]; unsigned long swbit[BITS_TO_LONGS(SW_CNT)]; struct list_head h_list; // input_handler链表,里面还有支持该设备的input_handler struct list_head node; // input_handle != input_handler
发配设置注册一个input_dev结构体,input_register_device注册,input_dev存入一个链表中,与右边的handler一一比较,如果右边handler可以支持,就会调用headler的connect来建立联系
input_dev有数据产生了,使用input_event函数发送数据,该函数有input_hande找到相应的input_handler
input_dev注册过程:
int input_register_device(struct input_dev *dev) // 注册一个input_dev { ... ... list_add_tail(&dev->node, &input_dev_list); // 放入核心层的input_dev_list list_for_each_entry(handler, &input_handler_list, node) // 对于input_handler_list一一匹配,匹配调用input_attch_handler input_attach_handler(dev, handler); // 调用handler->connect ... ... return 0; }
input_handler:
static const struct input_device_id evdev_ids[] = { { .driver_info = 1 }, /* Matches all devices */ { }, /* Terminating zero entry */ }; static struct input_handler evdev_handler = { .event = evdev_event, .events = evdev_events, .connect = evdev_connect, .disconnect = evdev_disconnect, .legacy_minors = true, .minor = EVDEV_MINOR_BASE, .name = "evdev", .id_table = evdev_ids, // 可以匹配所有的input_dev设备,与input_dev调用成功就会调用.connect函数 };