lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <8fa29d12-75ce-490b-9e05-827bd130de90@foxido.dev>
Date: Mon, 28 Jul 2025 01:38:51 +0300
From: foxido <foxido@...ido.dev>
To: foxido@...ido.dev
Cc: w_armin@....de, Hans de Goede <hansg@...nel.org>,
 Ilpo Järvinen <ilpo.jarvinen@...ux.intel.com>,
 linux-kernel@...r.kernel.org, platform-driver-x86@...r.kernel.org
Subject: Re: [PATCH 1/1] Add WMI driver for Redmibook keyboard.

This is my first interaction with mailing lists in general and upstream 
linux development in particular, so I apologize for all mistakes in 
advance. Please correct me, if you see some "behaviour"-kinda errors

--
foxido

On 7/28/25 01:34, Gladyshev Ilya wrote:
> This driver implements support for various Fn keys (like Cut) and Xiaomi
> specific AI button.
> 
> Signed-off-by: Gladyshev Ilya <foxido@...ido.dev>
> ---
>   MAINTAINERS                      |   6 ++
>   drivers/platform/x86/Kconfig     |  10 ++
>   drivers/platform/x86/Makefile    |   1 +
>   drivers/platform/x86/redmi-wmi.c | 164 +++++++++++++++++++++++++++++++
>   4 files changed, 181 insertions(+)
>   create mode 100644 drivers/platform/x86/redmi-wmi.c
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 10850512c118..b3956f3d2eb8 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -20965,6 +20965,12 @@ S:	Maintained
>   T:	git https://github.com/pkshih/rtw.git
>   F:	drivers/net/wireless/realtek/rtw89/
>   
> +REDMIBOOK WMI DRIVERS
> +M:	Gladyshev Ilya <foxido@...ido.dev>
> +L:	platform-driver-x86@...r.kernel.org
> +S:	Maintained
> +F:	drivers/platform/x86/redmi-wmi.c
> +
>   REDPINE WIRELESS DRIVER
>   L:	linux-wireless@...r.kernel.org
>   S:	Orphan
> diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
> index e5cbd58a99f3..b8d426e6b5a3 100644
> --- a/drivers/platform/x86/Kconfig
> +++ b/drivers/platform/x86/Kconfig
> @@ -109,6 +109,16 @@ config XIAOMI_WMI
>   	  To compile this driver as a module, choose M here: the module will
>   	  be called xiaomi-wmi.
>   
> +config REDMI_WMI
> +	tristate "Redmibook WMI key driver"
> +	depends on ACPI_WMI
> +	depends on INPUT
> +	help
> +	  Say Y here if you want to support WMI-based keys on Redmibooks.
> +
> +	  To compile this driver as a module, choose M here: the module will
> +	  be called redmi-wmi.
> +
>   config GIGABYTE_WMI
>   	tristate "Gigabyte WMI temperature driver"
>   	depends on ACPI_WMI
> diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
> index abbc2644ff6d..56903d7408cd 100644
> --- a/drivers/platform/x86/Makefile
> +++ b/drivers/platform/x86/Makefile
> @@ -13,6 +13,7 @@ obj-$(CONFIG_HUAWEI_WMI)		+= huawei-wmi.o
>   obj-$(CONFIG_MXM_WMI)			+= mxm-wmi.o
>   obj-$(CONFIG_NVIDIA_WMI_EC_BACKLIGHT)	+= nvidia-wmi-ec-backlight.o
>   obj-$(CONFIG_XIAOMI_WMI)		+= xiaomi-wmi.o
> +obj-$(CONFIG_REDMI_WMI)			+= redmi-wmi.o
>   obj-$(CONFIG_GIGABYTE_WMI)		+= gigabyte-wmi.o
>   
>   # Acer
> diff --git a/drivers/platform/x86/redmi-wmi.c b/drivers/platform/x86/redmi-wmi.c
> new file mode 100644
> index 000000000000..0bb6ea7b1081
> --- /dev/null
> +++ b/drivers/platform/x86/redmi-wmi.c
> @@ -0,0 +1,164 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/* WMI driver for Xiaomi Redmibooks */
> +
> +#include <linux/acpi.h>
> +#include <linux/device.h>
> +#include <linux/input.h>
> +#include <linux/module.h>
> +#include <linux/mutex.h>
> +#include <linux/wmi.h>
> +
> +#include <uapi/linux/input-event-codes.h>
> +
> +#define WMI_REDMIBOOK_KEYBOARD_EVENT_GUID "46c93e13-ee9b-4262-8488-563bca757fef"
> +
> +/* Supported WMI keys ... */
> +#define ACPI_CUT_PAYLOAD		0x00000201
> +#define ACPI_ALL_APPS_PAYLOAD		0x00000301
> +#define ACPI_SETUP_PAYLOAD		0x00001b01
> +#define ACPI_CST_KEY_PRESS_PAYLOAD	0x00011801
> +#define ACPI_CST_KEY_RELEASE_PAYLOAD	0x00011901
> +
> +/* ... and their mappings */
> +#define WMI_CUT_KEY		KEY_PROG1
> +#define WMI_ALL_APPS_KEY	KEY_ALL_APPLICATIONS
> +#define WMI_SETUP_KEY		KEY_SETUP
> +#define WMI_CST_KEY		KEY_ASSISTANT
> +
> +/* Keyboard backlight key (not supported yet) */
> +#define BACKLIGHT_LEVEL_0_PAYLOAD	0x00000501
> +#define BACKLIGHT_LEVEL_1_PAYLOAD	0x00800501
> +#define BACKLIGHT_LEVEL_2_PAYLOAD	0x00050501
> +#define BACKLIGHT_LEVEL_3_PAYLOAD	0x000a0501
> +
> +struct redmi_wmi {
> +	struct input_dev *input_dev;
> +	/* Protects the key event sequence */
> +	struct mutex key_lock;
> +};
> +
> +static void redmi_mutex_destroy(void *data)
> +{
> +	struct mutex *lock = data;
> +
> +	mutex_destroy(lock);
> +}
> +
> +static int redmi_wmi_probe(struct wmi_device *wdev, const void *context)
> +{
> +	struct redmi_wmi *data;
> +	int ret;
> +
> +	/* Init dev */
> +	data = devm_kzalloc(&wdev->dev, sizeof(struct redmi_wmi), GFP_KERNEL);
> +	if (!data)
> +		return -ENOMEM;
> +
> +	dev_set_drvdata(&wdev->dev, data);
> +
> +	/* Init mutex & setup destroy at exit */
> +	mutex_init(&data->key_lock);
> +	ret = devm_add_action_or_reset(&wdev->dev, redmi_mutex_destroy, &data->key_lock);
> +	if (ret < 0)
> +		return ret;
> +
> +	/* Setup input device */
> +	data->input_dev = devm_input_allocate_device(&wdev->dev);
> +	if (!data->input_dev)
> +		return -ENOMEM;
> +	data->input_dev->name = "Redmibook WMI keys";
> +	data->input_dev->phys = "wmi/input0";
> +
> +	set_bit(EV_KEY, data->input_dev->evbit);
> +
> +	/* "Cut" key*/
> +	set_bit(WMI_CUT_KEY, data->input_dev->keybit);
> +	/* "All apps" key*/
> +	set_bit(WMI_ALL_APPS_KEY, data->input_dev->keybit);
> +	/* "Settings" key */
> +	set_bit(WMI_SETUP_KEY, data->input_dev->keybit);
> +	/* Custom (AI?) key */
> +	set_bit(WMI_CST_KEY, data->input_dev->keybit);
> +
> +	return input_register_device(data->input_dev);
> +}
> +
> +static void press_and_release_key(struct input_dev *dev, unsigned int code)
> +{
> +	input_report_key(dev, code, 1);
> +	input_sync(dev);
> +	input_report_key(dev, code, 0);
> +	input_sync(dev);
> +}
> +
> +static void redmi_wmi_notify(struct wmi_device *wdev, union acpi_object *obj)
> +{
> +	struct redmi_wmi *data = dev_get_drvdata(&wdev->dev);
> +
> +	if (obj->type != ACPI_TYPE_BUFFER) {
> +		dev_err(&wdev->dev, "Bad response type %u\n", obj->type);
> +		return;
> +	}
> +
> +	if (obj->buffer.length < 4) {
> +		dev_err(&wdev->dev, "Invalid buffer length %u\n", obj->buffer.length);
> +		return;
> +	}
> +
> +	/* For linearizability */
> +	guard(mutex)(&data->key_lock);
> +
> +	u32 payload = ((u32 *)obj->buffer.pointer)[0];
> +
> +	switch (payload) {
> +	case ACPI_CUT_PAYLOAD:
> +		press_and_release_key(data->input_dev, WMI_CUT_KEY);
> +		break;
> +	case ACPI_ALL_APPS_PAYLOAD:
> +		press_and_release_key(data->input_dev, WMI_ALL_APPS_KEY);
> +		break;
> +	case ACPI_SETUP_PAYLOAD:
> +		press_and_release_key(data->input_dev, WMI_SETUP_KEY);
> +		break;
> +	case ACPI_CST_KEY_PRESS_PAYLOAD:
> +		input_report_key(data->input_dev, WMI_CST_KEY, 1);
> +		input_sync(data->input_dev);
> +		break;
> +	case ACPI_CST_KEY_RELEASE_PAYLOAD:
> +		input_report_key(data->input_dev, WMI_CST_KEY, 0);
> +		input_sync(data->input_dev);
> +		break;
> +	case BACKLIGHT_LEVEL_0_PAYLOAD:
> +	case BACKLIGHT_LEVEL_1_PAYLOAD:
> +	case BACKLIGHT_LEVEL_2_PAYLOAD:
> +	case BACKLIGHT_LEVEL_3_PAYLOAD:
> +		pr_debug("keyboard backlight WMI event, no action");
> +		break;
> +	default:
> +		pr_debug("unsupported Redmibook WMI event with 4byte payload %u", payload);
> +		break;
> +	}
> +}
> +
> +static const struct wmi_device_id redmi_wmi_id_table[] = {
> +	{ .guid_string = WMI_REDMIBOOK_KEYBOARD_EVENT_GUID },
> +	/* Terminating entry */
> +	{ }
> +};
> +
> +static struct wmi_driver redmi_wmi_driver = {
> +	.driver = {
> +		.name = "redmi-wmi",
> +		.probe_type = PROBE_PREFER_ASYNCHRONOUS
> +	},
> +	.id_table = redmi_wmi_id_table,
> +	.probe = redmi_wmi_probe,
> +	.notify = redmi_wmi_notify,
> +	.no_singleton = true,
> +};
> +module_wmi_driver(redmi_wmi_driver);
> +
> +MODULE_DEVICE_TABLE(wmi, redmi_wmi_id_table);
> +MODULE_AUTHOR("Gladyshev Ilya <foxido@...ido.dev>");
> +MODULE_DESCRIPTION("Redmibook WMI driver");
> +MODULE_LICENSE("GPL");


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ