From patchwork Fri Nov 6 21:28:49 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arnd Bergmann X-Patchwork-Id: 7573511 Return-Path: X-Original-To: patchwork-platform-driver-x86@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 48F679F1C4 for ; Fri, 6 Nov 2015 21:29:37 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 48596206E8 for ; Fri, 6 Nov 2015 21:29:36 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 359B2206E4 for ; Fri, 6 Nov 2015 21:29:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1161747AbbKFV3U (ORCPT ); Fri, 6 Nov 2015 16:29:20 -0500 Received: from mout.kundenserver.de ([212.227.126.130]:50678 "EHLO mout.kundenserver.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1161372AbbKFV3R (ORCPT ); Fri, 6 Nov 2015 16:29:17 -0500 Received: from wuerfel.localnet ([134.3.118.24]) by mrelayeu.kundenserver.de (mreue004) with ESMTPSA (Nemesis) id 0M2pyk-1alGlA3Qxi-00sawl; Fri, 06 Nov 2015 22:28:50 +0100 From: Arnd Bergmann To: platform-driver-x86@vger.kernel.org, Ike Panhc Cc: Darren Hart , linux-kernel@vger.kernel.org Subject: [PATCH] ideapad-laptop: add support for Yoga 3 ESC key Date: Fri, 06 Nov 2015 22:28:49 +0100 Message-ID: <3945339.hkrnUBKIiS@wuerfel> User-Agent: KMail/4.11.5 (Linux/3.16.0-10-generic; KDE/4.11.5; x86_64; ; ) MIME-Version: 1.0 X-Provags-ID: V03:K0:gIDlUkDq+VY++yZcC6rSwNF082tekpGXUFACo+hJspwPpcRwT+E T5zosyfNgloTJli2F3WvhPVUlxfqoCnaizl7yvg5+Lfd3ldBfgK2l8fuU6RaiG3Cg+KXdx5 8mnOXoV4bNhuQQZhy6SmbtXU/kKYTRxAj7+YgwmHke5BrDg0amW99OUK4+kSDOceJB5yELB X8UilVXO4Zyrj+/sgzR6g== X-UI-Out-Filterresults: notjunk:1; V01:K0:WPwMxYlZJ9k=:UEnsEAVsR8hzUklOi3cUW0 Brl2jb2ApRY0IAUbLWHm236ehKqDFs3K9PFHHZx7ddioM7j4ZzGDd3xknWhVFafB+Dlz8C9oI NmN9TDTf1XEXCJfSLKld5i1zGJkec8rztD1koZR/p+wKo1G3z0SK3he8hLWCPtNPeXK+6RlJZ FMPjgcd6XY73zkyKt/wcjKcBepThT8aAC3FTaug7FZ0MLFi5ZGL5f1jVh/2zAs8BurQ+qXQMw 9QEH8LGZosFemN7UP03Q1yJ7QdtR/blggkM1iuZ4wqksTcqA062gLsw+tI3KtQYe3tMy8WwOp sEhtWsymJmo3f+fA3NXYrfyYnSUWfmbw3AF0cjW/dGBm5XweV9S1QFOh0InTsesbAeUIOnBC4 GsMrN1rzZ6Zmp4ZNZHyrEScYCQjSIUZuftC9r5/rkZIFVOjgWNQimygkGFNIr++/RsmuxqoaM u4MF730hQYpzCwT9G1wxBj2ajXnyCjFPn5EEyCCW6Dc13iCJa0XN1CqMlK02ZbHtSMdlGUxAz y7dNiqTYHITRlX/FVqpvrh1Uh+zLiLbkvzugTJ1eaoKGR0qUvQgz1VuA+YAG3Ezdhn+RXGMiw 6Ve36UpPhg75Sx/0CnQdbG69ITZ97h5zZqFGlvkm5gccT6Pod/Qdy0GUkF930O/vEduOGqd2v hUcksXQb/KShR69sdrg1qFSOLV1zWVRe1VMmp3lPzRc9FEh4SlVuiVdmOZpq8nt2pM6BYCJM5 w5P/nJ1VEmlCskd3 Sender: platform-driver-x86-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: platform-driver-x86@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The ideapad-laptop handles most special keys on various Lenovo Laptops including the Yoga line. Unfortunately, the Yoga 3 11/13/14 models have one important exception, which is the Fn-ESC combination. On other Lenovo Laptops, this is FnLock, which switches the function keys between the primary (Mute, Vol down, Vol up, ...) and the secondary (F1, F2, F3, ...) behavior. On the new machines, FnLock is only available through BIOS setup (possibly through a yet-to-be-implemented feature in this driver) but not through Fn-ESC, but instead the ESC key itself switched between ESC and a "Paper Display" app for Windows. Unfortunately, that means that you can never have both ESC *and* the function keys working at the same time without needing to press Fn on one of them. As pointed out in the official Lenovo Forum by dozens of users, this makes the machine rather useless for any serious work [1]. I have now studied the ACPI DSDT one more time and found the event that is generated for the ESC key. Unlike all other key events on this machine, it is actually a WMI, while the other ones are read from the embedded controller. I am now installing a WMI notifier that uses the event number from the WMI subsystem as the scancode. The only event number generated here is '128', and that fits in nicely with the two existing ranges of scancodes used by the EC: 0-15 for the 16-bit VPCCMD_R_VPC register, 16-17 for the VPCCMD_R_NOVO register and 64-67 for VPCCMD_R_SPECIAL_BUTTONS. The only sane way to handle this button (in absence of the Windows Paper Display driver) seems to be to have it emit KEY_ESC, so that is what I use as the default. Should any user ever want to overwrite the default, they can install their own keymap. To ensure that we can still build the driver without adding a CONFIG_WMI dependency, all new code is enclosed in #ifdef. Signed-off-by: Arnd Bergmann [1] https://forums.lenovo.com/t5/Lenovo-Yoga-Series-Notebooks/YOGA-3-14-How-to-reclaim-my-Esc-key-and-permanently-disable/td-p/2070816 --- To unsubscribe from this list: send the line "unsubscribe platform-driver-x86" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index 02bbc70c332d..1089eaa02b00 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig @@ -345,6 +345,7 @@ config IDEAPAD_LAPTOP depends on SERIO_I8042 depends on BACKLIGHT_CLASS_DEVICE depends on ACPI_VIDEO || ACPI_VIDEO = n + depends on ACPI_WMI || ACPI_WMI = n select INPUT_SPARSEKMAP help This is a driver for Lenovo IdeaPad netbooks contains drivers for diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c index ad4b8b7e97cc..231db03a6417 100644 --- a/drivers/platform/x86/ideapad-laptop.c +++ b/drivers/platform/x86/ideapad-laptop.c @@ -47,6 +47,10 @@ #define CFG_WIFI_BIT (18) #define CFG_CAMERA_BIT (19) +#if IS_ENABLED(CONFIG_ACPI_WMI) +static const char ideapad_wmi_fnesc_event[] = "26CAB2E5-5CF1-46AE-AAC3-4A12B6BA50E6"; +#endif + enum { VPCCMD_R_VPC1 = 0x10, VPCCMD_R_BL_MAX, @@ -567,6 +571,8 @@ static const struct key_entry ideapad_keymap[] = { { KE_KEY, 65, { KEY_PROG4 } }, { KE_KEY, 66, { KEY_TOUCHPAD_OFF } }, { KE_KEY, 67, { KEY_TOUCHPAD_ON } }, + { KE_KEY, 128, { KEY_ESC } }, + { KE_END, 0 }, }; @@ -825,6 +831,19 @@ static void ideapad_acpi_notify(acpi_handle handle, u32 event, void *data) } } +#if IS_ENABLED(CONFIG_ACPI_WMI) +static void ideapad_wmi_notify(u32 value, void *context) +{ + switch (value) { + case 128: + ideapad_input_report(context, value); + break; + default: + pr_info("Unknown WMI event %u\n", value); + } +} +#endif + /* * Some ideapads don't have a hardware rfkill switch, reading VPCCMD_R_RF * always results in 0 on these models, causing ideapad_laptop to wrongly @@ -942,8 +961,18 @@ static int ideapad_acpi_add(struct platform_device *pdev) ACPI_DEVICE_NOTIFY, ideapad_acpi_notify, priv); if (ret) goto notification_failed; +#if IS_ENABLED(CONFIG_ACPI_WMI) + ret = wmi_install_notify_handler(ideapad_wmi_fnesc_event, ideapad_wmi_notify, priv); + if (ret != AE_OK && ret != AE_NOT_EXIST) + goto notification_failed_wmi; +#endif return 0; +#if IS_ENABLED(CONFIG_ACPI_WMI) +notification_failed_wmi: + acpi_remove_notify_handler(priv->adev->handle, + ACPI_DEVICE_NOTIFY, ideapad_acpi_notify); +#endif notification_failed: ideapad_backlight_exit(priv); backlight_failed: @@ -962,6 +991,9 @@ static int ideapad_acpi_remove(struct platform_device *pdev) struct ideapad_private *priv = dev_get_drvdata(&pdev->dev); int i; +#if IS_ENABLED(CONFIG_ACPI_WMI) + wmi_remove_notify_handler(ideapad_wmi_fnesc_event); +#endif acpi_remove_notify_handler(priv->adev->handle, ACPI_DEVICE_NOTIFY, ideapad_acpi_notify); ideapad_backlight_exit(priv);