Received: by 2002:a05:7412:2a8c:b0:e2:908c:2ebd with SMTP id u12csp638556rdh; Sun, 24 Sep 2023 05:45:22 -0700 (PDT) X-Google-Smtp-Source: AGHT+IF2IEDwtE+IRqgjutXYpibRI25krsrW+bMKLarHt5ydgtpLsn4ELHHYmUJfJ3Vws1xBzVtJ X-Received: by 2002:a17:90b:3b8d:b0:274:9a85:2596 with SMTP id pc13-20020a17090b3b8d00b002749a852596mr2510329pjb.32.1695559522245; Sun, 24 Sep 2023 05:45:22 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1695559522; cv=none; d=google.com; s=arc-20160816; b=Z9DrHwUPpsdSRWmM/Pp6C6sC7wLqkEbo1Qq1tmMmbUemYcLLM8DewDX2a4wmgXiKWM QBDDSq4uWF0BfpyQ5GazReg17ianIXPR7uFso4uhi0QimJprKwLj9CB6SStv2OlaQlNd H7i7mQVGO644LlP21jwDJ8kzyZOsCvNWEVJHtqoW/svc+2KUYRyv24JLnGKvEuA71aZ/ rxX4alY5dN6Ys4QM1DIHkvLZ7ZyWc43brtnAqVztBnQ/fxFUoFXAf8l2P02qPxusM7nD grFDS1kaA3FI9Qti1COlgv4WaU8cpgoP3B/Qb03/vwifk0g7GvprFCrxAVZWq45qQYM0 Yr4w== 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=K08yRjUV9Fj8hiI573kaHyfx4vQnMrFIZ7+FXpOmgNY=; fh=mOe1ko3f8kPYDE7PL8LsZW2fNDy1pqWYuuuyh7fh9Yg=; b=CRvhOE8QvyjKXY4pY2xz4SKxP9safYFm0rOqaD1xRhsmJKyDWO2S252EJqS7iu4OAC f4G1ft+A/c7z8O4y1JF13ov8Kzz7ZP+3HrSELxIxjT18CxQazElZP+A1OItcd3PckN+A aTgc2V1awnVx9esn+AnFmP8Ct5jF62ByVJ1wfL85h/TEbBTkHpvjN79caJeZgS1J7ws1 ZsdsOmElH0l7mMrVmMyO69Ngy/yM5cyWzgEpwktQDc2G74q53ZAvSyVzGPDtjFdkr2m6 CJFJ79l/XB4ReCaelDKW/+1m0kx+cvwXfiHQ5CGR9/l0aI9T7Tpz1tP6haTvRuDpx+a3 tX6g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@khvoinitsky.org header.s=key1 header.b=K+qqPsyZ; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.37 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=khvoinitsky.org Return-Path: Received: from snail.vger.email (snail.vger.email. [23.128.96.37]) by mx.google.com with ESMTPS id v135-20020a63618d000000b0056401aef836si7800419pgb.822.2023.09.24.05.45.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 24 Sep 2023 05:45:22 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.37 as permitted sender) client-ip=23.128.96.37; Authentication-Results: mx.google.com; dkim=pass header.i=@khvoinitsky.org header.s=key1 header.b=K+qqPsyZ; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.37 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=khvoinitsky.org Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by snail.vger.email (Postfix) with ESMTP id 09F1B807C65C; Sat, 23 Sep 2023 16:15:50 -0700 (PDT) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.10 at snail.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229554AbjIWXPx (ORCPT + 99 others); Sat, 23 Sep 2023 19:15:53 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52990 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229450AbjIWXPw (ORCPT ); Sat, 23 Sep 2023 19:15:52 -0400 Received: from out-190.mta1.migadu.com (out-190.mta1.migadu.com [IPv6:2001:41d0:203:375::be]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AA30A127 for ; Sat, 23 Sep 2023 16:15:45 -0700 (PDT) X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=khvoinitsky.org; s=key1; t=1695510942; 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=K08yRjUV9Fj8hiI573kaHyfx4vQnMrFIZ7+FXpOmgNY=; b=K+qqPsyZcHyzASvcBjjqgkvvRQJuX6PBwQACIuMG5MMWObeN+20AeKDsT9ATEUOgVvBBzS sCdH+EgW1/jxSDRl616YthVqK4etXjuHZG6cs0RzLUR6/Jo6JtJcu6xR5KTR2R+8eI/9kG +JX8phxC/wtkL37eEYWNWA3pM1D4O3M= From: Mikhail Khvainitski To: Jiri Kosina , Benjamin Tissoires Cc: linux-input@vger.kernel.org, linux-kernel@vger.kernel.org, Mikhail Khvainitski Subject: [PATCH] HID: lenovo: Detect quirk-free fw on cptkbd and stop applying workaround Date: Sun, 24 Sep 2023 01:58:30 +0300 Message-ID: <20230923231522.94060-2-me@khvoinitsky.org> In-Reply-To: <20230923231522.94060-1-me@khvoinitsky.org> References: <20230918145042.37368-1-me@khvoinitsky.org> <20230923231522.94060-1-me@khvoinitsky.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Migadu-Flow: FLOW_OUT X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_BLOCKED, SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (snail.vger.email [0.0.0.0]); Sat, 23 Sep 2023 16:15:50 -0700 (PDT) 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 --- 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 44763c0da444..9c1181313e44 100644 --- a/drivers/hid/hid-lenovo.c +++ b/drivers/hid/hid-lenovo.c @@ -51,7 +51,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; }; @@ -668,31 +673,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; } if (usage->type == EV_KEY && usage->code == KEY_FN_ESC && value == 1) { -- 2.42.0