diff options
| -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"); |
