您的位置:首页 > 其它

input_dev结构体分析

2013-03-30 09:34 106 查看
在输入子系统的设备驱动中,最重要的数据结构是struct input_dev,如下所示。需要完成的大部分工作都是围绕着它来的,它是驱动的主体。每个struct input_dev代表一个输入设备。 

 

/* include/linux/input.h */

struct input_dev {

 const char *name;//设备名

 const char *phys;

 const char *uniq;

 struct input_id id;//用于匹配事件处理层handler

 

 unsigned long evbit[BITS_TO_LONGS(EV_CNT)];//用于记录支持的事件类型的位图

 unsigned long keybit[BITS_TO_LONGS(KEY_CNT)];//记录支持的按键值的位图

 unsigned long relbit[BITS_TO_LONGS(REL_CNT)];//记录支持的相对坐标的位图

 unsigned long absbit[BITS_TO_LONGS(ABS_CNT)];//记录支持的绝对坐标的位图

 unsigned long mscbit[BITS_TO_LONGS(MSC_CNT)];

 unsigned long ledbit[BITS_TO_LONGS(LED_CNT)];//led

 unsigned long sndbit[BITS_TO_LONGS(SND_CNT)];//beep

 unsigned long ffbit[BITS_TO_LONGS(FF_CNT)];

 unsigned long swbit[BITS_TO_LONGS(SW_CNT)];

 

 unsigned int keycodemax;//支持的按键值的个数

 unsigned int keycodesize;//每个键值的字节数

 void *keycode;//存储按键值的数组首地址

 int (*setkeycode)(struct input_dev *dev,

     unsigned int scancode, unsigned int keycode);//修改键值的函数,可选

 int (*getkeycode)(struct input_dev *dev,

     unsigned int scancode, unsigned int *keycode);//获取扫描码的键值,可选

 

 struct ff_device *ff;

 

 unsigned int repeat_key;//最近一次按键值,用于连击

 struct timer_list timer;//自动连击计时器

 

 int sync;//最后一次同步后没有新的事件置1

 

 int abs[ABS_CNT];//当前各个坐标的值

 int rep[REP_MAX + 1];//自动连击的参数

 

 unsigned long key[BITS_TO_LONGS(KEY_CNT)];//反映当前按键状态的位图

 unsigned long led[BITS_TO_LONGS(LED_CNT)];//反映当前led状态的位图

 unsigned long snd[BITS_TO_LONGS(SND_CNT)];//反映当前beep状态的位图

 unsigned long sw[BITS_TO_LONGS(SW_CNT)];

 

   /*tp驱动代码里一般使用input_set_abs_params函数设置

     函数参数从右往左依次代表输入设备指针、坐标轴、最小值、最大值、分辨率、基准值。

      最后两个参数也可以填为0,代表设备非常精确并且总能精确的回到中心位置。*/

 int absmax[ABS_CNT];//记录各个坐标的最大值

 int absmin[ABS_CNT];//记录各个坐标的最小值

 int absfuzz[ABS_CNT];//记录各个坐标的分辨率

 int absflat[ABS_CNT];//记录各个坐标的基准值

 int absres[ABS_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 input_handle *grab;

 

 spinlock_t event_lock;

 struct mutex mutex;

 

 unsigned int users;

 bool going_away;

 

 struct device dev;

 

 struct list_head h_list;//handle链表

 struct list_head node;//input_dev链表

};

struct input_event是事件传送的载体,输入子系统的事件都是包装成struct input_event传给用户空间。各个成员如下所示:

/* include/linux/input.h */

struct input_event {

 struct timeval time;//时间戳

 __u16 type;//事件类型

 __u16 code;//事件代码

 __s32 value;//事件值,如坐标的偏移值

};

struct input_dev注册的时候需要跟匹配的hanlder建立连接,匹配的依据就是struct input_dev所包含的struct input_id。

/* include/linux/input.h */

struct input_id {

 __u16 bustype;//总线类型

 __u16 vendor;//生产商编号

 __u16 product;//产品编号

 __u16 version;//版本号

};

input_handler这个结构体是事件驱动的主体,每一种处理方式对应一个handler结构体。注册input_handler,其实就是将input_hangler加入到input_handler_list当中。使用input_register_handler注册。

/* include/linux/input.h */

struct input_handler {

    //私有数据指针

 void *private;

    //事件处理函数指针。设备驱动报告的事件最终由这个函数来处理

 void (*event)(struct input_handle *handle, unsigned int type, unsigned int code, int value);

 bool (*filter)(struct input_handle *handle, unsigned int type, unsigned int code, int value);

 bool (*match)(struct input_handler *handler, struct input_dev *dev);

    //连接handler和input_dev的函数指针

 int (*connect)(struct input_handler *handler, struct input_dev *dev, const struct input_device_id *id);

    //断开连接函数指针

 void (*disconnect)(struct input_handle *handle);

    //为给定的handle启动handler函数指针

 void (*start)(struct input_handle *handle);

 

    //文件操作结构体

 const struct file_operations *fops;

    //这个handler可以使用的32个次设备号的最小值

 int minor;

    //此handler的名字

 const char *name;

 

    //可以处理的input_device_ids列表

 const struct input_device_id *id_table;

    //需要被忽略的input_device_ids列表

        const struct input_device_id *blacklist;

 

    //用来连接handle的链表链表节点。每个与此handler相关的handle都放入此链表

 struct list_head h_list;

    //用来放入全局handler链表的节点

 struct list_head node;

};

input_handle这个结构体用来连接input_dev和input_handler。

/* include/linux/input.h */

struct input_handle {

 

 void *private;//私有数据指针

 

 int open;//记录本设备被打开的次数

 const char *name;//创建此handle的handler所赋予的名字

 

 struct input_dev *dev;//指向附着的input_dev

 struct input_handler *handler;//指向创建此handle的handler

 

 struct list_head d_node;//链表节点,用来加入附着的input_dev

 struct list_head h_node;//链表节点,用来加入附着的input_handler

};

input_dev和input_handler匹配过程中用到了input_device_id

/* include/linux/mod_devicetable.h */

struct input_device_id {

 

 kernel_ulong_t flags;//定义需要匹配input_id的哪些域

 

 __u16 bustype;//对应input_id的四个数据域

 __u16 vendor;

 __u16 product;

 __u16 version;

        //存储支持事件的位图,与input_dev中的同名数据成员功能一致

 kernel_ulong_t evbit[INPUT_DEVICE_ID_EV_MAX / BITS_PER_LONG + 1];

 kernel_ulong_t keybit[INPUT_DEVICE_ID_KEY_MAX / BITS_PER_LONG + 1];

 kernel_ulong_t relbit[INPUT_DEVICE_ID_REL_MAX / BITS_PER_LONG + 1];

 kernel_ulong_t absbit[INPUT_DEVICE_ID_ABS_MAX / BITS_PER_LONG + 1];

 kernel_ulong_t mscbit[INPUT_DEVICE_ID_MSC_MAX / BITS_PER_LONG + 1];

 kernel_ulong_t ledbit[INPUT_DEVICE_ID_LED_MAX / BITS_PER_LONG + 1];

 kernel_ulong_t sndbit[INPUT_DEVICE_ID_SND_MAX / BITS_PER_LONG + 1];

 kernel_ulong_t ffbit[INPUT_DEVICE_ID_FF_MAX / BITS_PER_LONG + 1];

 kernel_ulong_t swbit[INPUT_DEVICE_ID_SW_MAX / BITS_PER_LONG + 1];

 

 kernel_ulong_t driver_info;//指示结构体中是否含有驱动信息

};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: