keypad代码分析

keypad作为input设备注册到内核,与platform总线驱动match。

1、描述一个输入设备对象

1 static struct input_dev *kpd_input_dev;

告知输入子系统 kpd_input_dev 是一个input设备。

2、注册platform总线驱动

r = platform_driver_register(&kpd_pdrv);

 继续看kpd_pdrv有哪些信息:

 1 static struct platform_driver kpd_pdrv = {
 2     .probe        = kpd_pdrv_probe,
 3     .remove        = kpd_pdrv_remove,
 4 #ifndef CONFIG_HAS_EARLYSUSPEND    
 5     .suspend    = kpd_pdrv_suspend,
 6     .resume        = kpd_pdrv_resume,
 7 #endif    
 8     .driver        = {
 9         .name    = KPD_NAME,
10         .owner    = THIS_MODULE,
11     },
12 };

先关注probe这个重要角色,继续看kpd_pdrv_probe里做了哪些工作:

 1 static int kpd_pdrv_probe(struct platform_device *pdev)
 2 {
 3     
 4     int i, r;
 5     int err = 0;
 6         kpd_input_dev = input_allocate_device(); //初始化input设备 kpd_input_dev,通知输入子系统有新设备加入。
 7     if (!kpd_input_dev)
 8         return -ENOMEM;
 9     kpd_input_dev->name = KPD_NAME;              //设备名
10     kpd_input_dev->id.bustype = BUS_HOST;
11     kpd_input_dev->id.vendor = 0x2454;
12     kpd_input_dev->id.product = 0x6572;
13     kpd_input_dev->id.version = 0x0010;
14     kpd_input_dev->open = kpd_open;
15 
16     __set_bit(EV_KEY, kpd_input_dev->evbit);//设置input设备kpd_input_dev支持的设备类型:按键事件型
 1     kpd_input_dev->dev.parent = &pdev->dev;   //
 2     r = input_register_device(kpd_input_dev);  //完成上述工作后,便可以注册输入设备,通知事件处理层当有满足条件的事件发生时调用相应的函数
 3     if (r) {
 4         printk(KPD_SAY "register input device failed (%d)\n", r);
 5         input_free_device(kpd_input_dev);
 6         return r;
 7     }
1     /* register misc device (/dev/mtk-kpd) */
2     kpd_dev.parent = &pdev->dev;
3     r = misc_register(&kpd_dev); //注册kpd_dev这个混杂设备
4     if (r) {
5         printk(KPD_SAY "register device failed (%d)\n", r);
6         input_unregister_device(kpd_input_dev);
7         return r;
8     }
1     /* register IRQ and EINT */
2     kpd_set_debounce(KPD_KEY_DEBOUNCE);
3     r = request_irq(MT_KP_IRQ_ID, kpd_irq_handler, IRQF_TRIGGER_FALLING, KPD_NAME, NULL); //注册中断出发条件,中断号,中断函数
4     if (r) {
5         printk(KPD_SAY "register IRQ failed (%d)\n", r);
6         misc_deregister(&kpd_dev);                 //如果中断注册不成功,需卸载掉混杂设备kpd_dev的注册
7         input_unregister_device(kpd_input_dev);    //同样,也也需卸载掉input设备的注册
8         return r;
9     }
1     hrtimer_init(&aee_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
2     aee_timer.function = aee_timer_func;

 

1     if((err = kpd_create_attr(&kpd_pdrv.driver)))
2     {
3         kpd_print("create attr file fail\n");
4         kpd_delete_attr(&kpd_pdrv.driver);
5         return err;
6     }

 

 

 

posted on 2014-03-06 20:01  haitao2000s  阅读(630)  评论(0编辑  收藏  举报

导航