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 11/12] HID: input: accommodate priorities for slotted devices Date: Thu, 3 Feb 2022 15:32:25 +0100 [thread overview] Message-ID: <20220203143226.4023622-12-benjamin.tissoires@redhat.com> (raw) In-Reply-To: <20220203143226.4023622-1-benjamin.tissoires@redhat.com> Multitouch devices in hybrid mode are reporting multiple times the same collection. We should accommodate for this in our handling of priorities by defining the slots they belong to. Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> --- drivers/hid/hid-input.c | 103 ++++++++++++++++++++++++++++++++++++---- include/linux/hid.h | 1 + 2 files changed, 96 insertions(+), 8 deletions(-) diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 9f8853640648..56d4e91c4750 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -48,6 +48,16 @@ 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}}; +struct usage_priority { + __u32 usage; /* the HID usage associated */ + bool global; /* we assume all usages to be slotted, + * unless global + */ + unsigned int slot_overwrite; /* for globals: allows to set the usage + * before or after the slots + */ +}; + /* * hid-input will convert this list into priorities: * the first element will have the highest priority @@ -57,17 +67,30 @@ static const struct { * hid-input will then shift the priority by 8 bits to leave some space * in case drivers want to interleave other fields. * + * To accommodate slotted devices, the slot priority is + * defined in the next 8 bits (defined by 0xff - slot). + * * 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_ERASER, /* Eraser (eraser touching) must always come before tipswitch */ - HID_DG_INVERT, /* Invert must always come before In Range */ - HID_DG_TIPSWITCH, /* Is the tip of the tool touching? */ - HID_DG_TIPPRESSURE, /* Tip Pressure might emulate tip switch */ - HID_DG_INRANGE, /* In Range needs to come after the other tool states */ +static const struct usage_priority hidinput_usages_priorities[] = { + { /* Eraser (eraser touching) must always come before tipswitch */ + .usage = HID_DG_ERASER, + }, + { /* Invert must always come before In Range */ + .usage = HID_DG_INVERT, + }, + { /* Is the tip of the tool touching? */ + .usage = HID_DG_TIPSWITCH, + }, + { /* Tip Pressure might emulate tip switch */ + .usage = HID_DG_TIPPRESSURE, + }, + { /* In Range needs to come after the other tool states */ + .usage = HID_DG_INRANGE, + }, }; #define map_abs(c) hid_map_usage(hidinput, usage, &bit, &max, EV_ABS, (c)) @@ -612,6 +635,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel { struct input_dev *input = hidinput->input; struct hid_device *device = input_get_drvdata(input); + const struct usage_priority *usage_priority = NULL; int max = 0, code; unsigned int i = 0; unsigned long *bit = NULL; @@ -633,13 +657,26 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel /* 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]) { + if (usage->hid == hidinput_usages_priorities[i].usage) { + usage_priority = &hidinput_usages_priorities[i]; + field->usages_priorities[usage_index] = (ARRAY_SIZE(hidinput_usages_priorities) - i) << 8; break; } } + /* + * For slotted devices, we need to also add the slot index + * in the priority. + */ + if (usage_priority && usage_priority->global) + field->usages_priorities[usage_index] |= + usage_priority->slot_overwrite; + else + field->usages_priorities[usage_index] |= + (0xff - field->slot_idx) << 16; + if (device->driver->input_mapping) { int ret = device->driver->input_mapping(device, hidinput, field, usage, &bit, &max); @@ -2068,7 +2105,57 @@ static struct hid_input *hidinput_match_application(struct hid_report *report) static inline void hidinput_configure_usages(struct hid_input *hidinput, struct hid_report *report) { - int i, j; + int i, j, k; + int first_field_index = 0; + int slot_collection_index = -1; + int prev_collection_index = -1; + unsigned int slot_idx = 0; + struct hid_field *field; + + /* + * First tag all the fields that are part of a slot, + * a slot needs to have one Contact ID in the collection + */ + for (i = 0; i < report->maxfield; i++) { + field = report->field[i]; + + /* ignore fields without usage */ + if (field->maxusage < 1) + continue; + + /* + * janitoring when collection_index changes + */ + if (prev_collection_index != field->usage->collection_index) { + prev_collection_index = field->usage->collection_index; + first_field_index = i; + } + + /* + * if we already found a Contact ID in the collection, + * tag and continue to the next. + */ + if (slot_collection_index == field->usage->collection_index) { + field->slot_idx = slot_idx; + continue; + } + + /* check if the current field has Contact ID */ + for (j = 0; j < field->maxusage; j++) { + if (field->usage[j].hid == HID_DG_CONTACTID) { + slot_collection_index = field->usage->collection_index; + slot_idx++; + + /* + * mark all previous fields and this one in the + * current collection to be slotted. + */ + for (k = first_field_index; k <= i; k++) + report->field[k]->slot_idx = slot_idx; + break; + } + } + } for (i = 0; i < report->maxfield; i++) for (j = 0; j < report->field[i]->maxusage; j++) diff --git a/include/linux/hid.h b/include/linux/hid.h index feb8df61168f..4363a63b9775 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -492,6 +492,7 @@ struct hid_field { /* hidinput data */ struct hid_input *hidinput; /* associated input structure */ __u16 dpad; /* dpad input code */ + unsigned int slot_idx; /* slot index in a report */ }; #define HID_MAX_FIELDS 256 -- 2.33.1
next prev parent reply other threads:[~2022-02-03 14:36 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 ` [PATCH v2 09/12] HID: input: enforce Invert usage to be processed before InRange Benjamin Tissoires 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 ` Benjamin Tissoires [this message] 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-12-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 \ --subject='Re: [PATCH v2 11/12] HID: input: accommodate priorities for slotted devices' \ /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
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).