From patchwork Fri Dec 4 06:12:03 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Torokhov X-Patchwork-Id: 64777 Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id nB46C4Ik003814 for ; Fri, 4 Dec 2009 06:12:08 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751099AbZLDGMA (ORCPT ); Fri, 4 Dec 2009 01:12:00 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1751642AbZLDGMA (ORCPT ); Fri, 4 Dec 2009 01:12:00 -0500 Received: from mail-yw0-f182.google.com ([209.85.211.182]:58439 "EHLO mail-yw0-f182.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751099AbZLDGL7 (ORCPT ); Fri, 4 Dec 2009 01:11:59 -0500 Received: by mail-yw0-f182.google.com with SMTP id 12so2283458ywh.21 for ; Thu, 03 Dec 2009 22:12:06 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:from:subject:to:cc:date :message-id:in-reply-to:references:user-agent:mime-version :content-type:content-transfer-encoding; bh=b3L5RUf/6vRSw8fIn+mWAMoITcJ5pdV8VYFY9h+X/rA=; b=SNz+KNcVe8UCzdbndeojV00bt1XtcWkYu8ZN7GeqZAKgPHe4GrHlb/opMYPwtD3tmz JtJpkvUjC5B5ZPl6PfBJM3JnNa5uJCi6QxQFfj5VLtWR/80yCVV/77UNY3ckUn59xObe 2OSDGN+YL057T3GyCwkuj8g9xScIQfzrAHPSA= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=from:subject:to:cc:date:message-id:in-reply-to:references :user-agent:mime-version:content-type:content-transfer-encoding; b=adFsTjS3hV+Hu1GiKI/56GR2iNwIrMDA8Q0tPrXl6li1EY9VmhluXHbgt5nUKArjx2 sioYaJF/k17nwA3QMuTGJkUGM/+BAOWHbGwbMkZVYtfyL3AjlM0S6Su6H3pRA/97AvLh hV3SRQc4Y4/UaCjSfjrdZWv30TtAQUk6Dgc9s= Received: by 10.150.44.24 with SMTP id r24mr4628329ybr.249.1259907126194; Thu, 03 Dec 2009 22:12:06 -0800 (PST) Received: from mailhub.coreip.homeip.net (c-24-6-153-137.hsd1.ca.comcast.net [24.6.153.137]) by mx.google.com with ESMTPS id 9sm1102825ywf.20.2009.12.03.22.12.05 (version=TLSv1/SSLv3 cipher=RC4-MD5); Thu, 03 Dec 2009 22:12:05 -0800 (PST) From: Dmitry Torokhov Subject: [PATCH 2/9] Input: wistron_btns - switch to using sparse keymap library To: linux-input@vger.kernel.org, Len Brown Cc: linux-acpi@vger.kernel.org, Herton Ronaldo Krzesinski , Harald Welte , Corentin Chary , Carlos Corbacho , Wu Zhangjin , Anisse Astier Date: Thu, 03 Dec 2009 22:12:03 -0800 Message-ID: <20091204061203.28288.68062.stgit@localhost.localdomain> In-Reply-To: <20091204060701.28288.91430.stgit@localhost.localdomain> References: <20091204060701.28288.91430.stgit@localhost.localdomain> User-Agent: StGIT/0.14.3 MIME-Version: 1.0 Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index a9bb254..d25ecbb 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig @@ -80,6 +80,7 @@ config INPUT_WISTRON_BTNS tristate "x86 Wistron laptop button interface" depends on X86 && !X86_64 select INPUT_POLLDEV + select INPUT_SPARSEKMAP select NEW_LEDS select LEDS_CLASS select CHECK_SIGNATURE diff --git a/drivers/input/misc/wistron_btns.c b/drivers/input/misc/wistron_btns.c index 00eb9d6..b70c066 100644 --- a/drivers/input/misc/wistron_btns.c +++ b/drivers/input/misc/wistron_btns.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -224,19 +225,8 @@ static void bios_set_state(u8 subsys, int enable) /* Hardware database */ -struct key_entry { - char type; /* See KE_* below */ - u8 code; - union { - u16 keycode; /* For KE_KEY */ - struct { /* For KE_SW */ - u8 code; - u8 value; - } sw; - }; -}; - -enum { KE_END, KE_KEY, KE_SW, KE_WIFI, KE_BLUETOOTH }; +#define KE_WIFI (KE_LAST + 1) +#define KE_BLUETOOTH (KE_LAST + 2) #define FE_MAIL_LED 0x01 #define FE_WIFI_LED 0x02 @@ -1037,21 +1027,6 @@ static unsigned long jiffies_last_press; static bool wifi_enabled; static bool bluetooth_enabled; -static void report_key(struct input_dev *dev, unsigned int keycode) -{ - input_report_key(dev, keycode, 1); - input_sync(dev); - input_report_key(dev, keycode, 0); - input_sync(dev); -} - -static void report_switch(struct input_dev *dev, unsigned int code, int value) -{ - input_report_switch(dev, code, value); - input_sync(dev); -} - - /* led management */ static void wistron_mail_led_set(struct led_classdev *led_cdev, enum led_brightness value) @@ -1128,43 +1103,13 @@ static inline void wistron_led_resume(void) led_classdev_resume(&wistron_wifi_led); } -static struct key_entry *wistron_get_entry_by_scancode(int code) -{ - struct key_entry *key; - - for (key = keymap; key->type != KE_END; key++) - if (code == key->code) - return key; - - return NULL; -} - -static struct key_entry *wistron_get_entry_by_keycode(int keycode) -{ - struct key_entry *key; - - for (key = keymap; key->type != KE_END; key++) - if (key->type == KE_KEY && keycode == key->keycode) - return key; - - return NULL; -} - static void handle_key(u8 code) { - const struct key_entry *key = wistron_get_entry_by_scancode(code); + const struct key_entry *key = + sparse_keymap_entry_from_scancode(wistron_idev->input, code); if (key) { switch (key->type) { - case KE_KEY: - report_key(wistron_idev->input, key->keycode); - break; - - case KE_SW: - report_switch(wistron_idev->input, - key->sw.code, key->sw.value); - break; - case KE_WIFI: if (have_wifi) { wifi_enabled = !wifi_enabled; @@ -1180,7 +1125,9 @@ static void handle_key(u8 code) break; default: - BUG(); + sparse_keymap_report_entry(wistron_idev->input, + key, 1, true); + break; } jiffies_last_press = jiffies; } else @@ -1220,42 +1167,39 @@ static void wistron_poll(struct input_polled_dev *dev) dev->poll_interval = POLL_INTERVAL_DEFAULT; } -static int wistron_getkeycode(struct input_dev *dev, int scancode, int *keycode) +static int __devinit wistron_setup_keymap(struct input_dev *dev, + struct key_entry *entry) { - const struct key_entry *key = wistron_get_entry_by_scancode(scancode); + switch (entry->type) { - if (key && key->type == KE_KEY) { - *keycode = key->keycode; - return 0; - } - - return -EINVAL; -} + /* if wifi or bluetooth are not available, create normal keys */ + case KE_WIFI: + if (!have_wifi) { + entry->type = KE_KEY; + entry->keycode = KEY_WLAN; + } + break; -static int wistron_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 = wistron_get_entry_by_scancode(scancode); - if (key && key->type == KE_KEY) { - old_keycode = key->keycode; - key->keycode = keycode; - set_bit(keycode, dev->keybit); - if (!wistron_get_entry_by_keycode(old_keycode)) - clear_bit(old_keycode, dev->keybit); - return 0; + case KE_BLUETOOTH: + if (!have_bluetooth) { + entry->type = KE_KEY; + entry->keycode = KEY_BLUETOOTH; + } + break; + + case KE_END: + if (entry->code & FE_UNTESTED) + printk(KERN_WARNING "Untested laptop multimedia keys, " + "please report success or failure to " + "eric.piel@tremplin-utc.net\n"); + break; } - return -EINVAL; + return 0; } static int __devinit setup_input_dev(void) { - struct key_entry *key; struct input_dev *input_dev; int error; @@ -1273,56 +1217,21 @@ static int __devinit setup_input_dev(void) input_dev->id.bustype = BUS_HOST; input_dev->dev.parent = &wistron_device->dev; - input_dev->getkeycode = wistron_getkeycode; - input_dev->setkeycode = wistron_setkeycode; - - for (key = keymap; key->type != KE_END; key++) { - switch (key->type) { - case KE_KEY: - set_bit(EV_KEY, input_dev->evbit); - set_bit(key->keycode, input_dev->keybit); - break; - - case KE_SW: - set_bit(EV_SW, input_dev->evbit); - set_bit(key->sw.code, input_dev->swbit); - break; - - /* if wifi or bluetooth are not available, create normal keys */ - case KE_WIFI: - if (!have_wifi) { - key->type = KE_KEY; - key->keycode = KEY_WLAN; - key--; - } - break; - - case KE_BLUETOOTH: - if (!have_bluetooth) { - key->type = KE_KEY; - key->keycode = KEY_BLUETOOTH; - key--; - } - break; - - default: - break; - } - } - - /* reads information flags on KE_END */ - if (key->code & FE_UNTESTED) - printk(KERN_WARNING "Untested laptop multimedia keys, " - "please report success or failure to eric.piel" - "@tremplin-utc.net\n"); + error = sparse_keymap_setup(input_dev, keymap, wistron_setup_keymap); + if (error) + goto err_free_dev; error = input_register_polled_device(wistron_idev); - if (error) { - input_free_polled_device(wistron_idev); - return error; - } + if (error) + goto err_free_keymap; return 0; + + err_free_keymap: + sparse_keymap_free(input_dev); + err_free_dev: + input_free_polled_device(wistron_idev); + return error; } /* Driver core */ @@ -1371,6 +1280,7 @@ static int __devexit wistron_remove(struct platform_device *dev) { wistron_led_remove(); input_unregister_polled_device(wistron_idev); + sparse_keymap_free(wistron_idev->input); input_free_polled_device(wistron_idev); bios_detach();