linux-input.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Tomasz Pakuła" <tomasz.pakula.oficjalny@gmail.com>
To: jikos@kernel.org, bentiss@kernel.org
Cc: oleg@makarenk.ooo, linux-input@vger.kernel.org
Subject: [PATCH v2 07/17] HID: pidff: Simplify HID field/usage searching logic
Date: Wed, 13 Aug 2025 22:09:55 +0200	[thread overview]
Message-ID: <20250813201005.17819-8-tomasz.pakula.oficjalny@gmail.com> (raw)
In-Reply-To: <20250813201005.17819-1-tomasz.pakula.oficjalny@gmail.com>

Some deduplication and splitting into separate functions. This is now
way easier to comprehend and parse mentally.

Signed-off-by: Tomasz Pakuła <tomasz.pakula.oficjalny@gmail.com>
---
 drivers/hid/usbhid/hid-pidff.c | 105 +++++++++++++++++++--------------
 1 file changed, 62 insertions(+), 43 deletions(-)

diff --git a/drivers/hid/usbhid/hid-pidff.c b/drivers/hid/usbhid/hid-pidff.c
index c88442a087f1..2e8eac944be0 100644
--- a/drivers/hid/usbhid/hid-pidff.c
+++ b/drivers/hid/usbhid/hid-pidff.c
@@ -939,6 +939,43 @@ static void pidff_set_autocenter(struct input_dev *dev, u16 magnitude)
 	pidff_autocenter(dev->ff->private, magnitude);
 }
 
+/*
+ * Find specific usage in a given hid_field
+ */
+static int pidff_find_usage(struct hid_field *fld, unsigned int usage_code)
+{
+	for (int i = 0; i < fld->maxusage; i++) {
+		if (fld->usage[i].hid == usage_code)
+			return i;
+	}
+	return -1;
+}
+
+/*
+ * Find hid_field with a specific usage. Return the usage index as well
+ */
+static int pidff_find_field_with_usage(int *usage_index,
+				       struct hid_report *report,
+				       unsigned int usage_code)
+{
+	for (int i = 0; i < report->maxfield; i++) {
+		struct hid_field *fld = report->field[i];
+
+		if (fld->maxusage != fld->report_count) {
+			pr_debug("maxusage and report_count do not match, skipping\n");
+			continue;
+		}
+
+		int index = pidff_find_usage(fld, usage_code);
+
+		if (index >= 0) {
+			*usage_index = index;
+			return i;
+		}
+	}
+	return -1;
+}
+
 /*
  * Find fields from a report and fill a pidff_usage
  */
@@ -946,46 +983,38 @@ static int pidff_find_fields(struct pidff_usage *usage, const u8 *table,
 			     struct hid_report *report, int count, int strict,
 			     u32 *quirks)
 {
+	const u8 block_offset = pidff_set_condition[PID_PARAM_BLOCK_OFFSET];
+	const u8 delay = pidff_set_effect[PID_START_DELAY];
+
 	if (!report) {
 		pr_debug("%s, null report\n", __func__);
 		return -1;
 	}
 
-	int i, j, k, found;
+	for (int i = 0; i < count; i++) {
+		int index;
+		int found = pidff_find_field_with_usage(&index, report,
+							HID_UP_PID | table[i]);
 
-	for (k = 0; k < count; k++) {
-		found = 0;
-		for (i = 0; i < report->maxfield; i++) {
-			if (report->field[i]->maxusage !=
-			    report->field[i]->report_count) {
-				pr_debug("maxusage and report_count do not match, skipping\n");
-				continue;
-			}
-			for (j = 0; j < report->field[i]->maxusage; j++) {
-				if (report->field[i]->usage[j].hid ==
-				    (HID_UP_PID | table[k])) {
-					pr_debug("found %d at %d->%d\n",
-						 k, i, j);
-					usage[k].field = report->field[i];
-					usage[k].value =
-						&report->field[i]->value[j];
-					found = 1;
-					break;
-				}
-			}
-			if (found)
-				break;
+		if (found >= 0) {
+			pr_debug("found %d at %d->%d\n", i, found, index);
+			usage[i].field = report->field[found];
+			usage[i].value = &report->field[found]->value[index];
+			continue;
 		}
-		if (!found && table[k] == pidff_set_effect[PID_START_DELAY]) {
+
+		if (table[i] == delay) {
 			pr_debug("Delay field not found, but that's OK\n");
 			pr_debug("Setting MISSING_DELAY quirk\n");
 			*quirks |= HID_PIDFF_QUIRK_MISSING_DELAY;
-		} else if (!found && table[k] == pidff_set_condition[PID_PARAM_BLOCK_OFFSET]) {
+
+		} else if (table[i] == block_offset) {
 			pr_debug("PBO field not found, but that's OK\n");
 			pr_debug("Setting MISSING_PBO quirk\n");
 			*quirks |= HID_PIDFF_QUIRK_MISSING_PBO;
-		} else if (!found && strict) {
-			pr_debug("failed to locate %d\n", k);
+
+		} else if (strict) {
+			pr_debug("failed to locate %d\n", i);
 			return -1;
 		}
 	}
@@ -1054,9 +1083,7 @@ static void pidff_find_reports(struct hid_device *hid, int report_type,
  */
 static int pidff_reports_ok(struct pidff_device *pidff)
 {
-	int i;
-
-	for (i = 0; i < PID_REQUIRED_REPORTS; i++) {
+	for (int i = 0; i < PID_REQUIRED_REPORTS; i++) {
 		if (!pidff->reports[i]) {
 			hid_dbg(pidff->hid, "%d missing\n", i);
 			return 0;
@@ -1077,9 +1104,7 @@ static struct hid_field *pidff_find_special_field(struct hid_report *report,
 		return NULL;
 	}
 
-	int i;
-
-	for (i = 0; i < report->maxfield; i++) {
+	for (int i = 0; i < report->maxfield; i++) {
 		if (report->field[i]->logical == (HID_UP_PID | usage) &&
 		    report->field[i]->report_count > 0) {
 			if (!enforce_min ||
@@ -1099,18 +1124,12 @@ static struct hid_field *pidff_find_special_field(struct hid_report *report,
 static int pidff_find_special_keys(int *keys, struct hid_field *fld,
 				   const u8 *usagetable, int count)
 {
-
-	int i, j;
 	int found = 0;
 
-	for (i = 0; i < count; i++) {
-		for (j = 0; j < fld->maxusage; j++) {
-			if (fld->usage[j].hid == (HID_UP_PID | usagetable[i])) {
-				keys[i] = j + 1;
-				found++;
-				break;
-			}
-		}
+	for (int i = 0; i < count; i++) {
+		keys[i] = pidff_find_usage(fld, HID_UP_PID | usagetable[i]) + 1;
+		if (keys[i])
+			found++;
 	}
 	return found;
 }
-- 
2.50.1


  parent reply	other threads:[~2025-08-13 20:10 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-08-13 20:09 [PATCH v2 00/17] Further hid-pidff improvements and fixes Tomasz Pakuła
2025-08-13 20:09 ` [PATCH v2 01/17] HID: pidff: Use direction fix only for conditional effects Tomasz Pakuła
2025-08-13 20:09 ` [PATCH v2 02/17] HID: pidff: Remove unhelpful pidff_set_actuators helper Tomasz Pakuła
2025-08-13 20:09 ` [PATCH v2 03/17] HID: pidff: Remove unneeded debug Tomasz Pakuła
2025-08-13 20:09 ` [PATCH v2 04/17] HID: pidff: Use ARRAY_SIZE macro instead of sizeof Tomasz Pakuła
2025-08-13 20:09 ` [PATCH v2 05/17] HID: pidff: Treat PID_REQUIRED_REPORTS as count, not max Tomasz Pakuła
2025-08-13 20:09 ` [PATCH v2 06/17] HID: pidff: Better quirk assigment when searching for fields Tomasz Pakuła
2025-08-13 20:09 ` Tomasz Pakuła [this message]
2025-08-13 20:09 ` [PATCH v2 08/17] HID: pidff: Add support for AXES_ENABLE field Tomasz Pakuła
2025-08-13 20:09 ` [PATCH v2 09/17] HID: pidff: Update debug messages Tomasz Pakuła
2025-08-13 20:09 ` [PATCH v2 10/17] HID: pidff: Rework pidff_upload_effect Tomasz Pakuła
2025-08-13 20:09 ` [PATCH v2 11/17] HID: pidff: Separate check for infinite duration Tomasz Pakuła
2025-08-13 20:10 ` [PATCH v2 12/17] HID: pidff: PERMISSIVE_CONTROL quirk autodetection Tomasz Pakuła
2025-08-13 20:10 ` [PATCH v2 13/17] HID: pidff: Remove Anssi's email address from info msg Tomasz Pakuła
2025-08-13 20:10 ` [PATCH v2 14/17] HID: pidff: Define all cardinal directions Tomasz Pakuła
2025-08-13 20:10 ` [PATCH v2 15/17] HID: pidff: clang-format pass Tomasz Pakuła
2025-08-13 20:10 ` [PATCH v2 16/17] HID: universal-pidff: " Tomasz Pakuła
2025-08-13 20:10 ` [PATCH v2 17/17] HID: pidff: Reduce PID_EFFECT_OPERATION spam Tomasz Pakuła
2025-08-15 14:01 ` [PATCH v2 00/17] Further hid-pidff improvements and fixes Jiri Kosina

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20250813201005.17819-8-tomasz.pakula.oficjalny@gmail.com \
    --to=tomasz.pakula.oficjalny@gmail.com \
    --cc=bentiss@kernel.org \
    --cc=jikos@kernel.org \
    --cc=linux-input@vger.kernel.org \
    --cc=oleg@makarenk.ooo \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).