diff options
author | Henrik Rydberg <rydberg@bitmath.org> | 2010-11-12 09:11:53 +0100 |
---|---|---|
committer | John Rigby <john.rigby@linaro.org> | 2011-08-21 21:29:51 -0600 |
commit | be3a47a786d45878d49dee31f9c82e812879ec5d (patch) | |
tree | c9340cf200d76ecf896f716760a267577c537260 /drivers | |
parent | a0363cd7e96f16e56c9372e01abcfe586bf89bc4 (diff) |
hid: ntrig: Support single-touch devices
The current driver was regressed to not work for single-touch devices,
and the driver occasionally crashes in those cases. The HID report
which resets the array index is never received, resulting in out-of-range
memory access. This patch restores functionality by detecting the presence
of the multitouch firmware, and adds a range check to make the driver
resilient to unknown firmware versions.
Signed-off-by: Henrik Rydberg <rydberg@euromail.se>
Signed-off-by: Andy Whitcroft <apw@canonical.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/hid/hid-ntrig.c | 20 |
1 files changed, 19 insertions, 1 deletions
diff --git a/drivers/hid/hid-ntrig.c b/drivers/hid/hid-ntrig.c index 95d0b90b76e..27d249f39dc 100644 --- a/drivers/hid/hid-ntrig.c +++ b/drivers/hid/hid-ntrig.c @@ -50,6 +50,8 @@ struct ntrig_data { int nrow, ncol; int index, nindex; int nhold; + bool touch; + bool hasmt; }; @@ -209,7 +211,14 @@ static int ntrig_input_mapping(struct hid_device *hdev, struct hid_input *hi, return 1; } return 0; + case 0xff000000: + switch (usage->hid) { + case 0xff000001: + /* multi-touch firmware */ + nd->hasmt = true; + break; + } /* we do not want to map these: no input-oriented meaning */ return -1; } @@ -373,7 +382,9 @@ static int ntrig_event (struct hid_device *hid, struct hid_field *field, switch (usage->hid) { case HID_DG_TIPSWITCH: - nd->index = nd->nindex++; + nd->touch = value; + if (nd->nindex < MAX_SLOTS) + nd->index = nd->nindex++; break; case HID_GD_X: nd->col[nd->index].x = value; @@ -386,8 +397,15 @@ static int ntrig_event (struct hid_device *hid, struct hid_field *field, break; case HID_DG_HEIGHT: nd->col[nd->index].h = value; + if (!nd->hasmt) { + nd->nindex = 0; + nd->ncol = nd->touch; + report_frame(input, nd); + } break; case HID_DG_CONTACTCOUNT: /* End of a multitouch group */ + if (!nd->hasmt) + break; nd->nindex = 0; nd->ncol = value; report_frame(input, nd); |