linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Benjamin Tissoires <benjamin.tissoires@redhat.com>
To: "Jiri Kosina" <jikos@kernel.org>,
	"Dmitry Torokhov" <dmitry.torokhov@gmail.com>,
	"Jonathan Corbet" <corbet@lwn.net>,
	"Ahelenia Ziemiańska" <nabijaczleweli@nabijaczleweli.xyz>,
	"Ping Cheng" <pinglinux@gmail.com>,
	"Aaron Armstrong Skomra" <skomra@gmail.com>,
	"Jason Gerecke" <killertofu@gmail.com>,
	"Peter Hutterer" <peter.hutterer@who-t.net>
Cc: linux-input@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-kernel@vger.kernel.org,
	Benjamin Tissoires <benjamin.tissoires@redhat.com>
Subject: [PATCH v2 09/12] HID: input: enforce Invert usage to be processed before InRange
Date: Thu,  3 Feb 2022 15:32:23 +0100	[thread overview]
Message-ID: <20220203143226.4023622-10-benjamin.tissoires@redhat.com> (raw)
In-Reply-To: <20220203143226.4023622-1-benjamin.tissoires@redhat.com>

When a device exposes both Invert and InRange, Invert must be processed
before InRange. If we keep the order of the device and we process them
out of order, InRange will first set BTN_TOOL_PEN, and then Invert will
set BTN_TOOL_RUBBER. Userspace knows how to deal with that situation,
but fixing it in the kernel is now easier.

Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
---
 drivers/hid/hid-input.c | 34 ++++++++++++++++++++++++++++++++--
 include/linux/hid.h     |  4 +++-
 2 files changed, 35 insertions(+), 3 deletions(-)

diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index 8770d9a2b2af..61d91117f4ae 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -48,6 +48,25 @@ static const struct {
 	__s32 y;
 }  hid_hat_to_axis[] = {{ 0, 0}, { 0,-1}, { 1,-1}, { 1, 0}, { 1, 1}, { 0, 1}, {-1, 1}, {-1, 0}, {-1,-1}};
 
+/*
+ * hid-input will convert this list into priorities:
+ * the first element will have the highest priority
+ * (the length of the following array) and the last
+ * element the lowest (1).
+ *
+ * hid-input will then shift the priority by 8 bits to leave some space
+ * in case drivers want to interleave other fields.
+ *
+ * If drivers want to add fields before those, hid-input will
+ * leave out the first 8 bits of the priority value.
+ *
+ * This still leaves us 65535 individual priority values.
+ */
+static const __u32 hidinput_usages_priorities[] = {
+	HID_DG_INVERT,		/* Invert must always come before In Range */
+	HID_DG_INRANGE,
+};
+
 #define map_abs(c)	hid_map_usage(hidinput, usage, &bit, &max, EV_ABS, (c))
 #define map_rel(c)	hid_map_usage(hidinput, usage, &bit, &max, EV_REL, (c))
 #define map_key(c)	hid_map_usage(hidinput, usage, &bit, &max, EV_KEY, (c))
@@ -586,11 +605,12 @@ static bool hidinput_field_in_collection(struct hid_device *device, struct hid_f
 }
 
 static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_field *field,
-				     struct hid_usage *usage)
+				     struct hid_usage *usage, unsigned int usage_index)
 {
 	struct input_dev *input = hidinput->input;
 	struct hid_device *device = input_get_drvdata(input);
 	int max = 0, code;
+	unsigned int i = 0;
 	unsigned long *bit = NULL;
 
 	field->hidinput = hidinput;
@@ -608,6 +628,15 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
 		goto ignore;
 	}
 
+	/* assign a priority based on the static list declared here */
+	for (i = 0; i < ARRAY_SIZE(hidinput_usages_priorities); i++) {
+		if (usage->hid == hidinput_usages_priorities[i]) {
+			field->usages_priorities[usage_index] =
+				(ARRAY_SIZE(hidinput_usages_priorities) - i) << 8;
+			break;
+		}
+	}
+
 	if (device->driver->input_mapping) {
 		int ret = device->driver->input_mapping(device, hidinput, field,
 				usage, &bit, &max);
@@ -1962,7 +1991,8 @@ static inline void hidinput_configure_usages(struct hid_input *hidinput,
 	for (i = 0; i < report->maxfield; i++)
 		for (j = 0; j < report->field[i]->maxusage; j++)
 			hidinput_configure_usage(hidinput, report->field[i],
-						 report->field[i]->usage + j);
+						 report->field[i]->usage + j,
+						 j);
 }
 
 /*
diff --git a/include/linux/hid.h b/include/linux/hid.h
index f25020c0d6b8..eaad0655b05c 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -477,7 +477,9 @@ struct hid_field {
 	unsigned  report_type;		/* (input,output,feature) */
 	__s32    *value;		/* last known value(s) */
 	__s32    *new_value;		/* newly read value(s) */
-	__s32    *usages_priorities;	/* priority of each usage when reading the report */
+	__s32    *usages_priorities;	/* priority of each usage when reading the report
+					 * bits 8-16 are reserved for hid-input usage
+					 */
 	__s32     logical_minimum;
 	__s32     logical_maximum;
 	__s32     physical_minimum;
-- 
2.33.1


  parent reply	other threads:[~2022-02-03 14:35 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-02-03 14:32 [PATCH v2 00/12] HID: fix for generic input processing Benjamin Tissoires
2022-02-03 14:32 ` [PATCH v2 01/12] HID: core: statically allocate read buffers Benjamin Tissoires
2022-02-03 14:32 ` [PATCH v2 02/12] HID: core: de-duplicate some code in hid_input_field() Benjamin Tissoires
2022-02-03 14:32 ` [PATCH v2 03/12] HID: core: split data fetching from processing " Benjamin Tissoires
2022-02-03 14:32 ` [PATCH v2 04/12] HID: input: tag touchscreens as such if the physical is not there Benjamin Tissoires
2022-02-03 14:32 ` [PATCH v2 05/12] HID: input: rework spaghetti code with switch statements Benjamin Tissoires
2022-02-03 14:32 ` [PATCH v2 06/12] HID: input: move up out-of-range processing of input values Benjamin Tissoires
2022-02-03 14:32 ` [PATCH v2 07/12] HID: compute an ordered list of input fields to process Benjamin Tissoires
2022-02-03 14:32 ` [PATCH v2 08/12] HID: core: for input reports, process the usages by priority list Benjamin Tissoires
2022-02-03 14:32 ` Benjamin Tissoires [this message]
2022-02-03 14:32 ` [PATCH v2 10/12] HID: input: remove the need for HID_QUIRK_INVERT Benjamin Tissoires
2022-02-04  1:41   ` Ping Cheng
2022-02-10  5:21   ` Ping Cheng
2022-02-10  5:43     ` Ping Cheng
2022-02-14 10:23       ` Benjamin Tissoires
2022-02-15  2:04         ` Ping Cheng
2022-02-15  8:51           ` Benjamin Tissoires
2022-02-16 12:42             ` Benjamin Tissoires
2022-02-17  1:27               ` Ping Cheng
2022-02-03 14:32 ` [PATCH v2 11/12] HID: input: accommodate priorities for slotted devices Benjamin Tissoires
2022-02-03 14:32 ` [PATCH v2 12/12] Input: docs: add more details on the use of BTN_TOOL Benjamin Tissoires
2022-02-16  5:40   ` Peter Hutterer
2022-03-01 14:53 ` [PATCH v2 00/12] HID: fix for generic input processing 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=20220203143226.4023622-10-benjamin.tissoires@redhat.com \
    --to=benjamin.tissoires@redhat.com \
    --cc=corbet@lwn.net \
    --cc=dmitry.torokhov@gmail.com \
    --cc=jikos@kernel.org \
    --cc=killertofu@gmail.com \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-input@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=nabijaczleweli@nabijaczleweli.xyz \
    --cc=peter.hutterer@who-t.net \
    --cc=pinglinux@gmail.com \
    --cc=skomra@gmail.com \
    /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).