diff options
Diffstat (limited to 'drivers/hid/hid-3m-pct.c')
-rw-r--r-- | drivers/hid/hid-3m-pct.c | 22 |
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 | |||
27 | struct mmm_finger { | 30 | struct 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 | ||
33 | struct mmm_data { | 36 | struct 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"); |