Skip to content

Commit b43f977

Browse files
jigpuJiri Kosina
authored andcommitted
Revert "HID: wacom: generic: read the number of expected touches on a per collection basis"
This reverts commit 15893fa. The referenced commit broke pen and touch input for a variety of devices such as the Cintiq Pro 32. Affected devices may appear to work normally for a short amount of time, but eventually loose track of actual touch state and can leave touch arbitration enabled which prevents the pen from working. The commit is not itself required for any currently-available Bluetooth device, and so we revert it to correct the behavior of broken devices. This breakage occurs due to a mismatch between the order of collections and the order of usages on some devices. This commit tries to read the contact count before processing events, but will fail if the contact count does not occur prior to the first logical finger collection. This is the case for devices like the Cintiq Pro 32 which place the contact count at the very end of the report. Without the contact count set, touches will only be partially processed. The `wacom_wac_finger_slot` function will not open any slots since the number of contacts seen is greater than the expectation of 0, but we will still end up calling `input_mt_sync_frame` for each finger anyway. This can cause problems for userspace separate from the issue currently taking place in the kernel. Only once all of the individual finger collections have been processed do we finally get to the enclosing collection which contains the contact count. The value ends up being used for the *next* report, however. This delayed use of the contact count can cause the driver to loose track of the actual touch state and believe that there are contacts down when there aren't. This leaves touch arbitration enabled and prevents the pen from working. It can also cause userspace to incorrectly treat single- finger input as gestures. Link: linuxwacom/input-wacom#146 Signed-off-by: Jason Gerecke <[email protected]> Reviewed-by: Aaron Armstrong Skomra <[email protected]> Fixes: 15893fa ("HID: wacom: generic: read the number of expected touches on a per collection basis") Cc: [email protected] # 5.3+ Signed-off-by: Jiri Kosina <[email protected]>
1 parent 185af3e commit b43f977

File tree

1 file changed

+16
-63
lines changed

1 file changed

+16
-63
lines changed

drivers/hid/wacom_wac.c

Lines changed: 16 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -2637,9 +2637,25 @@ static void wacom_wac_finger_pre_report(struct hid_device *hdev,
26372637
case HID_DG_TIPSWITCH:
26382638
hid_data->last_slot_field = equivalent_usage;
26392639
break;
2640+
case HID_DG_CONTACTCOUNT:
2641+
hid_data->cc_report = report->id;
2642+
hid_data->cc_index = i;
2643+
hid_data->cc_value_index = j;
2644+
break;
26402645
}
26412646
}
26422647
}
2648+
2649+
if (hid_data->cc_report != 0 &&
2650+
hid_data->cc_index >= 0) {
2651+
struct hid_field *field = report->field[hid_data->cc_index];
2652+
int value = field->value[hid_data->cc_value_index];
2653+
if (value)
2654+
hid_data->num_expected = value;
2655+
}
2656+
else {
2657+
hid_data->num_expected = wacom_wac->features.touch_max;
2658+
}
26432659
}
26442660

26452661
static void wacom_wac_finger_report(struct hid_device *hdev,
@@ -2649,7 +2665,6 @@ static void wacom_wac_finger_report(struct hid_device *hdev,
26492665
struct wacom_wac *wacom_wac = &wacom->wacom_wac;
26502666
struct input_dev *input = wacom_wac->touch_input;
26512667
unsigned touch_max = wacom_wac->features.touch_max;
2652-
struct hid_data *hid_data = &wacom_wac->hid_data;
26532668

26542669
/* If more packets of data are expected, give us a chance to
26552670
* process them rather than immediately syncing a partial
@@ -2663,7 +2678,6 @@ static void wacom_wac_finger_report(struct hid_device *hdev,
26632678

26642679
input_sync(input);
26652680
wacom_wac->hid_data.num_received = 0;
2666-
hid_data->num_expected = 0;
26672681

26682682
/* keep touch state for pen event */
26692683
wacom_wac->shared->touch_down = wacom_wac_finger_count_touches(wacom_wac);
@@ -2738,73 +2752,12 @@ static void wacom_report_events(struct hid_device *hdev,
27382752
}
27392753
}
27402754

2741-
static void wacom_set_num_expected(struct hid_device *hdev,
2742-
struct hid_report *report,
2743-
int collection_index,
2744-
struct hid_field *field,
2745-
int field_index)
2746-
{
2747-
struct wacom *wacom = hid_get_drvdata(hdev);
2748-
struct wacom_wac *wacom_wac = &wacom->wacom_wac;
2749-
struct hid_data *hid_data = &wacom_wac->hid_data;
2750-
unsigned int original_collection_level =
2751-
hdev->collection[collection_index].level;
2752-
bool end_collection = false;
2753-
int i;
2754-
2755-
if (hid_data->num_expected)
2756-
return;
2757-
2758-
// find the contact count value for this segment
2759-
for (i = field_index; i < report->maxfield && !end_collection; i++) {
2760-
struct hid_field *field = report->field[i];
2761-
unsigned int field_level =
2762-
hdev->collection[field->usage[0].collection_index].level;
2763-
unsigned int j;
2764-
2765-
if (field_level != original_collection_level)
2766-
continue;
2767-
2768-
for (j = 0; j < field->maxusage; j++) {
2769-
struct hid_usage *usage = &field->usage[j];
2770-
2771-
if (usage->collection_index != collection_index) {
2772-
end_collection = true;
2773-
break;
2774-
}
2775-
if (wacom_equivalent_usage(usage->hid) == HID_DG_CONTACTCOUNT) {
2776-
hid_data->cc_report = report->id;
2777-
hid_data->cc_index = i;
2778-
hid_data->cc_value_index = j;
2779-
2780-
if (hid_data->cc_report != 0 &&
2781-
hid_data->cc_index >= 0) {
2782-
2783-
struct hid_field *field =
2784-
report->field[hid_data->cc_index];
2785-
int value =
2786-
field->value[hid_data->cc_value_index];
2787-
2788-
if (value)
2789-
hid_data->num_expected = value;
2790-
}
2791-
}
2792-
}
2793-
}
2794-
2795-
if (hid_data->cc_report == 0 || hid_data->cc_index < 0)
2796-
hid_data->num_expected = wacom_wac->features.touch_max;
2797-
}
2798-
27992755
static int wacom_wac_collection(struct hid_device *hdev, struct hid_report *report,
28002756
int collection_index, struct hid_field *field,
28012757
int field_index)
28022758
{
28032759
struct wacom *wacom = hid_get_drvdata(hdev);
28042760

2805-
if (WACOM_FINGER_FIELD(field))
2806-
wacom_set_num_expected(hdev, report, collection_index, field,
2807-
field_index);
28082761
wacom_report_events(hdev, report, collection_index, field_index);
28092762

28102763
/*

0 commit comments

Comments
 (0)