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

Commit 15893fa4 authored by Aaron Armstrong Skomra's avatar Aaron Armstrong Skomra Committed by Jiri Kosina
Browse files

HID: wacom: generic: read the number of expected touches on a per collection basis



Bluetooth connections may contain more than one set of touches,
or a partial set of touches, in one report.

Set the number of expected touches when reading a collection
instead of once per report (in the pre-report function).

Accordingly, reset the number of touches expected after each sync.

Signed-off-by: default avatarAaron Armstrong Skomra <aaron.skomra@wacom.com>
Signed-off-by: default avatarJiri Kosina <jkosina@suse.cz>
parent f4e11d59
Loading
Loading
Loading
Loading
+63 −16
Original line number Diff line number Diff line
@@ -2563,24 +2563,8 @@ static void wacom_wac_finger_pre_report(struct hid_device *hdev,
			case HID_DG_TIPSWITCH:
				hid_data->last_slot_field = equivalent_usage;
				break;
			case HID_DG_CONTACTCOUNT:
				hid_data->cc_report = report->id;
				hid_data->cc_index = i;
				hid_data->cc_value_index = j;
				break;
			}
			}
		}

	if (hid_data->cc_report != 0 &&
	    hid_data->cc_index >= 0) {
		struct hid_field *field = report->field[hid_data->cc_index];
		int value = field->value[hid_data->cc_value_index];
		if (value)
			hid_data->num_expected = value;
	}
	else {
		hid_data->num_expected = wacom_wac->features.touch_max;
	}
}

@@ -2591,6 +2575,7 @@ static void wacom_wac_finger_report(struct hid_device *hdev,
	struct wacom_wac *wacom_wac = &wacom->wacom_wac;
	struct input_dev *input = wacom_wac->touch_input;
	unsigned touch_max = wacom_wac->features.touch_max;
	struct hid_data *hid_data = &wacom_wac->hid_data;

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

	input_sync(input);
	wacom_wac->hid_data.num_received = 0;
	hid_data->num_expected = 0;

	/* keep touch state for pen event */
	wacom_wac->shared->touch_down = wacom_wac_finger_count_touches(wacom_wac);
@@ -2678,12 +2664,73 @@ static void wacom_report_events(struct hid_device *hdev,
	}
}

static void wacom_set_num_expected(struct hid_device *hdev,
				   struct hid_report *report,
				   int collection_index,
				   struct hid_field *field,
				   int field_index)
{
	struct wacom *wacom = hid_get_drvdata(hdev);
	struct wacom_wac *wacom_wac = &wacom->wacom_wac;
	struct hid_data *hid_data = &wacom_wac->hid_data;
	unsigned int original_collection_level =
		hdev->collection[collection_index].level;
	bool end_collection = false;
	int i;

	if (hid_data->num_expected)
		return;

	// find the contact count value for this segment
	for (i = field_index; i < report->maxfield && !end_collection; i++) {
		struct hid_field *field = report->field[i];
		unsigned int field_level =
			hdev->collection[field->usage[0].collection_index].level;
		unsigned int j;

		if (field_level != original_collection_level)
			continue;

		for (j = 0; j < field->maxusage; j++) {
			struct hid_usage *usage = &field->usage[j];

			if (usage->collection_index != collection_index) {
				end_collection = true;
				break;
			}
			if (wacom_equivalent_usage(usage->hid) == HID_DG_CONTACTCOUNT) {
				hid_data->cc_report = report->id;
				hid_data->cc_index = i;
				hid_data->cc_value_index = j;

				if (hid_data->cc_report != 0 &&
				    hid_data->cc_index >= 0) {

					struct hid_field *field =
						report->field[hid_data->cc_index];
					int value =
						field->value[hid_data->cc_value_index];

					if (value)
						hid_data->num_expected = value;
				}
			}
		}
	}

	if (hid_data->cc_report == 0 || hid_data->cc_index < 0)
		hid_data->num_expected = wacom_wac->features.touch_max;
}

static int wacom_wac_collection(struct hid_device *hdev, struct hid_report *report,
			 int collection_index, struct hid_field *field,
			 int field_index)
{
	struct wacom *wacom = hid_get_drvdata(hdev);

	if (WACOM_FINGER_FIELD(field))
		wacom_set_num_expected(hdev, report, collection_index, field,
				       field_index);
	wacom_report_events(hdev, report, collection_index, field_index);

	/*