input子系统
input子系统代码位置:kernel/drivers/input/input.c
这个文件完成input系统最原始的初始化,subsys_initcall开始子系统的初始化,并封装EXPORT_SYMBOL给其他驱动调用的接口
在input_init中,三件事:
err = class_register(&input_class); if (err) { pr_err("unable to register input_dev class\n"); return err; } err = input_proc_init(); if (err) goto fail1; err = register_chrdev(INPUT_MAJOR, "input", &input_fops); if (err) { pr_err("unable to register char major %d", INPUT_MAJOR); goto fail2; }
对开发很有用的是proc的节点,我们看下代码,才能更好地利用它
static int __init input_proc_init(void) { struct proc_dir_entry *entry; proc_bus_input_dir = proc_mkdir("bus/input", NULL); if (!proc_bus_input_dir) return -ENOMEM; entry = proc_create("devices", 0, proc_bus_input_dir, &input_devices_fileops); if (!entry) goto fail1; entry = proc_create("handlers", 0, proc_bus_input_dir, &input_handlers_fileops); if (!entry) goto fail2; return 0; fail2: remove_proc_entry("devices", proc_bus_input_dir); fail1: remove_proc_entry("bus/input", NULL); return -ENOMEM; }
1. "bus/input"目录创建
2. 在"bus/input"目录下创建proc目录devices,它的方法集有
static const struct file_operations input_devices_fileops = { .owner = THIS_MODULE, .open = input_proc_devices_open, .poll = input_proc_devices_poll, .read = seq_read, .llseek = seq_lseek, .release = seq_release, };
static const struct seq_operations input_devices_seq_ops = { .start = input_devices_seq_start, .next = input_devices_seq_next, .stop = input_seq_stop, .show = input_devices_seq_show, }; static int input_proc_devices_open(struct inode *inode, struct file *file) { return seq_open(file, &input_devices_seq_ops); }
“handlers”节点和“devieces”节点注册方式类似,里面关联的是很多的中断句柄
static const struct seq_operations input_handlers_seq_ops = { .start = input_handlers_seq_start, .next = input_handlers_seq_next, .stop = input_seq_stop, .show = input_handlers_seq_show, }; static int input_proc_handlers_open(struct inode *inode, struct file *file) { return seq_open(file, &input_handlers_seq_ops); } static const struct file_operations input_handlers_fileops = { .owner = THIS_MODULE, .open = input_proc_handlers_open, .read = seq_read, .llseek = seq_lseek, .release = seq_release, };
shell@android:/proc/bus/input # ls devices handlers shell@android:/proc/bus/input #
shell@android:/proc/bus/input # cat devices I: Bus=0000 Vendor=0001 Product=0001 Version=0100 N: Name="headsetdet" P: Phys= S: Sysfs=/devices/platform/headsetdet.0/input/input0 U: Uniq= H: Handlers=event0 B: PROP=0 B: EV=3 B: KEY=1 I: Bus=0019 Vendor=0001 Product=0001 Version=0100 N: Name="keypad" P: Phys=gpio-keys/input0 S: Sysfs=/devices/platform/keypad/input/input1 U: Uniq= H: Handlers=kbd event1 keychord B: PROP=0 B: EV=3 B: KEY=8000 100000 0 0 0 I: Bus=0000 Vendor=0000 Product=0000 Version=0000 N: Name="ft5x0x_ts" P: Phys= S: Sysfs=/devices/virtual/input/input2 U: Uniq= H: Handlers=cpufreq_interactive event2 B: PROP=2 B: EV=9 B: ABS=2658000 0 I: Bus=0000 Vendor=0000 Product=0000 Version=0000 N: Name="lightsensor-level" P: Phys= S: Sysfs=/devices/virtual/input/input3 U: Uniq= H: Handlers=event3 B: PROP=0 B: EV=9 B: ABS=100 10000000 shell@android:/proc/bus/input #
shell@android:/proc/bus/input # cat handlers N: Number=0 Name=kbd N: Number=1 Name=cpufreq_interactive N: Number=2 Name=sysrq (filter) N: Number=3 Name=evdev Minor=64 N: Number=4 Name=keychord shell@android:/proc/bus/input #