aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid/hid-3m-pct.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hid/hid-3m-pct.c')
-rw-r--r--drivers/hid/hid-3m-pct.c22
1 files changed, 18 insertions, 4 deletions
diff --git a/drivers/hid/hid-3m-pct.c b/drivers/hid/hid-3m-pct.c
index 2a0d56b7a02b..105743068cca 100644
--- a/drivers/hid/hid-3m-pct.c
+++ b/drivers/hid/hid-3m-pct.c
@@ -24,6 +24,9 @@ MODULE_LICENSE("GPL");
24 24
25#include "hid-ids.h" 25#include "hid-ids.h"
26 26
27#define MAX_SLOTS 60
28#define MAX_TRKID 59
29
27struct mmm_finger { 30struct mmm_finger {
28 __s32 x, y, w, h; 31 __s32 x, y, w, h;
29 __u8 rank; 32 __u8 rank;
@@ -31,8 +34,9 @@ struct mmm_finger {
31}; 34};
32 35
33struct mmm_data { 36struct mmm_data {
34 struct mmm_finger f[10]; 37 struct mmm_finger f[MAX_SLOTS];
35 __u8 curid, num; 38 __u8 curid, num;
39 __u8 nexp, nreal;
36 bool touch, valid; 40 bool touch, valid;
37}; 41};
38 42
@@ -93,7 +97,7 @@ static int mmm_input_mapping(struct hid_device *hdev, struct hid_input *hi,
93 1, 1, 0, 0); 97 1, 1, 0, 0);
94 return 1; 98 return 1;
95 case HID_DG_CONTACTID: 99 case HID_DG_CONTACTID:
96 field->logical_maximum = 59; 100 field->logical_maximum = MAX_TRKID;
97 hid_map_usage(hi, usage, bit, max, 101 hid_map_usage(hi, usage, bit, max,
98 EV_ABS, ABS_MT_TRACKING_ID); 102 EV_ABS, ABS_MT_TRACKING_ID);
99 return 1; 103 return 1;
@@ -133,7 +137,7 @@ static void mmm_filter_event(struct mmm_data *md, struct input_dev *input)
133 * we need to iterate on all fingers to decide if we have a press 137 * we need to iterate on all fingers to decide if we have a press
134 * or a release event in our touchscreen emulation. 138 * or a release event in our touchscreen emulation.
135 */ 139 */
136 for (i = 0; i < 10; ++i) { 140 for (i = 0; i < MAX_SLOTS; ++i) {
137 struct mmm_finger *f = &md->f[i]; 141 struct mmm_finger *f = &md->f[i];
138 if (!f->valid) { 142 if (!f->valid) {
139 /* this finger is just placeholder data, ignore */ 143 /* this finger is just placeholder data, ignore */
@@ -190,6 +194,7 @@ static void mmm_filter_event(struct mmm_data *md, struct input_dev *input)
190 } else if (released) { 194 } else if (released) {
191 input_event(input, EV_KEY, BTN_TOUCH, 0); 195 input_event(input, EV_KEY, BTN_TOUCH, 0);
192 } 196 }
197 input_sync(input);
193} 198}
194 199
195/* 200/*
@@ -223,10 +228,12 @@ static int mmm_event(struct hid_device *hid, struct hid_field *field,
223 md->f[md->curid].h = value; 228 md->f[md->curid].h = value;
224 break; 229 break;
225 case HID_DG_CONTACTID: 230 case HID_DG_CONTACTID:
231 value = clamp_val(value, 0, MAX_SLOTS - 1);
226 if (md->valid) { 232 if (md->valid) {
227 md->curid = value; 233 md->curid = value;
228 md->f[value].touch = md->touch; 234 md->f[value].touch = md->touch;
229 md->f[value].valid = 1; 235 md->f[value].valid = 1;
236 md->nreal++;
230 } 237 }
231 break; 238 break;
232 case HID_GD_X: 239 case HID_GD_X:
@@ -238,7 +245,12 @@ static int mmm_event(struct hid_device *hid, struct hid_field *field,
238 md->f[md->curid].y = value; 245 md->f[md->curid].y = value;
239 break; 246 break;
240 case HID_DG_CONTACTCOUNT: 247 case HID_DG_CONTACTCOUNT:
241 mmm_filter_event(md, input); 248 if (value)
249 md->nexp = value;
250 if (md->nreal >= md->nexp) {
251 mmm_filter_event(md, input);
252 md->nreal = 0;
253 }
242 break; 254 break;
243 } 255 }
244 } 256 }
@@ -255,6 +267,8 @@ static int mmm_probe(struct hid_device *hdev, const struct hid_device_id *id)
255 int ret; 267 int ret;
256 struct mmm_data *md; 268 struct mmm_data *md;
257 269
270 hdev->quirks |= HID_QUIRK_NO_INPUT_SYNC;
271
258 md = kzalloc(sizeof(struct mmm_data), GFP_KERNEL); 272 md = kzalloc(sizeof(struct mmm_data), GFP_KERNEL);
259 if (!md) { 273 if (!md) {
260 dev_err(&hdev->dev, "cannot allocate 3M data\n"); 274 dev_err(&hdev->dev, "cannot allocate 3M data\n");