Re: [PATCH] HID: multitouch: Add quirk for N-trig (1b96:1B05)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, Sep 17, 2015 at 11:25 AM, Benjamin Tissoires
<benjamin.tissoires@xxxxxxxxx> wrote:
> Hi Daniel,
>
> On Thu, Sep 17, 2015 at 11:06 AM, Daniel Martin
> <daniel.martin@xxxxxxxxxxx> wrote:
>> The N-trig (1b96:1B05) is an I2C device. It can be found in a
>> Microsoft Surface Pro 3. Users reported that sometimes the touschscreen
>> gets stuck during work - not responding to touches anymore.
>>
>> Under certain circumstances the touschscreen sends "ghost" reports.
>> Reports for contacts that have been lifted prior and with suspicious
>> data (ContactID == X == Y == W == H == 0xffff and Tipswitch == true). In
>> such a case evemu-record would report something like:
>>
>>   E: 44.290448 0003 002f 0006 # EV_ABS / ABS_MT_SLOT          6
>>   E: 44.290448 0003 0039 0024 # EV_ABS / ABS_MT_TRACKING_ID   24
>>   E: 44.290448 0003 0035 65535    # EV_ABS / ABS_MT_POSITION_X    65535
>>   E: 44.290448 0003 0036 65535    # EV_ABS / ABS_MT_POSITION_Y    65535
>>   E: 44.290448 0003 003c 65535    # EV_ABS / ABS_MT_TOOL_X        65535
>>   E: 44.290448 0003 003d 65535    # EV_ABS / ABS_MT_TOOL_Y        65535
>>   E: 44.290448 0003 0034 0000 # EV_ABS / ABS_MT_ORIENTATION   0
>>   E: 44.290448 0003 0030 32767    # EV_ABS / ABS_MT_TOUCH_MAJOR   32767
>>   E: 44.290448 0003 0031 32767    # EV_ABS / ABS_MT_TOUCH_MINOR   32767
>>
>> We never see that such a contact gets lifted (Tipswitch == false) and
>> therefore have an active unused slot. If we keep processing we end up
>> with all slots active, but none in use. Then input_mt_get_slot_by_key()
>> always returns -1 (can't get a slot) and we never send any event
>> anymore. MT_QUIRK_NOT_SEEN_MEANS_UP could fix this, but we don't want
>> to send such suspicious values to user-land.
>> Instead, we add MT_QUIRK_INVALID_CONTACTID_FFFF for this device and
>> don't try to get a slot for a report with ContactID=0xffff. Though, now,
>> we may miss a one valid contact (per input descriptor a contact id of
>> 0xffff is valid, that's its logic maximum).
>
> Facepalm. How did they managed to have such a bug in their protocol on
> their own device???? This is really depressing.
>
> This fix is fine IMO. 0xffff seems unlikely to be used before long
> after boot, and I wouldn't be surprised if they just roll back to 0
> when they arrive at 0xff for the contact ID.
>
> Small remark, we may not need to add the device ID to hid-ids.h given
> that it is not used anywhere else than in hid-multitouch.c.
>
> Besides this:
> Reviewed-by: Benjamin Tissoires <benjamin.tissoires@xxxxxxxxxx>

You forgot to CC Jiri, which is mandatory if you want your patch to
end up in a timely manner in his tree :)

>
> Thanks for the analysis and the patch!
>
> Cheers,
> Benjamin
>
>>
>> Lets look at input reports unveiling the problem. First 3 bytes
>> (Length=29 and ReportId=3) and last 4 bytes (ScanTime) have been
>> stripped.
>>
>> 1. frame - 10 reports (10 contacts active):
>>     ca 01 e7 31 00 3b 12 3b 12 15 05 15 05 69 02 76 03 ff ff ff ff 0a
>>     ca 01 e7 32 00 ba 0c ba 0c a1 01 a1 01 d3 01 c5 02 ff ff ff ff 00
>>     ca 01 e7 33 00 a8 07 a8 07 5b 03 5b 03 d3 01 14 02 ff ff ff ff 00
>>     ca 01 e7 37 00 92 0f 92 0f 79 01 79 01 d3 01 77 03 ff ff ff ff 00
>>     ca 01 e7 3d 00 82 09 82 09 2b 18 2b 18 cf 04 72 03 ff ff ff ff 00
>>     ca 01 e7 38 00 a9 21 a9 21 80 07 80 07 6f 02 14 02 ff ff ff ff 00
>>     ca 01 e7 39 00 c0 1c c0 1c 2c 05 2c 05 6f 02 c5 02 ff ff ff ff 00
>>     ca 01 e7 3a 00 a7 19 a7 19 55 05 55 05 e0 01 22 02 ff ff ff ff 00
>>     ca 01 e7 3b 00 bd 15 bd 15 80 09 80 09 db 01 1d 02 ff ff ff ff 00
>>     ca 01 e7 3c 00 f2 16 f2 16 56 13 56 13 76 01 a4 01 ff ff ff ff 00
>>     v---- v- v---- v---- v---- v---- v---- v---- v---- v---------- v-
>>     V1    CT CID   X     X     Y     Y     W     H     V2          CC
>>
>>   V1 ... Usage Page (Vendor Defined 0xFF00), Usage (0x01) [1x2 bytes]
>>          Frame sequence id?
>>   TC ... Tipswitch (bit 0) and Confidence (bit 2)
>>          (Confidence bit is always set)
>>   CID .. ContactID
>>   X/Y .. X/Y coordinate (yes, always twice the same value)
>>   W/H .. Width/Height
>>   V2 ... Usage Page (Vendor Defined 0xFF00), Usage (0x02) [4x1 byte]
>>          (always ff, not const, valid from 0 to 255?)
>>   CC ... ContactCount
>>
>>   We see that initially ContactCount is 10 and we get 10 reports. Each
>>   report shows an active slot (Tipswitch bit in TC is set, TC=e7).
>>   The contact ids are 31, 32, 33, 37, 38, 39, 3a, 3b, 3c and 3d.
>>
>> 2. frame - 10 reports (5 contacts active, 5 becoming inactive):
>>     cb 01 e4 31 00 3b 12 3b 12 15 05 15 05 69 02 76 03 ff ff ff ff 0a
>>     cb 01 e4 32 00 ba 0c ba 0c a1 01 a1 01 d3 01 c5 02 ff ff ff ff 00
>>     cb 01 e4 33 00 a8 07 a8 07 5b 03 5b 03 d3 01 14 02 ff ff ff ff 00
>>     cb 01 e4 37 00 92 0f 92 0f 79 01 79 01 d3 01 77 03 ff ff ff ff 00
>>     cb 01 e4 3d 00 82 09 82 09 2b 18 2b 18 cf 04 72 03 ff ff ff ff 00
>>     cb 01 e7 38 00 a9 21 a9 21 80 07 80 07 6f 02 14 02 ff ff ff ff 00
>>     cb 01 e7 39 00 c0 1c c0 1c 2c 05 2c 05 6f 02 c5 02 ff ff ff ff 00
>>     cb 01 e7 3a 00 a7 19 a7 19 57 05 57 05 e0 01 25 02 ff ff ff ff 00
>>     cb 01 e7 3b 00 bd 15 bd 15 81 09 81 09 dd 01 1f 02 ff ff ff ff 00
>>     cb 01 e7 3c 00 f6 16 f6 16 53 13 53 13 7e 01 ad 01 ff ff ff ff 00
>>
>>   5 contacts (31, 32, 33, 37 and 3d) become inactive (Tipswitch bit
>>   in TC is not set, TC=e4). Remaining contacts (38 to 3c) stay active.
>>
>> 3. frame - 10 reports (5 contacts active, 5 "ghosts"???)
>>     cc 01 e7 38 00 a9 21 a9 21 80 07 80 07 6f 02 14 02 ff ff ff ff 0a
>>     cc 01 e7 39 00 c0 1c c0 1c 2c 05 2c 05 6f 02 c5 02 ff ff ff ff 00
>>     cc 01 e7 3a 00 a6 19 a6 19 58 05 58 05 e2 01 27 02 ff ff ff ff 00
>>     cc 01 e7 3b 00 bc 15 bc 15 83 09 83 09 df 01 21 02 ff ff ff ff 00
>>     cc 01 e7 3c 00 f8 16 f8 16 4f 13 4f 13 85 01 b5 01 ff ff ff ff 00
>>     cc 01 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 00
>>     cc 01 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 00
>>     cc 01 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 00
>>     cc 01 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 00
>>     cc 01 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 00
>>
>>   The 5 active contacts (38 to 3c) from the previous frame stay active.
>>   Though, we get 5 suspicious reports! Ghosts from the last frame?
>>
>> 4. frame - 5 reports (5 contacts active)
>>     cd 01 e7 38 00 a9 21 a9 21 80 07 80 07 6f 02 14 02 ff ff ff ff 05
>>     cd 01 e7 39 00 c0 1c c0 1c 2c 05 2c 05 6f 02 c5 02 ff ff ff ff 00
>>     cd 01 e7 3a 00 a6 19 a6 19 5a 05 5a 05 e2 01 29 02 ff ff ff ff 00
>>     cd 01 e7 3b 00 bc 15 bc 15 84 09 84 09 df 01 24 02 ff ff ff ff 00
>>     cd 01 e7 3c 00 fb 16 fb 16 4c 13 4c 13 8b 01 bd 01 ff ff ff ff 00
>>
>>   Next frame and we're back to normal mode/data.
>>
>> Signed-off-by: Daniel Martin <consume.noise@xxxxxxxxx>
>> ---
>>  drivers/hid/hid-ids.h        |  1 +
>>  drivers/hid/hid-multitouch.c | 16 ++++++++++++++++
>>  2 files changed, 17 insertions(+)
>>
>> diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
>> index b3b225b..f297416 100644
>> --- a/drivers/hid/hid-ids.h
>> +++ b/drivers/hid/hid-ids.h
>> @@ -708,6 +708,7 @@
>>  #define USB_DEVICE_ID_NOVATEK_MOUSE    0x1602
>>
>>  #define USB_VENDOR_ID_NTRIG            0x1b96
>> +#define I2C_DEVICE_ID_NTRIG_TOUCH_SCREEN   0x1B05
>>  #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN   0x0001
>>  #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_1   0x0003
>>  #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_2   0x0004
>> diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
>> index 7c81125..8547b2e 100644
>> --- a/drivers/hid/hid-multitouch.c
>> +++ b/drivers/hid/hid-multitouch.c
>> @@ -67,6 +67,7 @@ MODULE_LICENSE("GPL");
>>  #define MT_QUIRK_HOVERING              (1 << 11)
>>  #define MT_QUIRK_CONTACT_CNT_ACCURATE  (1 << 12)
>>  #define MT_QUIRK_FORCE_GET_FEATURE     (1 << 13)
>> +#define MT_QUIRK_INVALID_CONTACTID_FFFF        (1 << 14)
>>
>>  #define MT_INPUTMODE_TOUCHSCREEN       0x02
>>  #define MT_INPUTMODE_TOUCHPAD          0x03
>> @@ -155,6 +156,7 @@ static void mt_post_parse(struct mt_device *td);
>>  #define MT_CLS_GENERALTOUCH_TWOFINGERS         0x0108
>>  #define MT_CLS_GENERALTOUCH_PWT_TENFINGERS     0x0109
>>  #define MT_CLS_VTL                             0x0110
>> +#define MT_CLS_NTRIG                           0x0111
>>
>>  #define MT_DEFAULT_MAXCONTACT  10
>>  #define MT_MAX_MAXCONTACT      250
>> @@ -265,6 +267,10 @@ static struct mt_class mt_classes[] = {
>>                         MT_QUIRK_CONTACT_CNT_ACCURATE |
>>                         MT_QUIRK_FORCE_GET_FEATURE,
>>         },
>> +       { .name = MT_CLS_NTRIG,
>> +               .quirks = MT_QUIRK_ALWAYS_VALID |
>> +                       MT_QUIRK_INVALID_CONTACTID_FFFF,
>> +       },
>>         { }
>>  };
>>
>> @@ -546,6 +552,10 @@ static int mt_compute_slot(struct mt_device *td, struct input_dev *input)
>>         if (quirks & MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE)
>>                 return td->curdata.contactid - 1;
>>
>> +       if (quirks & MT_QUIRK_INVALID_CONTACTID_FFFF &&
>> +           td->curdata.contactid == 0xffff)
>> +               return -1;
>> +
>>         return input_mt_get_slot_by_key(input, td->curdata.contactid);
>>  }
>>
>> @@ -1277,6 +1287,12 @@ static const struct hid_device_id mt_devices[] = {
>>                 MT_USB_DEVICE(USB_VENDOR_ID_TURBOX,
>>                         USB_DEVICE_ID_TURBOX_TOUCHSCREEN_MOSART) },
>>
>> +       /* N-trig */
>> +       { .driver_data = MT_CLS_NTRIG,
>> +               HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8,
>> +                       USB_VENDOR_ID_NTRIG,
>> +                       I2C_DEVICE_ID_NTRIG_TOUCH_SCREEN) },
>> +
>>         /* Panasonic panels */
>>         { .driver_data = MT_CLS_PANASONIC,
>>                 MT_USB_DEVICE(USB_VENDOR_ID_PANASONIC,
>> --
>> 2.1.4
>>
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux Media Devel]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Linux Wireless Networking]     [Linux Omap]

  Powered by Linux