• 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)
    ", 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)
    ", 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)
    ", 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
    ");
    4         kpd_delete_attr(&kpd_pdrv.driver);
    5         return err;
    6     }
  • 相关阅读:
    CSPS模拟 57
    CSPS模拟 56
    CSPS Oct目标
    CSPS模拟 55
    CSPS模拟 54
    CSPS模拟 53
    和manacher有关的乱写
    CSPS模拟 52
    CSPS模拟 51
    Git和代码规范
  • 原文地址:https://www.cnblogs.com/haimeng2010/p/3584914.html
Copyright © 2020-2023  润新知