summary refs log tree commit diff
path: root/drivers/hid/hid-uclogic-core.c
diff options
context:
space:
mode:
authorNikolai Kondrashov <spbnick@gmail.com>2022-02-19 11:01:50 +0100
committerJiri Kosina <jkosina@suse.cz>2022-03-01 15:28:14 +0100
commit8b013098be2c91ea5e15225c8b39ace08fdd7448 (patch)
tree06d9e5f2274325a0194994a5b4887597d823db0f /drivers/hid/hid-uclogic-core.c
parent606dadc1878f2fdeaa6e435c9c83f58a01387a7d (diff)
downloadlinux-8b013098be2c91ea5e15225c8b39ace08fdd7448.tar.gz
HID: uclogic: Replace pen_frame_flag with subreport_list
Replace a single pen_frame_flag in struct uclogic_params with
subreport_list in struct uclogic_params_pen to prepare for handling more
subreports in Huion HS610.

Signed-off-by: Nikolai Kondrashov <spbnick@gmail.com>
Signed-off-by: José Expósito <jose.exposito89@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers/hid/hid-uclogic-core.c')
-rw-r--r--drivers/hid/hid-uclogic-core.c40
1 files changed, 27 insertions, 13 deletions
diff --git a/drivers/hid/hid-uclogic-core.c b/drivers/hid/hid-uclogic-core.c
index 26849f1f5459..7092f86517a5 100644
--- a/drivers/hid/hid-uclogic-core.c
+++ b/drivers/hid/hid-uclogic-core.c
@@ -350,26 +350,40 @@ static int uclogic_raw_event(struct hid_device *hdev,
 	unsigned int report_id = report->id;
 	struct uclogic_drvdata *drvdata = hid_get_drvdata(hdev);
 	struct uclogic_params *params = &drvdata->params;
+	struct uclogic_params_pen_subreport *subreport;
+	struct uclogic_params_pen_subreport *subreport_list_end;
 
 	/* Do not handle anything but input reports */
 	if (report->type != HID_INPUT_REPORT)
 		return 0;
 
-	/* Tweak pen reports, if necessary */
-	if ((report_id == params->pen.id) && (size >= 2)) {
-		/* If it's the "virtual" frame controls report */
-		if (params->frame.id != 0 &&
-		    data[1] & params->pen_frame_flag) {
-			/* Change to virtual frame controls report ID */
-			report_id = data[0] = params->frame.id;
-		} else {
-			return uclogic_raw_event_pen(drvdata, data, size);
+	while (true) {
+		/* Tweak pen reports, if necessary */
+		if ((report_id == params->pen.id) && (size >= 2)) {
+			subreport_list_end =
+				params->pen.subreport_list +
+				ARRAY_SIZE(params->pen.subreport_list);
+			/* Try to match a subreport */
+			for (subreport = params->pen.subreport_list;
+			     subreport < subreport_list_end &&
+				(data[1] & subreport->mask) != subreport->mask;
+			     subreport++);
+			/* If a subreport matched */
+			if (subreport < subreport_list_end) {
+				/* Change to subreport ID, and restart */
+				report_id = data[0] = subreport->id;
+				continue;
+			} else {
+				return uclogic_raw_event_pen(drvdata, data, size);
+			}
 		}
-	}
 
-	/* Tweak frame control reports, if necessary */
-	if (report_id == params->frame.id)
-		return uclogic_raw_event_frame(drvdata, data, size);
+		/* Tweak frame control reports, if necessary */
+		if (report_id == params->frame.id)
+			return uclogic_raw_event_frame(drvdata, data, size);
+
+		break;
+	}
 
 	return 0;
 }