From patchwork Mon Sep 12 15:48:17 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oleksij Rempel X-Patchwork-Id: 9326907 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id DC6F06077F for ; Mon, 12 Sep 2016 15:49:34 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CE1A328DBA for ; Mon, 12 Sep 2016 15:49:34 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C16B228DD5; Mon, 12 Sep 2016 15:49:34 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 378AB28DBA for ; Mon, 12 Sep 2016 15:49:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752879AbcILPtT (ORCPT ); Mon, 12 Sep 2016 11:49:19 -0400 Received: from mout.gmx.net ([212.227.15.19]:57901 "EHLO mout.gmx.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751222AbcILPtR (ORCPT ); Mon, 12 Sep 2016 11:49:17 -0400 Received: from ultralex.fritz.box ([31.18.248.238]) by mail.gmx.com (mrgmx002) with ESMTPSA (Nemesis) id 0Lck9X-1bHaqV24NL-00k7SS; Mon, 12 Sep 2016 17:48:24 +0200 From: Oleksij Rempel To: fixed-term.Oleksij.Rempel@de.bosch.com Cc: Oleksij Rempel , Alex Henrie , Dmitry Torokhov , Corentin Chary , Darren Hart , acpi4asus-user@lists.sourceforge.net, platform-driver-x86@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH] asus-wmi: filter buggy scan codes on ASUS Q500A Date: Mon, 12 Sep 2016 17:48:17 +0200 Message-Id: <1473695297-10236-1-git-send-email-linux@rempel-privat.de> X-Mailer: git-send-email 2.7.4 In-Reply-To: <20160804005052.GC36266@dtor-ws> References: <20160804005052.GC36266@dtor-ws> X-Provags-ID: V03:K0:wXs0/0ESDgsC/EjOZSnoYnlt00p98Iclxg8R6sZ22hkB4AT+RUE TEthWUbpL8lmC9oqp7bATWpeQ9Qk/t1CO3j5PZ1PptoqVgYrwOFW3MgDW6sL/ph6MTMAegB e9UNzCO45rE0IEVsTLFw6WBPgNmrJrLTu33+uV0dehb0z5eEsbpBP+oY/AQ5xH7gwFUia63 TdR3r5d9YD08KXFJjCkPA== X-UI-Out-Filterresults: notjunk:1; V01:K0:R8eaX2eB7Do=:XdhhK6TQsNH6VZYy4TlYe/ ACx6bOTiEO5o2REY2h2Ckxg2N7R5qQlkmTR87MdktcPnir4YVpIy25BYCM4X2dNNfUXQWW0gL n8+BeSQViyCtL4yT8kxh+AO47GRr3A+KHasLMqsds9iiXOXDDXIs8JdJqec8fKne0g2EbXpjo OMZ755ziJCSp5RnthLqEmczMC4TPcm3xG5FpGuT8ry9IBBE8GrCjfHsGyS9dh9pEFYMvVJruC 7uSbs5EDLUUUsIxdOC1GWR+goAZqGHpos2HFWHG2tx9VS4+Kn85BEdmhS5tcmNmTKgbjuKR2g G8Z3ofAEpmeLt3JpoMrv5Rv3rCprHoI06Y4DyivnDdsM5Q0p67+ScX4poCs/Cn0Nw1UDiuX5b 3TkgUOfe1H8N4JOemlA83WEWKMeQ37tCtn7lB+HeOWwctAnUO2QTcAxx3avPLRXVMblnXV4Tn 06yIa0f9yyPe6Io0ef3oUiNz9XEEyumyR+JrEj8bEj22DWYpK4urEtYwCRBliEWJrCr7nZ3Ye eu5LIACXYJ/D+K+Rs3uUrXNK+2IUN7afi4wnMBhnlbGO1/Z0ZTEWU1Xecbwn7tcutjkYKbbNg ndLImPRXmDvJR+b5imogvA7htUByyC2tfOHpUiSc/A+sSVe6+GNSkYEeOeEeB7i3aJimEy0dA Li+L0JV3cHYQ1Gq1oHLCkHBnI8XSSKBwtd8sbGgApgIw7NthnB0tHcaNW5U7QCbU9S6uwJ79E 4SrhhzDsN4WRssQDSfmGYu6a6VD2pawxZTffKNgz4MTLlbINpxOnppufkSg= Sender: platform-driver-x86-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: platform-driver-x86@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Some revision of ASUS Q500A series have keyboard related issue which is reproducible only if Windows with installed ASUS tools was ever started. In this case the Linux side will have blocked keyboard or report wrong or incomplete hotkey events. To make Linux work properly again complete power down (unplug power supply and remove battery) should be made. Linux/atkbd after clean start will get fallowing code on VOLUME_UP key: {0xe0, 0x30, 0xe0, 0xb0}. After Windows, same key will generate this codes: {0xe1, 0x23, 0xe0, 0x30, 0xe0, 0xb0}. As result atkdb will be confused by buggy codes. This patch is filtering this buggy code out. https://bugzilla.kernel.org/show_bug.cgi?id=119391 Signed-off-by: Oleksij Rempel Cc: Alex Henrie Cc: Dmitry Torokhov Cc: Corentin Chary Cc: Darren Hart Cc: acpi4asus-user@lists.sourceforge.net Cc: platform-driver-x86@vger.kernel.org Cc: linux-kernel@vger.kernel.org --- drivers/platform/x86/asus-nb-wmi.c | 45 ++++++++++++++++++++++++++++++++++++++ drivers/platform/x86/asus-wmi.h | 4 ++++ 2 files changed, 49 insertions(+) diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c index adecc1c..787da83 100644 --- a/drivers/platform/x86/asus-nb-wmi.c +++ b/drivers/platform/x86/asus-nb-wmi.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "asus-wmi.h" @@ -55,10 +56,35 @@ MODULE_PARM_DESC(wapf, "WAPF value"); static struct quirk_entry *quirks; +static bool asus_q500a_i8042_filter(unsigned char data, unsigned char str, + struct serio *port) +{ + static bool extended; + bool ret = false; + + + if (str & I8042_STR_AUXDATA) + return false; + + if (unlikely(data == 0xe1)) { + extended = true; + ret = true; + } else if (unlikely(extended)) { + extended = false; + ret = true; + } + + return ret; +} + static struct quirk_entry quirk_asus_unknown = { .wapf = 0, }; +static struct quirk_entry quirk_asus_q500a = { + .i8042_filter = asus_q500a_i8042_filter, +}; + /* * For those machines that need software to control bt/wifi status * and can't adjust brightness through ACPI interface @@ -96,6 +122,15 @@ static int dmi_matched(const struct dmi_system_id *dmi) static const struct dmi_system_id asus_quirks[] = { { .callback = dmi_matched, + .ident = "ASUSTeK COMPUTER INC. Q500A", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "Q500A"), + }, + .driver_data = &quirk_asus_q500a, + }, + { + .callback = dmi_matched, .ident = "ASUSTeK COMPUTER INC. U32U", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), @@ -356,6 +391,8 @@ static const struct dmi_system_id asus_quirks[] = { static void asus_nb_wmi_quirks(struct asus_wmi_driver *driver) { + int ret; + quirks = &quirk_asus_unknown; dmi_check_system(asus_quirks); @@ -367,6 +404,14 @@ static void asus_nb_wmi_quirks(struct asus_wmi_driver *driver) quirks->wapf = wapf; else wapf = quirks->wapf; + + if (quirks->i8042_filter) { + ret = i8042_install_filter(quirks->i8042_filter); + if (ret) { + pr_warn("Unable to install key filter\n"); + } + pr_info("Using i8042 filter function for receiving events\n"); + } } static const struct key_entry asus_nb_wmi_keymap[] = { diff --git a/drivers/platform/x86/asus-wmi.h b/drivers/platform/x86/asus-wmi.h index 5de1df5..dd2e6cc 100644 --- a/drivers/platform/x86/asus-wmi.h +++ b/drivers/platform/x86/asus-wmi.h @@ -28,6 +28,7 @@ #define _ASUS_WMI_H_ #include +#include #define ASUS_WMI_KEY_IGNORE (-1) #define ASUS_WMI_BRN_DOWN 0x20 @@ -51,6 +52,9 @@ struct quirk_entry { * and let the ACPI interrupt to send out the key event. */ int no_display_toggle; + + bool (*i8042_filter)(unsigned char data, unsigned char str, + struct serio *serio); }; struct asus_wmi_driver {