由上图可知输入子系统核心层提供的支持以及如何上报事件到input event drivers。
作为输入设备的驱动开发者,需要做以下几步:
在驱动加载模块中,设置你的input设备支持的事件类型
注册中断处理函数,例如键盘设备需要编写按键的抬起、放下,触摸屏设备需要编写按下、抬起、绝对移动,鼠标设备需要编写单击、抬起、相对移动,并且需要在必要的时候提交硬件数据(键值/坐标/状态等等)
将输入设备注册到输入子系统中
///////////////////////////////////////////////////////////////////分割线/////////////////////////////////////////////////////////////////////////////////
输入核心提供了底层输入设备驱动程序所需的API,如分配/释放一个输入设备:
struct input_dev *input_allocate_device(void);
void input_free_device(struct input_dev *dev);
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | /** * input_allocate_device - allocate memory for new input device * * Returns prepared struct input_dev or NULL. * * NOTE: Use input_free_device() to free devices that have not been * registered; input_unregister_device() should be used for already * registered devices. */ struct input_dev *input_allocate_device(void) { struct input_dev *dev; /*分配一个input_dev结构体,并初始化为0*/ dev = kzalloc(sizeof(struct input_dev), GFP_KERNEL); if (dev) { dev->dev.type = &input_dev_type;/*初始化设备的类型*/ dev->dev.class = &input_class; /*设置为输入设备类*/ device_initialize(&dev->dev);/*初始化device结构*/ mutex_init(&dev->mutex); /*初始化互斥锁*/ spin_lock_init(&dev->event_lock); /*初始化事件自旋锁*/ INIT_LIST_HEAD(&dev->h_list);/*初始化链表*/ INIT_LIST_HEAD(&dev->node); /*初始化链表*/ __module_get(THIS_MODULE);/*模块引用技术加1*/ } return dev; } |
注册/注销输入设备用的接口如下:
int __must_check input_register_device(struct input_dev *);
void input_unregister_device(struct input_dev *);
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | /** * input_register_device - register device with input core * @dev: device to be registered * * This function registers device with input core. The device must be * allocated with input_allocate_device() and all it's capabilities * set up before registering. * If function fails the device must be freed with input_free_device(). * Once device has been successfully registered it can be unregistered * with input_unregister_device(); input_free_device() should not be * called in this case. */ int input_register_device(struct input_dev *dev) { //定义一些函数中将用到的局部变量 static atomic_t input_no = ATOMIC_INIT(0); struct input_handler *handler; const char *path; int error; //设置 input_dev 所支持的事件类型,由 evbit 成员来表示。具体类型在后面归纳。 /* Every input device generates EV_SYN/SYN_REPORT events. */ __set_bit(EV_SYN, dev->evbit); /* KEY_RESERVED is not supposed to be transmitted to userspace. */ __clear_bit(KEY_RESERVED, dev->keybit); /* Make sure that bitmasks not mentioned in dev->evbit are clean. */ input_cleanse_bitmasks(dev); //初始化 timer 定时器,用来处理重复点击按键。(去抖) |