Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1637958 > unrolled thread

[PATCH v2] platform/x86: peaq-wmi: Add new peaq-wmi driver

Started byHans de Goede <hdegoede@redhat.com>
First post2017-05-09 10:00 +0200
Last post2017-05-09 23:30 +0200
Articles 6 — 4 participants

Back to article view | Back to linux.kernel


Contents

  [PATCH v2] platform/x86: peaq-wmi: Add new peaq-wmi driver Hans de Goede <hdegoede@redhat.com> - 2017-05-09 10:00 +0200
    Re: [PATCH v2] platform/x86: peaq-wmi: Add new peaq-wmi driver Andy Shevchenko <andy.shevchenko@gmail.com> - 2017-05-09 16:40 +0200
    Re: [PATCH v2] platform/x86: peaq-wmi: Add new peaq-wmi driver Darren Hart <dvhart@infradead.org> - 2017-05-09 18:10 +0200
      Re: [PATCH v2] platform/x86: peaq-wmi: Add new peaq-wmi driver Dmitry Torokhov <dmitry.torokhov@gmail.com> - 2017-05-09 19:30 +0200
      Re: [PATCH v2] platform/x86: peaq-wmi: Add new peaq-wmi driver Hans de Goede <hdegoede@redhat.com> - 2017-05-09 20:40 +0200
        Re: [PATCH v2] platform/x86: peaq-wmi: Add new peaq-wmi driver Darren Hart <dvhart@infradead.org> - 2017-05-09 23:30 +0200

#1637958 — [PATCH v2] platform/x86: peaq-wmi: Add new peaq-wmi driver

FromHans de Goede <hdegoede@redhat.com>
Date2017-05-09 10:00 +0200
Subject[PATCH v2] platform/x86: peaq-wmi: Add new peaq-wmi driver
Message-ID<tF8dQ-7bU-23@gated-at.bofh.it>
PEAQ is a new European OEM, I've bought one of their 2-in-1 x86
devices, which is actually quite a nice device. Under Windows it has
Dolby software for "better" sound and you can select different equalizer
presets using a special button.

This WMI interface for this button is not really nice, as it does not do
notifies (it really does not I tripple checked), but since I had already
figured out the entire WMI interface for this I decided to go the full
mile anyways and also implent a WMI based input driver for this using
input_polldev since, well, we need to poll.

This commit adds support for this button making it report KEY_SOUND input
events. KEY_SOUND is already used in various places to switch sound into
theatre mode and things like that so it seems appropriate here.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
Changes in v2:
-Drop unneeded #include <linux/input.h>
-Add and use PEAQ_POLL_IGNORE_MS and PEAQ_POLL_MAX_MS defines
-Make globals static
-Call input_sync between reporting the button down and up
-Ignore events for at least 1 poll after an event even if the user has set
 poll_interval > PEAQ_POLL_IGNORE_MS
---
 drivers/platform/x86/Kconfig    |  7 +++
 drivers/platform/x86/Makefile   |  1 +
 drivers/platform/x86/peaq-wmi.c | 97 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 105 insertions(+)
 create mode 100644 drivers/platform/x86/peaq-wmi.c

diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index be2ffbd6eb6c..2bac2b2644f9 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -660,6 +660,13 @@ config MSI_WMI
 	 To compile this driver as a module, choose M here: the module will
 	 be called msi-wmi.
 
+config PEAQ_WMI
+	tristate "PEAQ 2-in-1 WMI hotkey driver"
+	depends on ACPI_WMI
+	depends on INPUT
+	help
+	 Say Y here if you want to support WMI-based hotkeys on PEAQ 2-in-1s.
+
 config TOPSTAR_LAPTOP
 	tristate "Topstar Laptop Extras"
 	depends on ACPI
diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
index de4ffb594ba5..02487f95dd27 100644
--- a/drivers/platform/x86/Makefile
+++ b/drivers/platform/x86/Makefile
@@ -34,6 +34,7 @@ obj-$(CONFIG_PANASONIC_LAPTOP)	+= panasonic-laptop.o
 obj-$(CONFIG_INTEL_MENLOW)	+= intel_menlow.o
 obj-$(CONFIG_ACPI_WMI)		+= wmi.o
 obj-$(CONFIG_MSI_WMI)		+= msi-wmi.o
+obj-$(CONFIG_PEAQ_WMI)		+= peaq-wmi.o
 obj-$(CONFIG_SURFACE3_WMI)	+= surface3-wmi.o
 obj-$(CONFIG_TOPSTAR_LAPTOP)	+= topstar-laptop.o
 
diff --git a/drivers/platform/x86/peaq-wmi.c b/drivers/platform/x86/peaq-wmi.c
new file mode 100644
index 000000000000..47b36b2fa895
--- /dev/null
+++ b/drivers/platform/x86/peaq-wmi.c
@@ -0,0 +1,97 @@
+/*
+ * PEAQ 2-in-1 WMI hotkey driver
+ * Copyright (C) 2017 Hans de Goede <hdegoede@redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/acpi.h>
+#include <linux/input-polldev.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#define PEAQ_DOLBY_BUTTON_GUID		"ABBC0F6F-8EA1-11D1-00A0-C90629100000"
+#define PEAQ_DOLBY_BUTTON_METHOD_ID	5
+#define PEAQ_POLL_INTERVAL_MS		250
+#define PEAQ_POLL_IGNORE_MS		500
+#define PEAQ_POLL_MAX_MS		1000
+
+MODULE_ALIAS("wmi:"PEAQ_DOLBY_BUTTON_GUID);
+
+static struct input_polled_dev *peaq_poll_dev;
+static unsigned int peaq_ignore_events_counter;
+
+/*
+ * The Dolby button (yes really a Dolby button) causes an ACPI variable to get
+ * set on both press and release. The WMI method checks and clears that flag.
+ * So for a press + release we will get back One from the WMI method either once
+ * (if polling after the release) or twice (polling between press and release).
+ * We ignore events for 0.5s after the first event to avoid reporting 2 presses.
+ */
+static void peaq_wmi_poll(struct input_polled_dev *dev)
+{
+	union acpi_object obj;
+	struct acpi_buffer buffer = { sizeof(obj), &obj };
+	acpi_status status;
+
+	status = wmi_evaluate_method(PEAQ_DOLBY_BUTTON_GUID, 1,
+				     PEAQ_DOLBY_BUTTON_METHOD_ID,
+				     NULL, &buffer);
+	if (ACPI_FAILURE(status))
+		return;
+
+	if (obj.type != ACPI_TYPE_INTEGER) {
+		dev_err(&peaq_poll_dev->input->dev,
+			"Error WMBC did not return an integer\n");
+		return;
+	}
+
+	if (peaq_ignore_events_counter && --peaq_ignore_events_counter > 0)
+		return;
+
+	if (obj.integer.value) {
+		input_event(peaq_poll_dev->input, EV_KEY, KEY_SOUND, 1);
+		input_sync(peaq_poll_dev->input);
+		input_event(peaq_poll_dev->input, EV_KEY, KEY_SOUND, 0);
+		input_sync(peaq_poll_dev->input);
+		peaq_ignore_events_counter = max(1u,
+			PEAQ_POLL_IGNORE_MS / peaq_poll_dev->poll_interval);
+	}
+}
+
+static int __init peaq_wmi_init(void)
+{
+	if (!wmi_has_guid(PEAQ_DOLBY_BUTTON_GUID))
+		return -ENODEV;
+
+	peaq_poll_dev = input_allocate_polled_device();
+	if (!peaq_poll_dev)
+		return -ENOMEM;
+
+	peaq_poll_dev->poll = peaq_wmi_poll;
+	peaq_poll_dev->poll_interval = PEAQ_POLL_INTERVAL_MS;
+	peaq_poll_dev->poll_interval_max = PEAQ_POLL_MAX_MS;
+	peaq_poll_dev->input->name = "PEAQ WMI hotkeys";
+	peaq_poll_dev->input->phys = "wmi/input0";
+	peaq_poll_dev->input->id.bustype = BUS_HOST;
+	input_set_capability(peaq_poll_dev->input, EV_KEY, KEY_SOUND);
+
+	return input_register_polled_device(peaq_poll_dev);
+}
+
+static void __exit peaq_wmi_exit(void)
+{
+	if (!wmi_has_guid(PEAQ_DOLBY_BUTTON_GUID))
+		return;
+
+	input_unregister_polled_device(peaq_poll_dev);
+}
+
+module_init(peaq_wmi_init);
+module_exit(peaq_wmi_exit);
+
+MODULE_DESCRIPTION("PEAQ 2-in-1 WMI hotkey driver");
+MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
+MODULE_LICENSE("GPL");
-- 
2.12.2

[toc] | [next] | [standalone]


#1638168

FromAndy Shevchenko <andy.shevchenko@gmail.com>
Date2017-05-09 16:40 +0200
Message-ID<tFesW-2Ya-29@gated-at.bofh.it>
In reply to#1637958
On Tue, May 9, 2017 at 10:54 AM, Hans de Goede <hdegoede@redhat.com> wrote:
> PEAQ is a new European OEM, I've bought one of their 2-in-1 x86
> devices, which is actually quite a nice device. Under Windows it has
> Dolby software for "better" sound and you can select different equalizer
> presets using a special button.
>
> This WMI interface for this button is not really nice, as it does not do
> notifies (it really does not I tripple checked), but since I had already
> figured out the entire WMI interface for this I decided to go the full
> mile anyways and also implent a WMI based input driver for this using
> input_polldev since, well, we need to poll.
>
> This commit adds support for this button making it report KEY_SOUND input
> events. KEY_SOUND is already used in various places to switch sound into
> theatre mode and things like that so it seems appropriate here.
>
> Signed-off-by: Hans de Goede <hdegoede@redhat.com>

Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>

> ---
> Changes in v2:
> -Drop unneeded #include <linux/input.h>
> -Add and use PEAQ_POLL_IGNORE_MS and PEAQ_POLL_MAX_MS defines
> -Make globals static
> -Call input_sync between reporting the button down and up
> -Ignore events for at least 1 poll after an event even if the user has set
>  poll_interval > PEAQ_POLL_IGNORE_MS
> ---
>  drivers/platform/x86/Kconfig    |  7 +++
>  drivers/platform/x86/Makefile   |  1 +
>  drivers/platform/x86/peaq-wmi.c | 97 +++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 105 insertions(+)
>  create mode 100644 drivers/platform/x86/peaq-wmi.c
>
> diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
> index be2ffbd6eb6c..2bac2b2644f9 100644
> --- a/drivers/platform/x86/Kconfig
> +++ b/drivers/platform/x86/Kconfig
> @@ -660,6 +660,13 @@ config MSI_WMI
>          To compile this driver as a module, choose M here: the module will
>          be called msi-wmi.
>
> +config PEAQ_WMI
> +       tristate "PEAQ 2-in-1 WMI hotkey driver"
> +       depends on ACPI_WMI
> +       depends on INPUT
> +       help
> +        Say Y here if you want to support WMI-based hotkeys on PEAQ 2-in-1s.
> +
>  config TOPSTAR_LAPTOP
>         tristate "Topstar Laptop Extras"
>         depends on ACPI
> diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
> index de4ffb594ba5..02487f95dd27 100644
> --- a/drivers/platform/x86/Makefile
> +++ b/drivers/platform/x86/Makefile
> @@ -34,6 +34,7 @@ obj-$(CONFIG_PANASONIC_LAPTOP)        += panasonic-laptop.o
>  obj-$(CONFIG_INTEL_MENLOW)     += intel_menlow.o
>  obj-$(CONFIG_ACPI_WMI)         += wmi.o
>  obj-$(CONFIG_MSI_WMI)          += msi-wmi.o
> +obj-$(CONFIG_PEAQ_WMI)         += peaq-wmi.o
>  obj-$(CONFIG_SURFACE3_WMI)     += surface3-wmi.o
>  obj-$(CONFIG_TOPSTAR_LAPTOP)   += topstar-laptop.o
>
> diff --git a/drivers/platform/x86/peaq-wmi.c b/drivers/platform/x86/peaq-wmi.c
> new file mode 100644
> index 000000000000..47b36b2fa895
> --- /dev/null
> +++ b/drivers/platform/x86/peaq-wmi.c
> @@ -0,0 +1,97 @@
> +/*
> + * PEAQ 2-in-1 WMI hotkey driver
> + * Copyright (C) 2017 Hans de Goede <hdegoede@redhat.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <linux/acpi.h>
> +#include <linux/input-polldev.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +
> +#define PEAQ_DOLBY_BUTTON_GUID         "ABBC0F6F-8EA1-11D1-00A0-C90629100000"
> +#define PEAQ_DOLBY_BUTTON_METHOD_ID    5
> +#define PEAQ_POLL_INTERVAL_MS          250
> +#define PEAQ_POLL_IGNORE_MS            500
> +#define PEAQ_POLL_MAX_MS               1000
> +
> +MODULE_ALIAS("wmi:"PEAQ_DOLBY_BUTTON_GUID);
> +
> +static struct input_polled_dev *peaq_poll_dev;
> +static unsigned int peaq_ignore_events_counter;
> +
> +/*
> + * The Dolby button (yes really a Dolby button) causes an ACPI variable to get
> + * set on both press and release. The WMI method checks and clears that flag.
> + * So for a press + release we will get back One from the WMI method either once
> + * (if polling after the release) or twice (polling between press and release).
> + * We ignore events for 0.5s after the first event to avoid reporting 2 presses.
> + */
> +static void peaq_wmi_poll(struct input_polled_dev *dev)
> +{
> +       union acpi_object obj;
> +       struct acpi_buffer buffer = { sizeof(obj), &obj };
> +       acpi_status status;
> +
> +       status = wmi_evaluate_method(PEAQ_DOLBY_BUTTON_GUID, 1,
> +                                    PEAQ_DOLBY_BUTTON_METHOD_ID,
> +                                    NULL, &buffer);
> +       if (ACPI_FAILURE(status))
> +               return;
> +
> +       if (obj.type != ACPI_TYPE_INTEGER) {
> +               dev_err(&peaq_poll_dev->input->dev,
> +                       "Error WMBC did not return an integer\n");
> +               return;
> +       }
> +
> +       if (peaq_ignore_events_counter && --peaq_ignore_events_counter > 0)
> +               return;
> +
> +       if (obj.integer.value) {
> +               input_event(peaq_poll_dev->input, EV_KEY, KEY_SOUND, 1);
> +               input_sync(peaq_poll_dev->input);
> +               input_event(peaq_poll_dev->input, EV_KEY, KEY_SOUND, 0);
> +               input_sync(peaq_poll_dev->input);
> +               peaq_ignore_events_counter = max(1u,
> +                       PEAQ_POLL_IGNORE_MS / peaq_poll_dev->poll_interval);
> +       }
> +}
> +
> +static int __init peaq_wmi_init(void)
> +{
> +       if (!wmi_has_guid(PEAQ_DOLBY_BUTTON_GUID))
> +               return -ENODEV;
> +
> +       peaq_poll_dev = input_allocate_polled_device();
> +       if (!peaq_poll_dev)
> +               return -ENOMEM;
> +
> +       peaq_poll_dev->poll = peaq_wmi_poll;
> +       peaq_poll_dev->poll_interval = PEAQ_POLL_INTERVAL_MS;
> +       peaq_poll_dev->poll_interval_max = PEAQ_POLL_MAX_MS;
> +       peaq_poll_dev->input->name = "PEAQ WMI hotkeys";
> +       peaq_poll_dev->input->phys = "wmi/input0";
> +       peaq_poll_dev->input->id.bustype = BUS_HOST;
> +       input_set_capability(peaq_poll_dev->input, EV_KEY, KEY_SOUND);
> +
> +       return input_register_polled_device(peaq_poll_dev);
> +}
> +
> +static void __exit peaq_wmi_exit(void)
> +{
> +       if (!wmi_has_guid(PEAQ_DOLBY_BUTTON_GUID))
> +               return;
> +
> +       input_unregister_polled_device(peaq_poll_dev);
> +}
> +
> +module_init(peaq_wmi_init);
> +module_exit(peaq_wmi_exit);
> +
> +MODULE_DESCRIPTION("PEAQ 2-in-1 WMI hotkey driver");
> +MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
> +MODULE_LICENSE("GPL");
> --
> 2.12.2
>



-- 
With Best Regards,
Andy Shevchenko

[toc] | [prev] | [next] | [standalone]


#1638244

FromDarren Hart <dvhart@infradead.org>
Date2017-05-09 18:10 +0200
Message-ID<tFfS1-41K-13@gated-at.bofh.it>
In reply to#1637958
On Tue, May 09, 2017 at 09:54:31AM +0200, Hans de Goede wrote:
> PEAQ is a new European OEM, I've bought one of their 2-in-1 x86
> devices, which is actually quite a nice device. Under Windows it has
> Dolby software for "better" sound and you can select different equalizer
> presets using a special button.
> 
> This WMI interface for this button is not really nice, as it does not do
> notifies (it really does not I tripple checked), but since I had already
> figured out the entire WMI interface for this I decided to go the full
> mile anyways and also implent a WMI based input driver for this using
> input_polldev since, well, we need to poll.
> 
> This commit adds support for this button making it report KEY_SOUND input
> events. KEY_SOUND is already used in various places to switch sound into
> theatre mode and things like that so it seems appropriate here.
> 
> Signed-off-by: Hans de Goede <hdegoede@redhat.com>

+Dmitry (in case he wants to add a Reviewed-by, left all context below)

Queued to testing, thanks Hans.

> ---
> Changes in v2:
> -Drop unneeded #include <linux/input.h>
> -Add and use PEAQ_POLL_IGNORE_MS and PEAQ_POLL_MAX_MS defines
> -Make globals static
> -Call input_sync between reporting the button down and up
> -Ignore events for at least 1 poll after an event even if the user has set
>  poll_interval > PEAQ_POLL_IGNORE_MS
> ---
>  drivers/platform/x86/Kconfig    |  7 +++
>  drivers/platform/x86/Makefile   |  1 +
>  drivers/platform/x86/peaq-wmi.c | 97 +++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 105 insertions(+)
>  create mode 100644 drivers/platform/x86/peaq-wmi.c
> 
> diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
> index be2ffbd6eb6c..2bac2b2644f9 100644
> --- a/drivers/platform/x86/Kconfig
> +++ b/drivers/platform/x86/Kconfig
> @@ -660,6 +660,13 @@ config MSI_WMI
>  	 To compile this driver as a module, choose M here: the module will
>  	 be called msi-wmi.
>  
> +config PEAQ_WMI
> +	tristate "PEAQ 2-in-1 WMI hotkey driver"
> +	depends on ACPI_WMI
> +	depends on INPUT
> +	help
> +	 Say Y here if you want to support WMI-based hotkeys on PEAQ 2-in-1s.
> +
>  config TOPSTAR_LAPTOP
>  	tristate "Topstar Laptop Extras"
>  	depends on ACPI
> diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
> index de4ffb594ba5..02487f95dd27 100644
> --- a/drivers/platform/x86/Makefile
> +++ b/drivers/platform/x86/Makefile
> @@ -34,6 +34,7 @@ obj-$(CONFIG_PANASONIC_LAPTOP)	+= panasonic-laptop.o
>  obj-$(CONFIG_INTEL_MENLOW)	+= intel_menlow.o
>  obj-$(CONFIG_ACPI_WMI)		+= wmi.o
>  obj-$(CONFIG_MSI_WMI)		+= msi-wmi.o
> +obj-$(CONFIG_PEAQ_WMI)		+= peaq-wmi.o
>  obj-$(CONFIG_SURFACE3_WMI)	+= surface3-wmi.o
>  obj-$(CONFIG_TOPSTAR_LAPTOP)	+= topstar-laptop.o
>  
> diff --git a/drivers/platform/x86/peaq-wmi.c b/drivers/platform/x86/peaq-wmi.c
> new file mode 100644
> index 000000000000..47b36b2fa895
> --- /dev/null
> +++ b/drivers/platform/x86/peaq-wmi.c
> @@ -0,0 +1,97 @@
> +/*
> + * PEAQ 2-in-1 WMI hotkey driver
> + * Copyright (C) 2017 Hans de Goede <hdegoede@redhat.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <linux/acpi.h>
> +#include <linux/input-polldev.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +
> +#define PEAQ_DOLBY_BUTTON_GUID		"ABBC0F6F-8EA1-11D1-00A0-C90629100000"
> +#define PEAQ_DOLBY_BUTTON_METHOD_ID	5
> +#define PEAQ_POLL_INTERVAL_MS		250
> +#define PEAQ_POLL_IGNORE_MS		500
> +#define PEAQ_POLL_MAX_MS		1000
> +
> +MODULE_ALIAS("wmi:"PEAQ_DOLBY_BUTTON_GUID);
> +
> +static struct input_polled_dev *peaq_poll_dev;
> +static unsigned int peaq_ignore_events_counter;
> +
> +/*
> + * The Dolby button (yes really a Dolby button) causes an ACPI variable to get
> + * set on both press and release. The WMI method checks and clears that flag.
> + * So for a press + release we will get back One from the WMI method either once
> + * (if polling after the release) or twice (polling between press and release).
> + * We ignore events for 0.5s after the first event to avoid reporting 2 presses.
> + */
> +static void peaq_wmi_poll(struct input_polled_dev *dev)
> +{
> +	union acpi_object obj;
> +	struct acpi_buffer buffer = { sizeof(obj), &obj };
> +	acpi_status status;
> +
> +	status = wmi_evaluate_method(PEAQ_DOLBY_BUTTON_GUID, 1,
> +				     PEAQ_DOLBY_BUTTON_METHOD_ID,
> +				     NULL, &buffer);
> +	if (ACPI_FAILURE(status))
> +		return;
> +
> +	if (obj.type != ACPI_TYPE_INTEGER) {
> +		dev_err(&peaq_poll_dev->input->dev,
> +			"Error WMBC did not return an integer\n");
> +		return;
> +	}
> +
> +	if (peaq_ignore_events_counter && --peaq_ignore_events_counter > 0)
> +		return;
> +
> +	if (obj.integer.value) {
> +		input_event(peaq_poll_dev->input, EV_KEY, KEY_SOUND, 1);
> +		input_sync(peaq_poll_dev->input);
> +		input_event(peaq_poll_dev->input, EV_KEY, KEY_SOUND, 0);
> +		input_sync(peaq_poll_dev->input);
> +		peaq_ignore_events_counter = max(1u,
> +			PEAQ_POLL_IGNORE_MS / peaq_poll_dev->poll_interval);
> +	}
> +}
> +
> +static int __init peaq_wmi_init(void)
> +{
> +	if (!wmi_has_guid(PEAQ_DOLBY_BUTTON_GUID))
> +		return -ENODEV;
> +
> +	peaq_poll_dev = input_allocate_polled_device();
> +	if (!peaq_poll_dev)
> +		return -ENOMEM;
> +
> +	peaq_poll_dev->poll = peaq_wmi_poll;
> +	peaq_poll_dev->poll_interval = PEAQ_POLL_INTERVAL_MS;
> +	peaq_poll_dev->poll_interval_max = PEAQ_POLL_MAX_MS;
> +	peaq_poll_dev->input->name = "PEAQ WMI hotkeys";
> +	peaq_poll_dev->input->phys = "wmi/input0";
> +	peaq_poll_dev->input->id.bustype = BUS_HOST;
> +	input_set_capability(peaq_poll_dev->input, EV_KEY, KEY_SOUND);
> +
> +	return input_register_polled_device(peaq_poll_dev);
> +}
> +
> +static void __exit peaq_wmi_exit(void)
> +{
> +	if (!wmi_has_guid(PEAQ_DOLBY_BUTTON_GUID))
> +		return;
> +
> +	input_unregister_polled_device(peaq_poll_dev);
> +}
> +
> +module_init(peaq_wmi_init);
> +module_exit(peaq_wmi_exit);
> +
> +MODULE_DESCRIPTION("PEAQ 2-in-1 WMI hotkey driver");
> +MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
> +MODULE_LICENSE("GPL");
> -- 
> 2.12.2
> 
> 

-- 
Darren Hart
VMware Open Source Technology Center

[toc] | [prev] | [next] | [standalone]


#1638314

FromDmitry Torokhov <dmitry.torokhov@gmail.com>
Date2017-05-09 19:30 +0200
Message-ID<tFh7r-4OR-13@gated-at.bofh.it>
In reply to#1638244
On Tue, May 09, 2017 at 09:00:55AM -0700, Darren Hart wrote:
> On Tue, May 09, 2017 at 09:54:31AM +0200, Hans de Goede wrote:
> > PEAQ is a new European OEM, I've bought one of their 2-in-1 x86
> > devices, which is actually quite a nice device. Under Windows it has
> > Dolby software for "better" sound and you can select different equalizer
> > presets using a special button.
> > 
> > This WMI interface for this button is not really nice, as it does not do
> > notifies (it really does not I tripple checked), but since I had already
> > figured out the entire WMI interface for this I decided to go the full
> > mile anyways and also implent a WMI based input driver for this using
> > input_polldev since, well, we need to poll.
> > 
> > This commit adds support for this button making it report KEY_SOUND input
> > events. KEY_SOUND is already used in various places to switch sound into
> > theatre mode and things like that so it seems appropriate here.
> > 
> > Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> 
> +Dmitry (in case he wants to add a Reviewed-by, left all context below)

Looks good to me.

Reviewed-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>

> 
> Queued to testing, thanks Hans.
> 
> > ---
> > Changes in v2:
> > -Drop unneeded #include <linux/input.h>
> > -Add and use PEAQ_POLL_IGNORE_MS and PEAQ_POLL_MAX_MS defines
> > -Make globals static
> > -Call input_sync between reporting the button down and up
> > -Ignore events for at least 1 poll after an event even if the user has set
> >  poll_interval > PEAQ_POLL_IGNORE_MS
> > ---
> >  drivers/platform/x86/Kconfig    |  7 +++
> >  drivers/platform/x86/Makefile   |  1 +
> >  drivers/platform/x86/peaq-wmi.c | 97 +++++++++++++++++++++++++++++++++++++++++
> >  3 files changed, 105 insertions(+)
> >  create mode 100644 drivers/platform/x86/peaq-wmi.c
> > 
> > diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
> > index be2ffbd6eb6c..2bac2b2644f9 100644
> > --- a/drivers/platform/x86/Kconfig
> > +++ b/drivers/platform/x86/Kconfig
> > @@ -660,6 +660,13 @@ config MSI_WMI
> >  	 To compile this driver as a module, choose M here: the module will
> >  	 be called msi-wmi.
> >  
> > +config PEAQ_WMI
> > +	tristate "PEAQ 2-in-1 WMI hotkey driver"
> > +	depends on ACPI_WMI
> > +	depends on INPUT
> > +	help
> > +	 Say Y here if you want to support WMI-based hotkeys on PEAQ 2-in-1s.
> > +
> >  config TOPSTAR_LAPTOP
> >  	tristate "Topstar Laptop Extras"
> >  	depends on ACPI
> > diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
> > index de4ffb594ba5..02487f95dd27 100644
> > --- a/drivers/platform/x86/Makefile
> > +++ b/drivers/platform/x86/Makefile
> > @@ -34,6 +34,7 @@ obj-$(CONFIG_PANASONIC_LAPTOP)	+= panasonic-laptop.o
> >  obj-$(CONFIG_INTEL_MENLOW)	+= intel_menlow.o
> >  obj-$(CONFIG_ACPI_WMI)		+= wmi.o
> >  obj-$(CONFIG_MSI_WMI)		+= msi-wmi.o
> > +obj-$(CONFIG_PEAQ_WMI)		+= peaq-wmi.o
> >  obj-$(CONFIG_SURFACE3_WMI)	+= surface3-wmi.o
> >  obj-$(CONFIG_TOPSTAR_LAPTOP)	+= topstar-laptop.o
> >  
> > diff --git a/drivers/platform/x86/peaq-wmi.c b/drivers/platform/x86/peaq-wmi.c
> > new file mode 100644
> > index 000000000000..47b36b2fa895
> > --- /dev/null
> > +++ b/drivers/platform/x86/peaq-wmi.c
> > @@ -0,0 +1,97 @@
> > +/*
> > + * PEAQ 2-in-1 WMI hotkey driver
> > + * Copyright (C) 2017 Hans de Goede <hdegoede@redhat.com>
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License version 2 as
> > + * published by the Free Software Foundation.
> > + */
> > +
> > +#include <linux/acpi.h>
> > +#include <linux/input-polldev.h>
> > +#include <linux/kernel.h>
> > +#include <linux/module.h>
> > +
> > +#define PEAQ_DOLBY_BUTTON_GUID		"ABBC0F6F-8EA1-11D1-00A0-C90629100000"
> > +#define PEAQ_DOLBY_BUTTON_METHOD_ID	5
> > +#define PEAQ_POLL_INTERVAL_MS		250
> > +#define PEAQ_POLL_IGNORE_MS		500
> > +#define PEAQ_POLL_MAX_MS		1000
> > +
> > +MODULE_ALIAS("wmi:"PEAQ_DOLBY_BUTTON_GUID);
> > +
> > +static struct input_polled_dev *peaq_poll_dev;
> > +static unsigned int peaq_ignore_events_counter;
> > +
> > +/*
> > + * The Dolby button (yes really a Dolby button) causes an ACPI variable to get
> > + * set on both press and release. The WMI method checks and clears that flag.
> > + * So for a press + release we will get back One from the WMI method either once
> > + * (if polling after the release) or twice (polling between press and release).
> > + * We ignore events for 0.5s after the first event to avoid reporting 2 presses.
> > + */
> > +static void peaq_wmi_poll(struct input_polled_dev *dev)
> > +{
> > +	union acpi_object obj;
> > +	struct acpi_buffer buffer = { sizeof(obj), &obj };
> > +	acpi_status status;
> > +
> > +	status = wmi_evaluate_method(PEAQ_DOLBY_BUTTON_GUID, 1,
> > +				     PEAQ_DOLBY_BUTTON_METHOD_ID,
> > +				     NULL, &buffer);
> > +	if (ACPI_FAILURE(status))
> > +		return;
> > +
> > +	if (obj.type != ACPI_TYPE_INTEGER) {
> > +		dev_err(&peaq_poll_dev->input->dev,
> > +			"Error WMBC did not return an integer\n");
> > +		return;
> > +	}
> > +
> > +	if (peaq_ignore_events_counter && --peaq_ignore_events_counter > 0)
> > +		return;
> > +
> > +	if (obj.integer.value) {
> > +		input_event(peaq_poll_dev->input, EV_KEY, KEY_SOUND, 1);
> > +		input_sync(peaq_poll_dev->input);
> > +		input_event(peaq_poll_dev->input, EV_KEY, KEY_SOUND, 0);
> > +		input_sync(peaq_poll_dev->input);
> > +		peaq_ignore_events_counter = max(1u,
> > +			PEAQ_POLL_IGNORE_MS / peaq_poll_dev->poll_interval);
> > +	}
> > +}
> > +
> > +static int __init peaq_wmi_init(void)
> > +{
> > +	if (!wmi_has_guid(PEAQ_DOLBY_BUTTON_GUID))
> > +		return -ENODEV;
> > +
> > +	peaq_poll_dev = input_allocate_polled_device();
> > +	if (!peaq_poll_dev)
> > +		return -ENOMEM;
> > +
> > +	peaq_poll_dev->poll = peaq_wmi_poll;
> > +	peaq_poll_dev->poll_interval = PEAQ_POLL_INTERVAL_MS;
> > +	peaq_poll_dev->poll_interval_max = PEAQ_POLL_MAX_MS;
> > +	peaq_poll_dev->input->name = "PEAQ WMI hotkeys";
> > +	peaq_poll_dev->input->phys = "wmi/input0";
> > +	peaq_poll_dev->input->id.bustype = BUS_HOST;
> > +	input_set_capability(peaq_poll_dev->input, EV_KEY, KEY_SOUND);
> > +
> > +	return input_register_polled_device(peaq_poll_dev);
> > +}
> > +
> > +static void __exit peaq_wmi_exit(void)
> > +{
> > +	if (!wmi_has_guid(PEAQ_DOLBY_BUTTON_GUID))
> > +		return;
> > +
> > +	input_unregister_polled_device(peaq_poll_dev);
> > +}
> > +
> > +module_init(peaq_wmi_init);
> > +module_exit(peaq_wmi_exit);
> > +
> > +MODULE_DESCRIPTION("PEAQ 2-in-1 WMI hotkey driver");
> > +MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
> > +MODULE_LICENSE("GPL");
> > -- 
> > 2.12.2
> > 
> > 
> 
> -- 
> Darren Hart
> VMware Open Source Technology Center

-- 
Dmitry

[toc] | [prev] | [next] | [standalone]


#1638341

FromHans de Goede <hdegoede@redhat.com>
Date2017-05-09 20:40 +0200
Message-ID<tFidb-5wm-7@gated-at.bofh.it>
In reply to#1638244
Hi,

On 05/09/2017 06:00 PM, Darren Hart wrote:
> On Tue, May 09, 2017 at 09:54:31AM +0200, Hans de Goede wrote:
>> PEAQ is a new European OEM, I've bought one of their 2-in-1 x86
>> devices, which is actually quite a nice device. Under Windows it has
>> Dolby software for "better" sound and you can select different equalizer
>> presets using a special button.
>>
>> This WMI interface for this button is not really nice, as it does not do
>> notifies (it really does not I tripple checked), but since I had already
>> figured out the entire WMI interface for this I decided to go the full
>> mile anyways and also implent a WMI based input driver for this using
>> input_polldev since, well, we need to poll.
>>
>> This commit adds support for this button making it report KEY_SOUND input
>> events. KEY_SOUND is already used in various places to switch sound into
>> theatre mode and things like that so it seems appropriate here.
>>
>> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
>
> +Dmitry (in case he wants to add a Reviewed-by, left all context below)
>
> Queued to testing, thanks Hans.

I just noticed that this is causing dmesg spew about the driver not
passing enough arguments to the WMBC method (it only consumes 2,
but apparently its signature says it takes 3). So I need to do a v3
fixing this, please drop this from your testing branch for now.

Regards,

Hans



>
>> ---
>> Changes in v2:
>> -Drop unneeded #include <linux/input.h>
>> -Add and use PEAQ_POLL_IGNORE_MS and PEAQ_POLL_MAX_MS defines
>> -Make globals static
>> -Call input_sync between reporting the button down and up
>> -Ignore events for at least 1 poll after an event even if the user has set
>>  poll_interval > PEAQ_POLL_IGNORE_MS
>> ---
>>  drivers/platform/x86/Kconfig    |  7 +++
>>  drivers/platform/x86/Makefile   |  1 +
>>  drivers/platform/x86/peaq-wmi.c | 97 +++++++++++++++++++++++++++++++++++++++++
>>  3 files changed, 105 insertions(+)
>>  create mode 100644 drivers/platform/x86/peaq-wmi.c
>>
>> diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
>> index be2ffbd6eb6c..2bac2b2644f9 100644
>> --- a/drivers/platform/x86/Kconfig
>> +++ b/drivers/platform/x86/Kconfig
>> @@ -660,6 +660,13 @@ config MSI_WMI
>>  	 To compile this driver as a module, choose M here: the module will
>>  	 be called msi-wmi.
>>
>> +config PEAQ_WMI
>> +	tristate "PEAQ 2-in-1 WMI hotkey driver"
>> +	depends on ACPI_WMI
>> +	depends on INPUT
>> +	help
>> +	 Say Y here if you want to support WMI-based hotkeys on PEAQ 2-in-1s.
>> +
>>  config TOPSTAR_LAPTOP
>>  	tristate "Topstar Laptop Extras"
>>  	depends on ACPI
>> diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
>> index de4ffb594ba5..02487f95dd27 100644
>> --- a/drivers/platform/x86/Makefile
>> +++ b/drivers/platform/x86/Makefile
>> @@ -34,6 +34,7 @@ obj-$(CONFIG_PANASONIC_LAPTOP)	+= panasonic-laptop.o
>>  obj-$(CONFIG_INTEL_MENLOW)	+= intel_menlow.o
>>  obj-$(CONFIG_ACPI_WMI)		+= wmi.o
>>  obj-$(CONFIG_MSI_WMI)		+= msi-wmi.o
>> +obj-$(CONFIG_PEAQ_WMI)		+= peaq-wmi.o
>>  obj-$(CONFIG_SURFACE3_WMI)	+= surface3-wmi.o
>>  obj-$(CONFIG_TOPSTAR_LAPTOP)	+= topstar-laptop.o
>>
>> diff --git a/drivers/platform/x86/peaq-wmi.c b/drivers/platform/x86/peaq-wmi.c
>> new file mode 100644
>> index 000000000000..47b36b2fa895
>> --- /dev/null
>> +++ b/drivers/platform/x86/peaq-wmi.c
>> @@ -0,0 +1,97 @@
>> +/*
>> + * PEAQ 2-in-1 WMI hotkey driver
>> + * Copyright (C) 2017 Hans de Goede <hdegoede@redhat.com>
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License version 2 as
>> + * published by the Free Software Foundation.
>> + */
>> +
>> +#include <linux/acpi.h>
>> +#include <linux/input-polldev.h>
>> +#include <linux/kernel.h>
>> +#include <linux/module.h>
>> +
>> +#define PEAQ_DOLBY_BUTTON_GUID		"ABBC0F6F-8EA1-11D1-00A0-C90629100000"
>> +#define PEAQ_DOLBY_BUTTON_METHOD_ID	5
>> +#define PEAQ_POLL_INTERVAL_MS		250
>> +#define PEAQ_POLL_IGNORE_MS		500
>> +#define PEAQ_POLL_MAX_MS		1000
>> +
>> +MODULE_ALIAS("wmi:"PEAQ_DOLBY_BUTTON_GUID);
>> +
>> +static struct input_polled_dev *peaq_poll_dev;
>> +static unsigned int peaq_ignore_events_counter;
>> +
>> +/*
>> + * The Dolby button (yes really a Dolby button) causes an ACPI variable to get
>> + * set on both press and release. The WMI method checks and clears that flag.
>> + * So for a press + release we will get back One from the WMI method either once
>> + * (if polling after the release) or twice (polling between press and release).
>> + * We ignore events for 0.5s after the first event to avoid reporting 2 presses.
>> + */
>> +static void peaq_wmi_poll(struct input_polled_dev *dev)
>> +{
>> +	union acpi_object obj;
>> +	struct acpi_buffer buffer = { sizeof(obj), &obj };
>> +	acpi_status status;
>> +
>> +	status = wmi_evaluate_method(PEAQ_DOLBY_BUTTON_GUID, 1,
>> +				     PEAQ_DOLBY_BUTTON_METHOD_ID,
>> +				     NULL, &buffer);
>> +	if (ACPI_FAILURE(status))
>> +		return;
>> +
>> +	if (obj.type != ACPI_TYPE_INTEGER) {
>> +		dev_err(&peaq_poll_dev->input->dev,
>> +			"Error WMBC did not return an integer\n");
>> +		return;
>> +	}
>> +
>> +	if (peaq_ignore_events_counter && --peaq_ignore_events_counter > 0)
>> +		return;
>> +
>> +	if (obj.integer.value) {
>> +		input_event(peaq_poll_dev->input, EV_KEY, KEY_SOUND, 1);
>> +		input_sync(peaq_poll_dev->input);
>> +		input_event(peaq_poll_dev->input, EV_KEY, KEY_SOUND, 0);
>> +		input_sync(peaq_poll_dev->input);
>> +		peaq_ignore_events_counter = max(1u,
>> +			PEAQ_POLL_IGNORE_MS / peaq_poll_dev->poll_interval);
>> +	}
>> +}
>> +
>> +static int __init peaq_wmi_init(void)
>> +{
>> +	if (!wmi_has_guid(PEAQ_DOLBY_BUTTON_GUID))
>> +		return -ENODEV;
>> +
>> +	peaq_poll_dev = input_allocate_polled_device();
>> +	if (!peaq_poll_dev)
>> +		return -ENOMEM;
>> +
>> +	peaq_poll_dev->poll = peaq_wmi_poll;
>> +	peaq_poll_dev->poll_interval = PEAQ_POLL_INTERVAL_MS;
>> +	peaq_poll_dev->poll_interval_max = PEAQ_POLL_MAX_MS;
>> +	peaq_poll_dev->input->name = "PEAQ WMI hotkeys";
>> +	peaq_poll_dev->input->phys = "wmi/input0";
>> +	peaq_poll_dev->input->id.bustype = BUS_HOST;
>> +	input_set_capability(peaq_poll_dev->input, EV_KEY, KEY_SOUND);
>> +
>> +	return input_register_polled_device(peaq_poll_dev);
>> +}
>> +
>> +static void __exit peaq_wmi_exit(void)
>> +{
>> +	if (!wmi_has_guid(PEAQ_DOLBY_BUTTON_GUID))
>> +		return;
>> +
>> +	input_unregister_polled_device(peaq_poll_dev);
>> +}
>> +
>> +module_init(peaq_wmi_init);
>> +module_exit(peaq_wmi_exit);
>> +
>> +MODULE_DESCRIPTION("PEAQ 2-in-1 WMI hotkey driver");
>> +MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
>> +MODULE_LICENSE("GPL");
>> --
>> 2.12.2
>>
>>
>

[toc] | [prev] | [next] | [standalone]


#1638409

FromDarren Hart <dvhart@infradead.org>
Date2017-05-09 23:30 +0200
Message-ID<tFkRI-7nu-5@gated-at.bofh.it>
In reply to#1638341
On Tue, May 09, 2017 at 08:33:13PM +0200, Hans de Goede wrote:
> Hi,
> 
> On 05/09/2017 06:00 PM, Darren Hart wrote:
> > On Tue, May 09, 2017 at 09:54:31AM +0200, Hans de Goede wrote:
> > > PEAQ is a new European OEM, I've bought one of their 2-in-1 x86
> > > devices, which is actually quite a nice device. Under Windows it has
> > > Dolby software for "better" sound and you can select different equalizer
> > > presets using a special button.
> > > 
> > > This WMI interface for this button is not really nice, as it does not do
> > > notifies (it really does not I tripple checked), but since I had already
> > > figured out the entire WMI interface for this I decided to go the full
> > > mile anyways and also implent a WMI based input driver for this using
> > > input_polldev since, well, we need to poll.
> > > 
> > > This commit adds support for this button making it report KEY_SOUND input
> > > events. KEY_SOUND is already used in various places to switch sound into
> > > theatre mode and things like that so it seems appropriate here.
> > > 
> > > Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> > 
> > +Dmitry (in case he wants to add a Reviewed-by, left all context below)
> > 
> > Queued to testing, thanks Hans.
> 
> I just noticed that this is causing dmesg spew about the driver not
> passing enough arguments to the WMBC method (it only consumes 2,
> but apparently its signature says it takes 3). So I need to do a v3
> fixing this, please drop this from your testing branch for now.

Done.
-- 
Darren Hart
VMware Open Source Technology Center

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web