aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid/hid-multitouch.c
diff options
context:
space:
mode:
authorHenrik Rydberg <rydberg@euromail.se>2012-09-01 13:46:58 -0400
committerHenrik Rydberg <rydberg@euromail.se>2012-09-19 13:50:20 -0400
commit3e1b5015d94ec0bdfa5bd8c80a19bcba82bc505c (patch)
treebb9ebac100f062b4beee13f523212e5b3e7910da /drivers/hid/hid-multitouch.c
parent76f5902aebdabcac5b1c34b8d9a238bad397364f (diff)
HID: hid-multitouch: Remove the redundant touch state
With the input_mt_sync_frame() function in place, there is no longer any need to keep the full touch state in the driver. This patch removes the slot state and replaces the lookup code with the input-mt equivalent. Reviewed-and-tested-by: Benjamin Tissoires <benjamin.tissoires@enac.fr> Acked-by: Jiri Kosina <jkosina@suse.cz> Signed-off-by: Henrik Rydberg <rydberg@euromail.se>
Diffstat (limited to 'drivers/hid/hid-multitouch.c')
-rw-r--r--drivers/hid/hid-multitouch.c88
1 files changed, 23 insertions, 65 deletions
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index 1df86a7536b8..eee19c9f7b36 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -56,7 +56,6 @@ struct mt_slot {
56 __s32 x, y, p, w, h; 56 __s32 x, y, p, w, h;
57 __s32 contactid; /* the device ContactID assigned to this slot */ 57 __s32 contactid; /* the device ContactID assigned to this slot */
58 bool touch_state; /* is the touch valid? */ 58 bool touch_state; /* is the touch valid? */
59 bool seen_in_this_frame;/* has this slot been updated */
60}; 59};
61 60
62struct mt_class { 61struct mt_class {
@@ -94,7 +93,6 @@ struct mt_device {
94 * > 1 means hybrid (multitouch) protocol */ 93 * > 1 means hybrid (multitouch) protocol */
95 bool serial_maybe; /* need to check for serial protocol */ 94 bool serial_maybe; /* need to check for serial protocol */
96 bool curvalid; /* is the current contact valid? */ 95 bool curvalid; /* is the current contact valid? */
97 struct mt_slot *slots;
98 unsigned mt_flags; /* flags to pass to input-mt */ 96 unsigned mt_flags; /* flags to pass to input-mt */
99}; 97};
100 98
@@ -136,25 +134,6 @@ static int cypress_compute_slot(struct mt_device *td)
136 return -1; 134 return -1;
137} 135}
138 136
139static int find_slot_from_contactid(struct mt_device *td)
140{
141 int i;
142 for (i = 0; i < td->maxcontacts; ++i) {
143 if (td->slots[i].contactid == td->curdata.contactid &&
144 td->slots[i].touch_state)
145 return i;
146 }
147 for (i = 0; i < td->maxcontacts; ++i) {
148 if (!td->slots[i].seen_in_this_frame &&
149 !td->slots[i].touch_state)
150 return i;
151 }
152 /* should not occurs. If this happens that means
153 * that the device sent more touches that it says
154 * in the report descriptor. It is ignored then. */
155 return -1;
156}
157
158static struct mt_class mt_classes[] = { 137static struct mt_class mt_classes[] = {
159 { .name = MT_CLS_DEFAULT, 138 { .name = MT_CLS_DEFAULT,
160 .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP }, 139 .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP },
@@ -448,7 +427,7 @@ static int mt_input_mapped(struct hid_device *hdev, struct hid_input *hi,
448 return -1; 427 return -1;
449} 428}
450 429
451static int mt_compute_slot(struct mt_device *td) 430static int mt_compute_slot(struct mt_device *td, struct input_dev *input)
452{ 431{
453 __s32 quirks = td->mtclass.quirks; 432 __s32 quirks = td->mtclass.quirks;
454 433
@@ -464,42 +443,23 @@ static int mt_compute_slot(struct mt_device *td)
464 if (quirks & MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE) 443 if (quirks & MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE)
465 return td->curdata.contactid - 1; 444 return td->curdata.contactid - 1;
466 445
467 return find_slot_from_contactid(td); 446 return input_mt_get_slot_by_key(input, td->curdata.contactid);
468} 447}
469 448
470/* 449/*
471 * this function is called when a whole contact has been processed, 450 * this function is called when a whole contact has been processed,
472 * so that it can assign it to a slot and store the data there 451 * so that it can assign it to a slot and store the data there
473 */ 452 */
474static void mt_complete_slot(struct mt_device *td) 453static void mt_complete_slot(struct mt_device *td, struct input_dev *input)
475{ 454{
476 td->curdata.seen_in_this_frame = true;
477 if (td->curvalid) { 455 if (td->curvalid) {
478 int slotnum = mt_compute_slot(td); 456 int slotnum = mt_compute_slot(td, input);
479 457 struct mt_slot *s = &td->curdata;
480 if (slotnum >= 0 && slotnum < td->maxcontacts)
481 td->slots[slotnum] = td->curdata;
482 }
483 td->num_received++;
484}
485
486
487/*
488 * this function is called when a whole packet has been received and processed,
489 * so that it can decide what to send to the input layer.
490 */
491static void mt_emit_event(struct mt_device *td, struct input_dev *input)
492{
493 int i;
494 458
495 for (i = 0; i < td->maxcontacts; ++i) { 459 if (slotnum < 0 || slotnum >= td->maxcontacts)
496 struct mt_slot *s = &(td->slots[i]); 460 return;
497 if ((td->mtclass.quirks & MT_QUIRK_NOT_SEEN_MEANS_UP) &&
498 !s->seen_in_this_frame) {
499 s->touch_state = false;
500 }
501 461
502 input_mt_slot(input, i); 462 input_mt_slot(input, slotnum);
503 input_mt_report_slot_state(input, MT_TOOL_FINGER, 463 input_mt_report_slot_state(input, MT_TOOL_FINGER,
504 s->touch_state); 464 s->touch_state);
505 if (s->touch_state) { 465 if (s->touch_state) {
@@ -516,24 +476,29 @@ static void mt_emit_event(struct mt_device *td, struct input_dev *input)
516 input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, major); 476 input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, major);
517 input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, minor); 477 input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, minor);
518 } 478 }
519 s->seen_in_this_frame = false;
520
521 } 479 }
522 480
481 td->num_received++;
482}
483
484/*
485 * this function is called when a whole packet has been received and processed,
486 * so that it can decide what to send to the input layer.
487 */
488static void mt_sync_frame(struct mt_device *td, struct input_dev *input)
489{
523 input_mt_sync_frame(input); 490 input_mt_sync_frame(input);
524 input_sync(input); 491 input_sync(input);
525 td->num_received = 0; 492 td->num_received = 0;
526} 493}
527 494
528
529
530static int mt_event(struct hid_device *hid, struct hid_field *field, 495static int mt_event(struct hid_device *hid, struct hid_field *field,
531 struct hid_usage *usage, __s32 value) 496 struct hid_usage *usage, __s32 value)
532{ 497{
533 struct mt_device *td = hid_get_drvdata(hid); 498 struct mt_device *td = hid_get_drvdata(hid);
534 __s32 quirks = td->mtclass.quirks; 499 __s32 quirks = td->mtclass.quirks;
535 500
536 if (hid->claimed & HID_CLAIMED_INPUT && td->slots) { 501 if (hid->claimed & HID_CLAIMED_INPUT) {
537 switch (usage->hid) { 502 switch (usage->hid) {
538 case HID_DG_INRANGE: 503 case HID_DG_INRANGE:
539 if (quirks & MT_QUIRK_ALWAYS_VALID) 504 if (quirks & MT_QUIRK_ALWAYS_VALID)
@@ -586,11 +551,11 @@ static int mt_event(struct hid_device *hid, struct hid_field *field,
586 } 551 }
587 552
588 if (usage->hid == td->last_slot_field) 553 if (usage->hid == td->last_slot_field)
589 mt_complete_slot(td); 554 mt_complete_slot(td, field->hidinput->input);
590 555
591 if (field->index == td->last_field_index 556 if (field->index == td->last_field_index
592 && td->num_received >= td->num_expected) 557 && td->num_received >= td->num_expected)
593 mt_emit_event(td, field->hidinput->input); 558 mt_sync_frame(td, field->hidinput->input);
594 559
595 } 560 }
596 561
@@ -690,6 +655,9 @@ static void mt_input_configured(struct hid_device *hdev, struct hid_input *hi)
690 if (cls->is_indirect) 655 if (cls->is_indirect)
691 td->mt_flags |= INPUT_MT_POINTER; 656 td->mt_flags |= INPUT_MT_POINTER;
692 657
658 if (cls->quirks & MT_QUIRK_NOT_SEEN_MEANS_UP)
659 td->mt_flags |= INPUT_MT_DROP_UNUSED;
660
693 input_mt_init_slots(input, td->maxcontacts, td->mt_flags); 661 input_mt_init_slots(input, td->maxcontacts, td->mt_flags);
694 662
695 td->mt_flags = 0; 663 td->mt_flags = 0;
@@ -743,15 +711,6 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
743 if (ret) 711 if (ret)
744 goto fail; 712 goto fail;
745 713
746 td->slots = kzalloc(td->maxcontacts * sizeof(struct mt_slot),
747 GFP_KERNEL);
748 if (!td->slots) {
749 dev_err(&hdev->dev, "cannot allocate multitouch slots\n");
750 hid_hw_stop(hdev);
751 ret = -ENOMEM;
752 goto fail;
753 }
754
755 ret = sysfs_create_group(&hdev->dev.kobj, &mt_attribute_group); 714 ret = sysfs_create_group(&hdev->dev.kobj, &mt_attribute_group);
756 715
757 mt_set_maxcontacts(hdev); 716 mt_set_maxcontacts(hdev);
@@ -782,7 +741,6 @@ static void mt_remove(struct hid_device *hdev)
782 struct mt_device *td = hid_get_drvdata(hdev); 741 struct mt_device *td = hid_get_drvdata(hdev);
783 sysfs_remove_group(&hdev->dev.kobj, &mt_attribute_group); 742 sysfs_remove_group(&hdev->dev.kobj, &mt_attribute_group);
784 hid_hw_stop(hdev); 743 hid_hw_stop(hdev);
785 kfree(td->slots);
786 kfree(td); 744 kfree(td);
787 hid_set_drvdata(hdev, NULL); 745 hid_set_drvdata(hdev, NULL);
788} 746}