分享

input设备使用方法和input_event说明

 兰宝888 2018-04-18

1.定义的结构体继承input_dev

  1. struct bma150_data {  
  2.     struct i2c_client *bma150_client;  
  3.     struct bma150_platform_data *platform_data;  
  4.     int IRQ;  
  5.     atomic_t delay;  
  6.     unsigned char mode;  
  7.     struct input_dev *input;  
  8.     struct bma150acc value;  
  9.     struct mutex value_mutex;  
  10.     struct mutex mode_mutex;  
  11.     struct delayed_work work;  
  12.     struct work_struct irq_work;  
  13. };  
2.给input_dev指定名字和总线类型,对input事件类型可以参考下面代码 EV_MSC 类型参考下面的

    set_bit(EV_MSC, dev->evbit);    
    set_bit(MSC_RAW, dev->mscbit);

EV_ABS类型参考下面的

    input->evbit[0] = BIT(EV_ABS);

    input->absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_Z);

  1. input_set_capability实际调用的也是__set_bit,  

input_set_abs_params调用实际上也是set_bit,对于参数(dev,axis,min,max,fuzz,flat)  fuzz有滤波作用,min,max代表范围,axis表示了坐标轴,flat暂时不知到用途

3.通过input_register_device(dev)注册input设备

  1. static int bma150_input_init(struct bma150_data *bma150)  
  2. {  
  3.     struct input_dev *dev;  
  4.     int err;  
  5.   
  6.     dev = input_allocate_device();  
  7.     if (!dev)  
  8.         return -ENOMEM;  
  9.     dev->name = SENSOR_NAME;  
  10.     dev->id.bustype = BUS_I2C;  
  11.   
  12.     input_set_capability(dev, EV_ABS, ABS_MISC);  
  13.     input_set_abs_params(dev, ABS_X, ABSMIN_2G, ABSMAX_2G, 0, 0);  
  14.     input_set_abs_params(dev, ABS_Y, ABSMIN_2G, ABSMAX_2G, 0, 0);  
  15.     input_set_abs_params(dev, ABS_Z, ABSMIN_2G, ABSMAX_2G, 0, 0);  
  16.     input_set_drvdata(dev, bma150);  
  17.   
  18.     err = input_register_device(dev);  
  19.     if (err < 0) {  
  20.         input_free_device(dev);  
  21.         return err;  
  22.     }  
  23.     bma150->input = dev;  
  24.   
  25.     return 0;  
  26. }  


据说可以指定input号

    dev->phys = "bma150/input0";
    dev->id.bustype = BUS_HOST;


4.在中断函数或者工作队列中调用input_event上报事件


static inline void input_report_abs(struct input_dev *dev, unsigned int code, int value)
{
    input_event(dev, EV_ABS, code, value);
}


input_event函数说明,input调用input_handle_event

对各种事件类型的处理主要体现在input_handle_event函数上

  1. static void input_handle_event(struct input_dev *dev,  
  2.                    unsigned int type, unsigned int code, int value)  
  3. {  
  4.     int disposition = INPUT_IGNORE_EVENT;//忽略事件  
  5.   
  6.     switch (type) {  
  7.   
  8.     case EV_SYN:  
  9.         switch (code) {  
  10.         case SYN_CONFIG:  
  11.             disposition = INPUT_PASS_TO_ALL;//传给设备和handle处理  
  12.             break;  
  13.   
  14.         case SYN_REPORT:  
  15.             if (!dev->sync) {  
  16.                 dev->sync = true;  
  17.                 disposition = INPUT_PASS_TO_HANDLERS;//传给handle处理 同步事件  
  18.             }  
  19.             break;  
  20.         case SYN_MT_REPORT:  
  21.             dev->sync = false;  
  22.             disposition = INPUT_PASS_TO_HANDLERS;//传给handle处理 多点触摸  
  23.             break;  
  24.         }  
  25.         break;  
  26.   
  27.     case EV_KEY:  
  28.         if (is_event_supported(code, dev->keybit, KEY_MAX) &&  
  29.             !!test_bit(code, dev->key) != value) {  
  30.   
  31.             if (value != 2) {  
  32.                 __change_bit(code, dev->key);  
  33.                 if (value)  
  34.                     input_start_autorepeat(dev, code);  
  35.                 else  
  36.                     input_stop_autorepeat(dev);  
  37.             }  
  38.   
  39.             disposition = INPUT_PASS_TO_HANDLERS;  
  40.         }  
  41.         break;  
  42.   
  43.     case EV_SW://耳机事件  
  44.         if (is_event_supported(code, dev->swbit, SW_MAX) &&  
  45.             !!test_bit(code, dev->sw) != value) {  
  46.   
  47.             __change_bit(code, dev->sw);  
  48.             disposition = INPUT_PASS_TO_HANDLERS;  
  49.         }  
  50.         break;  
  51.   
  52.     case EV_ABS:  
  53.         if (is_event_supported(code, dev->absbit, ABS_MAX))  
  54.             disposition = input_handle_abs_event(dev, code, &value);//这里调用的input_handle_abs_event会将上次值和这次值相同的事件过滤掉  
  55.   
  56.         break;  
  57.   
  58.     case EV_REL:  
  59.         if (is_event_supported(code, dev->relbit, REL_MAX) && value)  
  60.             disposition = INPUT_PASS_TO_HANDLERS;  
  61.   
  62.         break;  
  63.   
  64.     case EV_MSC:  
  65.         if (is_event_supported(code, dev->mscbit, MSC_MAX))  
  66.             disposition = INPUT_PASS_TO_ALL;  
  67.   
  68.         break;  
  69.   
  70.     case EV_LED:  
  71.         if (is_event_supported(code, dev->ledbit, LED_MAX) &&  
  72.             !!test_bit(code, dev->led) != value) {  
  73.   
  74.             __change_bit(code, dev->led);  
  75.             disposition = INPUT_PASS_TO_ALL;  
  76.         }  
  77.         break;  
  78.   
  79.     case EV_SND:  
  80.         if (is_event_supported(code, dev->sndbit, SND_MAX)) {  
  81.   
  82.             if (!!test_bit(code, dev->snd) != !!value)  
  83.                 __change_bit(code, dev->snd);  
  84.             disposition = INPUT_PASS_TO_ALL;  
  85.         }  
  86.         break;  
  87.   
  88.     case EV_REP:  
  89.         if (code <= REP_MAX && value >= 0 && dev->rep[code] != value) {  
  90.             dev->rep[code] = value;  
  91.             disposition = INPUT_PASS_TO_ALL;  
  92.         }  
  93.         break;  
  94.   
  95.     case EV_FF:  
  96.         if (value >= 0)  
  97.             disposition = INPUT_PASS_TO_ALL;  
  98.         break;  
  99.   
  100.     case EV_PWR:  
  101.         disposition = INPUT_PASS_TO_ALL;  
  102.         break;  
  103.     }  
  104.   
  105.     if (disposition != INPUT_IGNORE_EVENT && type != EV_SYN)  
  106.         dev->sync = false;  
  107.   
  108.     if ((disposition & INPUT_PASS_TO_DEVICE) && dev->event)  
  109.         dev->event(dev, type, code, value);  
  110.   
  111.     if (disposition & INPUT_PASS_TO_HANDLERS)  
  112.         input_pass_event(dev, type, code, value);  
  113. }  
  114.   
  115. /**  
  116.  * input_event() - report new input event  
  117.  * @dev: device that generated the event  
  118.  * @type: type of the event  
  119.  * @code: event code  
  120.  * @value: value of the event  
  121.  *  
  122.  * This function should be used by drivers implementing various input  
  123.  * devices to report input events. See also input_inject_event().  
  124.  *  
  125.  * NOTE: input_event() may be safely used right after input device was  
  126.  * allocated with input_allocate_device(), even before it is registered  
  127.  * with input_register_device(), but the event will not reach any of the  
  128.  * input handlers. Such early invocation of input_event() may be used  
  129.  * to 'seed' initial state of a switch or initial position of absolute  
  130.  * axis, etc.  
  131.  */  
  132. void input_event(struct input_dev *dev,  
  133.          unsigned int type, unsigned int code, int value)  
  134. {  
  135.     unsigned long flags;  
  136.   
  137.     if (is_event_supported(type, dev->evbit, EV_MAX)) {  
  138.   
  139.         spin_lock_irqsave(&dev->event_lock, flags);  
  140.         add_input_randomness(type, code, value);  
  141.         input_handle_event(dev, type, code, value);  
  142.         spin_unlock_irqrestore(&dev->event_lock, flags);  
  143.     }  
  144. }  
  145. EXPORT_SYMBOL(input_event);  
  1. static int input_handle_abs_event(struct input_dev *dev,  
  2.                   unsigned int code, int *pval)  
  3. {  
  4.     bool is_mt_event;  
  5.     int *pold;  
  6.   
  7.     if (code == ABS_MT_SLOT) {//多点触摸信号??  
  8.         /*  
  9.          * "Stage" the event; we'll flush it later, when we  
  10.          * get actual touch data.  
  11.          */  
  12.         if (*pval >= 0 && *pval < dev->mtsize)  
  13.             dev->slot = *pval;  
  14.   
  15.         return INPUT_IGNORE_EVENT;  
  16.     }  
  17.   
  18.     is_mt_event = code >= ABS_MT_FIRST && code <= ABS_MT_LAST;//多点触摸事件值  
  19.   
  20.     if (!is_mt_event) {//不是多点触摸值,旧将上次值保存在pold里面  
  21.         pold = &dev->absinfo[code].value;  
  22.     } else if (dev->mt) {  
  23.         struct input_mt_slot *mtslot = &dev->mt[dev->slot];  
  24.         pold = &mtslot->abs[code - ABS_MT_FIRST];  
  25.     } else {  
  26.         /*  
  27.          * Bypass filtering for multi-touch events when  
  28.          * not employing slots.  
  29.          */  
  30.         pold = NULL;  
  31.     }  
  32.   
  33.     if (pold) {  
  34.         *pval = input_defuzz_abs_event(*pval, *pold,//fuzz为0时,返回值为pold本身  
  35.                         dev->absinfo[code].fuzz);//这里fuzz是在2中设置类型时传入的参数input_set_abs_params(dev,axis,min,max.fuzz,flat)  
  36.         if (*pold == *pval)  
  37.             return INPUT_IGNORE_EVENT;  
  38.   
  39.         *pold = *pval;  
  40.     }  
  41.   
  42.     /* Flush pending "slot" event */  
  43.     if (is_mt_event && dev->slot != input_abs_get_val(dev, ABS_MT_SLOT)) {  
  44.         input_abs_set_val(dev, ABS_MT_SLOT, dev->slot);  
  45.         input_pass_event(dev, EV_ABS, ABS_MT_SLOT, dev->slot);  
  46.     }  
  47.   
  48.     return INPUT_PASS_TO_HANDLERS;  

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多