diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
commit | c71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch) | |
tree | ecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /drivers/hid/hid-ntrig.c | |
parent | ea53c912f8a86a8567697115b6a0d8152beee5c8 (diff) | |
parent | 6a00f206debf8a5c8899055726ad127dbeeed098 (diff) |
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts:
litmus/sched_cedf.c
Diffstat (limited to 'drivers/hid/hid-ntrig.c')
-rw-r--r-- | drivers/hid/hid-ntrig.c | 593 |
1 files changed, 348 insertions, 245 deletions
diff --git a/drivers/hid/hid-ntrig.c b/drivers/hid/hid-ntrig.c index fb69b8c4953f..9fae2ebdd758 100644 --- a/drivers/hid/hid-ntrig.c +++ b/drivers/hid/hid-ntrig.c | |||
@@ -90,6 +90,84 @@ struct ntrig_data { | |||
90 | }; | 90 | }; |
91 | 91 | ||
92 | 92 | ||
93 | /* | ||
94 | * This function converts the 4 byte raw firmware code into | ||
95 | * a string containing 5 comma separated numbers. | ||
96 | */ | ||
97 | static int ntrig_version_string(unsigned char *raw, char *buf) | ||
98 | { | ||
99 | __u8 a = (raw[1] & 0x0e) >> 1; | ||
100 | __u8 b = (raw[0] & 0x3c) >> 2; | ||
101 | __u8 c = ((raw[0] & 0x03) << 3) | ((raw[3] & 0xe0) >> 5); | ||
102 | __u8 d = ((raw[3] & 0x07) << 3) | ((raw[2] & 0xe0) >> 5); | ||
103 | __u8 e = raw[2] & 0x07; | ||
104 | |||
105 | /* | ||
106 | * As yet unmapped bits: | ||
107 | * 0b11000000 0b11110001 0b00011000 0b00011000 | ||
108 | */ | ||
109 | |||
110 | return sprintf(buf, "%u.%u.%u.%u.%u", a, b, c, d, e); | ||
111 | } | ||
112 | |||
113 | static inline int ntrig_get_mode(struct hid_device *hdev) | ||
114 | { | ||
115 | struct hid_report *report = hdev->report_enum[HID_FEATURE_REPORT]. | ||
116 | report_id_hash[0x0d]; | ||
117 | |||
118 | if (!report) | ||
119 | return -EINVAL; | ||
120 | |||
121 | usbhid_submit_report(hdev, report, USB_DIR_IN); | ||
122 | usbhid_wait_io(hdev); | ||
123 | return (int)report->field[0]->value[0]; | ||
124 | } | ||
125 | |||
126 | static inline void ntrig_set_mode(struct hid_device *hdev, const int mode) | ||
127 | { | ||
128 | struct hid_report *report; | ||
129 | __u8 mode_commands[4] = { 0xe, 0xf, 0x1b, 0x10 }; | ||
130 | |||
131 | if (mode < 0 || mode > 3) | ||
132 | return; | ||
133 | |||
134 | report = hdev->report_enum[HID_FEATURE_REPORT]. | ||
135 | report_id_hash[mode_commands[mode]]; | ||
136 | |||
137 | if (!report) | ||
138 | return; | ||
139 | |||
140 | usbhid_submit_report(hdev, report, USB_DIR_IN); | ||
141 | } | ||
142 | |||
143 | static void ntrig_report_version(struct hid_device *hdev) | ||
144 | { | ||
145 | int ret; | ||
146 | char buf[20]; | ||
147 | struct usb_device *usb_dev = hid_to_usb_dev(hdev); | ||
148 | unsigned char *data = kmalloc(8, GFP_KERNEL); | ||
149 | |||
150 | if (!data) | ||
151 | goto err_free; | ||
152 | |||
153 | ret = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0), | ||
154 | USB_REQ_CLEAR_FEATURE, | ||
155 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | | ||
156 | USB_DIR_IN, | ||
157 | 0x30c, 1, data, 8, | ||
158 | USB_CTRL_SET_TIMEOUT); | ||
159 | |||
160 | if (ret == 8) { | ||
161 | ret = ntrig_version_string(&data[2], buf); | ||
162 | |||
163 | hid_info(hdev, "Firmware version: %s (%02x%02x %02x%02x)\n", | ||
164 | buf, data[2], data[3], data[4], data[5]); | ||
165 | } | ||
166 | |||
167 | err_free: | ||
168 | kfree(data); | ||
169 | } | ||
170 | |||
93 | static ssize_t show_phys_width(struct device *dev, | 171 | static ssize_t show_phys_width(struct device *dev, |
94 | struct device_attribute *attr, | 172 | struct device_attribute *attr, |
95 | char *buf) | 173 | char *buf) |
@@ -377,8 +455,8 @@ static struct attribute_group ntrig_attribute_group = { | |||
377 | */ | 455 | */ |
378 | 456 | ||
379 | static int ntrig_input_mapping(struct hid_device *hdev, struct hid_input *hi, | 457 | static int ntrig_input_mapping(struct hid_device *hdev, struct hid_input *hi, |
380 | struct hid_field *field, struct hid_usage *usage, | 458 | struct hid_field *field, struct hid_usage *usage, |
381 | unsigned long **bit, int *max) | 459 | unsigned long **bit, int *max) |
382 | { | 460 | { |
383 | struct ntrig_data *nd = hid_get_drvdata(hdev); | 461 | struct ntrig_data *nd = hid_get_drvdata(hdev); |
384 | 462 | ||
@@ -448,13 +526,13 @@ static int ntrig_input_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
448 | /* width/height mapped on TouchMajor/TouchMinor/Orientation */ | 526 | /* width/height mapped on TouchMajor/TouchMinor/Orientation */ |
449 | case HID_DG_WIDTH: | 527 | case HID_DG_WIDTH: |
450 | hid_map_usage(hi, usage, bit, max, | 528 | hid_map_usage(hi, usage, bit, max, |
451 | EV_ABS, ABS_MT_TOUCH_MAJOR); | 529 | EV_ABS, ABS_MT_TOUCH_MAJOR); |
452 | return 1; | 530 | return 1; |
453 | case HID_DG_HEIGHT: | 531 | case HID_DG_HEIGHT: |
454 | hid_map_usage(hi, usage, bit, max, | 532 | hid_map_usage(hi, usage, bit, max, |
455 | EV_ABS, ABS_MT_TOUCH_MINOR); | 533 | EV_ABS, ABS_MT_TOUCH_MINOR); |
456 | input_set_abs_params(hi->input, ABS_MT_ORIENTATION, | 534 | input_set_abs_params(hi->input, ABS_MT_ORIENTATION, |
457 | 0, 1, 0, 0); | 535 | 0, 1, 0, 0); |
458 | return 1; | 536 | return 1; |
459 | } | 537 | } |
460 | return 0; | 538 | return 0; |
@@ -468,8 +546,8 @@ static int ntrig_input_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
468 | } | 546 | } |
469 | 547 | ||
470 | static int ntrig_input_mapped(struct hid_device *hdev, struct hid_input *hi, | 548 | static int ntrig_input_mapped(struct hid_device *hdev, struct hid_input *hi, |
471 | struct hid_field *field, struct hid_usage *usage, | 549 | struct hid_field *field, struct hid_usage *usage, |
472 | unsigned long **bit, int *max) | 550 | unsigned long **bit, int *max) |
473 | { | 551 | { |
474 | /* No special mappings needed for the pen and single touch */ | 552 | /* No special mappings needed for the pen and single touch */ |
475 | if (field->physical) | 553 | if (field->physical) |
@@ -489,279 +567,290 @@ static int ntrig_input_mapped(struct hid_device *hdev, struct hid_input *hi, | |||
489 | * and call input_mt_sync after each point if necessary | 567 | * and call input_mt_sync after each point if necessary |
490 | */ | 568 | */ |
491 | static int ntrig_event (struct hid_device *hid, struct hid_field *field, | 569 | static int ntrig_event (struct hid_device *hid, struct hid_field *field, |
492 | struct hid_usage *usage, __s32 value) | 570 | struct hid_usage *usage, __s32 value) |
493 | { | 571 | { |
494 | struct input_dev *input = field->hidinput->input; | ||
495 | struct ntrig_data *nd = hid_get_drvdata(hid); | 572 | struct ntrig_data *nd = hid_get_drvdata(hid); |
573 | struct input_dev *input; | ||
574 | |||
575 | /* Skip processing if not a claimed input */ | ||
576 | if (!(hid->claimed & HID_CLAIMED_INPUT)) | ||
577 | goto not_claimed_input; | ||
578 | |||
579 | /* This function is being called before the structures are fully | ||
580 | * initialized */ | ||
581 | if(!(field->hidinput && field->hidinput->input)) | ||
582 | return -EINVAL; | ||
583 | |||
584 | input = field->hidinput->input; | ||
496 | 585 | ||
497 | /* No special handling needed for the pen */ | 586 | /* No special handling needed for the pen */ |
498 | if (field->application == HID_DG_PEN) | 587 | if (field->application == HID_DG_PEN) |
499 | return 0; | 588 | return 0; |
500 | 589 | ||
501 | if (hid->claimed & HID_CLAIMED_INPUT) { | 590 | switch (usage->hid) { |
502 | switch (usage->hid) { | 591 | case 0xff000001: |
503 | case 0xff000001: | 592 | /* Tag indicating the start of a multitouch group */ |
504 | /* Tag indicating the start of a multitouch group */ | 593 | nd->reading_mt = 1; |
505 | nd->reading_mt = 1; | 594 | nd->first_contact_touch = 0; |
506 | nd->first_contact_touch = 0; | 595 | break; |
507 | break; | 596 | case HID_DG_TIPSWITCH: |
508 | case HID_DG_TIPSWITCH: | 597 | nd->tipswitch = value; |
509 | nd->tipswitch = value; | 598 | /* Prevent emission of touch until validated */ |
510 | /* Prevent emission of touch until validated */ | 599 | return 1; |
511 | return 1; | 600 | case HID_DG_CONFIDENCE: |
512 | case HID_DG_CONFIDENCE: | 601 | nd->confidence = value; |
513 | nd->confidence = value; | 602 | break; |
514 | break; | 603 | case HID_GD_X: |
515 | case HID_GD_X: | 604 | nd->x = value; |
516 | nd->x = value; | 605 | /* Clear the contact footer */ |
517 | /* Clear the contact footer */ | 606 | nd->mt_foot_count = 0; |
518 | nd->mt_foot_count = 0; | 607 | break; |
519 | break; | 608 | case HID_GD_Y: |
520 | case HID_GD_Y: | 609 | nd->y = value; |
521 | nd->y = value; | 610 | break; |
522 | break; | 611 | case HID_DG_CONTACTID: |
523 | case HID_DG_CONTACTID: | 612 | nd->id = value; |
524 | nd->id = value; | 613 | break; |
525 | break; | 614 | case HID_DG_WIDTH: |
526 | case HID_DG_WIDTH: | 615 | nd->w = value; |
527 | nd->w = value; | 616 | break; |
528 | break; | 617 | case HID_DG_HEIGHT: |
529 | case HID_DG_HEIGHT: | 618 | nd->h = value; |
530 | nd->h = value; | 619 | /* |
620 | * when in single touch mode, this is the last | ||
621 | * report received in a finger event. We want | ||
622 | * to emit a normal (X, Y) position | ||
623 | */ | ||
624 | if (!nd->reading_mt) { | ||
531 | /* | 625 | /* |
532 | * when in single touch mode, this is the last | 626 | * TipSwitch indicates the presence of a |
533 | * report received in a finger event. We want | 627 | * finger in single touch mode. |
534 | * to emit a normal (X, Y) position | ||
535 | */ | 628 | */ |
536 | if (!nd->reading_mt) { | 629 | input_report_key(input, BTN_TOUCH, |
537 | /* | 630 | nd->tipswitch); |
538 | * TipSwitch indicates the presence of a | 631 | input_report_key(input, BTN_TOOL_DOUBLETAP, |
539 | * finger in single touch mode. | 632 | nd->tipswitch); |
540 | */ | 633 | input_event(input, EV_ABS, ABS_X, nd->x); |
541 | input_report_key(input, BTN_TOUCH, | 634 | input_event(input, EV_ABS, ABS_Y, nd->y); |
542 | nd->tipswitch); | 635 | } |
543 | input_report_key(input, BTN_TOOL_DOUBLETAP, | 636 | break; |
544 | nd->tipswitch); | 637 | case 0xff000002: |
545 | input_event(input, EV_ABS, ABS_X, nd->x); | 638 | /* |
546 | input_event(input, EV_ABS, ABS_Y, nd->y); | 639 | * we receive this when the device is in multitouch |
547 | } | 640 | * mode. The first of the three values tagged with |
641 | * this usage tells if the contact point is real | ||
642 | * or a placeholder | ||
643 | */ | ||
644 | |||
645 | /* Shouldn't get more than 4 footer packets, so skip */ | ||
646 | if (nd->mt_foot_count >= 4) | ||
548 | break; | 647 | break; |
549 | case 0xff000002: | ||
550 | /* | ||
551 | * we receive this when the device is in multitouch | ||
552 | * mode. The first of the three values tagged with | ||
553 | * this usage tells if the contact point is real | ||
554 | * or a placeholder | ||
555 | */ | ||
556 | 648 | ||
557 | /* Shouldn't get more than 4 footer packets, so skip */ | 649 | nd->mt_footer[nd->mt_foot_count++] = value; |
558 | if (nd->mt_foot_count >= 4) | ||
559 | break; | ||
560 | 650 | ||
561 | nd->mt_footer[nd->mt_foot_count++] = value; | 651 | /* if the footer isn't complete break */ |
652 | if (nd->mt_foot_count != 4) | ||
653 | break; | ||
562 | 654 | ||
563 | /* if the footer isn't complete break */ | 655 | /* Pen activity signal. */ |
564 | if (nd->mt_foot_count != 4) | 656 | if (nd->mt_footer[2]) { |
565 | break; | 657 | /* |
658 | * When the pen deactivates touch, we see a | ||
659 | * bogus frame with ContactCount > 0. | ||
660 | * We can | ||
661 | * save a bit of work by ensuring act_state < 0 | ||
662 | * even if deactivation slack is turned off. | ||
663 | */ | ||
664 | nd->act_state = deactivate_slack - 1; | ||
665 | nd->confidence = 0; | ||
666 | break; | ||
667 | } | ||
566 | 668 | ||
567 | /* Pen activity signal. */ | 669 | /* |
568 | if (nd->mt_footer[2]) { | 670 | * The first footer value indicates the presence of a |
569 | /* | 671 | * finger. |
570 | * When the pen deactivates touch, we see a | 672 | */ |
571 | * bogus frame with ContactCount > 0. | 673 | if (nd->mt_footer[0]) { |
572 | * We can | 674 | /* |
573 | * save a bit of work by ensuring act_state < 0 | 675 | * We do not want to process contacts under |
574 | * even if deactivation slack is turned off. | 676 | * the size threshold, but do not want to |
575 | */ | 677 | * ignore them for activation state |
576 | nd->act_state = deactivate_slack - 1; | 678 | */ |
679 | if (nd->w < nd->min_width || | ||
680 | nd->h < nd->min_height) | ||
577 | nd->confidence = 0; | 681 | nd->confidence = 0; |
578 | break; | 682 | } else |
579 | } | 683 | break; |
580 | 684 | ||
685 | if (nd->act_state > 0) { | ||
581 | /* | 686 | /* |
582 | * The first footer value indicates the presence of a | 687 | * Contact meets the activation size threshold |
583 | * finger. | ||
584 | */ | 688 | */ |
585 | if (nd->mt_footer[0]) { | 689 | if (nd->w >= nd->activation_width && |
586 | /* | 690 | nd->h >= nd->activation_height) { |
587 | * We do not want to process contacts under | 691 | if (nd->id) |
588 | * the size threshold, but do not want to | 692 | /* |
589 | * ignore them for activation state | 693 | * first contact, activate now |
590 | */ | 694 | */ |
591 | if (nd->w < nd->min_width || | 695 | nd->act_state = 0; |
592 | nd->h < nd->min_height) | 696 | else { |
593 | nd->confidence = 0; | ||
594 | } else | ||
595 | break; | ||
596 | |||
597 | if (nd->act_state > 0) { | ||
598 | /* | ||
599 | * Contact meets the activation size threshold | ||
600 | */ | ||
601 | if (nd->w >= nd->activation_width && | ||
602 | nd->h >= nd->activation_height) { | ||
603 | if (nd->id) | ||
604 | /* | ||
605 | * first contact, activate now | ||
606 | */ | ||
607 | nd->act_state = 0; | ||
608 | else { | ||
609 | /* | ||
610 | * avoid corrupting this frame | ||
611 | * but ensure next frame will | ||
612 | * be active | ||
613 | */ | ||
614 | nd->act_state = 1; | ||
615 | break; | ||
616 | } | ||
617 | } else | ||
618 | /* | 697 | /* |
619 | * Defer adjusting the activation state | 698 | * avoid corrupting this frame |
620 | * until the end of the frame. | 699 | * but ensure next frame will |
700 | * be active | ||
621 | */ | 701 | */ |
702 | nd->act_state = 1; | ||
622 | break; | 703 | break; |
623 | } | 704 | } |
624 | 705 | } else | |
625 | /* Discarding this contact */ | ||
626 | if (!nd->confidence) | ||
627 | break; | ||
628 | |||
629 | /* emit a normal (X, Y) for the first point only */ | ||
630 | if (nd->id == 0) { | ||
631 | /* | 706 | /* |
632 | * TipSwitch is superfluous in multitouch | 707 | * Defer adjusting the activation state |
633 | * mode. The footer events tell us | 708 | * until the end of the frame. |
634 | * if there is a finger on the screen or | ||
635 | * not. | ||
636 | */ | 709 | */ |
637 | nd->first_contact_touch = nd->confidence; | 710 | break; |
638 | input_event(input, EV_ABS, ABS_X, nd->x); | 711 | } |
639 | input_event(input, EV_ABS, ABS_Y, nd->y); | ||
640 | } | ||
641 | 712 | ||
642 | /* Emit MT events */ | 713 | /* Discarding this contact */ |
643 | input_event(input, EV_ABS, ABS_MT_POSITION_X, nd->x); | 714 | if (!nd->confidence) |
644 | input_event(input, EV_ABS, ABS_MT_POSITION_Y, nd->y); | 715 | break; |
645 | 716 | ||
717 | /* emit a normal (X, Y) for the first point only */ | ||
718 | if (nd->id == 0) { | ||
646 | /* | 719 | /* |
647 | * Translate from height and width to size | 720 | * TipSwitch is superfluous in multitouch |
648 | * and orientation. | 721 | * mode. The footer events tell us |
722 | * if there is a finger on the screen or | ||
723 | * not. | ||
649 | */ | 724 | */ |
650 | if (nd->w > nd->h) { | 725 | nd->first_contact_touch = nd->confidence; |
651 | input_event(input, EV_ABS, | 726 | input_event(input, EV_ABS, ABS_X, nd->x); |
652 | ABS_MT_ORIENTATION, 1); | 727 | input_event(input, EV_ABS, ABS_Y, nd->y); |
653 | input_event(input, EV_ABS, | 728 | } |
654 | ABS_MT_TOUCH_MAJOR, nd->w); | ||
655 | input_event(input, EV_ABS, | ||
656 | ABS_MT_TOUCH_MINOR, nd->h); | ||
657 | } else { | ||
658 | input_event(input, EV_ABS, | ||
659 | ABS_MT_ORIENTATION, 0); | ||
660 | input_event(input, EV_ABS, | ||
661 | ABS_MT_TOUCH_MAJOR, nd->h); | ||
662 | input_event(input, EV_ABS, | ||
663 | ABS_MT_TOUCH_MINOR, nd->w); | ||
664 | } | ||
665 | input_mt_sync(field->hidinput->input); | ||
666 | break; | ||
667 | 729 | ||
668 | case HID_DG_CONTACTCOUNT: /* End of a multitouch group */ | 730 | /* Emit MT events */ |
669 | if (!nd->reading_mt) /* Just to be sure */ | 731 | input_event(input, EV_ABS, ABS_MT_POSITION_X, nd->x); |
670 | break; | 732 | input_event(input, EV_ABS, ABS_MT_POSITION_Y, nd->y); |
733 | |||
734 | /* | ||
735 | * Translate from height and width to size | ||
736 | * and orientation. | ||
737 | */ | ||
738 | if (nd->w > nd->h) { | ||
739 | input_event(input, EV_ABS, | ||
740 | ABS_MT_ORIENTATION, 1); | ||
741 | input_event(input, EV_ABS, | ||
742 | ABS_MT_TOUCH_MAJOR, nd->w); | ||
743 | input_event(input, EV_ABS, | ||
744 | ABS_MT_TOUCH_MINOR, nd->h); | ||
745 | } else { | ||
746 | input_event(input, EV_ABS, | ||
747 | ABS_MT_ORIENTATION, 0); | ||
748 | input_event(input, EV_ABS, | ||
749 | ABS_MT_TOUCH_MAJOR, nd->h); | ||
750 | input_event(input, EV_ABS, | ||
751 | ABS_MT_TOUCH_MINOR, nd->w); | ||
752 | } | ||
753 | input_mt_sync(field->hidinput->input); | ||
754 | break; | ||
671 | 755 | ||
672 | nd->reading_mt = 0; | 756 | case HID_DG_CONTACTCOUNT: /* End of a multitouch group */ |
757 | if (!nd->reading_mt) /* Just to be sure */ | ||
758 | break; | ||
673 | 759 | ||
760 | nd->reading_mt = 0; | ||
761 | |||
762 | |||
763 | /* | ||
764 | * Activation state machine logic: | ||
765 | * | ||
766 | * Fundamental states: | ||
767 | * state > 0: Inactive | ||
768 | * state <= 0: Active | ||
769 | * state < -deactivate_slack: | ||
770 | * Pen termination of touch | ||
771 | * | ||
772 | * Specific values of interest | ||
773 | * state == activate_slack | ||
774 | * no valid input since the last reset | ||
775 | * | ||
776 | * state == 0 | ||
777 | * general operational state | ||
778 | * | ||
779 | * state == -deactivate_slack | ||
780 | * read sufficient empty frames to accept | ||
781 | * the end of input and reset | ||
782 | */ | ||
783 | |||
784 | if (nd->act_state > 0) { /* Currently inactive */ | ||
785 | if (value) | ||
786 | /* | ||
787 | * Consider each live contact as | ||
788 | * evidence of intentional activity. | ||
789 | */ | ||
790 | nd->act_state = (nd->act_state > value) | ||
791 | ? nd->act_state - value | ||
792 | : 0; | ||
793 | else | ||
794 | /* | ||
795 | * Empty frame before we hit the | ||
796 | * activity threshold, reset. | ||
797 | */ | ||
798 | nd->act_state = nd->activate_slack; | ||
674 | 799 | ||
675 | /* | 800 | /* |
676 | * Activation state machine logic: | 801 | * Entered this block inactive and no |
677 | * | 802 | * coordinates sent this frame, so hold off |
678 | * Fundamental states: | 803 | * on button state. |
679 | * state > 0: Inactive | ||
680 | * state <= 0: Active | ||
681 | * state < -deactivate_slack: | ||
682 | * Pen termination of touch | ||
683 | * | ||
684 | * Specific values of interest | ||
685 | * state == activate_slack | ||
686 | * no valid input since the last reset | ||
687 | * | ||
688 | * state == 0 | ||
689 | * general operational state | ||
690 | * | ||
691 | * state == -deactivate_slack | ||
692 | * read sufficient empty frames to accept | ||
693 | * the end of input and reset | ||
694 | */ | 804 | */ |
695 | 805 | break; | |
696 | if (nd->act_state > 0) { /* Currently inactive */ | 806 | } else { /* Currently active */ |
697 | if (value) | 807 | if (value && nd->act_state >= |
698 | /* | 808 | nd->deactivate_slack) |
699 | * Consider each live contact as | ||
700 | * evidence of intentional activity. | ||
701 | */ | ||
702 | nd->act_state = (nd->act_state > value) | ||
703 | ? nd->act_state - value | ||
704 | : 0; | ||
705 | else | ||
706 | /* | ||
707 | * Empty frame before we hit the | ||
708 | * activity threshold, reset. | ||
709 | */ | ||
710 | nd->act_state = nd->activate_slack; | ||
711 | |||
712 | /* | 809 | /* |
713 | * Entered this block inactive and no | 810 | * Live point: clear accumulated |
714 | * coordinates sent this frame, so hold off | 811 | * deactivation count. |
715 | * on button state. | ||
716 | */ | 812 | */ |
717 | break; | 813 | nd->act_state = 0; |
718 | } else { /* Currently active */ | 814 | else if (nd->act_state <= nd->deactivate_slack) |
719 | if (value && nd->act_state >= | ||
720 | nd->deactivate_slack) | ||
721 | /* | ||
722 | * Live point: clear accumulated | ||
723 | * deactivation count. | ||
724 | */ | ||
725 | nd->act_state = 0; | ||
726 | else if (nd->act_state <= nd->deactivate_slack) | ||
727 | /* | ||
728 | * We've consumed the deactivation | ||
729 | * slack, time to deactivate and reset. | ||
730 | */ | ||
731 | nd->act_state = | ||
732 | nd->activate_slack; | ||
733 | else { /* Move towards deactivation */ | ||
734 | nd->act_state--; | ||
735 | break; | ||
736 | } | ||
737 | } | ||
738 | |||
739 | if (nd->first_contact_touch && nd->act_state <= 0) { | ||
740 | /* | 815 | /* |
741 | * Check to see if we're ready to start | 816 | * We've consumed the deactivation |
742 | * emitting touch events. | 817 | * slack, time to deactivate and reset. |
743 | * | ||
744 | * Note: activation slack will decrease over | ||
745 | * the course of the frame, and it will be | ||
746 | * inconsistent from the start to the end of | ||
747 | * the frame. However if the frame starts | ||
748 | * with slack, first_contact_touch will still | ||
749 | * be 0 and we will not get to this point. | ||
750 | */ | 818 | */ |
751 | input_report_key(input, BTN_TOOL_DOUBLETAP, 1); | 819 | nd->act_state = |
752 | input_report_key(input, BTN_TOUCH, 1); | 820 | nd->activate_slack; |
753 | } else { | 821 | else { /* Move towards deactivation */ |
754 | input_report_key(input, BTN_TOOL_DOUBLETAP, 0); | 822 | nd->act_state--; |
755 | input_report_key(input, BTN_TOUCH, 0); | 823 | break; |
756 | } | 824 | } |
757 | break; | 825 | } |
758 | 826 | ||
759 | default: | 827 | if (nd->first_contact_touch && nd->act_state <= 0) { |
760 | /* fall-back to the generic hidinput handling */ | 828 | /* |
761 | return 0; | 829 | * Check to see if we're ready to start |
830 | * emitting touch events. | ||
831 | * | ||
832 | * Note: activation slack will decrease over | ||
833 | * the course of the frame, and it will be | ||
834 | * inconsistent from the start to the end of | ||
835 | * the frame. However if the frame starts | ||
836 | * with slack, first_contact_touch will still | ||
837 | * be 0 and we will not get to this point. | ||
838 | */ | ||
839 | input_report_key(input, BTN_TOOL_DOUBLETAP, 1); | ||
840 | input_report_key(input, BTN_TOUCH, 1); | ||
841 | } else { | ||
842 | input_report_key(input, BTN_TOOL_DOUBLETAP, 0); | ||
843 | input_report_key(input, BTN_TOUCH, 0); | ||
762 | } | 844 | } |
845 | break; | ||
846 | |||
847 | default: | ||
848 | /* fall-back to the generic hidinput handling */ | ||
849 | return 0; | ||
763 | } | 850 | } |
764 | 851 | ||
852 | not_claimed_input: | ||
853 | |||
765 | /* we have handled the hidinput part, now remains hiddev */ | 854 | /* we have handled the hidinput part, now remains hiddev */ |
766 | if ((hid->claimed & HID_CLAIMED_HIDDEV) && hid->hiddev_hid_event) | 855 | if ((hid->claimed & HID_CLAIMED_HIDDEV) && hid->hiddev_hid_event) |
767 | hid->hiddev_hid_event(hid, field, usage, value); | 856 | hid->hiddev_hid_event(hid, field, usage, value); |
@@ -778,11 +867,12 @@ static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
778 | struct hid_report *report; | 867 | struct hid_report *report; |
779 | 868 | ||
780 | if (id->driver_data) | 869 | if (id->driver_data) |
781 | hdev->quirks |= HID_QUIRK_MULTI_INPUT; | 870 | hdev->quirks |= HID_QUIRK_MULTI_INPUT |
871 | | HID_QUIRK_NO_INIT_REPORTS; | ||
782 | 872 | ||
783 | nd = kmalloc(sizeof(struct ntrig_data), GFP_KERNEL); | 873 | nd = kmalloc(sizeof(struct ntrig_data), GFP_KERNEL); |
784 | if (!nd) { | 874 | if (!nd) { |
785 | dev_err(&hdev->dev, "cannot allocate N-Trig data\n"); | 875 | hid_err(hdev, "cannot allocate N-Trig data\n"); |
786 | return -ENOMEM; | 876 | return -ENOMEM; |
787 | } | 877 | } |
788 | 878 | ||
@@ -801,13 +891,13 @@ static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
801 | 891 | ||
802 | ret = hid_parse(hdev); | 892 | ret = hid_parse(hdev); |
803 | if (ret) { | 893 | if (ret) { |
804 | dev_err(&hdev->dev, "parse failed\n"); | 894 | hid_err(hdev, "parse failed\n"); |
805 | goto err_free; | 895 | goto err_free; |
806 | } | 896 | } |
807 | 897 | ||
808 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF); | 898 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF); |
809 | if (ret) { | 899 | if (ret) { |
810 | dev_err(&hdev->dev, "hw start failed\n"); | 900 | hid_err(hdev, "hw start failed\n"); |
811 | goto err_free; | 901 | goto err_free; |
812 | } | 902 | } |
813 | 903 | ||
@@ -845,8 +935,21 @@ static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
845 | 935 | ||
846 | /* This is needed for devices with more recent firmware versions */ | 936 | /* This is needed for devices with more recent firmware versions */ |
847 | report = hdev->report_enum[HID_FEATURE_REPORT].report_id_hash[0x0a]; | 937 | report = hdev->report_enum[HID_FEATURE_REPORT].report_id_hash[0x0a]; |
848 | if (report) | 938 | if (report) { |
849 | usbhid_submit_report(hdev, report, USB_DIR_OUT); | 939 | /* Let the device settle to ensure the wakeup message gets |
940 | * through */ | ||
941 | usbhid_wait_io(hdev); | ||
942 | usbhid_submit_report(hdev, report, USB_DIR_IN); | ||
943 | |||
944 | /* | ||
945 | * Sanity check: if the current mode is invalid reset it to | ||
946 | * something reasonable. | ||
947 | */ | ||
948 | if (ntrig_get_mode(hdev) >= 4) | ||
949 | ntrig_set_mode(hdev, 3); | ||
950 | } | ||
951 | |||
952 | ntrig_report_version(hdev); | ||
850 | 953 | ||
851 | ret = sysfs_create_group(&hdev->dev.kobj, | 954 | ret = sysfs_create_group(&hdev->dev.kobj, |
852 | &ntrig_attribute_group); | 955 | &ntrig_attribute_group); |
@@ -860,7 +963,7 @@ err_free: | |||
860 | static void ntrig_remove(struct hid_device *hdev) | 963 | static void ntrig_remove(struct hid_device *hdev) |
861 | { | 964 | { |
862 | sysfs_remove_group(&hdev->dev.kobj, | 965 | sysfs_remove_group(&hdev->dev.kobj, |
863 | &ntrig_attribute_group); | 966 | &ntrig_attribute_group); |
864 | hid_hw_stop(hdev); | 967 | hid_hw_stop(hdev); |
865 | kfree(hid_get_drvdata(hdev)); | 968 | kfree(hid_get_drvdata(hdev)); |
866 | } | 969 | } |