aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid
diff options
context:
space:
mode:
authorBenjamin Tissoires <benjamin.tissoires@gmail.com>2012-11-14 10:59:19 -0500
committerJiri Kosina <jkosina@suse.cz>2012-11-15 04:09:12 -0500
commit349fd6705b13946c04794bf27d67282940aa46b8 (patch)
tree45a7012eb24f99b589418c9cf4e4a1c581c4549e /drivers/hid
parentafbcb04c181f36634f4af207bb0c9cc46b7405e4 (diff)
HID: multitouch: support T and C for win8 devices
Win8 input specification clarifies the X and Y sent by devices. It distincts the position where the user wants to Touch (T) from the center of the ellipsoide (C). This patch enable supports for this distinction in hid-multitouch. Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com> Reviewed-by: Henrik Rydberg <rydberg@euromail.se> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers/hid')
-rw-r--r--drivers/hid/hid-multitouch.c46
1 files changed, 37 insertions, 9 deletions
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index 9c7415ff4aaf..a2963b238fde 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -54,7 +54,7 @@ MODULE_LICENSE("GPL");
54#define MT_QUIRK_NO_AREA (1 << 9) 54#define MT_QUIRK_NO_AREA (1 << 9)
55 55
56struct mt_slot { 56struct mt_slot {
57 __s32 x, y, p, w, h; 57 __s32 x, y, cx, cy, p, w, h;
58 __s32 contactid; /* the device ContactID assigned to this slot */ 58 __s32 contactid; /* the device ContactID assigned to this slot */
59 bool touch_state; /* is the touch valid? */ 59 bool touch_state; /* is the touch valid? */
60}; 60};
@@ -322,6 +322,7 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
322 struct mt_device *td = hid_get_drvdata(hdev); 322 struct mt_device *td = hid_get_drvdata(hdev);
323 struct mt_class *cls = &td->mtclass; 323 struct mt_class *cls = &td->mtclass;
324 int code; 324 int code;
325 struct hid_usage *prev_usage = NULL;
325 326
326 /* Only map fields from TouchScreen or TouchPad collections. 327 /* Only map fields from TouchScreen or TouchPad collections.
327 * We need to ignore fields that belong to other collections 328 * We need to ignore fields that belong to other collections
@@ -344,23 +345,42 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
344 if (field->physical == HID_DG_STYLUS) 345 if (field->physical == HID_DG_STYLUS)
345 return -1; 346 return -1;
346 347
348 if (usage->usage_index)
349 prev_usage = &field->usage[usage->usage_index - 1];
350
347 switch (usage->hid & HID_USAGE_PAGE) { 351 switch (usage->hid & HID_USAGE_PAGE) {
348 352
349 case HID_UP_GENDESK: 353 case HID_UP_GENDESK:
350 switch (usage->hid) { 354 switch (usage->hid) {
351 case HID_GD_X: 355 case HID_GD_X:
352 hid_map_usage(hi, usage, bit, max, 356 if (prev_usage && (prev_usage->hid == usage->hid)) {
357 hid_map_usage(hi, usage, bit, max,
358 EV_ABS, ABS_MT_TOOL_X);
359 set_abs(hi->input, ABS_MT_TOOL_X, field,
360 cls->sn_move);
361 } else {
362 hid_map_usage(hi, usage, bit, max,
353 EV_ABS, ABS_MT_POSITION_X); 363 EV_ABS, ABS_MT_POSITION_X);
354 set_abs(hi->input, ABS_MT_POSITION_X, field, 364 set_abs(hi->input, ABS_MT_POSITION_X, field,
355 cls->sn_move); 365 cls->sn_move);
366 }
367
356 mt_store_field(usage, td, hi); 368 mt_store_field(usage, td, hi);
357 td->last_field_index = field->index; 369 td->last_field_index = field->index;
358 return 1; 370 return 1;
359 case HID_GD_Y: 371 case HID_GD_Y:
360 hid_map_usage(hi, usage, bit, max, 372 if (prev_usage && (prev_usage->hid == usage->hid)) {
373 hid_map_usage(hi, usage, bit, max,
374 EV_ABS, ABS_MT_TOOL_Y);
375 set_abs(hi->input, ABS_MT_TOOL_Y, field,
376 cls->sn_move);
377 } else {
378 hid_map_usage(hi, usage, bit, max,
361 EV_ABS, ABS_MT_POSITION_Y); 379 EV_ABS, ABS_MT_POSITION_Y);
362 set_abs(hi->input, ABS_MT_POSITION_Y, field, 380 set_abs(hi->input, ABS_MT_POSITION_Y, field,
363 cls->sn_move); 381 cls->sn_move);
382 }
383
364 mt_store_field(usage, td, hi); 384 mt_store_field(usage, td, hi);
365 td->last_field_index = field->index; 385 td->last_field_index = field->index;
366 return 1; 386 return 1;
@@ -501,6 +521,8 @@ static void mt_complete_slot(struct mt_device *td, struct input_dev *input)
501 521
502 input_event(input, EV_ABS, ABS_MT_POSITION_X, s->x); 522 input_event(input, EV_ABS, ABS_MT_POSITION_X, s->x);
503 input_event(input, EV_ABS, ABS_MT_POSITION_Y, s->y); 523 input_event(input, EV_ABS, ABS_MT_POSITION_Y, s->y);
524 input_event(input, EV_ABS, ABS_MT_TOOL_X, s->cx);
525 input_event(input, EV_ABS, ABS_MT_TOOL_Y, s->cy);
504 input_event(input, EV_ABS, ABS_MT_ORIENTATION, wide); 526 input_event(input, EV_ABS, ABS_MT_ORIENTATION, wide);
505 input_event(input, EV_ABS, ABS_MT_PRESSURE, s->p); 527 input_event(input, EV_ABS, ABS_MT_PRESSURE, s->p);
506 input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, major); 528 input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, major);
@@ -552,10 +574,16 @@ static int mt_event(struct hid_device *hid, struct hid_field *field,
552 td->curdata.p = value; 574 td->curdata.p = value;
553 break; 575 break;
554 case HID_GD_X: 576 case HID_GD_X:
555 td->curdata.x = value; 577 if (usage->code == ABS_MT_TOOL_X)
578 td->curdata.cx = value;
579 else
580 td->curdata.x = value;
556 break; 581 break;
557 case HID_GD_Y: 582 case HID_GD_Y:
558 td->curdata.y = value; 583 if (usage->code == ABS_MT_TOOL_Y)
584 td->curdata.cy = value;
585 else
586 td->curdata.y = value;
559 break; 587 break;
560 case HID_DG_WIDTH: 588 case HID_DG_WIDTH:
561 td->curdata.w = value; 589 td->curdata.w = value;