aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid/hid-3m-pct.c
diff options
context:
space:
mode:
authorHenrik Rydberg <rydberg@euromail.se>2010-09-21 10:11:44 -0400
committerJiri Kosina <jkosina@suse.cz>2010-09-21 10:11:44 -0400
commit41035901df14e90ab70db826e940712dde2c1a0d (patch)
treec46be5b40def0f77db59d3e8213b354fefcb2807 /drivers/hid/hid-3m-pct.c
parent24750f3e469bef81a96c0036cd4700df5fb48925 (diff)
HID: 3m: Adjust to sequential MT HID protocol
The multitouch extensions to the HID protocol allows for contact data to be sent over several reports, which is also the case for the 3M M2256PW touchscreen. This patch modifies the logic to only synchronize the input layer when all contacts have been received. Consequentially, the full 60-finger capacity of the device is enabled. Signed-off-by: Henrik Rydberg <rydberg@euromail.se> Acked-by: Stephane Chatty <chatty@enac.fr> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
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");