keypad做爲input設備註冊到內核,與platform總線驅動match。函數
一、描述一個輸入設備對象spa
1 static struct input_dev *kpd_input_dev;
告知輸入子系統 kpd_input_dev 是一個input設備。code
二、註冊platform總線驅動orm
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裏作了哪些工做:blog
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 }