input系统------kernel层上报(1)

   我们以input_report_abs(data->input_dev, ABS_MT_POSITION_X, event->au16_x[i]);为例子

首先看

static inline void input_report_abs(struct input_dev *dev, unsigned int code, int value)
{
input_event(dev, EV_ABS, code, value);
}

所有的都是以input_event的形式上报

再看

void input_event(struct input_dev *dev,
unsigned int type, unsigned int code, int value)
{
unsigned long flags;


if (is_event_supported(type, dev->evbit, EV_MAX)) {


spin_lock_irqsave(&dev->event_lock, flags);
input_handle_event(dev, type, code, value);
spin_unlock_irqrestore(&dev->event_lock, flags);
}
}

再到了

static void input_handle_event(struct input_dev *dev,
      unsigned int type, unsigned int code, int value)
{
int disposition;


disposition = input_get_disposition(dev, type, code, value);
      
if ((disposition & INPUT_PASS_TO_DEVICE) && dev->event)
dev->event(dev, type, code, value);


if (!dev->vals)
return;
//disposition = INPUT_PASS_TO_HANDLERS | INPUT_FLUSH;
if (disposition & INPUT_PASS_TO_HANDLERS) {
struct input_value *v;


if (disposition & INPUT_SLOT) {
v = &dev->vals[dev->num_vals++];
v->type = EV_ABS;
v->code = ABS_MT_SLOT;
v->value = dev->mt->slot;
}


v = &dev->vals[dev->num_vals++];
v->type = type;
v->code = code;
v->value = value;
}


if (disposition & INPUT_FLUSH) {   //当input_event(dev, EV_SYN, SYN_REPORT, 0);这个上报完表示驱动的数据已经上报完毕,这里才pass
if (dev->num_vals >= 2)
input_pass_values(dev, dev->vals, dev->num_vals);
 
dev->num_vals = 0;
} else if (dev->num_vals >= dev->max_vals - 2) {
dev->vals[dev->num_vals++] = input_value_sync;
input_pass_values(dev, dev->vals, dev->num_vals);
dev->num_vals = 0;
}


}


然后到了

static void input_pass_values(struct input_dev *dev,
     struct input_value *vals, unsigned int count)
{
struct input_handle *handle;
struct input_value *v;


if (!count)
return;


rcu_read_lock();


handle = rcu_dereference(dev->grab);
//printk("matt-count=%d\n",count);
if (handle) {
    
count = input_to_handler(handle, vals, count);
} else {
list_for_each_entry_rcu(handle, &dev->h_list, d_node)
if (handle->open)
count = input_to_handler(handle, vals, count);
}


rcu_read_unlock();


add_input_randomness(vals->type, vals->code, vals->value);


/* trigger auto repeat for key events */
for (v = vals; v != vals + count; v++) {
if (v->type == EV_KEY && v->value != 2) {
if (v->value)
input_start_autorepeat(dev, v->code);
else
input_stop_autorepeat(dev);
}
}
}

跑到了

static unsigned int input_to_handler(struct input_handle *handle,
struct input_value *vals, unsigned int count)
{
struct input_handler *handler = handle->handler;
struct input_value *end = vals;
struct input_value *v;


for (v = vals; v != vals + count; v++) {
if (handler->filter &&
   handler->filter(handle, v->type, v->code, v->value))
continue;
if (end != v)
*end = *v;
end++;
}


count = end - vals;
if (!count)
return 0;


if (handler->events)
{
// printk("matt-1\n");
handler->events(handle, vals, count);//down
}
else if (handler->event)
{
//printk("matt-2\n");
for (v = vals; v != end; v++)  //up
handler->event(handle, v->type, v->code, v->value);
}


return count;
}

调用了

handler->event(handle, v->type, v->code, v->value); 这是up然后是handler->events(handle, vals, count);//这是down


这个handler->event则是

Evdev.c (drivers\input) 

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,
};

看看

static void evdev_events(struct input_handle *handle,
const struct input_value *vals, unsigned int count)
{
struct evdev *evdev = handle->private;
struct evdev_client *client;
ktime_t time_mono, time_real;


time_mono = ktime_get();
time_real = ktime_sub(time_mono, ktime_get_monotonic_offset());


rcu_read_lock();


client = rcu_dereference(evdev->grab);


if (client)
evdev_pass_values(client, vals, count, time_mono, time_real);
else
list_for_each_entry_rcu(client, &evdev->client_list, node)
evdev_pass_values(client, vals, count,
 time_mono, time_real);


rcu_read_unlock();
}

然后到了

static void evdev_pass_values(struct evdev_client *client,
const struct input_value *vals, unsigned int count,
ktime_t mono, ktime_t real)
{
struct evdev *evdev = client->evdev;
const struct input_value *v;
struct input_event event;
bool wakeup = false;


event.time = ktime_to_timeval(client->clkid == CLOCK_MONOTONIC ?
     mono : real);


/* Interrupts are disabled, just acquire the lock. */
spin_lock(&client->buffer_lock);


for (v = vals; v != vals + count; v++) {
event.type = v->type;
event.code = v->code;
event.value = v->value;
__pass_event(client, &event);
if (v->type == EV_SYN && v->code == SYN_REPORT)
wakeup = true;
}


spin_unlock(&client->buffer_lock);
       printk("matt-wakeup=%d\n",wakeup);
 // wakeup=false;
if (wakeup)
wake_up_interruptible(&evdev->wait);  //这里唤醒wait的进程让它读取下面的buffer中的数据


这个static ssize_t evdev_read(struct file *file, char __user *buffer,
 size_t count, loff_t *ppos)
{
struct evdev_client *client = file->private_data;
struct evdev *evdev = client->evdev;
struct input_event event;
size_t read = 0;
int error;


if (count != 0 && count < input_event_size())
return -EINVAL;


for (;;) {
if (!evdev->exist)
return -ENODEV;


if (client->packet_head == client->tail &&
   (file->f_flags & O_NONBLOCK))
return -EAGAIN;


/*
* count == 0 is special - no IO is done but we check
* for error conditions (see above).
*/
if (count == 0)
break;
          
while (read + input_event_size() <= count &&
      evdev_fetch_next_event(client, &event)) {


if (input_event_to_user(buffer + read, &event))
return -EFAULT;


read += input_event_size();

}
               printk("matt-read==%ld",read);
if (read)
{
// printk("matt-read\n");
break;
}
//printk("matt-read+1\n");


if (!(file->f_flags & O_NONBLOCK)) {
error = wait_event_interruptible(evdev->wait,   //这个read会一直wait在这边
client->packet_head != client->tail ||
!evdev->exist);

if (error)
return error;
}
}


return read;
}

}  

到了

static void __pass_event(struct evdev_client *client,
const struct input_event *event)
{
client->buffer[client->head++] = *event;   //就是放到这个buffer中
client->head &= client->bufsize - 1;


if (unlikely(client->head == client->tail)) {
/*
* This effectively "drops" all unconsumed events, leaving
* EV_SYN/SYN_DROPPED plus the newest event in the queue.
*/
client->tail = (client->head - 2) & (client->bufsize - 1);


client->buffer[client->tail].time = event->time;
client->buffer[client->tail].type = EV_SYN;
client->buffer[client->tail].code = SYN_DROPPED;
client->buffer[client->tail].value = 0;


client->packet_head = client->tail;
if (client->use_wake_lock)
wake_unlock(&client->wake_lock);
}


if (event->type == EV_SYN && event->code == SYN_REPORT) {
client->packet_head = client->head;
if (client->use_wake_lock)
wake_lock(&client->wake_lock);
kill_fasync(&client->fasync, SIGIO, POLL_IN);
}
}这个函数把client填充之后


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值