All of lore.kernel.org
 help / color / mirror / Atom feed
From: Hans de Goede <hdegoede@redhat.com>
To: Philipp Jungkamp <p.jungkamp@gmx.net>, Mark Gross <markgross@kernel.org>
Cc: platform-driver-x86@vger.kernel.org
Subject: Re: [PATCH] Add IdeaPad WMI Fn Keys driver
Date: Mon, 19 Sep 2022 08:54:49 +0100	[thread overview]
Message-ID: <c251e107-2ad2-417d-c184-b67e778b905a@redhat.com> (raw)
In-Reply-To: <6c38ca87-d427-d34b-73d1-edb6df75af1b@redhat.com>

Hi again,

On 9/11/22 17:18, Hans de Goede wrote:
> Hi Philipp,
> 
> On 9/11/22 18:04, Philipp Jungkamp wrote:
>> 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 as well as the event emitted on 'Fn+R' which
>> toggles between 60Hz and 90Hz display refresh rate on windows.
>>
>> Signed-off-by: Philipp Jungkamp <p.jungkamp@gmx.net>
>> ---
>> I found this patch by poking in the DSDT. I have not submitted any
>> notable patches yet and hope you can help me improve in case I make
>> unfortunate choices during submission.
> 
> No worries at a first glance (I have not looked at this in any
> detail yet) this looks pretty good for a first submission.
> 
> And thank you for contributing to the Linux kernel!
> 
> 
>> Philipp Jungkamp
>>
>>  drivers/platform/x86/Kconfig       |  13 +++
>>  drivers/platform/x86/Makefile      |   1 +
>>  drivers/platform/x86/ideapad-wmi.c | 153 +++++++++++++++++++++++++++++
>>  3 files changed, 167 insertions(+)
>>  create mode 100644 drivers/platform/x86/ideapad-wmi.c
>>
>> diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
>> index f2f98e942cf2..e7c5148e5cb4 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
>> +	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.
>> +
>>  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 5a428caa654a..d8bec884d6bc 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)		+= ideapad-wmi.o
>>
>>  # Acer
>>  obj-$(CONFIG_ACERHDF)		+= acerhdf.o
>> diff --git a/drivers/platform/x86/ideapad-wmi.c b/drivers/platform/x86/ideapad-wmi.c
>> new file mode 100644
>> index 000000000000..38f7b3d0c171
>> --- /dev/null
>> +++ b/drivers/platform/x86/ideapad-wmi.c
>> @@ -0,0 +1,153 @@
>> +// SPDX-License-Identifier: GPL-2.0-or-later
>> +/*
>> + * ideapad-wmi.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"
> 
> At a first hunch (basically huh, don't we have a driver for that
> already?) I grepped through the kernel sources and found:
> 
> drivers/platform/x86/ideapad-laptop.c
> 
> can you see if you can make things work with that driver?

So I have taken a quick look at this and it seems to me that this
really should be able to work with the existing ideapad-laptop.c code ?

For starters you could add a debug printk / dev_info to this block,

#if IS_ENABLED(CONFIG_ACPI_WMI)
        for (i = 0; i < ARRAY_SIZE(ideapad_wmi_fnesc_events); i++) {
                status = wmi_install_notify_handler(ideapad_wmi_fnesc_events[i],
                                                    ideapad_wmi_notify, priv);
                if (ACPI_SUCCESS(status)) {
                        priv->fnesc_guid = ideapad_wmi_fnesc_events[i];
                        break;
                }
        }

        if (ACPI_FAILURE(status) && status != AE_NOT_EXIST) {
                err = -EIO;
                goto notification_failed_wmi;
        }
#endif

checking which event GUID ideapad-laptop binds to on your laptop. Assuming that
it does bind to the GUID this driver is binding to too, then it would be
a matter of extending the existing ideapad_wmi_notify() to do the same
as your notify function in this stand-alone driver. Note you can get the
the equivalend of the union acpi_object *data argument in your wmi handler
by calling wmi_get_event_data().

Regards,

Hans



>> +
>> +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 } },
>> +	/* Refresh Rate Toggle */
>> +	{ KE_KEY,	0x0a, { KEY_DISPLAYTOGGLE } },
>> +	{ 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",
>> +	},
>> +	.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.3
>>


  reply	other threads:[~2022-09-19  7:54 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-09-11 16:04 [PATCH] Add IdeaPad WMI Fn Keys driver Philipp Jungkamp
2022-09-11 16:18 ` Hans de Goede
2022-09-19  7:54   ` Hans de Goede [this message]
2022-11-10 20:02     ` Philipp Jungkamp
2022-11-10 21:02       ` Hans de Goede
2022-11-13 12:12         ` [PATCH v2 1/2] platform/x86: wmi: Disambiguate WMI event data on some ACPI tables Philipp Jungkamp
2022-11-13 12:12           ` [PATCH v2 2/2] platform/x86: ideapad-laptop: support for more special keys in WMI Philipp Jungkamp
2022-11-13 20:30           ` [PATCH v2 1/2] platform/x86: wmi: Disambiguate WMI event data on some ACPI tables Armin Wolf
2022-11-13 21:42             ` Philipp Jungkamp
2022-11-13 23:02               ` Armin Wolf
2022-11-14 14:41                 ` [PATCH v3] platform/x86: ideapad-laptop: support for more special keys in WMI Philipp Jungkamp
2022-11-14 16:15                   ` Hans de Goede
2022-11-14 16:41                   ` Hans de Goede
2022-11-15  0:09                     ` [PATCH v4] " Philipp Jungkamp
2022-11-15 21:19                       ` Hans de Goede
2022-11-16 11:06                         ` [PATCH v5] " Philipp Jungkamp
2022-11-16 14:43                           ` Hans de Goede
2022-11-15  2:27                     ` [PATCH v3] " Armin Wolf
2022-11-15 11:19                       ` Hans de Goede

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=c251e107-2ad2-417d-c184-b67e778b905a@redhat.com \
    --to=hdegoede@redhat.com \
    --cc=markgross@kernel.org \
    --cc=p.jungkamp@gmx.net \
    --cc=platform-driver-x86@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.