Skip to content

Commit

Permalink
HID: 3m: Adjust to sequential MT HID protocol
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Henrik Rydberg authored and Jiri Kosina committed Sep 21, 2010
1 parent 24750f3 commit 4103590
Showing 1 changed file with 18 additions and 4 deletions.
22 changes: 18 additions & 4 deletions drivers/hid/hid-3m-pct.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,19 @@ MODULE_LICENSE("GPL");

#include "hid-ids.h"

#define MAX_SLOTS 60
#define MAX_TRKID 59

struct mmm_finger {
__s32 x, y, w, h;
__u8 rank;
bool touch, valid;
};

struct mmm_data {
struct mmm_finger f[10];
struct mmm_finger f[MAX_SLOTS];
__u8 curid, num;
__u8 nexp, nreal;
bool touch, valid;
};

Expand Down Expand Up @@ -93,7 +97,7 @@ static int mmm_input_mapping(struct hid_device *hdev, struct hid_input *hi,
1, 1, 0, 0);
return 1;
case HID_DG_CONTACTID:
field->logical_maximum = 59;
field->logical_maximum = MAX_TRKID;
hid_map_usage(hi, usage, bit, max,
EV_ABS, ABS_MT_TRACKING_ID);
return 1;
Expand Down Expand Up @@ -133,7 +137,7 @@ static void mmm_filter_event(struct mmm_data *md, struct input_dev *input)
* we need to iterate on all fingers to decide if we have a press
* or a release event in our touchscreen emulation.
*/
for (i = 0; i < 10; ++i) {
for (i = 0; i < MAX_SLOTS; ++i) {
struct mmm_finger *f = &md->f[i];
if (!f->valid) {
/* this finger is just placeholder data, ignore */
Expand Down Expand Up @@ -190,6 +194,7 @@ static void mmm_filter_event(struct mmm_data *md, struct input_dev *input)
} else if (released) {
input_event(input, EV_KEY, BTN_TOUCH, 0);
}
input_sync(input);
}

/*
Expand Down Expand Up @@ -223,10 +228,12 @@ static int mmm_event(struct hid_device *hid, struct hid_field *field,
md->f[md->curid].h = value;
break;
case HID_DG_CONTACTID:
value = clamp_val(value, 0, MAX_SLOTS - 1);
if (md->valid) {
md->curid = value;
md->f[value].touch = md->touch;
md->f[value].valid = 1;
md->nreal++;
}
break;
case HID_GD_X:
Expand All @@ -238,7 +245,12 @@ static int mmm_event(struct hid_device *hid, struct hid_field *field,
md->f[md->curid].y = value;
break;
case HID_DG_CONTACTCOUNT:
mmm_filter_event(md, input);
if (value)
md->nexp = value;
if (md->nreal >= md->nexp) {
mmm_filter_event(md, input);
md->nreal = 0;
}
break;
}
}
Expand All @@ -255,6 +267,8 @@ static int mmm_probe(struct hid_device *hdev, const struct hid_device_id *id)
int ret;
struct mmm_data *md;

hdev->quirks |= HID_QUIRK_NO_INPUT_SYNC;

md = kzalloc(sizeof(struct mmm_data), GFP_KERNEL);
if (!md) {
dev_err(&hdev->dev, "cannot allocate 3M data\n");
Expand Down

0 comments on commit 4103590

Please sign in to comment.