Linux29内核输入子系统多点上报机制实现


电容屏被广泛使用,多点触摸机制也随之发展,可惜29内核不支持多点上报,30以后内核才支持。

特此记录移植过程。

1、修改include/linux/input.h

Index: include/linux/input.h   

  1. ===================================================================   
  2. --- include/linux/input.h       (revision 1550)   
  3. +++ include/linux/input.h       (working copy)   
  4. @@ -106,6 +106,7 @@  
  5.    
  6.  #define SYN_REPORT             0  
  7.  #define SYN_CONFIG             1   
  8. +#define SYN_MT_REPORT          2   
  9.     
  10.  /*  
  11.   * Keys and buttons  
  12. @@ -644,6 +645,18 @@  
  13.  #define ABS_TOOL_WIDTH         0x1c  
  14.  #define ABS_VOLUME             0x20  
  15.  #define ABS_MISC               0x28  
  16. +  
  17. +#define ABS_MT_TOUCH_MAJOR     0x30    /* Major axis of touching ellipse */  
  18. +#define ABS_MT_TOUCH_MINOR     0x31    /* Minor axis (omit if circular) */  
  19. +#define ABS_MT_WIDTH_MAJOR     0x32    /* Major axis of approaching ellipse */  
  20. +#define ABS_MT_WIDTH_MINOR     0x33    /* Minor axis (omit if circular) */  
  21. +#define ABS_MT_ORIENTATION     0x34    /* Ellipse orientation */  
  22. +#define ABS_MT_POSITION_X              0x35    /* Center X ellipse position */  
  23. +#define ABS_MT_POSITION_Y              0x36    /* Center Y ellipse position */  
  24. +#define ABS_MT_TOOL_TYPE               0x37    /* Type of touching device */  
  25. +#define ABS_MT_BLOB_ID                 0x38    /* Group a set of packets as a blob */  
  26. +#define ABS_MT_TRACKING_ID             0x39    /* Unique ID of initiated contact */  
  27. +  
  28.  #define ABS_MAX                        0x3f  
  29.  #define ABS_CNT                        (ABS_MAX+1)   
  30.     
  31. @@ -742,6 +755,12 @@  
  32.  #define BUS_ATARI              0x1B   
  33.     
  34.  /*  
  35. + * MT_TOOL types  
  36. + */  
  37. +#define MT_TOOL_FINGER         0   
  38. +#define MT_TOOL_PEN            1   
  39. +   
  40. +/*  
  41.   * Values describing the status of a force-feedback effect  
  42.   */ 
  43.  #define FF_STATUS_STOPPED      0x00   
  44. @@ -1310,6 +1329,11 @@   
  45.         input_event(dev, EV_SYN, SYN_REPORT, 0);   
  46.  }   
  47.     
  48. +static inline void input_mt_sync(struct input_dev *dev)   
  49. +{   
  50. +       input_event(dev, EV_SYN, SYN_MT_REPORT, 0);   
  51. +}   
  52. +   
  53.  void input_set_capability(struct input_dev *dev, unsigned int type, unsigned int code);  

2、修改drivers/input/input.c

  1. Index: drivers/input/input.c   
  2. ===================================================================   
  3. --- drivers/input/input.c       (revision 1550)   
  4. +++ drivers/input/input.c       (working copy)   
  5. @@ -29,6 +29,25 @@   
  6.     
  7.  #define INPUT_DEVICES  256   
  8.     
  9. +/*  
  10. + * EV_ABS events which should not be cached are listed here.  
  11. + */  
  12. +static unsigned int input_abs_bypass_init_data[] __initdata = {   
  13. +       ABS_MT_TOUCH_MAJOR,   
  14. +       ABS_MT_TOUCH_MINOR,   
  15. +       ABS_MT_WIDTH_MAJOR,   
  16. +       ABS_MT_WIDTH_MINOR,   
  17. +       ABS_MT_ORIENTATION,   
  18. +       ABS_MT_POSITION_X,   
  19. +       ABS_MT_POSITION_Y,   
  20. +       ABS_MT_TOOL_TYPE,   
  21. +       ABS_MT_BLOB_ID,   
  22. +       ABS_MT_TRACKING_ID,   
  23. +       0   
  24. +};   
  25. +static unsigned long input_abs_bypass[BITS_TO_LONGS(ABS_CNT)];   
  26. +   
  27. +   
  28.  static LIST_HEAD(input_dev_list);   
  29.  static LIST_HEAD(input_handler_list);   
  30.     
  31. @@ -149,13 +168,17 @@   
  32.                 case SYN_CONFIG:   
  33.                         disposition = INPUT_PASS_TO_ALL;   
  34.                         break;   
  35. -   
  36. +   
  37.                 case SYN_REPORT:   
  38.                         if (!dev->sync) {   
  39.                                 dev->sync = 1;   
  40.                                 disposition = INPUT_PASS_TO_HANDLERS;   
  41.                         }   
  42.                         break;   
  43. +               case SYN_MT_REPORT:   
  44. +                       dev->sync = 0;   
  45. +                       disposition = INPUT_PASS_TO_HANDLERS;   
  46. +                       break;   
  47.                 }   
  48.                 break;   
  49.     
  50. @@ -185,6 +208,11 @@   
  51.         case EV_ABS:   
  52.                 if (is_event_supported(code, dev->absbit, ABS_MAX)) {   
  53.     
  54. +                       if (test_bit(code, input_abs_bypass)) {   
  55. +                               disposition = INPUT_PASS_TO_HANDLERS;   
  56. +                               break;   
  57. +                       }   
  58. +   
  59.                         value = input_defuzz_abs_event(value,   
  60.                                         dev->abs[code], dev->absfuzz[code]);   
  61.     
  62. @@ -1630,10 +1658,20 @@   
  63.         .open = input_open_file,   
  64.  };   
  65.     
  66. +static void __init input_init_abs_bypass(void)   
  67. +{   
  68. +       const unsigned int *p;   
  69. +   
  70. +       for (p = input_abs_bypass_init_data; *p; p++)   
  71. +               input_abs_bypass[BIT_WORD(*p)] |= BIT_MASK(*p);   
  72. +}   
  73. +   
  74.  static int __init input_init(void)   
  75.  {   
  76.         int err;   
  77.     
  78. +       input_init_abs_bypass();   
  79. +   
  80.         err = class_register(&input_class);   
  81.         if (err) {   
  82.                 printk(KERN_ERR "input: unable to register input_dev class\n");  

3、输入子系统的初始化

  1. input_dev->evbit[0] = BIT(EV_SYN) | BIT(EV_KEY) | BIT(EV_ABS);   
  2. input_dev->absbit[0] =    
  3.  BIT_MASK(ABS_X) |   
  4.  BIT_MASK(ABS_Y) |    
  5.  BIT_MASK(ABS_MT_TOUCH_MAJOR) |   
  6.  BIT_MASK(ABS_MT_WIDTH_MAJOR) |   
  7.  BIT_MASK(ABS_MT_POSITION_X) |   
  8.  BIT_MASK(ABS_MT_POSITION_Y) |   
  9.  BIT_MASK(ABS_MT_TRACKING_ID);  

4、子系统上报

  1. input_report_key(ts->input, ABS_MT_TRACKING_ID, touch_num);    
  2. input_report_abs(ts->input, ABS_MT_POSITION_X,  mxt224_datablock.T_point[touch_num].x);   
  3. input_report_abs(ts->input, ABS_MT_POSITION_Y, mxt224_datablock.T_point[touch_num].y);   
  4. input_report_abs(ts->input, ABS_MT_TOUCH_MAJOR, mxt224_datablock.T_point[touch_num].amplitude);   
  5. input_report_abs(ts->input, ABS_MT_WIDTH_MAJOR, mxt224_datablock.T_point[touch_num].area);   
  6. input_report_abs(ts->input, ABS_PRESSURE,mxt224_datablock.T_gesture[touch_num].value);    
  7. /*input_report_key(ts->input, BTN_TOUCH, 1);*/  
  8.   
  9. input_mt_sync(ts->input);  

相关内容