From: Hans de Goede <hdegoede@redhat.com>
To: Philipp Jungkamp <p.jungkamp@gmx.net>,
Armin Wolf <W_Armin@gmx.de>, Mark Gross <markgross@kernel.org>
Cc: platform-driver-x86@vger.kernel.org
Subject: Re: [PATCH v3] platform/x86: ideapad-laptop: support for more special keys in WMI
Date: Mon, 14 Nov 2022 17:15:09 +0100 [thread overview]
Message-ID: <777e0ff5-e10a-c9b0-2ca9-c480d7232b9f@redhat.com> (raw)
In-Reply-To: <20221114144140.5054-1-p.jungkamp@gmx.net>
Hi Philiph,
On 11/14/22 15:41, Philipp Jungkamp wrote:
> The event data of the WMI event 0xD0, which is assumed to be the
> fn_lock, is used to indicate several special keys on newer Yoga 7/9
> laptops.
>
> The notify_id 0xD0 is non-unique in the DSDT of the Yoga 9 14IAP7, this
> causes wmi_get_event_data() to report wrong values.
> Port the ideapad-laptop WMI code to the wmi bus infrastructure which
> does not suffer from the shortcomings of wmi_get_event_data().
>
> Signed-off-by: Philipp Jungkamp <p.jungkamp@gmx.net>
> ---
> Hello,
>
> is this about right? It works for me.
>
> What I don't really like here is the dev_set_drvdata() which takes a non-const
> void * and I pass it a const pointer. I do cast the value of dev_get_drvdata()
> back to a const pointer, but this seems rather ugly.
> I preferred it over allocating a single int for the device or casting an enum
> to a void *. This additionally removes the need for a remove funtion.
Thank you for both the v2 and this new interesting approach. Unfortunately
I have a bit of a patch backlog so I'm not sure when I will get around to
this. I will try to get this reviewed / commented on no later then sometime
next week.
Regards,
Hans
>
> Regards,
> Philipp
>
> drivers/platform/x86/ideapad-laptop.c | 109 +++++++++++++++++++-------
> 1 file changed, 80 insertions(+), 29 deletions(-)
>
> diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c
> index 33b3dfdd1b08..6d35a9e961cf 100644
> --- a/drivers/platform/x86/ideapad-laptop.c
> +++ b/drivers/platform/x86/ideapad-laptop.c
> @@ -30,6 +30,7 @@
> #include <linux/seq_file.h>
> #include <linux/sysfs.h>
> #include <linux/types.h>
> +#include <linux/wmi.h>
>
> #include <acpi/video.h>
>
> @@ -38,10 +39,19 @@
> #define IDEAPAD_RFKILL_DEV_NUM 3
>
> #if IS_ENABLED(CONFIG_ACPI_WMI)
> -static const char *const ideapad_wmi_fnesc_events[] = {
> - "26CAB2E5-5CF1-46AE-AAC3-4A12B6BA50E6", /* Yoga 3 */
> - "56322276-8493-4CE8-A783-98C991274F5E", /* Yoga 700 */
> - "8FC0DE0C-B4E4-43FD-B0F3-8871711C1294", /* Legion 5 */
> +enum ideapad_wmi_event_type {
> + IDEAPAD_WMI_EVENT_ESC,
> + IDEAPAD_WMI_EVENT_FN_KEYS,
> +};
> +
> +enum ideapad_wmi_event_type ideapad_wmi_esc = IDEAPAD_WMI_EVENT_ESC,
> +enum ideapad_wmi_event_type ideapad_wmi_fn_keys = IDEAPAD_WMI_EVENT_FN_KEYS;
> +
> +static const struct wmi_device_id ideapad_wmi_id_table[] = {
> + { "26CAB2E5-5CF1-46AE-AAC3-4A12B6BA50E6", &ideapad_wmi_esc }, /* Yoga 3 */
> + { "56322276-8493-4CE8-A783-98C991274F5E", &ideapad_wmi_esc }, /* Yoga 700 */
> + { "8FC0DE0C-B4E4-43FD-B0F3-8871711C1294", &ideapad_wmi_fn_keys }, /* Legion 5 */
> + {}
> };
> #endif
>
> @@ -130,7 +140,7 @@ struct ideapad_private {
> struct ideapad_dytc_priv *dytc;
> struct dentry *debug;
> unsigned long cfg;
> - const char *fnesc_guid;
> + struct wmi_driver wmi_drv;
> struct {
> bool conservation_mode : 1;
> bool dytc : 1;
> @@ -1074,6 +1084,7 @@ static void ideapad_sysfs_exit(struct ideapad_private *priv)
> /*
> * input device
> */
> +#define IDEAPAD_WMI_KEY 0x100
> static const struct key_entry ideapad_keymap[] = {
> { KE_KEY, 6, { KEY_SWITCHVIDEOMODE } },
> { KE_KEY, 7, { KEY_CAMERA } },
> @@ -1087,6 +1098,26 @@ static const struct key_entry ideapad_keymap[] = {
> { KE_KEY, 66, { KEY_TOUCHPAD_OFF } },
> { KE_KEY, 67, { KEY_TOUCHPAD_ON } },
> { KE_KEY, 128, { KEY_ESC } },
> +
> + /*
> + * WMI keys
> + */
> +
> + /* FnLock (handled by the firmware) */
> + { KE_IGNORE, 0x02 | IDEAPAD_WMI_KEY },
> + /* Customizable Lenovo Hotkey ("star" with 'S' inside) */
> + { KE_KEY, 0x01 | IDEAPAD_WMI_KEY, { KEY_FAVORITES } },
> + /* Dark mode toggle */
> + { KE_KEY, 0x13 | IDEAPAD_WMI_KEY, { KEY_PROG1 } },
> + /* Sound profile switch */
> + { KE_KEY, 0x12 | IDEAPAD_WMI_KEY, { KEY_PROG2 } },
> + /* Lenovo Virtual Background application */
> + { KE_KEY, 0x28 | IDEAPAD_WMI_KEY, { KEY_PROG3 } },
> + /* Lenovo Support */
> + { KE_KEY, 0x27 | IDEAPAD_WMI_KEY, { KEY_HELP } },
> + /* Refresh Rate Toggle */
> + { KE_KEY, 0x0a | IDEAPAD_WMI_KEY, { KEY_DISPLAYTOGGLE } },
> +
> { KE_END },
> };
>
> @@ -1491,25 +1522,47 @@ 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)
> +static int ideapad_wmi_probe(struct wmi_device *wdev, const void *context)
> {
> - struct ideapad_private *priv = context;
> + dev_set_drvdata(&wdev->dev, (void *) context);
> + return 0;
> +}
> +
> +static void ideapad_wmi_notify(struct wmi_device *wdev, union acpi_object *data)
> +{
> + struct wmi_driver *wdrv = container_of(wdev->dev.driver,
> + struct wmi_driver,
> + driver);
> + struct ideapad_private *priv = container_of(wdrv,
> + struct ideapad_private,
> + wmi_drv);
> + const enum ideapad_wmi_event_type *event = dev_get_drvdata(&wdev->dev);
> unsigned long result;
>
> - switch (value) {
> - case 128:
> - ideapad_input_report(priv, value);
> + switch (*event) {
> + case IDEAPAD_WMI_EVENT_ESC:
> + ideapad_input_report(priv, 128);
> break;
> - case 208:
> + case IDEAPAD_WMI_EVENT_FN_KEYS:
> if (!eval_hals(priv->adev->handle, &result)) {
> bool state = test_bit(HALS_FNLOCK_STATE_BIT, &result);
>
> exec_sals(priv->adev->handle, state ? SALS_FNLOCK_ON : SALS_FNLOCK_OFF);
> }
> +
> + if (data->type != ACPI_TYPE_INTEGER) {
> + dev_warn(&wdev->dev,
> + "WMI event data is not an integer\n");
> + break;
> + }
> +
> + dev_dbg(&wdev->dev, "WMI fn-key event: 0x%llx\n",
> + data->integer.value);
> +
> + ideapad_input_report(priv,
> + data->integer.value | IDEAPAD_WMI_KEY);
> +
> break;
> - default:
> - dev_info(&priv->platform_device->dev,
> - "Unknown WMI event: %u\n", value);
> }
> }
> #endif
> @@ -1671,25 +1724,24 @@ static int ideapad_acpi_add(struct platform_device *pdev)
> }
>
> #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;
> - }
> - }
> + priv->wmi_drv = (struct wmi_driver) {
> + .driver = {
> + .name = "ideapad-wmi-fn-keys",
> + },
> + .id_table = ideapad_wmi_id_table,
> + .probe = ideapad_wmi_probe,
> + .notify = ideapad_wmi_notify,
> + };
>
> - if (ACPI_FAILURE(status) && status != AE_NOT_EXIST) {
> - err = -EIO;
> - goto notification_failed_wmi;
> - }
> + err = wmi_driver_register(&priv->wmi_drv);
> + if (err)
> + goto register_failed_wmi;
> #endif
>
> return 0;
>
> #if IS_ENABLED(CONFIG_ACPI_WMI)
> -notification_failed_wmi:
> +register_failed_wmi:
> acpi_remove_notify_handler(priv->adev->handle,
> ACPI_DEVICE_NOTIFY,
> ideapad_acpi_notify);
> @@ -1720,8 +1772,7 @@ static int ideapad_acpi_remove(struct platform_device *pdev)
> int i;
>
> #if IS_ENABLED(CONFIG_ACPI_WMI)
> - if (priv->fnesc_guid)
> - wmi_remove_notify_handler(priv->fnesc_guid);
> + wmi_driver_unregister(&priv->wmi_drv);
> #endif
>
> acpi_remove_notify_handler(priv->adev->handle,
> --
> 2.38.1
>
next prev parent reply other threads:[~2022-11-14 16:16 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
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 [this message]
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=777e0ff5-e10a-c9b0-2ca9-c480d7232b9f@redhat.com \
--to=hdegoede@redhat.com \
--cc=W_Armin@gmx.de \
--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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox