diff mbox

[v2,08/11] HID: hid-multitouch: fix Win 8 protocol

Message ID 1351241067-9521-9-git-send-email-benjamin.tissoires@gmail.com (mailing list archive)
State New, archived
Delegated to: Jiri Kosina
Headers show

Commit Message

Benjamin Tissoires Oct. 26, 2012, 8:44 a.m. UTC
Win 8 specification is much more precise than the Win 7 one.
Moreover devices that need to take certification must be submitted
to Microsoft.

The result is a better protocol support and we can rely on that to
skip all the messy tests we used to do.

The protocol specify the fact that each valid touch must be reported
within a frame, and that the release touch coordinate must be the
same than the last known touch.
So we can use the always_valid quirk and dismiss reports when we
touch coordiante do not follow this rule.

Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
---
 drivers/hid/hid-multitouch.c | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

Comments

Henrik Rydberg Oct. 29, 2012, 10:19 p.m. UTC | #1
On Fri, Oct 26, 2012 at 10:44:24AM +0200, Benjamin Tissoires wrote:
> Win 8 specification is much more precise than the Win 7 one.
> Moreover devices that need to take certification must be submitted
> to Microsoft.
> 
> The result is a better protocol support and we can rely on that to
> skip all the messy tests we used to do.
> 
> The protocol specify the fact that each valid touch must be reported
> within a frame, and that the release touch coordinate must be the
> same than the last known touch.
> So we can use the always_valid quirk and dismiss reports when we
> touch coordiante do not follow this rule.
> 
> Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
> ---
>  drivers/hid/hid-multitouch.c | 16 ++++++++++++++--
>  1 file changed, 14 insertions(+), 2 deletions(-)

Why do we need this patch?

> diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
> index 43bd8e8..bd23f19 100644
> --- a/drivers/hid/hid-multitouch.c
> +++ b/drivers/hid/hid-multitouch.c
> @@ -510,6 +510,18 @@ static void mt_complete_slot(struct mt_device *td, struct input_dev *input)
>  		int slotnum = mt_compute_slot(td, input);
>  		struct mt_slot *s = &td->curdata;
>  
> +		if (td->mtclass.quirks & MT_QUIRK_WIN_8_CERTIFIED &&
> +		    !s->touch_state) {
> +			struct input_mt_slot *slot = &input->mt->slots[slotnum];
> +			int prv_x = input_mt_get_value(slot, ABS_MT_POSITION_X);
> +			int prv_y = input_mt_get_value(slot, ABS_MT_POSITION_Y);
> +			/* valid releases occurs when the last x and y positions
> +			 * are the same as the last known touch. */
> +			if (!input_mt_is_active(slot) ||
> +			    prv_x != s->x || prv_y != s->y)
> +				return;
> +		}
> +
>  		if (slotnum < 0 || slotnum >= td->maxcontacts)
>  			return;
>  
> @@ -681,8 +693,8 @@ static void mt_post_parse_default_settings(struct mt_device *td)
>  {
>  	__s32 quirks = td->mtclass.quirks;
>  
> -	/* unknown serial device needs special quirks */
> -	if (td->touches_by_report == 1) {
> +	/* unknown serial devices or win8 ones need special quirks */
> +	if (td->touches_by_report == 1 || quirks & MT_QUIRK_WIN_8_CERTIFIED) {
>  		quirks |= MT_QUIRK_ALWAYS_VALID;
>  		quirks &= ~MT_QUIRK_NOT_SEEN_MEANS_UP;
>  		quirks &= ~MT_QUIRK_VALID_IS_INRANGE;
> -- 
> 1.7.11.7
> 

Henrik
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Benjamin Tissoires Oct. 30, 2012, 10:24 a.m. UTC | #2
Hi Henrik,

On Mon, Oct 29, 2012 at 11:19 PM, Henrik Rydberg <rydberg@euromail.se> wrote:
> On Fri, Oct 26, 2012 at 10:44:24AM +0200, Benjamin Tissoires wrote:
>> Win 8 specification is much more precise than the Win 7 one.
>> Moreover devices that need to take certification must be submitted
>> to Microsoft.
>>
>> The result is a better protocol support and we can rely on that to
>> skip all the messy tests we used to do.
>>
>> The protocol specify the fact that each valid touch must be reported
>> within a frame, and that the release touch coordinate must be the
>> same than the last known touch.
>> So we can use the always_valid quirk and dismiss reports when we
>> touch coordiante do not follow this rule.
>>
>> Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
>> ---
>>  drivers/hid/hid-multitouch.c | 16 ++++++++++++++--
>>  1 file changed, 14 insertions(+), 2 deletions(-)
>
> Why do we need this patch?

This patch prevents a corner case where the device use contactID 0 for
it's first reported touch.
Once you got the invalid touches, most of the time, contactID will be
0, x, y, and other fields too. So this ensures to avoid conflict
between valid values and garbage values. The problem lies in the fact
that we don't have the whole overview of the frame (with the contact
count) to decide which contacts are good and which are not.

Cheers,
Benjamin

>
>> diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
>> index 43bd8e8..bd23f19 100644
>> --- a/drivers/hid/hid-multitouch.c
>> +++ b/drivers/hid/hid-multitouch.c
>> @@ -510,6 +510,18 @@ static void mt_complete_slot(struct mt_device *td, struct input_dev *input)
>>               int slotnum = mt_compute_slot(td, input);
>>               struct mt_slot *s = &td->curdata;
>>
>> +             if (td->mtclass.quirks & MT_QUIRK_WIN_8_CERTIFIED &&
>> +                 !s->touch_state) {
>> +                     struct input_mt_slot *slot = &input->mt->slots[slotnum];
>> +                     int prv_x = input_mt_get_value(slot, ABS_MT_POSITION_X);
>> +                     int prv_y = input_mt_get_value(slot, ABS_MT_POSITION_Y);
>> +                     /* valid releases occurs when the last x and y positions
>> +                      * are the same as the last known touch. */
>> +                     if (!input_mt_is_active(slot) ||
>> +                         prv_x != s->x || prv_y != s->y)
>> +                             return;
>> +             }
>> +
>>               if (slotnum < 0 || slotnum >= td->maxcontacts)
>>                       return;
>>
>> @@ -681,8 +693,8 @@ static void mt_post_parse_default_settings(struct mt_device *td)
>>  {
>>       __s32 quirks = td->mtclass.quirks;
>>
>> -     /* unknown serial device needs special quirks */
>> -     if (td->touches_by_report == 1) {
>> +     /* unknown serial devices or win8 ones need special quirks */
>> +     if (td->touches_by_report == 1 || quirks & MT_QUIRK_WIN_8_CERTIFIED) {
>>               quirks |= MT_QUIRK_ALWAYS_VALID;
>>               quirks &= ~MT_QUIRK_NOT_SEEN_MEANS_UP;
>>               quirks &= ~MT_QUIRK_VALID_IS_INRANGE;
>> --
>> 1.7.11.7
>>
>
> Henrik
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Henrik Rydberg Oct. 31, 2012, 6:53 p.m. UTC | #3
Hi Benjamin,

> On Mon, Oct 29, 2012 at 11:19 PM, Henrik Rydberg <rydberg@euromail.se> wrote:
> > On Fri, Oct 26, 2012 at 10:44:24AM +0200, Benjamin Tissoires wrote:
> >> Win 8 specification is much more precise than the Win 7 one.
> >> Moreover devices that need to take certification must be submitted
> >> to Microsoft.
> >>
> >> The result is a better protocol support and we can rely on that to
> >> skip all the messy tests we used to do.
> >>
> >> The protocol specify the fact that each valid touch must be reported
> >> within a frame, and that the release touch coordinate must be the
> >> same than the last known touch.
> >> So we can use the always_valid quirk and dismiss reports when we
> >> touch coordiante do not follow this rule.
> >>
> >> Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
> >> ---
> >>  drivers/hid/hid-multitouch.c | 16 ++++++++++++++--
> >>  1 file changed, 14 insertions(+), 2 deletions(-)
> >
> > Why do we need this patch?
> 
> This patch prevents a corner case where the device use contactID 0 for
> it's first reported touch.
> Once you got the invalid touches, most of the time, contactID will be
> 0, x, y, and other fields too. So this ensures to avoid conflict
> between valid values and garbage values. The problem lies in the fact
> that we don't have the whole overview of the frame (with the contact
> count) to decide which contacts are good and which are not.

I am sorry, but your explanation did not make me any wiser. :-) Are
you saying that touch state changes and touch property changes are
mutually exclusive? For all win8 devices, or just for the serial
protocol ones? For what devices is the current implementation a
problem?

I am asking because this looks more like a device quirk than anything
else.

Thanks,
Henrik
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Benjamin Tissoires Nov. 2, 2012, 2:18 p.m. UTC | #4
Hi Henrik,

On Wed, Oct 31, 2012 at 7:53 PM, Henrik Rydberg <rydberg@euromail.se> wrote:
> Hi Benjamin,
>
>> On Mon, Oct 29, 2012 at 11:19 PM, Henrik Rydberg <rydberg@euromail.se> wrote:
>> > On Fri, Oct 26, 2012 at 10:44:24AM +0200, Benjamin Tissoires wrote:
>> >> Win 8 specification is much more precise than the Win 7 one.
>> >> Moreover devices that need to take certification must be submitted
>> >> to Microsoft.
>> >>
>> >> The result is a better protocol support and we can rely on that to
>> >> skip all the messy tests we used to do.
>> >>
>> >> The protocol specify the fact that each valid touch must be reported
>> >> within a frame, and that the release touch coordinate must be the
>> >> same than the last known touch.
>> >> So we can use the always_valid quirk and dismiss reports when we
>> >> touch coordiante do not follow this rule.
>> >>
>> >> Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
>> >> ---
>> >>  drivers/hid/hid-multitouch.c | 16 ++++++++++++++--
>> >>  1 file changed, 14 insertions(+), 2 deletions(-)
>> >
>> > Why do we need this patch?
>>
>> This patch prevents a corner case where the device use contactID 0 for
>> it's first reported touch.
>> Once you got the invalid touches, most of the time, contactID will be
>> 0, x, y, and other fields too. So this ensures to avoid conflict
>> between valid values and garbage values. The problem lies in the fact
>> that we don't have the whole overview of the frame (with the contact
>> count) to decide which contacts are good and which are not.
>
> I am sorry, but your explanation did not make me any wiser. :-) Are

Sorry, for that. Let's try with other words.

> you saying that touch state changes and touch property changes are
> mutually exclusive? For all win8 devices, or just for the serial
> protocol ones? For what devices is the current implementation a
> problem?

The goal of this patch is to implement in a reliable way Win 8
multitouch protocol (to avoid quirking many devices). Thanks to the
precision they made in the specification, I think it is feasible:
they add the dynamic part that were missing in Win 7 spec:
"""
When sending data in hybrid or parallel mode, a contact that is
delivered in one report must be delivered in all subsequent reports
until it is lifted off the screen. If time is needed to adequate
determine if the contact was lifted off the surface, the device must
report the last known position of the contact and then deliver the
“UP” state of the contact in a subsequent report. Devices should not
send a report without the information for that contact while trying to
determine its current state.
"""

Thus, the quirk ALWAYS_VALID fits very well with win 8 devices (the
device has to send the touch until it is lifted and out of range, and
the device must send the 'up' state).

The problem lies that some devices may reuse contact id 0 within the
frame for the end of the report (my Win8 device doesn't has this kind
of problem):

With the following hid usages:
I -> contact Id
T -> tip switch
X, Y -> X, Y
S -> scan time
C -> contact count

a friendly device would report:

I:1 T:1 X:125 X:130 Y:750 Y:755 I:0 T:0 X:0 X:0 Y:0 Y:0 S:0 C:01
I:1 T:1 X:130 X:135 Y:750 Y:755 I:0 T:0 X:0 X:0 Y:0 Y:0 S:1 C:01
I:1 T:1 X:135 X:140 Y:750 Y:755 I:0 T:0 X:0 X:0 Y:0 Y:0 S:2 C:01
I:1 T:1 X:140 X:145 Y:750 Y:755 I:0 T:0 X:0 X:0 Y:0 Y:0 S:3 C:01
I:1 T:0 X:140 X:145 Y:750 Y:755 I:0 T:0 X:0 X:0 Y:0 Y:0 S:4 C:01

*but*, I've already seen win 7 devices, that do send:

I:0 T:1 X:125 X:130 Y:750 Y:755 I:0 T:0 X:0 X:0 Y:0 Y:0 S:0 C:01
I:0 T:1 X:130 X:135 Y:750 Y:755 I:0 T:0 X:0 X:0 Y:0 Y:0 S:1 C:01
I:0 T:1 X:135 X:140 Y:750 Y:755 I:0 T:0 X:0 X:0 Y:0 Y:0 S:2 C:01
I:0 T:1 X:140 X:145 Y:750 Y:755 I:0 T:0 X:0 X:0 Y:0 Y:0 S:3 C:01
I:0 T:0 X:140 X:145 Y:750 Y:755 I:0 T:0 X:0 X:0 Y:0 Y:0 S:4 C:01

The difference lies in the first bit, contact id is 0.

So, the quirk always valid is not sufficient because the second touch
in the frame will override the values of the first (the valid one).

As Microsoft says that "the device must report the last known position
of the contact and then deliver the “UP” state of the contact", so we
can safely discard the second touch because X and Y do not match the
current state of the valid touch.

Then, as exposed in the "How to Design and Test Multitouch Hardware
Solutions for Windows 8" document here:
http://msdn.microsoft.com/en-us/library/windows/hardware/hh872968.aspx
when the device attempt the certification, if the "up" is not valid,
the error "Last move location different" raises, which, I hope will
prevent the device to get the certification.

I hope it is clearer now.

>
> I am asking because this looks more like a device quirk than anything
> else.

and yes, it looks like a quirk, we could make the "Last move location
different" presented like a quirk, but it is only followed by win 8
devices (or it is by luck).

Cheers,
Benjamin


>
> Thanks,
> Henrik
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Henrik Rydberg Nov. 4, 2012, 8:54 p.m. UTC | #5
Hi Benjamin,

> The goal of this patch is to implement in a reliable way Win 8
> multitouch protocol (to avoid quirking many devices). Thanks to the
> precision they made in the specification, I think it is feasible:
> they add the dynamic part that were missing in Win 7 spec:
> """
> When sending data in hybrid or parallel mode, a contact that is
> delivered in one report must be delivered in all subsequent reports
> until it is lifted off the screen. If time is needed to adequate
> determine if the contact was lifted off the surface, the device must
> report the last known position of the contact and then deliver the
> “UP” state of the contact in a subsequent report. Devices should not
> send a report without the information for that contact while trying to
> determine its current state.
> """

The text seems to say that devices are not required to send touch
state information in a separate frame, but if the device needs time to
determine the touch state, the touch properties should stay the same
during that time.

> Thus, the quirk ALWAYS_VALID fits very well with win 8 devices (the
> device has to send the touch until it is lifted and out of range, and
> the device must send the 'up' state).

One could simply add another quirk which fits the win8 case exactly
instead. No need to change the existing one.

> The problem lies that some devices may reuse contact id 0 within the
> frame for the end of the report (my Win8 device doesn't has this kind
> of problem):
> 
> With the following hid usages:
> I -> contact Id
> T -> tip switch
> X, Y -> X, Y
> S -> scan time
> C -> contact count
> 
> a friendly device would report:
> 
> I:1 T:1 X:125 X:130 Y:750 Y:755 I:0 T:0 X:0 X:0 Y:0 Y:0 S:0 C:01
> I:1 T:1 X:130 X:135 Y:750 Y:755 I:0 T:0 X:0 X:0 Y:0 Y:0 S:1 C:01
> I:1 T:1 X:135 X:140 Y:750 Y:755 I:0 T:0 X:0 X:0 Y:0 Y:0 S:2 C:01
> I:1 T:1 X:140 X:145 Y:750 Y:755 I:0 T:0 X:0 X:0 Y:0 Y:0 S:3 C:01
> I:1 T:0 X:140 X:145 Y:750 Y:755 I:0 T:0 X:0 X:0 Y:0 Y:0 S:4 C:01
> 
> *but*, I've already seen win 7 devices, that do send:
> 
> I:0 T:1 X:125 X:130 Y:750 Y:755 I:0 T:0 X:0 X:0 Y:0 Y:0 S:0 C:01
> I:0 T:1 X:130 X:135 Y:750 Y:755 I:0 T:0 X:0 X:0 Y:0 Y:0 S:1 C:01
> I:0 T:1 X:135 X:140 Y:750 Y:755 I:0 T:0 X:0 X:0 Y:0 Y:0 S:2 C:01
> I:0 T:1 X:140 X:145 Y:750 Y:755 I:0 T:0 X:0 X:0 Y:0 Y:0 S:3 C:01
> I:0 T:0 X:140 X:145 Y:750 Y:755 I:0 T:0 X:0 X:0 Y:0 Y:0 S:4 C:01

I see, more brain-damaged usage. :-) Still, there seems to be a
simpler way to distinguish this case: if there are more than one touch
with the same id in the frame, use the one with T=1.

> The difference lies in the first bit, contact id is 0.
> 
> So, the quirk always valid is not sufficient because the second touch
> in the frame will override the values of the first (the valid one).
> 
> As Microsoft says that "the device must report the last known position
> of the contact and then deliver the “UP” state of the contact", so we
> can safely discard the second touch because X and Y do not match the
> current state of the valid touch.
> 
> Then, as exposed in the "How to Design and Test Multitouch Hardware
> Solutions for Windows 8" document here:
> http://msdn.microsoft.com/en-us/library/windows/hardware/hh872968.aspx
> when the device attempt the certification, if the "up" is not valid,
> the error "Last move location different" raises, which, I hope will
> prevent the device to get the certification.

I think it would be too fragile to rely on this assumption. Hopefully
the suggestion above will work equally well.

Thanks,
Henrik
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Benjamin Tissoires Nov. 5, 2012, 9:51 a.m. UTC | #6
On Sun, Nov 4, 2012 at 9:54 PM, Henrik Rydberg <rydberg@euromail.se> wrote:
> Hi Benjamin,
>
>> The goal of this patch is to implement in a reliable way Win 8
>> multitouch protocol (to avoid quirking many devices). Thanks to the
>> precision they made in the specification, I think it is feasible:
>> they add the dynamic part that were missing in Win 7 spec:
>> """
>> When sending data in hybrid or parallel mode, a contact that is
>> delivered in one report must be delivered in all subsequent reports
>> until it is lifted off the screen. If time is needed to adequate
>> determine if the contact was lifted off the surface, the device must
>> report the last known position of the contact and then deliver the
>> “UP” state of the contact in a subsequent report. Devices should not
>> send a report without the information for that contact while trying to
>> determine its current state.
>> """
>
> The text seems to say that devices are not required to send touch
> state information in a separate frame, but if the device needs time to
> determine the touch state, the touch properties should stay the same
> during that time.

Yes and no:
- yes, if the device needs time to determine the "up" state, it should
send at every frame the last known properties.
- no, I never said that the information should be split in separate
frames: I think you are confused by the serial protocol. I'm talking
here about the parallel or the hybrid one.

>
>> Thus, the quirk ALWAYS_VALID fits very well with win 8 devices (the
>> device has to send the touch until it is lifted and out of range, and
>> the device must send the 'up' state).
>
> One could simply add another quirk which fits the win8 case exactly
> instead. No need to change the existing one.

I never changed the existing one. The quirk ALWAYS_VALID means that
whatever the device sends, the information are valid. The fact is that
the serial protocol can be handled with this quirk (otherwise, we
would have called this quirk SERIAL, and not ALWAYS_VALID). So the Win
8 case doesn't need a new quirk, the ALWAYS_VALID fits.

>
>> The problem lies that some devices may reuse contact id 0 within the
>> frame for the end of the report (my Win8 device doesn't has this kind
>> of problem):
>>
>> With the following hid usages:
>> I -> contact Id
>> T -> tip switch
>> X, Y -> X, Y
>> S -> scan time
>> C -> contact count
>>
>> a friendly device would report:
>>
>> I:1 T:1 X:125 X:130 Y:750 Y:755 I:0 T:0 X:0 X:0 Y:0 Y:0 S:0 C:01
>> I:1 T:1 X:130 X:135 Y:750 Y:755 I:0 T:0 X:0 X:0 Y:0 Y:0 S:1 C:01
>> I:1 T:1 X:135 X:140 Y:750 Y:755 I:0 T:0 X:0 X:0 Y:0 Y:0 S:2 C:01
>> I:1 T:1 X:140 X:145 Y:750 Y:755 I:0 T:0 X:0 X:0 Y:0 Y:0 S:3 C:01
>> I:1 T:0 X:140 X:145 Y:750 Y:755 I:0 T:0 X:0 X:0 Y:0 Y:0 S:4 C:01
>>
>> *but*, I've already seen win 7 devices, that do send:
>>
>> I:0 T:1 X:125 X:130 Y:750 Y:755 I:0 T:0 X:0 X:0 Y:0 Y:0 S:0 C:01
>> I:0 T:1 X:130 X:135 Y:750 Y:755 I:0 T:0 X:0 X:0 Y:0 Y:0 S:1 C:01
>> I:0 T:1 X:135 X:140 Y:750 Y:755 I:0 T:0 X:0 X:0 Y:0 Y:0 S:2 C:01
>> I:0 T:1 X:140 X:145 Y:750 Y:755 I:0 T:0 X:0 X:0 Y:0 Y:0 S:3 C:01
>> I:0 T:0 X:140 X:145 Y:750 Y:755 I:0 T:0 X:0 X:0 Y:0 Y:0 S:4 C:01
>
> I see, more brain-damaged usage. :-) Still, there seems to be a
> simpler way to distinguish this case: if there are more than one touch
> with the same id in the frame, use the one with T=1.

sigh... the problem in your sentence is there: "with the same id in the frame".
This forces me to introduce the function input_mt_is_used in mt.h...

>
>> The difference lies in the first bit, contact id is 0.
>>
>> So, the quirk always valid is not sufficient because the second touch
>> in the frame will override the values of the first (the valid one).
>>
>> As Microsoft says that "the device must report the last known position
>> of the contact and then deliver the “UP” state of the contact", so we
>> can safely discard the second touch because X and Y do not match the
>> current state of the valid touch.
>>
>> Then, as exposed in the "How to Design and Test Multitouch Hardware
>> Solutions for Windows 8" document here:
>> http://msdn.microsoft.com/en-us/library/windows/hardware/hh872968.aspx
>> when the device attempt the certification, if the "up" is not valid,
>> the error "Last move location different" raises, which, I hope will
>> prevent the device to get the certification.
>
> I think it would be too fragile to rely on this assumption. Hopefully
> the suggestion above will work equally well.

I'm not sure it is fragile, because otherwise that means that the
certification is worthless.
But anyway, your solution is valid too, so I'll implement it.

Cheers,
Benjamin

>
> Thanks,
> Henrik
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index 43bd8e8..bd23f19 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -510,6 +510,18 @@  static void mt_complete_slot(struct mt_device *td, struct input_dev *input)
 		int slotnum = mt_compute_slot(td, input);
 		struct mt_slot *s = &td->curdata;
 
+		if (td->mtclass.quirks & MT_QUIRK_WIN_8_CERTIFIED &&
+		    !s->touch_state) {
+			struct input_mt_slot *slot = &input->mt->slots[slotnum];
+			int prv_x = input_mt_get_value(slot, ABS_MT_POSITION_X);
+			int prv_y = input_mt_get_value(slot, ABS_MT_POSITION_Y);
+			/* valid releases occurs when the last x and y positions
+			 * are the same as the last known touch. */
+			if (!input_mt_is_active(slot) ||
+			    prv_x != s->x || prv_y != s->y)
+				return;
+		}
+
 		if (slotnum < 0 || slotnum >= td->maxcontacts)
 			return;
 
@@ -681,8 +693,8 @@  static void mt_post_parse_default_settings(struct mt_device *td)
 {
 	__s32 quirks = td->mtclass.quirks;
 
-	/* unknown serial device needs special quirks */
-	if (td->touches_by_report == 1) {
+	/* unknown serial devices or win8 ones need special quirks */
+	if (td->touches_by_report == 1 || quirks & MT_QUIRK_WIN_8_CERTIFIED) {
 		quirks |= MT_QUIRK_ALWAYS_VALID;
 		quirks &= ~MT_QUIRK_NOT_SEEN_MEANS_UP;
 		quirks &= ~MT_QUIRK_VALID_IS_INRANGE;