From patchwork Mon Mar 8 17:42:18 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?0L3QsNCx?= X-Patchwork-Id: 12123091 X-Patchwork-Delegate: jikos@jikos.cz Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.1 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_SANE_1 autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id D7295C433E0 for ; Mon, 8 Mar 2021 17:43:20 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id B247865228 for ; Mon, 8 Mar 2021 17:43:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230200AbhCHRmt (ORCPT ); Mon, 8 Mar 2021 12:42:49 -0500 Received: from [139.28.40.42] ([139.28.40.42]:54286 "EHLO tarta.nabijaczleweli.xyz" rhost-flags-FAIL-FAIL-OK-OK) by vger.kernel.org with ESMTP id S230050AbhCHRmV (ORCPT ); Mon, 8 Mar 2021 12:42:21 -0500 Received: from tarta.nabijaczleweli.xyz (unknown [192.168.1.250]) by tarta.nabijaczleweli.xyz (Postfix) with ESMTPSA id 7CA523602D8; Mon, 8 Mar 2021 18:42:19 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=nabijaczleweli.xyz; s=202006; t=1615225339; bh=O3opi9rvyEpgs9nlMtb3A5XUwC6OHkH6ahCapGdL/hs=; h=Date:From:Cc:Subject:References:In-Reply-To:From; b=SvwdSa3yVVW9ZP1ubMdmgBQmmi+ZhxESnXAc6EpAR2uqicG0VC850oEvsoimg9QXf lM4Y2S+xcTVYVjAoqCzfCyRIJ+9vVOb46onYgcoKyJFL0kxQOe1oIgacJVDr6fScFJ OKiEjbs+nF/CL0U241YHYE91ZEkmfzAe5nif4FGNGmZkqh0aE00g2YYsa2ADammlot GUIk66QxtRIWAunV8NMrFqhpoMO2JwW4e5/Pdn2L47f3cWmTp6l5YDgcohRVPPUUAl CPMB69qkBaa1zh2sPXbROOZ2Huty3/jYnpR/DL6CGr3draWJce1zlJ2vkFYTBHMyr6 M7QQesQhqmtTg== Date: Mon, 8 Mar 2021 18:42:18 +0100 From: Ahelenia =?utf-8?q?Ziemia=C5=84ska?= Cc: Benjamin Tissoires , Peter Hutterer , Jiri Kosina , linux-input@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 4/4] HID: input: work around Win8 stylus-on-touchscreen reporting Message-ID: <2ca91ac7cf92e3048a236db3cd519f04e12c1e61.1615224800.git.nabijaczleweli@nabijaczleweli.xyz> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: NeoMutt/20210205 To: unlisted-recipients:; (no To-header on input) Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org With this, these devices now behave as tablets as expected by userspace The search in hidinput_is_win8_touching() terminates at f=0, u=0 on Goodix screens (27C6:0111, 27C6:0113), but I expect it to have negligible impact on devices that don't have TipSwitch as the first report as well Signed-off-by: Ahelenia ZiemiaƄska --- Notes: changes in v2: * hidinput_fixup_win8_inrange() became hidinput_is_win8_touching() * BarrelSwitch now anded with TipSwitch drivers/hid/hid-input.c | 48 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index a5ba92978473..aee1f1283c1d 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -1273,6 +1273,42 @@ static void hidinput_handle_scroll(struct hid_usage *usage, input_event(input, EV_REL, usage->code, hi_res); } +/* + * Win8 tablet stylus devices send, in order: + * HID_DG_TIPSWITCH (BTN_TOUCH) + * HID_DG_INVERT (BTN_TOOL_RUBBER) + * HID_DG_ERASER (BTN_TOUCH) + * HID_DG_INRANGE (BTN_TOOL_PEN) + * + * For each of these states: + * hover : INRANGE + * touching : TIPSWITCH + * hover+2 : INVERT INRANGE + * touching+2: ERASER INRANGE + * + * Which means we'd send BTN_TOUCH=0 + BTN_TOOL_PEN=1 on proximity, + * then BTN_TOUCH=1 and BTN_TOOL_PEN=0 in consecutive groups when touched, + * indicating the stylus leaving the screen as soon as the two meet. + * + * Additionally, HID_DG_BARRELSWITCH corresponds directly to the button, + * regardless of the tip switch, making it borderline impossible to use precisely. + */ +static bool hidinput_is_win8_touching(struct hid_device *hid, struct hid_field *field) +{ + unsigned f, u; + struct hid_field *rfield; + + for (f = 0; f < field->report->maxfield; ++f) { + rfield = field->report->field[f]; + for (u = 0; u < rfield->maxusage; ++u) { + if (rfield->usage[u].hid == HID_DG_TIPSWITCH) + return rfield->value[u]; + } + } + + return false; +} + void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value) { struct input_dev *input; @@ -1306,7 +1342,13 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct return; } + if (usage->hid == HID_DG_ERASER && value) + *quirks |= HID_QUIRK_INVERT; + if (usage->hid == HID_DG_INRANGE) { + if (hid->group == HID_GROUP_MULTITOUCH_WIN_8) + value = value || hidinput_is_win8_touching(hid, field); + if (value) { input_event(input, usage->type, (*quirks & HID_QUIRK_INVERT) ? BTN_TOOL_RUBBER : usage->code, 1); return; @@ -1322,6 +1364,12 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct input_event(input, EV_KEY, BTN_TOUCH, value > a + ((b - a) >> 3)); } + if (usage->hid == HID_DG_BARRELSWITCH && hid->group == HID_GROUP_MULTITOUCH_WIN_8) { + value = value && hidinput_is_win8_touching(hid, field); + input_event(input, usage->type, usage->code, value); + return; + } + if (usage->hid == (HID_UP_PID | 0x83UL)) { /* Simultaneous Effects Max */ dbg_hid("Maximum Effects - %d\n",value); return;