现在看用户获取触摸屏输入的一个流程(以tsdev为例/drivers/input/tsdev.c):
static struct file_operations tsdev_fops = {
.owner = THIS_MODULE,
.open = tsdev_open,
.release = tsdev_release,
.read = tsdev_read,
.poll = tsdev_poll,
.fasync = tsdev_fasync,
.ioctl = tsdev_ioctl,
};
假设所有初始化早已完成,用户open该设备后,使用read系统调用进入内核,系统
转移控制到tsdev_read,使用wait_event_interruptible等待事件。
此时驱动层得到用户输入,于是调用input_report_abs,input_report_abs只是
input_event的简单包装:
static inline void input_report_abs(struct input_dev *dev,
unsigned int code, int value)
{
input_event(dev, EV_ABS, code, value);
}
void input_event(struct input_dev *dev, unsigned int type,
unsigned int code, int value)
{
...
switch (type) {
...
case EV_ABS:
...
break;
...
}
...
if (dev->grab)
dev->grab->handler->event(dev->grab, type, code, value);
else
list_for_each_entry(handle, &dev->h_list, d_node)
if (handle->open)
handle->handler->event(handle, type, code, value);
}
前面的处理关系具体设备,见最后对handler函数的调用,就是从input_dev的h_list链
上的input_handle获得每一个相关input_handler,并调用其中的event函数,对tsdev
来说:
static struct input_handler tsdev_handler = {
.event = tsdev_event,
.connect = tsdev_connect,
.disconnect = tsdev_disconnect,
.fops = &tsdev_fops,
.minor = TSDEV_MINOR_BASE,
.name = "tsdev",
.id_table = tsdev_ids,
};
即调用tsdev_event函数,接着看:
static void tsdev_event(struct input_handle *handle, unsigned int type,
unsigned int code, int value)
{
...
switch (type) {
case EV_ABS:
break;
...
list_for_each_entry(list, &tsdev->list, node) {
int x, y, tmp;
do_gettimeofday(&time);
list->event[list->head].millisecs = time.tv_usec / 100;
list->event[list->head].pressure = tsdev->pressure;
x = tsdev->x;
y = tsdev->y;
/* Calibration */
if (!list->raw) {
x = ((x * tsdev->cal.xscale) >> 8) + tsdev->cal.xtrans;
y = ((y * tsdev->cal.yscale) >> 8) + tsdev->cal.ytrans;
if (tsdev->cal.xyswap) {
tmp = x; x = y; y = tmp;
}
}
list->event[list->head].x = x;
list->event[list->head].y = y;
list->head = (list->head + 1) & (TSDEV_BUFFER_SIZE - 1);
kill_fasync(&list->fasync, SIGIO, POLL_IN);
}
wake_up_interruptible(&tsdev->wait);
}
它填充数据,并唤醒等待着的请求。于是前面等待着的read请求就可继续了,
回到tsdev_read中,copy_to_user拷贝数据,最后返回用户层。
一个简单流程就结束了。
[转]输入简单流程
最新推荐文章于 2024-07-12 22:49:43 发布