summarylogtreecommitdiffstats
path: root/0004-Add-IdeaPad-WMI-Fn-Keys-driver.patch
diff options
context:
space:
mode:
authorUlrich Huber2022-09-21 22:22:53 +0200
committerUlrich Huber2022-09-21 22:24:35 +0200
commit778a33aea26bdc9b92b9681980e2081c4899ddb9 (patch)
tree96bffb72ec28614e08a89141c26dca1da39031f4 /0004-Add-IdeaPad-WMI-Fn-Keys-driver.patch
parent3b45b83f896a7e2fa1d88201c4f561c9decabc2e (diff)
downloadaur-linux-yoga9.tar.gz
Update to 5.19.9-arch1 with adapted fixes from Philipp Jungkamp
Diffstat (limited to '0004-Add-IdeaPad-WMI-Fn-Keys-driver.patch')
-rw-r--r--0004-Add-IdeaPad-WMI-Fn-Keys-driver.patch216
1 files changed, 216 insertions, 0 deletions
diff --git a/0004-Add-IdeaPad-WMI-Fn-Keys-driver.patch b/0004-Add-IdeaPad-WMI-Fn-Keys-driver.patch
new file mode 100644
index 000000000000..79109cbb4340
--- /dev/null
+++ b/0004-Add-IdeaPad-WMI-Fn-Keys-driver.patch
@@ -0,0 +1,216 @@
+From 7a622d9869602cf5587cadf418f3eed48a39ab90 Mon Sep 17 00:00:00 2001
+From: Philipp Jungkamp <p.jungkamp@gmx.net>
+Date: Sat, 30 Jul 2022 15:21:20 +0200
+Subject: [PATCH 4/9] Add IdeaPad WMI Fn Keys driver
+
+Create an input device for WMI events corresponding to some special
+keys on the 'Lenovo Yoga' line.
+
+This include the 3 keys to the right on the 'Lenovo Yoga9 14IAP7' and
+additionally the 'Lenovo Support' and 'Lenovo Favorites' (star with 'S'
+inside) in the fn key row.
+
+Signed-off-by: Philipp Jungkamp <p.jungkamp@gmx.net>
+---
+ drivers/platform/x86/Kconfig | 13 ++
+ drivers/platform/x86/Makefile | 1 +
+ drivers/platform/x86/ideapad-wmi-fn-keys.c | 151 +++++++++++++++++++++
+ 3 files changed, 165 insertions(+)
+ create mode 100644 drivers/platform/x86/ideapad-wmi-fn-keys.c
+
+diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
+index bc4013e950ed..6ff757332aa0 100644
+--- a/drivers/platform/x86/Kconfig
++++ b/drivers/platform/x86/Kconfig
+@@ -140,6 +140,19 @@ config YOGABOOK_WMI
+ To compile this driver as a module, choose M here: the module will
+ be called lenovo-yogabook-wmi.
+
++config IDEAPAD_WMI_FN_KEYS
++ tristate "Lenovo IdeaPad WMI Fn Keys"
++ depends on ACPI_WMI
++ depends on INPUT
++ select INPUT_SPARSEKMAP
++ help
++ Say Y here if you want to receive key presses from some lenovo
++ specific keys. (Star Key, Support Key, Virtual Background,
++ Dark Mode Toggle, ...)
++
++ To compile this driver as a module, choose M here: the module will
++ be called ideapad-wmi-fn-keys.
++
+ config ACERHDF
+ tristate "Acer Aspire One temperature and fan driver"
+ depends on ACPI && THERMAL
+diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
+index 4a59f47a46e2..5e9b678e48b9 100644
+--- a/drivers/platform/x86/Makefile
++++ b/drivers/platform/x86/Makefile
+@@ -16,6 +16,7 @@ obj-$(CONFIG_PEAQ_WMI) += peaq-wmi.o
+ obj-$(CONFIG_XIAOMI_WMI) += xiaomi-wmi.o
+ obj-$(CONFIG_GIGABYTE_WMI) += gigabyte-wmi.o
+ obj-$(CONFIG_YOGABOOK_WMI) += lenovo-yogabook-wmi.o
++obj-$(CONFIG_IDEAPAD_WMI_FN_KEYS) += ideapad-wmi-fn-keys.o
+
+ # Acer
+ obj-$(CONFIG_ACERHDF) += acerhdf.o
+diff --git a/drivers/platform/x86/ideapad-wmi-fn-keys.c b/drivers/platform/x86/ideapad-wmi-fn-keys.c
+new file mode 100644
+index 000000000000..04cac40bc044
+--- /dev/null
++++ b/drivers/platform/x86/ideapad-wmi-fn-keys.c
+@@ -0,0 +1,151 @@
++// SPDX-License-Identifier: GPL-2.0-or-later
++/*
++ * ideapad-wmi-fn-keys.c - Ideapad WMI fn keys driver
++ *
++ * Copyright (C) 2022 Philipp Jungkamp <p.jungkamp@gmx.net>
++ */
++
++#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
++
++#include <linux/acpi.h>
++#include <linux/input.h>
++#include <linux/input/sparse-keymap.h>
++#include <linux/list.h>
++#include <linux/module.h>
++#include <linux/wmi.h>
++
++#define IDEAPAD_FN_KEY_EVENT_GUID "8FC0DE0C-B4E4-43FD-B0F3-8871711C1294"
++
++struct ideapad_wmi_private {
++ struct wmi_device *wmi_device;
++ struct input_dev *input_dev;
++};
++
++static const struct key_entry ideapad_wmi_fn_key_keymap[] = {
++ /* FnLock (handled by the firmware) */
++ { KE_IGNORE, 0x02 },
++ /* Customizable Lenovo Hotkey ("star" with 'S' inside) */
++ { KE_KEY, 0x01, { KEY_FAVORITES } },
++ /* Dark mode toggle */
++ { KE_KEY, 0x13, { KEY_PROG1 } },
++ /* Sound profile switch */
++ { KE_KEY, 0x12, { KEY_PROG2 } },
++ /* Lenovo Virtual Background application */
++ { KE_KEY, 0x28, { KEY_PROG3 } },
++ /* Lenovo Support */
++ { KE_KEY, 0x27, { KEY_HELP } },
++ { KE_END },
++};
++
++static int ideapad_wmi_input_init(struct ideapad_wmi_private *priv)
++{
++ struct input_dev *input_dev;
++ int err;
++
++ input_dev = input_allocate_device();
++ if (!input_dev) {
++ return -ENOMEM;
++ }
++
++ input_dev->name = "Ideapad WMI Fn Keys";
++ input_dev->phys = IDEAPAD_FN_KEY_EVENT_GUID "/input0";
++ input_dev->id.bustype = BUS_HOST;
++ input_dev->dev.parent = &priv->wmi_device->dev;
++
++ err = sparse_keymap_setup(input_dev, ideapad_wmi_fn_key_keymap, NULL);
++ if (err) {
++ dev_err(&priv->wmi_device->dev,
++ "Could not set up input device keymap: %d\n", err);
++ goto err_free_dev;
++ }
++
++ err = input_register_device(input_dev);
++ if (err) {
++ dev_err(&priv->wmi_device->dev,
++ "Could not register input device: %d\n", err);
++ goto err_free_dev;
++ }
++
++ priv->input_dev = input_dev;
++ return 0;
++
++err_free_dev:
++ input_free_device(input_dev);
++ return err;
++}
++
++static void ideapad_wmi_input_exit(struct ideapad_wmi_private *priv)
++{
++ input_unregister_device(priv->input_dev);
++ priv->input_dev = NULL;
++}
++
++static void ideapad_wmi_input_report(struct ideapad_wmi_private *priv,
++ unsigned int scancode)
++{
++ sparse_keymap_report_event(priv->input_dev, scancode, 1, true);
++}
++
++static int ideapad_wmi_probe(struct wmi_device *wdev, const void *ctx)
++{
++ struct ideapad_wmi_private *priv;
++ int err;
++
++ priv = devm_kzalloc(&wdev->dev, sizeof(*priv), GFP_KERNEL);
++ if (!priv)
++ return -ENOMEM;
++
++ dev_set_drvdata(&wdev->dev, priv);
++
++ priv->wmi_device = wdev;
++
++ err = ideapad_wmi_input_init(priv);
++ if (err)
++ return err;
++
++ return 0;
++}
++
++static void ideapad_wmi_remove(struct wmi_device *wdev)
++{
++ struct ideapad_wmi_private *priv = dev_get_drvdata(&wdev->dev);
++
++ ideapad_wmi_input_exit(priv);
++}
++
++static void ideapad_wmi_notify(struct wmi_device *wdev, union acpi_object *data)
++{
++ struct ideapad_wmi_private *priv = dev_get_drvdata(&wdev->dev);
++
++ if(data->type != ACPI_TYPE_INTEGER) {
++ dev_warn(&priv->wmi_device->dev,
++ "WMI event data is not an integer\n");
++ return;
++ }
++
++ ideapad_wmi_input_report(priv, data->integer.value);
++}
++
++static const struct wmi_device_id ideapad_wmi_id_table[] = {
++ { /* Special Keys on the Yoga 9 14IAP7 */
++ .guid_string = IDEAPAD_FN_KEY_EVENT_GUID
++ },
++ { }
++};
++
++static struct wmi_driver ideapad_wmi_driver = {
++ .driver = {
++ .name = "ideapad-wmi-fn-keys",
++ },
++ .id_table = ideapad_wmi_id_table,
++ .probe = ideapad_wmi_probe,
++ .remove = ideapad_wmi_remove,
++ .notify = ideapad_wmi_notify,
++};
++
++module_wmi_driver(ideapad_wmi_driver);
++
++MODULE_DEVICE_TABLE(wmi, ideapad_wmi_id_table);
++MODULE_AUTHOR("Philipp Jungkamp <p.jungkamp@gmx.net>");
++MODULE_DESCRIPTION("Ideapad WMI fn keys driver");
++MODULE_LICENSE("GPL");
+--
+2.37.1
+