diff options
author | Henrik Rydberg <rydberg@bitmath.org> | 2010-11-12 09:11:53 +0100 |
---|---|---|
committer | John Rigby <john.rigby@linaro.org> | 2011-11-16 14:23:25 -0700 |
commit | b89480c08da756b26e97a399a898f9cd4ccd6b5c (patch) | |
tree | 85350fd0f0fe9e57504fb58c1118fa54f42f6e00 /drivers | |
parent | 4aad048331c127350f6e1fd14ccf0575c6b8a46b (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); |