aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid/hid-multitouch.c
diff options
context:
space:
mode:
authorBenjamin Tissoires <benjamin.tissoires@enac.fr>2011-04-21 08:15:59 -0400
committerJiri Kosina <jkosina@suse.cz>2011-04-22 05:54:42 -0400
commit2955caed8b9865c1f04fcde6bd7103d5d5ec9415 (patch)
tree33b6774855886c0ab18333d9b73c375858b37333 /drivers/hid/hid-multitouch.c
parentf786bba4499cf3de20da345ce090457ebcef03b0 (diff)
HID: hid-multitouch: refactor last_field_index
the current implementation requires the devices to report HID_DG_CONTACTCOUNT to set the last_field_index value. However, devices reporting in serial mode (DWAV and PenMount) do not send this field. Other devices (3M) add other fields in the reports descriptor that are not multitouch related at the end, thus the need to add a special case in the default case when handling events. A first work around has been set up but with PenMount devices, we have reached the limit. The idea is to calculate the last_field_index by relying only on multitouch fields the device send. This allows us to remove the handling of non-multitouch events in hid-multitouch, and guarantee that the function mt_emit_event is always called. Signed-off-by: Benjamin Tissoires <benjamin.tissoires@enac.fr> Reviewed-and-tested-by: Henrik Rydberg <rydberg@euromail.se> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers/hid/hid-multitouch.c')
-rw-r--r--drivers/hid/hid-multitouch.c23
1 files changed, 11 insertions, 12 deletions
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index 0175f8583095..6005e7888b14 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -210,6 +210,7 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
210 /* touchscreen emulation */ 210 /* touchscreen emulation */
211 set_abs(hi->input, ABS_X, field, cls->sn_move); 211 set_abs(hi->input, ABS_X, field, cls->sn_move);
212 td->last_slot_field = usage->hid; 212 td->last_slot_field = usage->hid;
213 td->last_field_index = field->index;
213 return 1; 214 return 1;
214 case HID_GD_Y: 215 case HID_GD_Y:
215 if (quirks & MT_QUIRK_EGALAX_XYZ_FIXUP) 216 if (quirks & MT_QUIRK_EGALAX_XYZ_FIXUP)
@@ -221,6 +222,7 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
221 /* touchscreen emulation */ 222 /* touchscreen emulation */
222 set_abs(hi->input, ABS_Y, field, cls->sn_move); 223 set_abs(hi->input, ABS_Y, field, cls->sn_move);
223 td->last_slot_field = usage->hid; 224 td->last_slot_field = usage->hid;
225 td->last_field_index = field->index;
224 return 1; 226 return 1;
225 } 227 }
226 return 0; 228 return 0;
@@ -229,18 +231,22 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
229 switch (usage->hid) { 231 switch (usage->hid) {
230 case HID_DG_INRANGE: 232 case HID_DG_INRANGE:
231 td->last_slot_field = usage->hid; 233 td->last_slot_field = usage->hid;
234 td->last_field_index = field->index;
232 return 1; 235 return 1;
233 case HID_DG_CONFIDENCE: 236 case HID_DG_CONFIDENCE:
234 td->last_slot_field = usage->hid; 237 td->last_slot_field = usage->hid;
238 td->last_field_index = field->index;
235 return 1; 239 return 1;
236 case HID_DG_TIPSWITCH: 240 case HID_DG_TIPSWITCH:
237 hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH); 241 hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH);
238 input_set_capability(hi->input, EV_KEY, BTN_TOUCH); 242 input_set_capability(hi->input, EV_KEY, BTN_TOUCH);
239 td->last_slot_field = usage->hid; 243 td->last_slot_field = usage->hid;
244 td->last_field_index = field->index;
240 return 1; 245 return 1;
241 case HID_DG_CONTACTID: 246 case HID_DG_CONTACTID:
242 input_mt_init_slots(hi->input, td->maxcontacts); 247 input_mt_init_slots(hi->input, td->maxcontacts);
243 td->last_slot_field = usage->hid; 248 td->last_slot_field = usage->hid;
249 td->last_field_index = field->index;
244 return 1; 250 return 1;
245 case HID_DG_WIDTH: 251 case HID_DG_WIDTH:
246 hid_map_usage(hi, usage, bit, max, 252 hid_map_usage(hi, usage, bit, max,
@@ -248,6 +254,7 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
248 set_abs(hi->input, ABS_MT_TOUCH_MAJOR, field, 254 set_abs(hi->input, ABS_MT_TOUCH_MAJOR, field,
249 cls->sn_width); 255 cls->sn_width);
250 td->last_slot_field = usage->hid; 256 td->last_slot_field = usage->hid;
257 td->last_field_index = field->index;
251 return 1; 258 return 1;
252 case HID_DG_HEIGHT: 259 case HID_DG_HEIGHT:
253 hid_map_usage(hi, usage, bit, max, 260 hid_map_usage(hi, usage, bit, max,
@@ -257,6 +264,7 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
257 input_set_abs_params(hi->input, 264 input_set_abs_params(hi->input,
258 ABS_MT_ORIENTATION, 0, 1, 0, 0); 265 ABS_MT_ORIENTATION, 0, 1, 0, 0);
259 td->last_slot_field = usage->hid; 266 td->last_slot_field = usage->hid;
267 td->last_field_index = field->index;
260 return 1; 268 return 1;
261 case HID_DG_TIPPRESSURE: 269 case HID_DG_TIPPRESSURE:
262 if (quirks & MT_QUIRK_EGALAX_XYZ_FIXUP) 270 if (quirks & MT_QUIRK_EGALAX_XYZ_FIXUP)
@@ -269,13 +277,15 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
269 set_abs(hi->input, ABS_PRESSURE, field, 277 set_abs(hi->input, ABS_PRESSURE, field,
270 cls->sn_pressure); 278 cls->sn_pressure);
271 td->last_slot_field = usage->hid; 279 td->last_slot_field = usage->hid;
280 td->last_field_index = field->index;
272 return 1; 281 return 1;
273 case HID_DG_CONTACTCOUNT: 282 case HID_DG_CONTACTCOUNT:
274 td->last_field_index = field->report->maxfield - 1; 283 td->last_field_index = field->index;
275 return 1; 284 return 1;
276 case HID_DG_CONTACTMAX: 285 case HID_DG_CONTACTMAX:
277 /* we don't set td->last_slot_field as contactcount and 286 /* we don't set td->last_slot_field as contactcount and
278 * contact max are global to the report */ 287 * contact max are global to the report */
288 td->last_field_index = field->index;
279 return -1; 289 return -1;
280 } 290 }
281 /* let hid-input decide for the others */ 291 /* let hid-input decide for the others */
@@ -424,23 +434,12 @@ static int mt_event(struct hid_device *hid, struct hid_field *field,
424 break; 434 break;
425 435
426 default: 436 default:
427 if (td->last_field_index
428 && field->index == td->last_field_index)
429 /* we reach here when the last field in the
430 * report is not related to multitouch.
431 * This is not good. As a temporary solution,
432 * we trigger our mt event completion and
433 * ignore the field.
434 */
435 break;
436 /* fallback to the generic hidinput handling */ 437 /* fallback to the generic hidinput handling */
437 return 0; 438 return 0;
438 } 439 }
439 440
440 if (usage->hid == td->last_slot_field) { 441 if (usage->hid == td->last_slot_field) {
441 mt_complete_slot(td); 442 mt_complete_slot(td);
442 if (!td->last_field_index)
443 mt_emit_event(td, field->hidinput->input);
444 } 443 }
445 444
446 if (field->index == td->last_field_index 445 if (field->index == td->last_field_index