From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id EE8D1C4332F for ; Tue, 7 Nov 2023 16:00:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1343914AbjKGQAo (ORCPT ); Tue, 7 Nov 2023 11:00:44 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60534 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1344599AbjKGP7U (ORCPT ); Tue, 7 Nov 2023 10:59:20 -0500 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 24CC77A83; Tue, 7 Nov 2023 07:52:11 -0800 (PST) Received: by smtp.kernel.org (Postfix) with ESMTPSA id A3555C433C9; Tue, 7 Nov 2023 15:52:10 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1699372331; bh=vyefD/3zIztutmESLIgo+iS24PgXOvk/d6ea8CtU5pE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=fYgw1QPspEpGOBxLUPBAkkiB9C+jC6QktnB238xBEHQviUJtCXPyvqZkT+wnX8lF/ My4VFT2U4S22dLqmZunmO00e2iKMnmRI3qxFCHl70ltTEfM857SsOQDZwE+JgvWxT4 sZnsgHb9erjMQ8zvm1fKxHyRq8TrdfBxx85AhIxknPk9UYa8QnDAzkWQYNslPCT4O/ W/YOMXE+G8hrIXekLmVm2ofnv2M74i9bD71w5+QxpMz6OLzZ9/dE/PETbuaj9/I92x vL8VsGVshtoHz0L7hnAFH1dqavOt7F8hYrPFwbcBIloUxuWkxfZXvZmGM581+T4VK7 Vk9wOCNB6Gi7A== From: Sasha Levin To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: Mikhail Khvainitski , Jiri Kosina , Sasha Levin , jikos@kernel.org, benjamin.tissoires@redhat.com, linux-input@vger.kernel.org Subject: [PATCH AUTOSEL 5.15 10/22] HID: lenovo: Detect quirk-free fw on cptkbd and stop applying workaround Date: Tue, 7 Nov 2023 10:51:19 -0500 Message-ID: <20231107155146.3767610-10-sashal@kernel.org> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20231107155146.3767610-1-sashal@kernel.org> References: <20231107155146.3767610-1-sashal@kernel.org> MIME-Version: 1.0 X-stable: review X-Patchwork-Hint: Ignore X-stable-base: Linux 5.15.137 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Mikhail Khvainitski [ Upstream commit 46a0a2c96f0f47628190f122c2e3d879e590bcbe ] Built-in firmware of cptkbd handles scrolling by itself (when middle button is pressed) but with issues: it does not support horizontal and hi-res scrolling and upon middle button release it sends middle button click even if there was a scrolling event. Commit 3cb5ff0220e3 ("HID: lenovo: Hide middle-button press until release") workarounds last issue but it's impossible to workaround scrolling-related issues without firmware modification. Likely, Dennis Schneider has reverse engineered the firmware and provided an instruction on how to patch it [1]. However, aforementioned workaround prevents userspace (libinput) from knowing exact moment when middle button has been pressed down and performing "On-Button scrolling". This commit detects correctly-behaving patched firmware if cursor movement events has been received during middle button being pressed and stops applying workaround for this device. Link: https://hohlerde.org/rauch/en/elektronik/projekte/tpkbd-fix/ [1] Signed-off-by: Mikhail Khvainitski Signed-off-by: Jiri Kosina Signed-off-by: Sasha Levin --- drivers/hid/hid-lenovo.c | 68 ++++++++++++++++++++++++++-------------- 1 file changed, 45 insertions(+), 23 deletions(-) diff --git a/drivers/hid/hid-lenovo.c b/drivers/hid/hid-lenovo.c index 93b1f935e526e..901c1959efed4 100644 --- a/drivers/hid/hid-lenovo.c +++ b/drivers/hid/hid-lenovo.c @@ -50,7 +50,12 @@ struct lenovo_drvdata { int select_right; int sensitivity; int press_speed; - u8 middlebutton_state; /* 0:Up, 1:Down (undecided), 2:Scrolling */ + /* 0: Up + * 1: Down (undecided) + * 2: Scrolling + * 3: Patched firmware, disable workaround + */ + u8 middlebutton_state; bool fn_lock; }; @@ -529,31 +534,48 @@ static int lenovo_event_cptkbd(struct hid_device *hdev, { struct lenovo_drvdata *cptkbd_data = hid_get_drvdata(hdev); - /* "wheel" scroll events */ - if (usage->type == EV_REL && (usage->code == REL_WHEEL || - usage->code == REL_HWHEEL)) { - /* Scroll events disable middle-click event */ - cptkbd_data->middlebutton_state = 2; - return 0; - } + if (cptkbd_data->middlebutton_state != 3) { + /* REL_X and REL_Y events during middle button pressed + * are only possible on patched, bug-free firmware + * so set middlebutton_state to 3 + * to never apply workaround anymore + */ + if (cptkbd_data->middlebutton_state == 1 && + usage->type == EV_REL && + (usage->code == REL_X || usage->code == REL_Y)) { + cptkbd_data->middlebutton_state = 3; + /* send middle button press which was hold before */ + input_event(field->hidinput->input, + EV_KEY, BTN_MIDDLE, 1); + input_sync(field->hidinput->input); + } - /* Middle click events */ - if (usage->type == EV_KEY && usage->code == BTN_MIDDLE) { - if (value == 1) { - cptkbd_data->middlebutton_state = 1; - } else if (value == 0) { - if (cptkbd_data->middlebutton_state == 1) { - /* No scrolling inbetween, send middle-click */ - input_event(field->hidinput->input, - EV_KEY, BTN_MIDDLE, 1); - input_sync(field->hidinput->input); - input_event(field->hidinput->input, - EV_KEY, BTN_MIDDLE, 0); - input_sync(field->hidinput->input); + /* "wheel" scroll events */ + if (usage->type == EV_REL && (usage->code == REL_WHEEL || + usage->code == REL_HWHEEL)) { + /* Scroll events disable middle-click event */ + cptkbd_data->middlebutton_state = 2; + return 0; + } + + /* Middle click events */ + if (usage->type == EV_KEY && usage->code == BTN_MIDDLE) { + if (value == 1) { + cptkbd_data->middlebutton_state = 1; + } else if (value == 0) { + if (cptkbd_data->middlebutton_state == 1) { + /* No scrolling inbetween, send middle-click */ + input_event(field->hidinput->input, + EV_KEY, BTN_MIDDLE, 1); + input_sync(field->hidinput->input); + input_event(field->hidinput->input, + EV_KEY, BTN_MIDDLE, 0); + input_sync(field->hidinput->input); + } + cptkbd_data->middlebutton_state = 0; } - cptkbd_data->middlebutton_state = 0; + return 1; } - return 1; } return 0; -- 2.42.0