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: Thu, 10 Nov 2022 22:02:20 +0100 [thread overview]
Message-ID: <8d54fbbb-0933-aaea-5f66-bb7807f5506d@redhat.com> (raw)
In-Reply-To: <362cfa1aa490d226218b30d10d2b392fd7e96abb.camel@gmx.net>
Hi Philipp,
On 11/10/22 21:02, Philipp Jungkamp wrote:
> On Mon, 2022-09-19 at 08:54 +0100, Hans de Goede wrote:
>> 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
>>
>
> Hello Hans,
>
> I did actually start by doing that.
> The problem lies with the wmi_get_event_data() function not working
> for my ACPI.
>
> wmi_get_event_data() takes the event notify_id as input and is supposed
> to give the data associated with the event back. This occures by
> calling _WED on the first WMI block that contains said notify_id.
>
> drivers/platform/x86/wmi.c:657:
> list_for_each_entry(wblock, &wmi_block_list, list) {
> struct guid_block *gblock = &wblock->gblock;
>
> if ((gblock->flags & ACPI_WMI_EVENT) && gblock-
>> notify_id == event)
> return get_event_data(wblock, out);
> }
>
> The ACPI of the Lenovo Yoga 9 14IAP7 contains multiple WMI event
> blocks hat contain the same notify_id 0xD0.
>
> Here are two of the four WMI objects found in the DSDT:
>
> in _WDG of block WMIY:
> 06129D99-6083-4164-81AD-F092F9D773A6:
> notify_id: 0xD0
> instance_count: 1
> flags: 0x8 ACPI_WMI_EVENT
>
> in _WDG of block WMIU:
> 8FC0DE0C-B4E4-43FD-B0F3-8871711C1294:
> notify_id: 0xD0
> instance_count: 1
> flags: 0x8 ACPI_WMI_EVENT
>
> These event block belong to different WMI devices and report
> unrelated values from different _WED handlers. WMIY for example
> triggers its event on "mode changes", e.g. laptop/tablet/tent based
> on the accelometers/hinge.
> WMIU is the WMI block with the event which reports the special keys
> I'm interested in.
>
> WMIY comes before WMIU in the wmi_block_list.
> Calling wmi_get_event_data() in ideapad_wmi_notify() calls the wrong
> _WED (the one of WMIY) and thus returns the wrong event data.
>
> I noticed that the wmi_driver interface does not incur the problem
> with the event because it binds to a wmi_block and calls the _WED
> directly without searching through other WMI devices.
Right, I see in that case I guess that using the wmi_driver
interface does make sense.
> I thought of changing the signature of wmi_get_event_data() to include
> the GUID of the correct WMI block, but chose wmi_driver instead.
> Would you consider adding a wmi_get_event_data_for_guid() function to
> the wmi module and using that in the ideapad_wmi_notify function to be
> a better solution than the one in the patch presented here?
So the problem is that ideapad-laptop is using the old interface
and it does:
status = wmi_install_notify_handler(ideapad_wmi_fnesc_events[i],
ideapad_wmi_notify, priv);
And then the code to call that notifier in wmi.c goes like this:
if (test_bit(WMI_PROBED, &wblock->flags) && wblock->dev.dev.driver) {
struct wmi_driver *driver = drv_to_wdrv(wblock->dev.dev.driver);
struct acpi_buffer evdata = { ACPI_ALLOCATE_BUFFER, NULL };
acpi_status status;
if (!driver->no_notify_data) {
status = get_event_data(wblock, &evdata);
if (ACPI_FAILURE(status)) {
dev_warn(&wblock->dev.dev, "failed to get event data\n");
return;
}
}
if (driver->notify)
driver->notify(&wblock->dev, evdata.pointer);
kfree(evdata.pointer);
} else if (wblock->handler) {
/* Legacy handler */
wblock->handler(event, wblock->handler_data);
}
So if we move ahead with your new style wmi-driver for GUID
8FC0DE0C-B4E4-43FD-B0F3-8871711C1294.
Then we hit the "true" path of the if and the legacy handler
(registered by ideapad-laptop) will never trigger.
I guess you could argue that this is a feature since your
new-style driver "replaces" ideapad-laptop, but ending up with
2 drivers for ideapad laptops / for GUID
8FC0DE0C-B4E4-43FD-B0F3-8871711C1294 and them having them have
to coordinate to decide which one to load sounds less then ideal.
So I think that your idea to add a wmi_get_event_data_for_guid()
function to wmi.c is actually a good idea.
Can you give that a try please and see how that goes ?
Regards,
Hans
next prev parent reply other threads:[~2022-11-10 21:03 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 [this message]
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=8d54fbbb-0933-aaea-5f66-bb7807f5506d@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.