linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] platform/x86: peaq-wmi: Add new peaq-wmi driver
@ 2017-05-08 19:56 Hans de Goede
  2017-05-08 21:04 ` Darren Hart
  0 siblings, 1 reply; 5+ messages in thread
From: Hans de Goede @ 2017-05-08 19:56 UTC (permalink / raw)
  To: Darren Hart, Andy Shevchenko
  Cc: Hans de Goede, platform-driver-x86, linux-kernel

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>
---
 drivers/platform/x86/Kconfig    |  7 +++
 drivers/platform/x86/Makefile   |  1 +
 drivers/platform/x86/peaq-wmi.c | 94 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 102 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..8cd6b962ce5e
--- /dev/null
+++ b/drivers/platform/x86/peaq-wmi.c
@@ -0,0 +1,94 @@
+/*
+ * 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.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
+
+MODULE_ALIAS("wmi:"PEAQ_DOLBY_BUTTON_GUID);
+
+struct input_polled_dev *peaq_poll_dev;
+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_event(peaq_poll_dev->input, EV_KEY, KEY_SOUND, 0);
+		input_sync(peaq_poll_dev->input);
+		peaq_ignore_events_counter = 500 / 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 = 1000; /* 1 second */
+	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

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH] platform/x86: peaq-wmi: Add new peaq-wmi driver
  2017-05-08 19:56 [PATCH] platform/x86: peaq-wmi: Add new peaq-wmi driver Hans de Goede
@ 2017-05-08 21:04 ` Darren Hart
  2017-05-08 21:34   ` Dmitry Torokhov
  2017-05-09  6:42   ` Hans de Goede
  0 siblings, 2 replies; 5+ messages in thread
From: Darren Hart @ 2017-05-08 21:04 UTC (permalink / raw)
  To: Hans de Goede, Dmitry Torokhov
  Cc: Andy Shevchenko, platform-driver-x86, linux-kernel

On Mon, May 08, 2017 at 09:56:31PM +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>

Thanks Hans,

A couple nits below, otherwise, looks good to me.

+Dmitry in case he cares to weigh in on input/input-polldev usage

> ---
>  drivers/platform/x86/Kconfig    |  7 +++
>  drivers/platform/x86/Makefile   |  1 +
>  drivers/platform/x86/peaq-wmi.c | 94 +++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 102 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..8cd6b962ce5e
> --- /dev/null
> +++ b/drivers/platform/x86/peaq-wmi.c
> @@ -0,0 +1,94 @@
> +/*
> + * 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.h>

input-polldev includes input, no need for both.

> +#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
> +
> +MODULE_ALIAS("wmi:"PEAQ_DOLBY_BUTTON_GUID);
> +
> +struct input_polled_dev *peaq_poll_dev;
> +int peaq_ignore_events_counter;

Please make local globals static if they are needed.

Once we make WMI a bus with devices, we should be able to clean this up with
devm.

> +
> +/*
> + * 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_event(peaq_poll_dev->input, EV_KEY, KEY_SOUND, 0);
> +		input_sync(peaq_poll_dev->input);
> +		peaq_ignore_events_counter = 500 / peaq_poll_dev->poll_interval;

Might as well define 500 above with the interval and keep these parameters
together, keep the units obvious, etc. e.g.

#define PEAQ_POLL_IGNORE_MS 500

Or similar

> +	}
> +}
> +
> +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 = 1000; /* 1 second */
> +	peaq_poll_dev->input->name = "PEAQ WMI hotkeys";

Are there additional keys/buttons?

> +	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

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] platform/x86: peaq-wmi: Add new peaq-wmi driver
  2017-05-08 21:04 ` Darren Hart
@ 2017-05-08 21:34   ` Dmitry Torokhov
  2017-05-09  6:42   ` Hans de Goede
  1 sibling, 0 replies; 5+ messages in thread
From: Dmitry Torokhov @ 2017-05-08 21:34 UTC (permalink / raw)
  To: Darren Hart
  Cc: Hans de Goede, Andy Shevchenko, platform-driver-x86, linux-kernel

On Mon, May 08, 2017 at 02:04:41PM -0700, Darren Hart wrote:
> On Mon, May 08, 2017 at 09:56:31PM +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>
> 
> Thanks Hans,
> 
> A couple nits below, otherwise, looks good to me.
> 
> +Dmitry in case he cares to weigh in on input/input-polldev usage
> 
> > ---
> >  drivers/platform/x86/Kconfig    |  7 +++
> >  drivers/platform/x86/Makefile   |  1 +
> >  drivers/platform/x86/peaq-wmi.c | 94 +++++++++++++++++++++++++++++++++++++++++
> >  3 files changed, 102 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..8cd6b962ce5e
> > --- /dev/null
> > +++ b/drivers/platform/x86/peaq-wmi.c
> > @@ -0,0 +1,94 @@
> > +/*
> > + * 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.h>
> 
> input-polldev includes input, no need for both.
> 
> > +#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
> > +
> > +MODULE_ALIAS("wmi:"PEAQ_DOLBY_BUTTON_GUID);
> > +
> > +struct input_polled_dev *peaq_poll_dev;
> > +int peaq_ignore_events_counter;
> 
> Please make local globals static if they are needed.
> 
> Once we make WMI a bus with devices, we should be able to clean this up with
> devm.
> 
> > +
> > +/*
> > + * 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() here as well please.

> > +		input_event(peaq_poll_dev->input, EV_KEY, KEY_SOUND, 0);
> > +		input_sync(peaq_poll_dev->input);
> > +		peaq_ignore_events_counter = 500 / peaq_poll_dev->poll_interval;
> 
> Might as well define 500 above with the interval and keep these parameters
> together, keep the units obvious, etc. e.g.
> 
> #define PEAQ_POLL_IGNORE_MS 500
> 
> Or similar
> 
> > +	}
> > +}
> > +
> > +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 = 1000; /* 1 second */
> > +	peaq_poll_dev->input->name = "PEAQ WMI hotkeys";
> 
> Are there additional keys/buttons?
> 
> > +	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

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] platform/x86: peaq-wmi: Add new peaq-wmi driver
  2017-05-08 21:04 ` Darren Hart
  2017-05-08 21:34   ` Dmitry Torokhov
@ 2017-05-09  6:42   ` Hans de Goede
  2017-05-09 14:32     ` Darren Hart
  1 sibling, 1 reply; 5+ messages in thread
From: Hans de Goede @ 2017-05-09  6:42 UTC (permalink / raw)
  To: Darren Hart, Dmitry Torokhov
  Cc: Andy Shevchenko, platform-driver-x86, linux-kernel

Hi,

Darren, Dmitry, thank you for the review.

On 08-05-17 23:04, Darren Hart wrote:
> On Mon, May 08, 2017 at 09:56:31PM +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>
> 
> Thanks Hans,
> 
> A couple nits below, otherwise, looks good to me.
> 
> +Dmitry in case he cares to weigh in on input/input-polldev usage
> 
>> ---
>>   drivers/platform/x86/Kconfig    |  7 +++
>>   drivers/platform/x86/Makefile   |  1 +
>>   drivers/platform/x86/peaq-wmi.c | 94 +++++++++++++++++++++++++++++++++++++++++
>>   3 files changed, 102 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..8cd6b962ce5e
>> --- /dev/null
>> +++ b/drivers/platform/x86/peaq-wmi.c
>> @@ -0,0 +1,94 @@
>> +/*
>> + * 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.h>
> 
> input-polldev includes input, no need for both.
> 
>> +#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
>> +
>> +MODULE_ALIAS("wmi:"PEAQ_DOLBY_BUTTON_GUID);
>> +
>> +struct input_polled_dev *peaq_poll_dev;
>> +int peaq_ignore_events_counter;
> 
> Please make local globals static if they are needed.
> 
> Once we make WMI a bus with devices, we should be able to clean this up with
> devm.
> 
>> +
>> +/*
>> + * 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_event(peaq_poll_dev->input, EV_KEY, KEY_SOUND, 0);
>> +		input_sync(peaq_poll_dev->input);
>> +		peaq_ignore_events_counter = 500 / peaq_poll_dev->poll_interval;
> 
> Might as well define 500 above with the interval and keep these parameters
> together, keep the units obvious, etc. e.g.
> 
> #define PEAQ_POLL_IGNORE_MS 500
> 
> Or similar
> 
>> +	}
>> +}
>> +
>> +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 = 1000; /* 1 second */
>> +	peaq_poll_dev->input->name = "PEAQ WMI hotkeys";
> 
> Are there additional keys/buttons?

Not through the WMI interface on this model, I decided on the
"PEAQ WMI hotkeys" name rather then say "PEAQ Dolby button"
as future proofing (this gets exported to userspace so
we should not change it in the future) in case this driver
ends up delivering events for more special buttons on
PEAQ devices.

As for all the other remarks from both you and Dmitry I agree
with all of them and I will send a v2 addressing them all.

Regards,

Hans


> 
>> +	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
>>
>>
> 

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] platform/x86: peaq-wmi: Add new peaq-wmi driver
  2017-05-09  6:42   ` Hans de Goede
@ 2017-05-09 14:32     ` Darren Hart
  0 siblings, 0 replies; 5+ messages in thread
From: Darren Hart @ 2017-05-09 14:32 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Dmitry Torokhov, Andy Shevchenko, platform-driver-x86, linux-kernel

On Tue, May 09, 2017 at 08:42:21AM +0200, Hans de Goede wrote:
> On 08-05-17 23:04, Darren Hart wrote:
> > On Mon, May 08, 2017 at 09:56:31PM +0200, Hans de Goede wrote:

> > > +	peaq_poll_dev->input->name = "PEAQ WMI hotkeys";
> > 
> > Are there additional keys/buttons?
> 
> Not through the WMI interface on this model, I decided on the
> "PEAQ WMI hotkeys" name rather then say "PEAQ Dolby button"
> as future proofing (this gets exported to userspace so
> we should not change it in the future) in case this driver
> ends up delivering events for more special buttons on
> PEAQ devices.
> 
> As for all the other remarks from both you and Dmitry I agree
> with all of them and I will send a v2 addressing them all.
> 

Sounds good, thanks Hans.

-- 
Darren Hart
VMware Open Source Technology Center

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2017-05-09 14:32 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-05-08 19:56 [PATCH] platform/x86: peaq-wmi: Add new peaq-wmi driver Hans de Goede
2017-05-08 21:04 ` Darren Hart
2017-05-08 21:34   ` Dmitry Torokhov
2017-05-09  6:42   ` Hans de Goede
2017-05-09 14:32     ` Darren Hart

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).