Merge branch 'for-4.15/multitouch' into for-linus
authorJiri Kosina <jkosina@suse.cz>
Wed, 15 Nov 2017 10:08:49 +0000 (11:08 +0100)
committerJiri Kosina <jkosina@suse.cz>
Wed, 15 Nov 2017 10:09:23 +0000 (11:09 +0100)
- make sure that we forward MSC_TIMESTAMP in accordance to the specification,
  from Nicolas Boichat

Signed-off-by: Jiri Kosina <jkosina@suse.cz>
1  2 
drivers/hid/hid-multitouch.c

index 9e8c4d2ba11d2cc7c2559f34dc46fe646640e131,996bdc9bf0e50a7d2db579e2eb5d5c388a01e61d..86fd7f4b1b26552774794a3be39958b123e9eaba
@@@ -43,6 -43,7 +43,7 @@@
  #include <linux/module.h>
  #include <linux/slab.h>
  #include <linux/input/mt.h>
+ #include <linux/jiffies.h>
  #include <linux/string.h>
  #include <linux/timer.h>
  
@@@ -136,6 -137,9 +137,9 @@@ struct mt_device 
        bool serial_maybe;      /* need to check for serial protocol */
        bool curvalid;          /* is the current contact valid? */
        unsigned mt_flags;      /* flags to pass to input-mt */
+       __s32 dev_time;         /* the scan time provided by the device */
+       unsigned long jiffies;  /* the frame's jiffies */
+       int timestamp;          /* the timestamp to be sent */
  };
  
  static void mt_post_parse_default_settings(struct mt_device *td);
@@@ -177,6 -181,12 +181,12 @@@ static void mt_post_parse(struct mt_dev
  #define MT_DEFAULT_MAXCONTACT 10
  #define MT_MAX_MAXCONTACT     250
  
+ /*
+  * Resync device and local timestamps after that many microseconds without
+  * receiving data.
+  */
+ #define MAX_TIMESTAMP_INTERVAL        1000000
  #define MT_USB_DEVICE(v, p)   HID_DEVICE(BUS_USB, HID_GROUP_MULTITOUCH, v, p)
  #define MT_BT_DEVICE(v, p)    HID_DEVICE(BUS_BLUETOOTH, HID_GROUP_MULTITOUCH, v, p)
  
@@@ -583,6 -593,12 +593,12 @@@ static int mt_touch_input_mapping(struc
                                cls->sn_pressure);
                        mt_store_field(usage, td, hi);
                        return 1;
+               case HID_DG_SCANTIME:
+                       hid_map_usage(hi, usage, bit, max,
+                               EV_MSC, MSC_TIMESTAMP);
+                       input_set_capability(hi->input, EV_MSC, MSC_TIMESTAMP);
+                       mt_store_field(usage, td, hi);
+                       return 1;
                case HID_DG_CONTACTCOUNT:
                        /* Ignore if indexes are out of bounds. */
                        if (field->index >= field->report->maxfield ||
@@@ -718,6 -734,7 +734,7 @@@ static void mt_complete_slot(struct mt_
  static void mt_sync_frame(struct mt_device *td, struct input_dev *input)
  {
        input_mt_sync_frame(input);
+       input_event(input, EV_MSC, MSC_TIMESTAMP, td->timestamp);
        input_sync(input);
        td->num_received = 0;
        if (test_bit(MT_IO_FLAGS_ACTIVE_SLOTS, &td->mt_io_flags))
        clear_bit(MT_IO_FLAGS_ACTIVE_SLOTS, &td->mt_io_flags);
  }
  
+ static int mt_compute_timestamp(struct mt_device *td, struct hid_field *field,
+               __s32 value)
+ {
+       long delta = value - td->dev_time;
+       unsigned long jdelta = jiffies_to_usecs(jiffies - td->jiffies);
+       td->jiffies = jiffies;
+       td->dev_time = value;
+       if (delta < 0)
+               delta += field->logical_maximum;
+       /* HID_DG_SCANTIME is expressed in 100us, we want it in us. */
+       delta *= 100;
+       if (jdelta > MAX_TIMESTAMP_INTERVAL)
+               /* No data received for a while, resync the timestamp. */
+               return 0;
+       else
+               return td->timestamp + delta;
+ }
  static int mt_touch_event(struct hid_device *hid, struct hid_field *field,
                                struct hid_usage *usage, __s32 value)
  {
@@@ -787,6 -826,9 +826,9 @@@ static void mt_process_mt_event(struct 
                case HID_DG_HEIGHT:
                        td->curdata.h = value;
                        break;
+               case HID_DG_SCANTIME:
+                       td->timestamp = mt_compute_timestamp(td, field, value);
+                       break;
                case HID_DG_CONTACTCOUNT:
                        break;
                case HID_DG_TOUCH:
@@@ -930,7 -972,6 +972,7 @@@ static int mt_input_mapping(struct hid_
            field->application != HID_DG_PEN &&
            field->application != HID_DG_TOUCHPAD &&
            field->application != HID_GD_KEYBOARD &&
 +          field->application != HID_GD_SYSTEM_CONTROL &&
            field->application != HID_CP_CONSUMER_CONTROL &&
            field->application != HID_GD_WIRELESS_RADIO_CTLS &&
            !(field->application == HID_VD_ASUS_CUSTOM_MEDIA_KEYS &&
@@@ -1420,12 -1461,6 +1462,12 @@@ static const struct hid_device_id mt_de
                        USB_VENDOR_ID_ALPS_JP,
                        HID_DEVICE_ID_ALPS_U1_DUAL_3BTN_PTP) },
  
 +      /* Lenovo X1 TAB Gen 2 */
 +      { .driver_data = MT_CLS_WIN_8_DUAL,
 +              HID_DEVICE(BUS_USB, HID_GROUP_MULTITOUCH_WIN_8,
 +                         USB_VENDOR_ID_LENOVO,
 +                         USB_DEVICE_ID_LENOVO_X1_TAB) },
 +
        /* Anton devices */
        { .driver_data = MT_CLS_EXPORT_ALL_INPUTS,
                MT_USB_DEVICE(USB_VENDOR_ID_ANTON,