操作环境:
开发板:mini2440
CPU:(samsung)s3c2440
Linux版本:Linux-2.6.32.2
/************* input.c ************/
subsys_initcall(input_init);
input_init(void) --> class_register(&input_class);
register_chrdev(INPUT_MAJOR, "input", &input_fops);
static const struct file_operations input_fops = {
.owner = THIS_MODULE,
.open = input_open_file,
}; |
V
old_fops = file->f_op = new_fops = fops_get(handler->fops)
handler = input_table[iminor(inode) >> 5]
static struct input_handler *input_table[8];
/************* evdev.c ************/
module_init(evdev_init); /**********************************************/
int __init evdev_init(void) ---------> input_register_handler(&evdev_handler);
input_table[handler->minor >> 5] = handler;
list_add_tail(&handler->node, &input_handler_list);
list_for_each_entry(dev, &input_dev_list, node){
input_attach_handler(dev, handler);
}
/**********************************************/
static struct input_handler evdev_handler = {
.event = evdev_event,
.connect = evdev_connect,
.disconnect = evdev_disconnect,
.fops = &evdev_fops,
.minor = EVDEV_MINOR_BASE,
.name = "evdev",
.id_table = evdev_ids,
};
static const struct file_operations evdev_fops = {
.owner = THIS_MODULE,
.read = evdev_read,
.write = evdev_write,
.poll = evdev_poll,
.open = evdev_open,
.release = evdev_release,
.unlocked_ioctl = evdev_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = evdev_ioctl_compat,
#endif
.fasync = evdev_fasync,
.flush = evdev_flush
};
/************* gpio_keys.c ************/
module_init(gpio_keys_init);
gpio_keys_init(void) ---> platform_driver_register(&gpio_keys_device_driver);
returnstatic struct platform_driver gpio_keys_device_driver = {
.probe = gpio_keys_probe,
.remove = __devexit_p(gpio_keys_remove),
.driver = {
.name = "gpio-keys", //匹配名字
.owner = THIS_MODULE,
#ifdef CONFIG_PM
.pm = &gpio_keys_pm_ops,
#endif
}
static int __devinit gpio_keys_probe(struct platform_device *pdev){
.........
input = input_allocate_device(); //分配input
.........
input->name = pdev->name; //设置
input->phys = "gpio-keys/input0";
input->dev.parent = &pdev->dev;
.........
error = input_register_device(input); //注册,最主要的
........
}
int input_register_device(struct input_dev *dev){
list_add_tail(&dev->node, &input_dev_list);
list_for_each_entry(handler, &input_handler_list, node)
input_attach_handler(dev, handler);
}
static int input_attach_handler(struct input_dev *dev, struct input_handler *handler){
id = input_match_device(handler, dev);
error = handler->connect(handler, dev, id);
}
static int evdev_connect(struct input_handler *handler, struct input_dev *dev,const struct input_device_id *id){
struct evdev *evdev;
evdev = kzalloc(sizeof(struct evdev), GFP_KERNEL); //分配
evdev->handle.dev = input_get_device(dev); //设置
evdev->handle.name = dev_name(&evdev->dev);
evdev->handle.handler = handler;
evdev->handle.private = evdev;
error = input_register_handle(&evdev->handle); //注册handle
}
Input_dev->h_list ----> &evdev->handle -----> handler
Input_handler->h_list ----> &evdev->handle -----> dev
/************* mach-mini2440.c ************/
/* gpio-keys */
static struct gpio_keys_button s3c2440_gpio_keys_button[]=
{
{KEY_1, S3C2410_GPG(0), 1, "key1", EV_KEY, 0, 100},
{KEY_2, S3C2410_GPG(3), 1, "key2", EV_KEY, 0, 100},
{KEY_3, S3C2410_GPG(5), 1, "key3", EV_KEY, 0, 100},
{KEY_4, S3C2410_GPG(6), 1, "key4", EV_KEY, 0, 100},
{KEY_5, S3C2410_GPG(7), 1, "key5", EV_KEY, 0, 100},
{KEY_6, S3C2410_GPG(11), 1, "key6", EV_KEY, 0, 100},
};
static struct gpio_keys_platform_data s3c2440_gpio_keys_data=
{
.buttons=s3c2440_gpio_keys_button,
.nbuttons=ARRAY_SIZE(s3c2440_gpio_keys_button),
.rep = 1,
};
static struct platform_device s3c2440_gpio_keys = {
.name = "gpio-keys",
.dev = {
.platform_data = &s3c2440_gpio_keys_data,
},
};
static struct platform_device *mini2440_devices[] __initdata = {
........
&s3c2440_gpio_keys,
};