输入设备(按键、键盘、触摸屏、鼠标)是典型的字符设备,工作机理是底层在按键、触摸等动作发生时产生一个中断(或驱动timer定时查询),然后CPU通过SPI、I2C或外部存储器总线读取键值,坐标等数据。输入核心层提供了底层输入设备驱动程序所需的API,如分配/释放一个输入设备struct input_dev *input_allocate_device(void);void input_free_device(struct input_dev *dev);input_allocate_device()返回的是1个input_dev的结构体,此结构体用于表征1个输入设备注册/注销输入设备用的接口input_register_device(struct input_dev *);void input_unregister_device(struct input_dev *);报告输入事件的接口,指定type, code, valuevoid input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value);input通用数据结构1. input_dev是input设备基本的设备结构,每个input驱动程序必须分配初始化这样一个结构include/linux/input.hstruct input_dev {const char *name; //设备名称const char *phys;//设备在系统的物理路径const char *uniq;//统一的IDstruct input_id id;//设备IDunsigned 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)];//LEDunsigned long sndbit[BITS_TO_LONGS(SND_CNT)];//声音设备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;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)];unsigned long snd[BITS_TO_LONGS(SND_CNT)];unsigned long sw[BITS_TO_LONGS(SW_CNT)];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_headh_list;struct list_headnode;};2. input_event 驱动层向input子系统核心报告事件的函数。void input_event(struct input_dev *dev,unsigned int type, unsigned int code, int value); 不同设备内容的报告均是通过input_event函数来完成的,选择使用了不同参数而已@type:类型(EV_KEY键盘,EV_REL相对,EV_ABS绝对)@code:编码(事件代码,如键盘代码)@value:值(EV_KEY当按键按下时值为1,松开时值为0,如果事件为EV_REL,value的正数值和负数值分别代表两个不同的方向)键盘keyboard属于按键设备EV_KEY
轨迹属于相对设备EV_REL
触模屏属于绝对设备EV_ABS
3. 分配并初始化input_devinput_allocate_device()4. 向内核注册一个input设备input_register_device()5. input驱动流程1)定义input设备结构struct input_dev *input;2)分配并初始化input_dev接构input = input_allocate_device();input->name = "gpio-keys";input->phys = "gpio-keys/input0";input->id.bustype = BUS_HOST;input->id.vendor = 0x0001;input->id.product = 0x0001;input->id.version = 0x0100;3) 记录本设备对于哪些事件感兴趣(对其进行处理)input_set_capability();定义/drivers/input/input.cvoid input_set_capability(struct input_dev *dev, unsigned int type, unsigned int code)input_set_capability(input, EV_KEY, 101);4)向内核注册一个input设备input_register_device(input);5)记录按键状态int state = (gpio_get_value((S3C64XX_GPN(0)) ? 1 : 0) ^ 1 ;6)汇报输入事件input_event(input, EV_KEY, 101, !!state);7)等待输入事件处理完成input_sync(input);8)注销一个input设备input_unregister_device(input);
转自
阅读(936) | 评论(0) | 转发(0) |