Received: by 2002:a05:6a10:1a4d:0:0:0:0 with SMTP id nk13csp2582796pxb; Thu, 3 Feb 2022 09:33:32 -0800 (PST) X-Google-Smtp-Source: ABdhPJz+XZngPPiWBCa6TEhun66NzRPQ6BgTAtXmeB9b5dWqT2T024YajW2bbpP4NpYpc8pMBFzQ X-Received: by 2002:a17:90a:3e4a:: with SMTP id t10mr14981024pjm.70.1643909612211; Thu, 03 Feb 2022 09:33:32 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1643909612; cv=none; d=google.com; s=arc-20160816; b=CoKYQWpIr56rc/mEeS2yoTrPZbAaIJiPaD9tNKX7bx6SqW4Owg/GSyUBkc+3/5m5rh yO5TFI6ls1rTI1WzV8T9UhzZCJGp0sDABINMNbEcPQKB0e2viDmc/E9jeK/cDMf19xGW Rd3zIMwZiHlvuKDJnGSGj2Lul/Amg1n/WtGHzxLYxst36EKv0ET4BNSX7dMY3JWQ1fL0 sipGIqB8Ue1uxgRWGe0Ni/mtZIbUSEwyT3mvyUfv5dF33AYITQ1wLjaaIMc5ZS82N9lm doQi0/Hb0M3ZvT9IPrCEg6CioV7ac/QM5YeT7Whs3IK8RiMxhphDAAseink29yWZ3F8R JlWg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=HY6dBUSJ0foycx8WGBmzVTABhlhALHZsF0lp5qfhzAI=; b=ioEU3PDxjVN+0aS8oToO8Y6g97YQ81a1QmldmKrbNHRH8e57FG+WpS18Y6TnebF8r3 sKp/kW+Q4+rLqkc3JvTuwxo1sOLVXIjDh38MbQYEUf+8nlH4H5VH503+BilstD22B9jS JFpCe4w7lCBR8F6Z7NLN+v1ABh+EqPSljNIW1MuRhC3lZPSwov6nHaTuV9hAiQiCk2EB fGPdE2XgKL/C40jPXAy1MWmTgwgv1aLsOrQWzWMAVU1A2SWJvf3ooMicRXoSvG+8rG7c 3KHvBNB5tNUEfSwDod/WwhbmOzSBs0LYHr8PUjl+1Tidwt2TgesAZ0E4lOHUlLQtSq28 U77g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=Wh2iz9Nv; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id j9si23481398plx.86.2022.02.03.09.33.20; Thu, 03 Feb 2022 09:33:32 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=Wh2iz9Nv; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1351519AbiBCOfH (ORCPT + 99 others); Thu, 3 Feb 2022 09:35:07 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:23684 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1351244AbiBCOds (ORCPT ); Thu, 3 Feb 2022 09:33:48 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1643898828; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=HY6dBUSJ0foycx8WGBmzVTABhlhALHZsF0lp5qfhzAI=; b=Wh2iz9NvUtnA93e1zL1uw6b3UeGGWl/p/10SDzcuGd3nNl+1LQ2gotr7AR+nBu8HwAux4v +iJlHDzZZ7aFL6pKzxtuEjEIQOC+ZEi1Xpmx9kUS443wNV2SiVAsNOewwMKse8hJ1+TfR0 c+RSHBCNHwSjx7NiB6WGxmQEFpDm6eo= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-124-TeHdgIQJM3qMMFvrWP3ZCw-1; Thu, 03 Feb 2022 09:33:44 -0500 X-MC-Unique: TeHdgIQJM3qMMFvrWP3ZCw-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 4FE90190A7A2; Thu, 3 Feb 2022 14:33:42 +0000 (UTC) Received: from plouf.redhat.com (unknown [10.39.192.114]) by smtp.corp.redhat.com (Postfix) with ESMTP id DDDB47D4D0; Thu, 3 Feb 2022 14:33:39 +0000 (UTC) From: Benjamin Tissoires To: Jiri Kosina , Dmitry Torokhov , Jonathan Corbet , =?UTF-8?q?Ahelenia=20Ziemia=C5=84ska?= , Ping Cheng , Aaron Armstrong Skomra , Jason Gerecke , Peter Hutterer Cc: linux-input@vger.kernel.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, Benjamin Tissoires Subject: [PATCH v2 09/12] HID: input: enforce Invert usage to be processed before InRange Date: Thu, 3 Feb 2022 15:32:23 +0100 Message-Id: <20220203143226.4023622-10-benjamin.tissoires@redhat.com> In-Reply-To: <20220203143226.4023622-1-benjamin.tissoires@redhat.com> References: <20220203143226.4023622-1-benjamin.tissoires@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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 --- 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