Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 499522c8 authored by Jason Gerecke's avatar Jason Gerecke Committed by Jiri Kosina
Browse files

HID: wacom: Tie cached HID_DG_CONTACTCOUNT indices to report ID



The cached indicies 'cc_index' and 'cc_value_index' introduced in 1b5d514a
are only valid for a single report ID. If a touchscreen has multiple
reports with a HID_DG_CONTACTCOUNT usage, its possible that the values
will not be correct for the report we're handling, resulting in an
incorrect value for 'num_expected'. This has been observed with the Cintiq
Companion 2.

To address this, we store the ID of the report those indicies are valid
for in a new  'cc_report' variable. Before using them to get the expected
contact count, we first check if the ID of the report we're processing
matches 'cc_report'. If it doesn't, we update the indicies to point to
the HID_DG_CONTACTCOUNT usage of the current report (if it has one).

Cc: stable@vger.kernel.org
Signed-off-by: default avatarJason Gerecke <jason.gerecke@wacom.com>
Signed-off-by: default avatarJiri Kosina <jkosina@suse.cz>
parent e8e88438
Loading
Loading
Loading
Loading
+26 −0
Original line number Diff line number Diff line
@@ -1628,6 +1628,7 @@ static void wacom_wac_finger_usage_mapping(struct hid_device *hdev,
		wacom_map_usage(input, usage, field, EV_KEY, BTN_TOUCH, 0);
		break;
	case HID_DG_CONTACTCOUNT:
		wacom_wac->hid_data.cc_report = field->report->id;
		wacom_wac->hid_data.cc_index = field->index;
		wacom_wac->hid_data.cc_value_index = usage->usage_index;
		break;
@@ -1715,6 +1716,31 @@ static void wacom_wac_finger_pre_report(struct hid_device *hdev,
	struct wacom_wac *wacom_wac = &wacom->wacom_wac;
	struct hid_data* hid_data = &wacom_wac->hid_data;

	if (hid_data->cc_report != 0 &&
	    hid_data->cc_report != report->id) {
		int i;

		hid_data->cc_report = report->id;
		hid_data->cc_index = -1;
		hid_data->cc_value_index = -1;

		for (i = 0; i < report->maxfield; i++) {
			struct hid_field *field = report->field[i];
			int j;

			for (j = 0; j < field->maxusage; j++) {
				if (field->usage[j].hid == HID_DG_CONTACTCOUNT) {
					hid_data->cc_index = i;
					hid_data->cc_value_index = j;

					/* break */
					i = report->maxfield;
					j = field->maxusage;
				}
			}
		}
	}

	if (hid_data->cc_index >= 0) {
		struct hid_field *field = report->field[hid_data->cc_index];
		int value = field->value[hid_data->cc_value_index];
+1 −0
Original line number Diff line number Diff line
@@ -198,6 +198,7 @@ struct hid_data {
	int width;
	int height;
	int id;
	int cc_report;
	int cc_index;
	int cc_value_index;
	int num_expected;