diff options
author | Jiri Kosina <jkosina@suse.cz> | 2017-11-15 05:08:49 -0500 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2017-11-15 05:09:23 -0500 |
commit | ea3bbd0a2117d7291ae705caffbb99089315ec7b (patch) | |
tree | 6f2324daba8e224a4cd8a7fb8d07f71a7a58d7ae | |
parent | 6101cb7ea26efd4b6b4f15b4db707bb097cf97eb (diff) | |
parent | 29cc309d8bf19a36c5196bf626662319af6e3c0b (diff) |
Merge branch 'for-4.15/multitouch' into for-linus
- make sure that we forward MSC_TIMESTAMP in accordance to the specification,
from Nicolas Boichat
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
-rw-r--r-- | drivers/hid/hid-multitouch.c | 42 | ||||
-rw-r--r-- | include/linux/hid.h | 1 |
2 files changed, 43 insertions, 0 deletions
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 9e8c4d2ba11d..86fd7f4b1b26 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c | |||
@@ -43,6 +43,7 @@ | |||
43 | #include <linux/module.h> | 43 | #include <linux/module.h> |
44 | #include <linux/slab.h> | 44 | #include <linux/slab.h> |
45 | #include <linux/input/mt.h> | 45 | #include <linux/input/mt.h> |
46 | #include <linux/jiffies.h> | ||
46 | #include <linux/string.h> | 47 | #include <linux/string.h> |
47 | #include <linux/timer.h> | 48 | #include <linux/timer.h> |
48 | 49 | ||
@@ -136,6 +137,9 @@ struct mt_device { | |||
136 | bool serial_maybe; /* need to check for serial protocol */ | 137 | bool serial_maybe; /* need to check for serial protocol */ |
137 | bool curvalid; /* is the current contact valid? */ | 138 | bool curvalid; /* is the current contact valid? */ |
138 | unsigned mt_flags; /* flags to pass to input-mt */ | 139 | unsigned mt_flags; /* flags to pass to input-mt */ |
140 | __s32 dev_time; /* the scan time provided by the device */ | ||
141 | unsigned long jiffies; /* the frame's jiffies */ | ||
142 | int timestamp; /* the timestamp to be sent */ | ||
139 | }; | 143 | }; |
140 | 144 | ||
141 | static void mt_post_parse_default_settings(struct mt_device *td); | 145 | static void mt_post_parse_default_settings(struct mt_device *td); |
@@ -177,6 +181,12 @@ static void mt_post_parse(struct mt_device *td); | |||
177 | #define MT_DEFAULT_MAXCONTACT 10 | 181 | #define MT_DEFAULT_MAXCONTACT 10 |
178 | #define MT_MAX_MAXCONTACT 250 | 182 | #define MT_MAX_MAXCONTACT 250 |
179 | 183 | ||
184 | /* | ||
185 | * Resync device and local timestamps after that many microseconds without | ||
186 | * receiving data. | ||
187 | */ | ||
188 | #define MAX_TIMESTAMP_INTERVAL 1000000 | ||
189 | |||
180 | #define MT_USB_DEVICE(v, p) HID_DEVICE(BUS_USB, HID_GROUP_MULTITOUCH, v, p) | 190 | #define MT_USB_DEVICE(v, p) HID_DEVICE(BUS_USB, HID_GROUP_MULTITOUCH, v, p) |
181 | #define MT_BT_DEVICE(v, p) HID_DEVICE(BUS_BLUETOOTH, HID_GROUP_MULTITOUCH, v, p) | 191 | #define MT_BT_DEVICE(v, p) HID_DEVICE(BUS_BLUETOOTH, HID_GROUP_MULTITOUCH, v, p) |
182 | 192 | ||
@@ -583,6 +593,12 @@ static int mt_touch_input_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
583 | cls->sn_pressure); | 593 | cls->sn_pressure); |
584 | mt_store_field(usage, td, hi); | 594 | mt_store_field(usage, td, hi); |
585 | return 1; | 595 | return 1; |
596 | case HID_DG_SCANTIME: | ||
597 | hid_map_usage(hi, usage, bit, max, | ||
598 | EV_MSC, MSC_TIMESTAMP); | ||
599 | input_set_capability(hi->input, EV_MSC, MSC_TIMESTAMP); | ||
600 | mt_store_field(usage, td, hi); | ||
601 | return 1; | ||
586 | case HID_DG_CONTACTCOUNT: | 602 | case HID_DG_CONTACTCOUNT: |
587 | /* Ignore if indexes are out of bounds. */ | 603 | /* Ignore if indexes are out of bounds. */ |
588 | if (field->index >= field->report->maxfield || | 604 | if (field->index >= field->report->maxfield || |
@@ -718,6 +734,7 @@ static void mt_complete_slot(struct mt_device *td, struct input_dev *input) | |||
718 | static void mt_sync_frame(struct mt_device *td, struct input_dev *input) | 734 | static void mt_sync_frame(struct mt_device *td, struct input_dev *input) |
719 | { | 735 | { |
720 | input_mt_sync_frame(input); | 736 | input_mt_sync_frame(input); |
737 | input_event(input, EV_MSC, MSC_TIMESTAMP, td->timestamp); | ||
721 | input_sync(input); | 738 | input_sync(input); |
722 | td->num_received = 0; | 739 | td->num_received = 0; |
723 | if (test_bit(MT_IO_FLAGS_ACTIVE_SLOTS, &td->mt_io_flags)) | 740 | if (test_bit(MT_IO_FLAGS_ACTIVE_SLOTS, &td->mt_io_flags)) |
@@ -727,6 +744,28 @@ static void mt_sync_frame(struct mt_device *td, struct input_dev *input) | |||
727 | clear_bit(MT_IO_FLAGS_ACTIVE_SLOTS, &td->mt_io_flags); | 744 | clear_bit(MT_IO_FLAGS_ACTIVE_SLOTS, &td->mt_io_flags); |
728 | } | 745 | } |
729 | 746 | ||
747 | static int mt_compute_timestamp(struct mt_device *td, struct hid_field *field, | ||
748 | __s32 value) | ||
749 | { | ||
750 | long delta = value - td->dev_time; | ||
751 | unsigned long jdelta = jiffies_to_usecs(jiffies - td->jiffies); | ||
752 | |||
753 | td->jiffies = jiffies; | ||
754 | td->dev_time = value; | ||
755 | |||
756 | if (delta < 0) | ||
757 | delta += field->logical_maximum; | ||
758 | |||
759 | /* HID_DG_SCANTIME is expressed in 100us, we want it in us. */ | ||
760 | delta *= 100; | ||
761 | |||
762 | if (jdelta > MAX_TIMESTAMP_INTERVAL) | ||
763 | /* No data received for a while, resync the timestamp. */ | ||
764 | return 0; | ||
765 | else | ||
766 | return td->timestamp + delta; | ||
767 | } | ||
768 | |||
730 | static int mt_touch_event(struct hid_device *hid, struct hid_field *field, | 769 | static int mt_touch_event(struct hid_device *hid, struct hid_field *field, |
731 | struct hid_usage *usage, __s32 value) | 770 | struct hid_usage *usage, __s32 value) |
732 | { | 771 | { |
@@ -787,6 +826,9 @@ static void mt_process_mt_event(struct hid_device *hid, struct hid_field *field, | |||
787 | case HID_DG_HEIGHT: | 826 | case HID_DG_HEIGHT: |
788 | td->curdata.h = value; | 827 | td->curdata.h = value; |
789 | break; | 828 | break; |
829 | case HID_DG_SCANTIME: | ||
830 | td->timestamp = mt_compute_timestamp(td, field, value); | ||
831 | break; | ||
790 | case HID_DG_CONTACTCOUNT: | 832 | case HID_DG_CONTACTCOUNT: |
791 | break; | 833 | break; |
792 | case HID_DG_TOUCH: | 834 | case HID_DG_TOUCH: |
diff --git a/include/linux/hid.h b/include/linux/hid.h index ab05a86269dc..47dd962d9a7a 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h | |||
@@ -289,6 +289,7 @@ struct hid_item { | |||
289 | #define HID_DG_DEVICEINDEX 0x000d0053 | 289 | #define HID_DG_DEVICEINDEX 0x000d0053 |
290 | #define HID_DG_CONTACTCOUNT 0x000d0054 | 290 | #define HID_DG_CONTACTCOUNT 0x000d0054 |
291 | #define HID_DG_CONTACTMAX 0x000d0055 | 291 | #define HID_DG_CONTACTMAX 0x000d0055 |
292 | #define HID_DG_SCANTIME 0x000d0056 | ||
292 | #define HID_DG_BUTTONTYPE 0x000d0059 | 293 | #define HID_DG_BUTTONTYPE 0x000d0059 |
293 | #define HID_DG_BARRELSWITCH2 0x000d005a | 294 | #define HID_DG_BARRELSWITCH2 0x000d005a |
294 | #define HID_DG_TOOLSERIALNUMBER 0x000d005b | 295 | #define HID_DG_TOOLSERIALNUMBER 0x000d005b |