From patchwork Wed Feb 9 18:17:55 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [3/3] UBUNTU: SAUCE: Dell WMI: Use sparse keymaps and tidy up code. Date: Wed, 09 Feb 2011 08:17:55 -0000 From: Colin King X-Patchwork-Id: 82510 Message-Id: <1297275475-31429-4-git-send-email-colin.king@canonical.com> To: kernel-team@lists.ubuntu.com From: Colin Ian King The original implementaion failed to use spare keymaps which resulted in quite a bit of unwanted bloat. Use spare keymaps and tidy up the code. BugLink: http://bugs.launchpad.net/bugs/701530 Signed-off-by: Colin Ian King Acked-by: Brad Figg --- drivers/platform/x86/dell-wmi-aio.c | 132 ++++++----------------------------- 1 files changed, 22 insertions(+), 110 deletions(-) diff --git a/drivers/platform/x86/dell-wmi-aio.c b/drivers/platform/x86/dell-wmi-aio.c index e770cb3..755c6d2 100644 --- a/drivers/platform/x86/dell-wmi-aio.c +++ b/drivers/platform/x86/dell-wmi-aio.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -46,99 +47,14 @@ MODULE_ALIAS("dmi:*:*Dell*:*:"); MODULE_ALIAS("wmi:"EVENT_GUID1); MODULE_ALIAS("wmi:"EVENT_GUID2); -struct key_entry { - char type; /* See KE_* below */ - u16 code; - u16 keycode; -}; - -enum { KE_KEY, KE_SW, KE_IGNORE, KE_END }; - -/* - * Certain keys are flagged as KE_IGNORE. All of these are either - * notifications (rather than requests for change) or are also sent - * via the keyboard controller so should not be sent again. - */ - static struct key_entry dell_wmi_aio_keymap[] = { - { KE_KEY, 0xc0, KEY_VOLUMEUP }, - { KE_KEY, 0xc1, KEY_VOLUMEDOWN }, + { KE_KEY, 0xc0, { KEY_VOLUMEUP } }, + { KE_KEY, 0xc1, { KEY_VOLUMEDOWN } }, { KE_END, 0 } }; static struct input_dev *dell_wmi_aio_input_dev; -static struct key_entry *dell_wmi_aio_get_entry_by_scancode(int code) -{ - struct key_entry *key; - - for (key = dell_wmi_aio_keymap; key->type != KE_END; key++) - if (code == key->code) - return key; - - return NULL; -} - -static struct key_entry *dell_wmi_aio_get_entry_by_keycode(int keycode) -{ - struct key_entry *key; - - for (key = dell_wmi_aio_keymap; key->type != KE_END; key++) - if (key->type == KE_KEY && keycode == key->keycode) - return key; - - return NULL; -} - -static int dell_wmi_aio_getkeycode(struct input_dev *dev, int scancode, - int *keycode) -{ - struct key_entry *key = dell_wmi_aio_get_entry_by_scancode(scancode); - - if (key && key->type == KE_KEY) { - *keycode = key->keycode; - return 0; - } - - return -EINVAL; -} - -static int dell_wmi_aio_setkeycode(struct input_dev *dev, int scancode, - int keycode) -{ - struct key_entry *key; - int old_keycode; - - if (keycode < 0 || keycode > KEY_MAX) - return -EINVAL; - - key = dell_wmi_aio_get_entry_by_scancode(scancode); - if (key && key->type == KE_KEY) { - old_keycode = key->keycode; - key->keycode = keycode; - set_bit(keycode, dev->keybit); - if (!dell_wmi_aio_get_entry_by_keycode(old_keycode)) - clear_bit(old_keycode, dev->keybit); - return 0; - } - 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\n", - scancode); -} - static void dell_wmi_aio_notify(u32 value, void *context) { struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL }; @@ -159,13 +75,16 @@ static void dell_wmi_aio_notify(u32 value, void *context) case ACPI_TYPE_INTEGER: /* Most All-In-One correctly return integer scancode */ scancode = obj->integer.value; - dell_wmi_aio_handle_key(scancode); + sparse_keymap_report_event(dell_wmi_aio_input_dev, + scancode, 1, true); 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); + sparse_keymap_report_event( + dell_wmi_aio_input_dev, + scancode, 1, true); } break; } @@ -175,7 +94,6 @@ static void dell_wmi_aio_notify(u32 value, void *context) static int __init dell_wmi_aio_input_setup(void) { - struct key_entry *key; int err; dell_wmi_aio_input_dev = input_allocate_device(); @@ -186,30 +104,25 @@ static int __init dell_wmi_aio_input_setup(void) dell_wmi_aio_input_dev->name = "Dell AIO WMI hotkeys"; dell_wmi_aio_input_dev->phys = "wmi/input0"; dell_wmi_aio_input_dev->id.bustype = BUS_HOST; - dell_wmi_aio_input_dev->getkeycode = dell_wmi_aio_getkeycode; - dell_wmi_aio_input_dev->setkeycode = dell_wmi_aio_setkeycode; - for (key = dell_wmi_aio_keymap; key->type != KE_END; key++) { - switch (key->type) { - case KE_KEY: - set_bit(EV_KEY, dell_wmi_aio_input_dev->evbit); - set_bit(key->keycode, dell_wmi_aio_input_dev->keybit); - break; - case KE_SW: - set_bit(EV_SW, dell_wmi_aio_input_dev->evbit); - set_bit(key->keycode, dell_wmi_aio_input_dev->swbit); - break; - } + err = sparse_keymap_setup(dell_wmi_aio_input_dev, + dell_wmi_aio_keymap, NULL); + if (err) { + pr_err("Unable to setup input device keymap\n"); + goto err_free_dev; } - err = input_register_device(dell_wmi_aio_input_dev); - if (err) { - input_free_device(dell_wmi_aio_input_dev); - return err; + pr_info("Unable to register input device\n"); + goto err_free_keymap; } - return 0; + +err_free_keymap: + sparse_keymap_free(dell_wmi_aio_input_dev); +err_free_dev: + input_free_device(dell_wmi_aio_input_dev); + return err; } static char *dell_wmi_aio_find(void) @@ -236,14 +149,13 @@ static int __init dell_wmi_aio_init(void) return err; err = wmi_install_notify_handler(guid, - dell_wmi_aio_notify, NULL); + dell_wmi_aio_notify, NULL); if (err) { input_unregister_device(dell_wmi_aio_input_dev); pr_err(AIO_PREFIX "Unable to register" " notify handler - %d\n", err); return err; } - } else pr_warning(AIO_PREFIX "No known WMI GUID found\n");