* patches 1-9 has already been reviewed and are ready for inclusion I would say.
* Jiri, I kept your ack on patch 4 even if I changed the place of the comment in hid.h
* patch 10 is half new as it is splitted from a patch of the v3
* patch 11 has been changed according to Henrik's comments
* patches 12-13 have been splitted since v3 to introduce QUIRK_HOVERING and setup WIN 8
devices in a better way.
* patch 14 has been copied from the v3 as Dmitry wanted to use a MSC event for the timestamp.
Cheers,
Benjamin
v1 introduction:
So, this is an update for supporting Win 8 multitouch devices in the kernel.
As I wanted to reliably forward the resolution, I noticed a bug in the
processing of the unit_exponent in the hid core layer.
Thus the fixes for hid-core and hid-input.
v2 changes:
* added missing initial patch that prevents the series to be applied on top of Jiri's tree
* update to include latest hid changes
* taken into account Alan's patch: "hid: put the case in the right switch statement"
v3 changes:
* splitted "round return value of hidinput_calc_abs_res" in a separate patch
* export snto32 in hid.h as we need to use it in hid-input.c
* didn't change all drivers, but add a field in hid_usage instead
* add quirk MT_QUIRK_IGNORE_DUPLICATES so that any device can rely on it
* easier understandable support of hovering devices
* changed scan time definition
* applied new definition of scan time in hid-multitouch
* some other few things.
v4 changes:
* introduced QUIRK_HOVERING for hovering devices (not necessarily win 8 ones)
* removed QUIRK_WIN8_CERTIFIED as it's not relevant anymore
* made the change in input-mt.c
* add a test against input->mt != null
Benjamin Tissoires (14):
HID: hid-input: export hidinput_calc_abs_res
HID: hid-input: round return value of hidinput_calc_abs_res
HID: core: fix unit exponent parsing
HID: hid-input: add usage_index in struct hid_usage.
HID: hid-multitouch: support arrays for the split of the touches in a
report
HID: hid-multitouch: get maxcontacts also from logical_max value
HID: hid-multitouch: support T and C for win8 devices
HID: hid-multitouch: move ALWAYS_VALID quirk check
Input: introduce EV_MSC Timestamp
Input: mt: add input_mt_is_used
HID: hid-multitouch: add MT_QUIRK_IGNORE_DUPLICATES
HID: hid-multitouch: support for hovering devices
HID: hid-multitouch: fix Win 8 protocol
HID: hid-multitouch: forwards MSC_TIMESTAMP
hidinput_calc_abs_res should return the closest int in the division
instead of the floor.
On a device with a logical_max of 3008 and a physical_max of 255mm,
previous implementation gave a resolution of 11 instead of 12.
With 11, user-space computes a physical size of 273.5mm and the
round_closest results gives 250.6mm.
The old implementation introduced an error of 2cm in this example.
Computes the device timestamp according to the specification.
It also ensures that if the time between two events is greater
than MAX_TIMESTAMP_INTERVAL, the timestamp will be reset.
@@ -98,6 +99,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 */
+ unsigned timestamp; /* the timestamp to be sent */
};
Some devices provides the actual timestamp (hid_dg_scan_time in win8 ones)
computed by the hardware itself. This value is global to the frame and is
not specific to the multitouch protocol.
diff --git a/Documentation/input/event-codes.txt b/Documentation/input/event-codes.txt
index 53305bd..f1ea2c6 100644
--- a/Documentation/input/event-codes.txt
+++ b/Documentation/input/event-codes.txt
@@ -196,6 +196,17 @@ EV_MSC:
EV_MSC events are used for input and output events that do not fall under other
categories.
+A few EV_MSC codes have special meaning:
+
+* MSC_TIMESTAMP:
+ - Used to report the number of microseconds since the last reset. This event
+ should be coded as an uint32 value, which is allowed to wrap around with
+ no special consequence. It is assumed that the time difference between two
+ consecutive events is reliable on a reasonable time scale (hours).
+ A reset to zero can happen, in which case the time since the last event is
+ unknown. If the device does not provide this information, the driver must
+ not provide it to user space.
+
EV_LED:
----------
EV_LED events are used for input and output to set and query the state of
diff --git a/include/linux/input.h b/include/linux/input.h
index ba48743..25354f3 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -858,6 +858,7 @@ struct input_keymap_entry {
#define MSC_GESTURE 0x02
#define MSC_RAW 0x03
#define MSC_SCAN 0x04
+#define MSC_TIMESTAMP 0x05
#define MSC_MAX 0x07
#define MSC_CNT (MSC_MAX+1)
Exporting the function allows us to calculate the resolution in third
party drivers like hid-multitouch.
This patch also complete the function with additional valid axes.
Win 8 device specification changed the requirements for the hid usages
of the multitouch devices. Now InRange is optional and must be only
used when the device supports hovering.
This ensures that the quirk ALWAYS_VALID is taken into account and
also ensures its precedence over the other VALID* quirks.
Signed-off-by: Benjamin Tissoires <benjamin.tissoi...@gmail.com>
Reviewed-by: Henrik Rydberg <rydb...@euromail.se>
---
drivers/hid/hid-multitouch.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
Win8 devices are required to present the feature "Maximum Contact Number".
Fortunately all win7 devices I've seen presents this feature.
If the current value is 0, then, the driver can get the actual supported
contact count by refering to the logical_max.
This win8 specification ensures that logical_max may not be above 250.
This also allows us to detect when devices like irtouch or stantum reports
an obviously wrong value of 255.
Signed-off-by: Benjamin Tissoires <benjamin.tissoi...@gmail.com>
Acked-by: Henrik Rydberg <rydb...@euromail.se>
---
drivers/hid/hid-multitouch.c | 4 ++++
1 file changed, 4 insertions(+)
Win8 devices supporting hovering must provides InRange HID field.
The information that the finger is here but is not touching the surface
is sent to the user space through ABS_MT_DISTANCE as required by the
multitouch protocol.
struct mt_slot {
__s32 x, y, cx, cy, p, w, h;
__s32 contactid; /* the device ContactID assigned to this slot */
bool touch_state; /* is the touch valid? */
+ bool inrange_state; /* is the finger in proximity of the sensor? */
};
Win8 input specification clarifies the X and Y sent by devices.
It distincts the position where the user wants to Touch (T) from
the center of the ellipsoide (C). This patch enable supports for this
distinction in hid-multitouch.
Signed-off-by: Benjamin Tissoires <benjamin.tissoi...@gmail.com>
Reviewed-by: Henrik Rydberg <rydb...@euromail.se>
---
drivers/hid/hid-multitouch.c | 46 +++++++++++++++++++++++++++++++++++---------
1 file changed, 37 insertions(+), 9 deletions(-)
struct mt_slot {
- __s32 x, y, p, w, h;
+ __s32 x, y, cx, cy, p, w, h;
__s32 contactid; /* the device ContactID assigned to this slot */
bool touch_state; /* is the touch valid? */
};
@@ -323,6 +323,7 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
struct mt_device *td = hid_get_drvdata(hdev);
struct mt_class *cls = &td->mtclass;
int code;
+ struct hid_usage *prev_usage = NULL;
/* Only map fields from TouchScreen or TouchPad collections.
* We need to ignore fields that belong to other collections
@@ -345,23 +346,42 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
if (field->physical == HID_DG_STYLUS)
return -1;
Currently, there is no way to know the index of the current field
in the .input_mapping and .event callbacks when this field is inside
an array of HID fields.
This patch adds this index to the struct hid_usage so that this
information is available to input_mapping and event callbacks.
The Win 8 protocol specify the fact that each valid touch must be reported
within a frame until it is released.
We can therefore use the always_valid quirk and dismiss reports when we see
duplicate contacts ID.
We recognize Win8 certified devices from their vendor feature 0xff0000c5
where Microsoft put a signed blob in the report to check if the device
passed the certification.
On Wed, Nov 14, 2012 at 04:59:21PM +0100, Benjamin Tissoires wrote:
> Some devices provides the actual timestamp (hid_dg_scan_time in win8 ones)
> computed by the hardware itself. This value is global to the frame and is
> not specific to the multitouch protocol.
> Signed-off-by: Benjamin Tissoires <benjamin.tissoi...@gmail.com>
> Reviewed-by: Henrik Rydberg <rydb...@euromail.se>
> diff --git a/Documentation/input/event-codes.txt b/Documentation/input/event-codes.txt
> index 53305bd..f1ea2c6 100644
> --- a/Documentation/input/event-codes.txt
> +++ b/Documentation/input/event-codes.txt
> @@ -196,6 +196,17 @@ EV_MSC:
> EV_MSC events are used for input and output events that do not fall under other
> categories.
> +A few EV_MSC codes have special meaning:
> +
> +* MSC_TIMESTAMP:
> + - Used to report the number of microseconds since the last reset. This event
> + should be coded as an uint32 value, which is allowed to wrap around with
> + no special consequence. It is assumed that the time difference between two
> + consecutive events is reliable on a reasonable time scale (hours).
> + A reset to zero can happen, in which case the time since the last event is
> + unknown. If the device does not provide this information, the driver must
> + not provide it to user space.
> +
> EV_LED:
> ----------
> EV_LED events are used for input and output to set and query the state of
> diff --git a/include/linux/input.h b/include/linux/input.h
> index ba48743..25354f3 100644
> --- a/include/linux/input.h
> +++ b/include/linux/input.h
> @@ -858,6 +858,7 @@ struct input_keymap_entry {
> #define MSC_GESTURE 0x02
> #define MSC_RAW 0x03
> #define MSC_SCAN 0x04
> +#define MSC_TIMESTAMP 0x05
> #define MSC_MAX 0x07
> #define MSC_CNT (MSC_MAX+1)
On Wed, Nov 14, 2012 at 04:59:22PM +0100, Benjamin Tissoires wrote:
> This patch extracts the test (slot->frame == mt->frame) so that it can
> be used in third party drivers.
On Wed, Nov 14, 2012 at 04:59:21PM +0100, Benjamin Tissoires wrote:
> Some devices provides the actual timestamp (hid_dg_scan_time in win8 ones)
> computed by the hardware itself. This value is global to the frame and is
> not specific to the multitouch protocol.
> Signed-off-by: Benjamin Tissoires <benjamin.tissoi...@gmail.com>
> Reviewed-by: Henrik Rydberg <rydb...@euromail.se>
> ---
Does not directly apply to 3.7 due to the uapi changes, but trivial enough.
On Wed, Nov 14, 2012 at 04:59:23PM +0100, Benjamin Tissoires wrote:
> This quirk allows a device to reuse a contact id when sending garbage
> inactive contacts at the end of a report.
On Wed, Nov 14, 2012 at 04:59:24PM +0100, Benjamin Tissoires wrote:
> Win8 devices supporting hovering must provides InRange HID field.
> The information that the finger is here but is not touching the surface
> is sent to the user space through ABS_MT_DISTANCE as required by the
> multitouch protocol.
> struct mt_slot {
> __s32 x, y, cx, cy, p, w, h;
> __s32 contactid; /* the device ContactID assigned to this slot */
> bool touch_state; /* is the touch valid? */
> + bool inrange_state; /* is the finger in proximity of the sensor? */
> };
On Wed, Nov 14, 2012 at 04:59:25PM +0100, Benjamin Tissoires wrote:
> The Win 8 protocol specify the fact that each valid touch must be reported
> within a frame until it is released.
> We can therefore use the always_valid quirk and dismiss reports when we see
> duplicate contacts ID.
> We recognize Win8 certified devices from their vendor feature 0xff0000c5
> where Microsoft put a signed blob in the report to check if the device
> passed the certification.
> Computes the device timestamp according to the specification.
> It also ensures that if the time between two events is greater
> than MAX_TIMESTAMP_INTERVAL, the timestamp will be reset.
> Signed-off-by: Benjamin Tissoires <benjamin.tissoi...@gmail.com>
> ---
This was not what I envisioned from the discussion yesterday, I was
probably too vague. Firstly, the absolute time interval checked seems
to be 500 ms, which is arbitrary. Second, the wrap should probably use
(logical_maximum + 1). Third, we are still not sure whether we should
take the 'time = 0 means reset' logic literally, I think it needs to
be tested.
In light of this, I would like to suggest the patch below instead. It
should follow the current interpretation of the definition to the
letter. I imagine very few devices will actually do anything but wrap
the counter, but that remains to be seen. In that case, we could
simplify the code further, since we will have no hope of detecting
large intervals properly anyways.
Thanks,
Henrik
From 448808dd988e96d58b79148292fde147935305ab Mon Sep 17 00:00:00 2001
From: Henrik Rydberg <rydb...@euromail.se>
Date: Wed, 14 Nov 2012 20:53:17 +0100
Subject: [PATCH] HID: hid-multitouch: send the device timestamp when present
Compute and relay the device timestamp when present. The counter
value range varies between devices, but the MSC_TIMESTAMP event
is always 32 bits long. A value of zero means the time since the
previous event is unknown.
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index 61543c0..586f9c6 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -98,6 +98,8 @@ 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 */
+ unsigned dev_time; /* device scan time in units of 100 us */
+ unsigned timestamp; /* the timestamp to be sent */
};
/* classes of device behavior */
@@ -458,12 +460,19 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
mt_store_field(usage, td, hi);
td->last_field_index = field->index;
return 1;
+ case HID_DG_SCANTIME:
+ hid_map_usage(hi, usage, bit, max,
+ EV_MSC, MSC_TIMESTAMP);
+ set_bit(MSC_TIMESTAMP, hi->input->mscbit);
+ td->last_field_index = field->index;
+ return 1;
case HID_DG_CONTACTCOUNT:
td->last_field_index = field->index;
return 1;
case HID_DG_CONTACTMAX:
- /* we don't set td->last_slot_field as contactcount and
- * contact max are global to the report */
+ /* we don't set td->last_slot_field as scan time,
+ * contactcount and contact max are global to the
+ * report */
td->last_field_index = field->index;
return -1;
case HID_DG_TOUCH:
@@ -492,7 +501,8 @@ static int mt_input_mapped(struct hid_device *hdev, struct hid_input *hi,
struct hid_field *field, struct hid_usage *usage,
unsigned long **bit, int *max)
{
- if (usage->type == EV_KEY || usage->type == EV_ABS)
+ if (usage->type == EV_KEY || usage->type == EV_ABS ||
+ usage->type == EV_MSC)
set_bit(usage->type, hi->input->evbit);
> * patches 1-9 has already been reviewed and are ready for inclusion I would say.
> * Jiri, I kept your ack on patch 4 even if I changed the place of the comment in hid.h
> * patch 10 is half new as it is splitted from a patch of the v3
> * patch 11 has been changed according to Henrik's comments
> * patches 12-13 have been splitted since v3 to introduce QUIRK_HOVERING and setup WIN 8
> devices in a better way.
> * patch 14 has been copied from the v3 as Dmitry wanted to use a MSC event for the timestamp.
Everything but the last patch looks good now, me thinks. Thanks!
>> Computes the device timestamp according to the specification.
>> It also ensures that if the time between two events is greater
>> than MAX_TIMESTAMP_INTERVAL, the timestamp will be reset.
>> Signed-off-by: Benjamin Tissoires <benjamin.tissoi...@gmail.com>
>> ---
> This was not what I envisioned from the discussion yesterday, I was
> probably too vague. Firstly, the absolute time interval checked seems
> to be 500 ms, which is arbitrary. Second, the wrap should probably use
Not exactly. The time interval was 5s, near enough the minimum requirement for this field (6.5535 s).
> (logical_maximum + 1). Third, we are still not sure whether we should
> take the 'time = 0 means reset' logic literally, I think it needs to
> be tested.
Again, the device I have never does any reset at the first touch, it just wraps the counter.
The problem is that when there is no event, we now that no events occurred since the previous timestamp, modulus 6.5535 seconds.
> In light of this, I would like to suggest the patch below instead. It
> should follow the current interpretation of the definition to the
> letter. I imagine very few devices will actually do anything but wrap
> the counter, but that remains to be seen. In that case, we could
> simplify the code further, since we will have no hope of detecting
> large intervals properly anyways.
> Thanks,
> Henrik
> From 448808dd988e96d58b79148292fde147935305ab Mon Sep 17 00:00:00 2001
> From: Henrik Rydberg <rydb...@euromail.se>
> Date: Wed, 14 Nov 2012 20:53:17 +0100
> Subject: [PATCH] HID: hid-multitouch: send the device timestamp when present
> Compute and relay the device timestamp when present. The counter
> value range varies between devices, but the MSC_TIMESTAMP event
> is always 32 bits long. A value of zero means the time since the
> previous event is unknown.
> diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
> index 61543c0..586f9c6 100644
> --- a/drivers/hid/hid-multitouch.c
> +++ b/drivers/hid/hid-multitouch.c
> @@ -98,6 +98,8 @@ 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 */
> + unsigned dev_time; /* device scan time in units of 100 us */
> + unsigned timestamp; /* the timestamp to be sent */
> };
> /* classes of device behavior */
> @@ -458,12 +460,19 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
> mt_store_field(usage, td, hi);
> td->last_field_index = field->index;
> return 1;
> + case HID_DG_SCANTIME:
> + hid_map_usage(hi, usage, bit, max,
> + EV_MSC, MSC_TIMESTAMP);
> + set_bit(MSC_TIMESTAMP, hi->input->mscbit);
> + td->last_field_index = field->index;
> + return 1;
> case HID_DG_CONTACTCOUNT:
> td->last_field_index = field->index;
> return 1;
> case HID_DG_CONTACTMAX:
> - /* we don't set td->last_slot_field as contactcount and
> - * contact max are global to the report */
> + /* we don't set td->last_slot_field as scan time,
> + * contactcount and contact max are global to the
> + * report */
> td->last_field_index = field->index;
> return -1;
> case HID_DG_TOUCH:
> @@ -492,7 +501,8 @@ static int mt_input_mapped(struct hid_device *hdev, struct hid_input *hi,
> struct hid_field *field, struct hid_usage *usage,
> unsigned long **bit, int *max)
> {
> - if (usage->type == EV_KEY || usage->type == EV_ABS)
> + if (usage->type == EV_KEY || usage->type == EV_ABS ||
> + usage->type == EV_MSC)
> set_bit(usage->type, hi->input->evbit);
The curious thing is that this is not working on my kernel:
this is the output of the following printk:
printk(KERN_ERR "%s timestamp=%d value=%d dt=%d field->logical_maximum=%d !td->timestamp=%d\n", __func__, td->timestamp, value, dt, field->logical_maximum, !td->timestamp);
I don't understand the meaning of adding !td->timestamp. :/
> + } else {
> + td->timestamp = 0;
My particular device never falls into this case... So I never reset the timestamp.
This is problematic because we compute the timestamp on an unsigned, and the struct input_absinfo sends __s32... I'm afraid we will have some troubles after a long use of the device.
Anyway, many thanks for the review of this whole patchset!
On Wed, 14 Nov 2012, Dmitry Torokhov wrote:
> On Wed, Nov 14, 2012 at 04:59:21PM +0100, Benjamin Tissoires wrote:
> > Some devices provides the actual timestamp (hid_dg_scan_time in win8 ones)
> > computed by the hardware itself. This value is global to the frame and is
> > not specific to the multitouch protocol.
> > Signed-off-by: Benjamin Tissoires <benjamin.tissoi...@gmail.com>
> > Reviewed-by: Henrik Rydberg <rydb...@euromail.se>
> > diff --git a/Documentation/input/event-codes.txt b/Documentation/input/event-codes.txt
> > index 53305bd..f1ea2c6 100644
> > --- a/Documentation/input/event-codes.txt
> > +++ b/Documentation/input/event-codes.txt
> > @@ -196,6 +196,17 @@ EV_MSC:
> > EV_MSC events are used for input and output events that do not fall under other
> > categories.
> > +A few EV_MSC codes have special meaning:
> > +
> > +* MSC_TIMESTAMP:
> > + - Used to report the number of microseconds since the last reset. This event
> > + should be coded as an uint32 value, which is allowed to wrap around with
> > + no special consequence. It is assumed that the time difference between two
> > + consecutive events is reliable on a reasonable time scale (hours).
> > + A reset to zero can happen, in which case the time since the last event is
> > + unknown. If the device does not provide this information, the driver must
> > + not provide it to user space.
> > +
> > EV_LED:
> > ----------
> > EV_LED events are used for input and output to set and query the state of
> > diff --git a/include/linux/input.h b/include/linux/input.h
> > index ba48743..25354f3 100644
> > --- a/include/linux/input.h
> > +++ b/include/linux/input.h
> > @@ -858,6 +858,7 @@ struct input_keymap_entry {
> > #define MSC_GESTURE 0x02
> > #define MSC_RAW 0x03
> > #define MSC_SCAN 0x04
> > +#define MSC_TIMESTAMP 0x05
> > #define MSC_MAX 0x07
> > #define MSC_CNT (MSC_MAX+1)
On Wed, 14 Nov 2012, Henrik Rydberg wrote:
> > * patches 1-9 has already been reviewed and are ready for inclusion I would say.
> > * Jiri, I kept your ack on patch 4 even if I changed the place of the comment in hid.h
> > * patch 10 is half new as it is splitted from a patch of the v3
> > * patch 11 has been changed according to Henrik's comments
> > * patches 12-13 have been splitted since v3 to introduce QUIRK_HOVERING and setup WIN 8
> > devices in a better way.
> > * patch 14 has been copied from the v3 as Dmitry wanted to use a MSC event for the timestamp.
> Everything but the last patch looks good now, me thinks. Thanks!
I have now applied everything (with all the gathered Acks/Reviewed-by incorporated) but the patch #14.