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

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

 



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>

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