OSDN Git Service

HID: multitouch: Add quirk for N-trig (1b96:1B05)
authorDaniel Martin <daniel.martin@secunet.com>
Thu, 17 Sep 2015 15:06:34 +0000 (17:06 +0200)
committerChih-Wei Huang <cwhuang@linux.org.tw>
Wed, 20 Jan 2016 15:03:14 +0000 (23:03 +0800)
commit580138b75d87aff9da3caf67ff397de270de1478
treed9852274219fc1ab882de81e80f70864aee73513
parent56d49e7f8b26cf4abfae3cce1e664405e20a506e
HID: multitouch: Add quirk for N-trig (1b96:1B05)

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).

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@gmail.com>
Reviewed-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
drivers/hid/hid-ids.h
drivers/hid/hid-multitouch.c