紧接着上一节的实例我们来分析调用的input子系统的接口:
1. input_dev,用来标识输入设备
1: struct input_dev {
2: const char *name; //设备名
3: const char *phys; // 设备在系统中路径
4: const char *uniq;
5: struct input_id id; //与input_handler匹配用的id
   6:   7: unsigned long propbit[BITS_TO_LONGS(INPUT_PROP_CNT)];
   8:   9: unsigned long evbit[BITS_TO_LONGS(EV_CNT)]; //设备所支持事件类型,主要有EV_SYNC,EV_KEY,EV_REL,EV_ABS等
10: unsigned long keybit[BITS_TO_LONGS(KEY_CNT)];// 按键所对应的位图
11: unsigned long relbit[BITS_TO_LONGS(REL_CNT)];// 相对坐标对应位图
12: unsigned long absbit[BITS_TO_LONGS(ABS_CNT)];// 绝对坐标对应位图
13: unsigned long mscbit[BITS_TO_LONGS(MSC_CNT)];//支持其它事件
14: unsigned long ledbit[BITS_TO_LONGS(LED_CNT)];//支持led事件
15: unsigned long sndbit[BITS_TO_LONGS(SND_CNT)];//支持声音事件
16: unsigned long ffbit[BITS_TO_LONGS(FF_CNT)];//支持受力事件
17: unsigned long swbit[BITS_TO_LONGS(SW_CNT)];//支持开关机事件
  18:   19: unsigned int hint_events_per_packet;
  20:   21: unsigned int keycodemax;
22: unsigned int keycodesize;
23: void *keycode;
  24:   25: int (*setkeycode)(struct input_dev *dev,
26: const struct input_keymap_entry *ke,
27: unsigned int *old_keycode);
28: int (*getkeycode)(struct input_dev *dev,
29: struct input_keymap_entry *ke);
  30:   31: struct ff_device *ff;
  32:   33: unsigned int repeat_key;//最近一次的按键值
34: struct timer_list timer;
  35:   36: int rep[REP_CNT];
  37:   38: struct input_mt_slot *mt;
39: int mtsize;
40: int slot;
41: int trkid;
  42:   43: struct input_absinfo *absinfo;
  44:   45: unsigned long key[BITS_TO_LONGS(KEY_CNT)];//反应设备当前的按键状态
46: unsigned long led[BITS_TO_LONGS(LED_CNT)];//反应设备当前的led状态
47: unsigned long snd[BITS_TO_LONGS(SND_CNT)];//反应设备当前的声音输入状态
48: unsigned long sw[BITS_TO_LONGS(SW_CNT)];//反应设备当前的开关状态
  49:   50: int (*open)(struct input_dev *dev);//第一次打开设备时调用,初始化设备用
51: void (*close)(struct input_dev *dev);//最后一个应用程序释放设备时用,关闭设备
52: int (*flush)(struct input_dev *dev, struct file *file);/*用于处理传递给设备的事件,如LED事件和声音事件*/
53: // 事件处理函数,主要是接收用户下发的命令,如点亮led;
54: int (*event)(struct input_dev *dev, unsigned int type, unsigned int code, int value);
  55:   56: struct input_handle __rcu *grab; //当前占有该设备的input_handle
  57:     58:      spinlock_t event_lock;59: struct mutex mutex;
  60:   61: unsigned int users; //打开该设备的用户数量(input handlers)
62: bool going_away;
  63:   64: bool sync;
  65:   66: struct device dev;
  67:   68: struct list_head h_list; // 设备所支持的input handle;
69: struct list_head node; //用于将此input_dev链接到input_dev_list
  70:  };
2.把输入设备注册进核心层  int input_register_device(struct input_dev *dev)
1: int input_register_device(struct input_dev *dev)
   2:  {3: static atomic_t input_no = ATOMIC_INIT(0);
4: struct input_handler *handler;
5: const char *path;
6: int error;
   7:   8: /* Every input device generates EV_SYN/SYN_REPORT events. */
9: __set_bit(EV_SYN, dev->evbit);// /*表示设备支持所有的事件*/
  10:   11: /* KEY_RESERVED is not supposed to be transmitted to userspace. */
  12:      __clear_bit(KEY_RESERVED, dev->keybit);  13:   14: /* Make sure that bitmasks not mentioned in dev->evbit are clean. */
  15:      input_cleanse_bitmasks(dev);  16:   17: if (!dev->hint_events_per_packet)
  18:          dev->hint_events_per_packet =  19:                  input_estimate_events_per_packet(dev);  20:   21: /*
22: * If delay and period are pre-set by the driver, then autorepeating
23: * is handled by the driver itself and we don‘t do it in input.c.
24: */
25: init_timer(&dev->timer);//初始化定时器
26: /*如果dev->rep[REP_DELAY]和dev->rep[REP_PERIOD]没有设值,
27: 则将其赋默认值,这主要是为自动处理重复按键定义*/
28: if (!dev->rep[REP_DELAY] && !dev->rep[REP_PERIOD]) {
29: dev->timer.data = (long) dev;
30: dev->timer.function = input_repeat_key;//定时器处理函数
  31:          dev->rep[REP_DELAY] = 250;  32:          dev->rep[REP_PERIOD] = 33;  33:      }  34:   35: if (!dev->getkeycode)//获取键值
  36:          dev->getkeycode = input_default_getkeycode;  37:   38: if (!dev->setkeycode)//设置键值
  39:          dev->setkeycode = input_default_setkeycode;40: //设置input_dev中的device的名字
41: dev_set_name(&dev->dev, "input%ld",
42: (unsigned long) atomic_inc_return(&input_no) - 1);
  43:   44: error = device_add(&dev->dev);//将input_dev包含的device结构注册到Linux设备模型中,并可以在sysfs文件系统中表现出来。
45: if (error)
46: return error;
  47:     48:      path = kobject_get_path(&dev->dev.kobj, GFP_KERNEL);49: pr_info("%s as %s\n",
50: dev->name ? dev->name : "Unspecified device",
51: path ? path : "N/A");
  52:      kfree(path);  53:     54:      error = mutex_lock_interruptible(&input_mutex);55: if (error) {
  56:          device_del(&dev->dev);57: return error;
  58:      }  59:   60: list_add_tail(&dev->node, &input_dev_list);//添加到input device 链表
  61:   62: list_for_each_entry(handler, &input_handler_list, node)//
  63:          input_attach_handler(dev, handler);  64:     65:      input_wakeup_procfs_readers();  66:     67:      mutex_unlock(&input_mutex);  68:   69: return 0;
3.调用input_report_key函数报告此事件
1: static inline void input_report_key(struct input_dev *dev, unsigned int code, int value)
   2:  {3: input_event(dev, EV_KEY, code, !!value);
   4:  }input_report_key函数参数,1.input_dev设备,2。按键值 3.按键的状态(1按下,0松开)
在input.h中定义了按键类code的值,BTN_0,BTN_1,KEY_A KEY_B等等这样的键值
此函数只是调用了input_event函数,这个函数是总的事件报告函数,
1: void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
   2:  {3: unsigned long flags;
   4:   5: if (is_event_supported(type, dev->evbit, EV_MAX)) { //(1)
   6:   7: spin_lock_irqsave(&dev->event_lock, flags); //(2)
8: add_input_randomness(type, code, value); //(3)
9: input_handle_event(dev, type, code, value); //(4)
10: spin_unlock_irqrestore(&dev->event_lock, flags);//(5)
  11:      }  12:  }参数1.input_dev 2.事件类型(如EV_KEY键盘事件) 3.此类型具体事件code(如KEY_A,键A) 4.此事件的值(如1,按键按下)
(1)设备是否支持该事件类型。下面分析
(2)自旋锁上锁
(3)因为按键是随机事件,所以对随机熵有贡献,对于驱动无关。具体不懂
(4)进一步处理报告的事件
(5)自旋锁解锁
原文:http://www.cnblogs.com/xuyh/p/4991449.html