aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorHenrik Rydberg <rydberg@bitmath.org>2010-11-12 09:11:53 +0100
committerJohn Rigby <john.rigby@linaro.org>2011-11-16 14:23:25 -0700
commitb89480c08da756b26e97a399a898f9cd4ccd6b5c (patch)
tree85350fd0f0fe9e57504fb58c1118fa54f42f6e00 /drivers
parent4aad048331c127350f6e1fd14ccf0575c6b8a46b (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.c20
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);