All of lore.kernel.org
 help / color / mirror / Atom feed
From: Dave Carey <carvsdriver@gmail.com>
To: jikos@kernel.org
Cc: bentiss@kernel.org, linux-input@vger.kernel.org,
	linux-kernel@vger.kernel.org, Dave Carey <carvsdriver@gmail.com>
Subject: [PATCH] HID: multitouch: Fix Yoga Book 9 14IAH10 touchscreen misclassification
Date: Thu,  2 Apr 2026 14:29:37 -0400	[thread overview]
Message-ID: <20260402182937.388847-1-carvsdriver@gmail.com> (raw)

The Lenovo Yoga Book 9 14IAH10 (83KJ) uses a composite USB HID device
(17EF:6161) where three descriptor quirks combine to cause hid-multitouch
to incorrectly set INPUT_PROP_BUTTONPAD on both touchscreen nodes, making
libinput treat them as indirect clickpads rather than direct touchscreens.

Quirk 1: The HID_DG_TOUCHSCREEN application collection contains
HID_UP_BUTTON usages (stylus barrel buttons). The generic heuristic in
mt_touch_input_mapping() treats any touchscreen-with-buttons as a
touchpad, setting INPUT_MT_POINTER.

Quirk 2: A HID_DG_TOUCHPAD collection ("Emulated Touchpad") sets
INPUT_MT_POINTER unconditionally in mt_allocate_application().

Quirk 3: The HID_DG_BUTTONTYPE feature report (0x51) returns
MT_BUTTONTYPE_CLICKPAD, directly setting td->is_buttonpad = true.

These combine to produce INPUT_PROP_BUTTONPAD on the touchscreen input
nodes. libinput treats the devices as indirect clickpads and suppresses
direct touch events, leaving the touchscreens non-functional under
KDE/Wayland.

Additionally, the firmware resets if any USB control request is received
during the CDC ACM initialization window. The existing GET_REPORT call
in mt_check_input_mode() during probe triggers this reset.

Fix by extending MT_QUIRK_YOGABOOK9I (already defined for the earlier
Yoga Book 9i) to guard all three BUTTONPAD heuristics and skip the
HID_DG_BUTTONTYPE GET_REPORT during probe for this device.

Signed-off-by: Dave Carey <carvsdriver@gmail.com>
Tested-by: Dave Carey <carvsdriver@gmail.com>
---
 drivers/hid/hid-multitouch.c | 34 +++++++++++++++++++++++++++-------
 1 file changed, 27 insertions(+), 7 deletions(-)

diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index e82a3c4e5..1bef32b1d 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -549,7 +549,14 @@ static void mt_feature_mapping(struct hid_device *hdev,
 
 	switch (usage->hid) {
 	case HID_DG_CONTACTMAX:
-		mt_get_feature(hdev, field->report);
+		/*
+		 * Yoga Book 9: skip GET_REPORT during probe; the firmware
+		 * resets if it receives any control request before the init
+		 * Output report is sent (within ~1.18s of USB enumeration).
+		 * Logical maximum from the descriptor is used as the fallback.
+		 */
+		if (!(td->mtclass.quirks & MT_QUIRK_YOGABOOK9I))
+			mt_get_feature(hdev, field->report);
 
 		td->maxcontacts = field->value[0];
 		if (!td->maxcontacts &&
@@ -566,6 +573,10 @@ static void mt_feature_mapping(struct hid_device *hdev,
 			break;
 		}
 
+		/* Yoga Book 9 reports Clickpad but is a direct touchscreen */
+		if (td->mtclass.quirks & MT_QUIRK_YOGABOOK9I)
+			break;
+
 		mt_get_feature(hdev, field->report);
 		switch (field->value[usage->usage_index]) {
 		case MT_BUTTONTYPE_CLICKPAD:
@@ -579,7 +590,9 @@ static void mt_feature_mapping(struct hid_device *hdev,
 		break;
 	case 0xff0000c5:
 		/* Retrieve the Win8 blob once to enable some devices */
-		if (usage->usage_index == 0)
+		/* Yoga Book 9: skip; firmware resets before init if queried */
+		if (usage->usage_index == 0 &&
+		    !(td->mtclass.quirks & MT_QUIRK_YOGABOOK9I))
 			mt_get_feature(hdev, field->report);
 		break;
 	}
@@ -644,8 +657,11 @@ static struct mt_application *mt_allocate_application(struct mt_device *td,
 
 	/*
 	 * Model touchscreens providing buttons as touchpads.
+	 * Yoga Book 9 has an emulated touchpad but its touch surfaces
+	 * are direct screens, not indirect pointers.
 	 */
-	if (application == HID_DG_TOUCHPAD) {
+	if (application == HID_DG_TOUCHPAD &&
+	    !(td->mtclass.quirks & MT_QUIRK_YOGABOOK9I)) {
 		mt_application->mt_flags |= INPUT_MT_POINTER;
 		td->inputmode_value = MT_INPUTMODE_TOUCHPAD;
 	}
@@ -802,11 +818,15 @@ static int mt_touch_input_mapping(struct hid_device *hdev, struct hid_input *hi,
 
 	/*
 	 * Model touchscreens providing buttons as touchpads.
+	 * Skip for Yoga Book 9 which has stylus buttons inside
+	 * touchscreen collections, not physical touchpad buttons.
 	 */
 	if (field->application == HID_DG_TOUCHSCREEN &&
 	    (usage->hid & HID_USAGE_PAGE) == HID_UP_BUTTON) {
-		app->mt_flags |= INPUT_MT_POINTER;
-		td->inputmode_value = MT_INPUTMODE_TOUCHPAD;
+		if (!(app->quirks & MT_QUIRK_YOGABOOK9I)) {
+			app->mt_flags |= INPUT_MT_POINTER;
+			td->inputmode_value = MT_INPUTMODE_TOUCHPAD;
+		}
 	}
 
 	/* count the buttons on touchpads */
@@ -1420,7 +1440,6 @@ static int mt_touch_input_configured(struct hid_device *hdev,
 	 */
 	if (cls->quirks & MT_QUIRK_APPLE_TOUCHBAR)
 		app->mt_flags |= INPUT_MT_DIRECT;
-
 	if (cls->is_indirect)
 		app->mt_flags |= INPUT_MT_POINTER;
 
@@ -1432,7 +1451,8 @@ static int mt_touch_input_configured(struct hid_device *hdev,
 
 	/* check for clickpads */
 	if ((app->mt_flags & INPUT_MT_POINTER) &&
-	    (app->buttons_count == 1))
+	    (app->buttons_count == 1) &&
+	    !(app->quirks & MT_QUIRK_YOGABOOK9I))
 		td->is_buttonpad = true;
 
 	if (td->is_buttonpad)
-- 
2.53.0


             reply	other threads:[~2026-04-02 18:29 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-04-02 18:29 Dave Carey [this message]
2026-04-03 13:02 ` [PATCH] HID: multitouch: Fix Yoga Book 9 14IAH10 touchscreen misclassification Benjamin Tissoires
     [not found]   ` <CALPvROSB4y0UsPvF5-ZS=_rGmj1NgM6QvBAbHO13bkgpAwQSyA@mail.gmail.com>
2026-04-03 16:51     ` Benjamin Tissoires
2026-04-13 12:58 ` [PATCH v2] " Dave Carey
2026-05-12 15:39   ` Jiri Kosina
2026-05-13 12:57     ` Dave Carey

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=20260402182937.388847-1-carvsdriver@gmail.com \
    --to=carvsdriver@gmail.com \
    --cc=bentiss@kernel.org \
    --cc=jikos@kernel.org \
    --cc=linux-input@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.