diff options
-rw-r--r-- | drivers/hid/wacom_wac.c | 94 |
1 files changed, 68 insertions, 26 deletions
diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index d532c1ebf2ee..7a0a7f67e7ed 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c | |||
@@ -2072,7 +2072,7 @@ static void wacom_wac_pad_pre_report(struct hid_device *hdev, | |||
2072 | } | 2072 | } |
2073 | 2073 | ||
2074 | static void wacom_wac_pad_report(struct hid_device *hdev, | 2074 | static void wacom_wac_pad_report(struct hid_device *hdev, |
2075 | struct hid_report *report) | 2075 | struct hid_report *report, struct hid_field *field) |
2076 | { | 2076 | { |
2077 | struct wacom *wacom = hid_get_drvdata(hdev); | 2077 | struct wacom *wacom = hid_get_drvdata(hdev); |
2078 | struct wacom_wac *wacom_wac = &wacom->wacom_wac; | 2078 | struct wacom_wac *wacom_wac = &wacom->wacom_wac; |
@@ -2080,7 +2080,7 @@ static void wacom_wac_pad_report(struct hid_device *hdev, | |||
2080 | bool active = wacom_wac->hid_data.inrange_state != 0; | 2080 | bool active = wacom_wac->hid_data.inrange_state != 0; |
2081 | 2081 | ||
2082 | /* report prox for expresskey events */ | 2082 | /* report prox for expresskey events */ |
2083 | if ((wacom_equivalent_usage(report->field[0]->physical) == HID_DG_TABLETFUNCTIONKEY) && | 2083 | if ((wacom_equivalent_usage(field->physical) == HID_DG_TABLETFUNCTIONKEY) && |
2084 | wacom_wac->hid_data.pad_input_event_flag) { | 2084 | wacom_wac->hid_data.pad_input_event_flag) { |
2085 | input_event(input, EV_ABS, ABS_MISC, active ? PAD_DEVICE_ID : 0); | 2085 | input_event(input, EV_ABS, ABS_MISC, active ? PAD_DEVICE_ID : 0); |
2086 | input_sync(input); | 2086 | input_sync(input); |
@@ -2627,11 +2627,13 @@ void wacom_wac_event(struct hid_device *hdev, struct hid_field *field, | |||
2627 | wacom_wac_finger_event(hdev, field, usage, value); | 2627 | wacom_wac_finger_event(hdev, field, usage, value); |
2628 | } | 2628 | } |
2629 | 2629 | ||
2630 | static void wacom_report_events(struct hid_device *hdev, struct hid_report *report) | 2630 | static void wacom_report_events(struct hid_device *hdev, |
2631 | struct hid_report *report, int collection_index, | ||
2632 | int field_index) | ||
2631 | { | 2633 | { |
2632 | int r; | 2634 | int r; |
2633 | 2635 | ||
2634 | for (r = 0; r < report->maxfield; r++) { | 2636 | for (r = field_index; r < report->maxfield; r++) { |
2635 | struct hid_field *field; | 2637 | struct hid_field *field; |
2636 | unsigned count, n; | 2638 | unsigned count, n; |
2637 | 2639 | ||
@@ -2641,30 +2643,23 @@ static void wacom_report_events(struct hid_device *hdev, struct hid_report *repo | |||
2641 | if (!(HID_MAIN_ITEM_VARIABLE & field->flags)) | 2643 | if (!(HID_MAIN_ITEM_VARIABLE & field->flags)) |
2642 | continue; | 2644 | continue; |
2643 | 2645 | ||
2644 | for (n = 0; n < count; n++) | 2646 | for (n = 0 ; n < count; n++) { |
2645 | wacom_wac_event(hdev, field, &field->usage[n], field->value[n]); | 2647 | if (field->usage[n].collection_index == collection_index) |
2648 | wacom_wac_event(hdev, field, &field->usage[n], | ||
2649 | field->value[n]); | ||
2650 | else | ||
2651 | return; | ||
2652 | } | ||
2646 | } | 2653 | } |
2647 | } | 2654 | } |
2648 | 2655 | ||
2649 | void wacom_wac_report(struct hid_device *hdev, struct hid_report *report) | 2656 | int wacom_wac_collection(struct hid_device *hdev, struct hid_report *report, |
2657 | int collection_index, struct hid_field *field, | ||
2658 | int field_index) | ||
2650 | { | 2659 | { |
2651 | struct wacom *wacom = hid_get_drvdata(hdev); | 2660 | struct wacom *wacom = hid_get_drvdata(hdev); |
2652 | struct wacom_wac *wacom_wac = &wacom->wacom_wac; | ||
2653 | struct hid_field *field = report->field[0]; | ||
2654 | |||
2655 | if (wacom_wac->features.type != HID_GENERIC) | ||
2656 | return; | ||
2657 | |||
2658 | wacom_wac_battery_pre_report(hdev, report); | ||
2659 | |||
2660 | if (WACOM_PAD_FIELD(field) && wacom->wacom_wac.pad_input) | ||
2661 | wacom_wac_pad_pre_report(hdev, report); | ||
2662 | else if (WACOM_PEN_FIELD(field) && wacom->wacom_wac.pen_input) | ||
2663 | wacom_wac_pen_pre_report(hdev, report); | ||
2664 | else if (WACOM_FINGER_FIELD(field) && wacom->wacom_wac.touch_input) | ||
2665 | wacom_wac_finger_pre_report(hdev, report); | ||
2666 | 2661 | ||
2667 | wacom_report_events(hdev, report); | 2662 | wacom_report_events(hdev, report, collection_index, field_index); |
2668 | 2663 | ||
2669 | /* | 2664 | /* |
2670 | * Non-input reports may be sent prior to the device being | 2665 | * Non-input reports may be sent prior to the device being |
@@ -2674,16 +2669,63 @@ void wacom_wac_report(struct hid_device *hdev, struct hid_report *report) | |||
2674 | * processing functions. | 2669 | * processing functions. |
2675 | */ | 2670 | */ |
2676 | if (report->type != HID_INPUT_REPORT) | 2671 | if (report->type != HID_INPUT_REPORT) |
2677 | return; | 2672 | return -1; |
2678 | |||
2679 | wacom_wac_battery_report(hdev, report); | ||
2680 | 2673 | ||
2681 | if (WACOM_PAD_FIELD(field) && wacom->wacom_wac.pad_input) | 2674 | if (WACOM_PAD_FIELD(field) && wacom->wacom_wac.pad_input) |
2682 | wacom_wac_pad_report(hdev, report); | 2675 | wacom_wac_pad_report(hdev, report, field); |
2683 | else if (WACOM_PEN_FIELD(field) && wacom->wacom_wac.pen_input) | 2676 | else if (WACOM_PEN_FIELD(field) && wacom->wacom_wac.pen_input) |
2684 | wacom_wac_pen_report(hdev, report); | 2677 | wacom_wac_pen_report(hdev, report); |
2685 | else if (WACOM_FINGER_FIELD(field) && wacom->wacom_wac.touch_input) | 2678 | else if (WACOM_FINGER_FIELD(field) && wacom->wacom_wac.touch_input) |
2686 | wacom_wac_finger_report(hdev, report); | 2679 | wacom_wac_finger_report(hdev, report); |
2680 | |||
2681 | return 0; | ||
2682 | } | ||
2683 | |||
2684 | void wacom_wac_report(struct hid_device *hdev, struct hid_report *report) | ||
2685 | { | ||
2686 | struct wacom *wacom = hid_get_drvdata(hdev); | ||
2687 | struct wacom_wac *wacom_wac = &wacom->wacom_wac; | ||
2688 | struct hid_field *field; | ||
2689 | bool pad_in_hid_field = false, pen_in_hid_field = false, | ||
2690 | finger_in_hid_field = false; | ||
2691 | int r; | ||
2692 | int prev_collection = -1; | ||
2693 | |||
2694 | if (wacom_wac->features.type != HID_GENERIC) | ||
2695 | return; | ||
2696 | |||
2697 | for (r = 0; r < report->maxfield; r++) { | ||
2698 | field = report->field[r]; | ||
2699 | |||
2700 | if (WACOM_PAD_FIELD(field)) | ||
2701 | pad_in_hid_field = true; | ||
2702 | if (WACOM_PEN_FIELD(field)) | ||
2703 | pen_in_hid_field = true; | ||
2704 | if (WACOM_FINGER_FIELD(field)) | ||
2705 | finger_in_hid_field = true; | ||
2706 | } | ||
2707 | |||
2708 | wacom_wac_battery_pre_report(hdev, report); | ||
2709 | |||
2710 | if (pad_in_hid_field && wacom->wacom_wac.pad_input) | ||
2711 | wacom_wac_pad_pre_report(hdev, report); | ||
2712 | if (pen_in_hid_field && wacom->wacom_wac.pen_input) | ||
2713 | wacom_wac_pen_pre_report(hdev, report); | ||
2714 | if (finger_in_hid_field && wacom->wacom_wac.touch_input) | ||
2715 | wacom_wac_finger_pre_report(hdev, report); | ||
2716 | |||
2717 | for (r = 0; r < report->maxfield; r++) { | ||
2718 | field = report->field[r]; | ||
2719 | |||
2720 | if (field->usage[0].collection_index != prev_collection) { | ||
2721 | if (wacom_wac_collection(hdev, report, | ||
2722 | field->usage[0].collection_index, field, r) < 0) | ||
2723 | return; | ||
2724 | prev_collection = field->usage[0].collection_index; | ||
2725 | } | ||
2726 | } | ||
2727 | |||
2728 | wacom_wac_battery_report(hdev, report); | ||
2687 | } | 2729 | } |
2688 | 2730 | ||
2689 | static int wacom_bpt_touch(struct wacom_wac *wacom) | 2731 | static int wacom_bpt_touch(struct wacom_wac *wacom) |