-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
platform/x86: peaq-wmi: Add new peaq-wmi driver
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 triple checked), but since I had already figured out the entire WMI interface for this I decided to go the full mile anyway and implement 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> Reviewed-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> [dvhart: minor declaration ordering and commit log typo fixes] Signed-off-by: Darren Hart (VMware) <dvhart@infradead.org>
- Loading branch information
Hans de Goede
authored and
Andy Shevchenko
committed
May 15, 2017
1 parent
9b4bbbd
commit 13bb0fd
Showing
3 changed files
with
108 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
/* | ||
* 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 unsigned int peaq_ignore_events_counter; | ||
static struct input_polled_dev *peaq_poll_dev; | ||
|
||
/* | ||
* 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; | ||
acpi_status status; | ||
u32 dummy = 0; | ||
|
||
struct acpi_buffer input = { sizeof(dummy), &dummy }; | ||
struct acpi_buffer output = { sizeof(obj), &obj }; | ||
|
||
status = wmi_evaluate_method(PEAQ_DOLBY_BUTTON_GUID, 1, | ||
PEAQ_DOLBY_BUTTON_METHOD_ID, | ||
&input, &output); | ||
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"); |