FAQ Search Today's Posts Mark Forums Read
» Video Reviews

» Linux Archive

Linux-archive is a website aiming to archive linux email lists and to make them easily accessible for linux users/developers.


» Sponsor

» Partners

» Sponsor

Go Back   Linux Archive > Ubuntu > Ubuntu Kernel Team

 
 
LinkBack Thread Tools
 
Old 01-11-2011, 10:08 PM
Brad Figg
 
Default UBUNTU: SAUCE: Add WMI hotkeys support for another Dell All-In-One series

On 01/11/2011 10:42 AM, Colin King wrote:

From: Colin Ian King<colin.king@canonical.com>

Enable WMI hotkeys on event GUID 02314822-307C-4F66-bf0E-48AEAEB26CC8. This
enables the volume up and down keys. This Dell All-In-One enablement also works
around an implementation bug where the _WED method should return an integer
containing the key code and in fact the method returns the key code in element
zero of a buffer.

BugLink: http://bugs.launchpad.net/bugs/701530

Signed-off-by: Colin Ian King<colin.king@canonical.com>
---
drivers/platform/x86/dell-wmi-aio.c | 84 +++++++++++++++++++++++++---------
1 files changed, 62 insertions(+), 22 deletions(-)

diff --git a/drivers/platform/x86/dell-wmi-aio.c b/drivers/platform/x86/dell-wmi-aio.c
index c693473..e770cb3 100644
--- a/drivers/platform/x86/dell-wmi-aio.c
+++ b/drivers/platform/x86/dell-wmi-aio.c
@@ -30,14 +30,22 @@
MODULE_DESCRIPTION("WMI hotkeys driver for Dell All-In-One series");
MODULE_LICENSE("GPL");

-#define EVENT_GUID "284A0E6B-380E-472A-921F-E52786257FB4"
+#define EVENT_GUID1 "284A0E6B-380E-472A-921F-E52786257FB4"
+#define EVENT_GUID2 "02314822-307C-4F66-bf0E-48AEAEB26CC8"

-MODULE_ALIAS("wmi:"EVENT_GUID);
+static char *dell_wmi_aio_guids[] = {
+ EVENT_GUID1,
+ EVENT_GUID2,
+ NULL
+};

/* Temporary workaround until the WMI sysfs interface goes in.
Borrowed from acer-wmi */
MODULE_ALIAS("dmi:*:*Dell*:*:");

+MODULE_ALIAS("wmi:"EVENT_GUID1);
+MODULE_ALIAS("wmi:"EVENT_GUID2);
+
struct key_entry {
char type; /* See KE_* below */
u16 code;
@@ -116,10 +124,24 @@ static int dell_wmi_aio_setkeycode(struct input_dev *dev, int scancode,
return -EINVAL;
}

+static void dell_wmi_aio_handle_key(unsigned int scancode)
+{
+ static struct key_entry *key;
+
+ key = dell_wmi_aio_get_entry_by_scancode(scancode);
+ if (key) {
+ input_report_key(dell_wmi_aio_input_dev, key->keycode, 1);
+ input_sync(dell_wmi_aio_input_dev);
+ input_report_key(dell_wmi_aio_input_dev, key->keycode, 0);
+ input_sync(dell_wmi_aio_input_dev);
+ } else if (scancode)
+ pr_info(AIO_PREFIX "Unknown key %x pressed
",
+ scancode);
+}
+
static void dell_wmi_aio_notify(u32 value, void *context)
{
struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL };
- static struct key_entry *key;
union acpi_object *obj;
acpi_status status;

@@ -130,21 +152,23 @@ static void dell_wmi_aio_notify(u32 value, void *context)
}

obj = (union acpi_object *)response.pointer;
-
- if (obj&& obj->type == ACPI_TYPE_INTEGER) {
- int scancode = obj->integer.value;
-
- key = dell_wmi_aio_get_entry_by_scancode(scancode);
- if (key) {
- input_report_key(dell_wmi_aio_input_dev,
- key->keycode, 1);
- input_sync(dell_wmi_aio_input_dev);
- input_report_key(dell_wmi_aio_input_dev,
- key->keycode, 0);
- input_sync(dell_wmi_aio_input_dev);
- } else if (scancode)
- pr_info(AIO_PREFIX "Unknown key %x pressed
",
- scancode);
+ if (obj) {
+ unsigned int scancode;
+
+ switch (obj->type) {
+ case ACPI_TYPE_INTEGER:
+ /* Most All-In-One correctly return integer scancode */
+ scancode = obj->integer.value;
+ dell_wmi_aio_handle_key(scancode);
+ break;
+ case ACPI_TYPE_BUFFER:
+ /* Broken machines return the scancode in a buffer */
+ if (obj->buffer.pointer&& obj->buffer.length> 0) {
+ scancode = obj->buffer.pointer[0];
+ dell_wmi_aio_handle_key(scancode);
+ }
+ break;
+ }
}
kfree(obj);
}
@@ -188,17 +212,30 @@ static int __init dell_wmi_aio_input_setup(void)
return 0;
}

+static char *dell_wmi_aio_find(void)
+{
+ int i;
+
+ for (i = 0; dell_wmi_aio_guids[i] != NULL; i++)
+ if (wmi_has_guid(dell_wmi_aio_guids[i]))
+ return dell_wmi_aio_guids[i];
+
+ return NULL;
+}
+
static int __init dell_wmi_aio_init(void)
{
int err;
+ char *guid;

- if (wmi_has_guid(EVENT_GUID)) {
+ guid = dell_wmi_aio_find();
+ if (guid) {
err = dell_wmi_aio_input_setup();

if (err)
return err;

- err = wmi_install_notify_handler(EVENT_GUID,
+ err = wmi_install_notify_handler(guid,
dell_wmi_aio_notify, NULL);
if (err) {
input_unregister_device(dell_wmi_aio_input_dev);
@@ -215,8 +252,11 @@ static int __init dell_wmi_aio_init(void)

static void __exit dell_wmi_aio_exit(void)
{
- if (wmi_has_guid(EVENT_GUID)) {
- wmi_remove_notify_handler(EVENT_GUID);
+ char *guid;
+
+ guid = dell_wmi_aio_find();
+ if (guid) {
+ wmi_remove_notify_handler(guid);
input_unregister_device(dell_wmi_aio_input_dev);
}
}


Acked-by: Brad Figg<brad.figg@canonical.com>

--
Brad Figg brad.figg@canonical.com http://www.canonical.com

--
kernel-team mailing list
kernel-team@lists.ubuntu.com
https://lists.ubuntu.com/mailman/listinfo/kernel-team
 

Thread Tools




All times are GMT. The time now is 07:01 AM.

VBulletin, Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO ©2007, Crawlability, Inc.
Copyright 2007 - 2008, www.linux-archive.org