aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/misc/wistron_btns.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/misc/wistron_btns.c')
-rw-r--r--drivers/input/misc/wistron_btns.c256
1 files changed, 83 insertions, 173 deletions
diff --git a/drivers/input/misc/wistron_btns.c b/drivers/input/misc/wistron_btns.c
index a932179c4c9e..38da6ab04384 100644
--- a/drivers/input/misc/wistron_btns.c
+++ b/drivers/input/misc/wistron_btns.c
@@ -21,6 +21,7 @@
#include <linux/dmi.h>
#include <linux/init.h>
#include <linux/input-polldev.h>
+#include <linux/input/sparse-keymap.h>
#include <linux/interrupt.h>
#include <linux/jiffies.h>
#include <linux/kernel.h>
@@ -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
@@ -644,10 +634,10 @@ static struct key_entry keymap_prestigio[] __initdata = {
* a list of buttons and their key codes (reported when loading this module
* with force=1) and the output of dmidecode to $MODULE_AUTHOR.
*/
-static struct dmi_system_id dmi_ids[] __initdata = {
+static const struct dmi_system_id __initconst dmi_ids[] = {
{
+ /* Fujitsu-Siemens Amilo Pro V2000 */
.callback = dmi_matched,
- .ident = "Fujitsu-Siemens Amilo Pro V2000",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pro V2000"),
@@ -655,8 +645,8 @@ static struct dmi_system_id dmi_ids[] __initdata = {
.driver_data = keymap_fs_amilo_pro_v2000
},
{
+ /* Fujitsu-Siemens Amilo Pro Edition V3505 */
.callback = dmi_matched,
- .ident = "Fujitsu-Siemens Amilo Pro Edition V3505",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pro Edition V3505"),
@@ -664,8 +654,8 @@ static struct dmi_system_id dmi_ids[] __initdata = {
.driver_data = keymap_fs_amilo_pro_v3505
},
{
+ /* Fujitsu-Siemens Amilo M7400 */
.callback = dmi_matched,
- .ident = "Fujitsu-Siemens Amilo M7400",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
DMI_MATCH(DMI_PRODUCT_NAME, "AMILO M "),
@@ -673,8 +663,8 @@ static struct dmi_system_id dmi_ids[] __initdata = {
.driver_data = keymap_fs_amilo_pro_v2000
},
{
+ /* Maxdata Pro 7000 DX */
.callback = dmi_matched,
- .ident = "Maxdata Pro 7000 DX",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "MAXDATA"),
DMI_MATCH(DMI_PRODUCT_NAME, "Pro 7000"),
@@ -682,8 +672,8 @@ static struct dmi_system_id dmi_ids[] __initdata = {
.driver_data = keymap_fs_amilo_pro_v2000
},
{
+ /* Fujitsu N3510 */
.callback = dmi_matched,
- .ident = "Fujitsu N3510",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
DMI_MATCH(DMI_PRODUCT_NAME, "N3510"),
@@ -691,8 +681,8 @@ static struct dmi_system_id dmi_ids[] __initdata = {
.driver_data = keymap_fujitsu_n3510
},
{
+ /* Acer Aspire 1500 */
.callback = dmi_matched,
- .ident = "Acer Aspire 1500",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1500"),
@@ -700,8 +690,8 @@ static struct dmi_system_id dmi_ids[] __initdata = {
.driver_data = keymap_acer_aspire_1500
},
{
+ /* Acer Aspire 1600 */
.callback = dmi_matched,
- .ident = "Acer Aspire 1600",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1600"),
@@ -709,8 +699,8 @@ static struct dmi_system_id dmi_ids[] __initdata = {
.driver_data = keymap_acer_aspire_1600
},
{
+ /* Acer Aspire 3020 */
.callback = dmi_matched,
- .ident = "Acer Aspire 3020",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 3020"),
@@ -718,8 +708,8 @@ static struct dmi_system_id dmi_ids[] __initdata = {
.driver_data = keymap_acer_aspire_5020
},
{
+ /* Acer Aspire 5020 */
.callback = dmi_matched,
- .ident = "Acer Aspire 5020",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5020"),
@@ -727,8 +717,8 @@ static struct dmi_system_id dmi_ids[] __initdata = {
.driver_data = keymap_acer_aspire_5020
},
{
+ /* Acer TravelMate 2100 */
.callback = dmi_matched,
- .ident = "Acer TravelMate 2100",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2100"),
@@ -736,8 +726,8 @@ static struct dmi_system_id dmi_ids[] __initdata = {
.driver_data = keymap_acer_aspire_5020
},
{
+ /* Acer TravelMate 2410 */
.callback = dmi_matched,
- .ident = "Acer TravelMate 2410",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2410"),
@@ -745,8 +735,8 @@ static struct dmi_system_id dmi_ids[] __initdata = {
.driver_data = keymap_acer_travelmate_2410
},
{
+ /* Acer TravelMate C300 */
.callback = dmi_matched,
- .ident = "Acer TravelMate C300",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate C300"),
@@ -754,8 +744,8 @@ static struct dmi_system_id dmi_ids[] __initdata = {
.driver_data = keymap_acer_travelmate_300
},
{
+ /* Acer TravelMate C100 */
.callback = dmi_matched,
- .ident = "Acer TravelMate C100",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate C100"),
@@ -763,8 +753,8 @@ static struct dmi_system_id dmi_ids[] __initdata = {
.driver_data = keymap_acer_travelmate_300
},
{
+ /* Acer TravelMate C110 */
.callback = dmi_matched,
- .ident = "Acer TravelMate C110",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate C110"),
@@ -772,8 +762,8 @@ static struct dmi_system_id dmi_ids[] __initdata = {
.driver_data = keymap_acer_travelmate_110
},
{
+ /* Acer TravelMate 380 */
.callback = dmi_matched,
- .ident = "Acer TravelMate 380",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 380"),
@@ -781,8 +771,8 @@ static struct dmi_system_id dmi_ids[] __initdata = {
.driver_data = keymap_acer_travelmate_380
},
{
+ /* Acer TravelMate 370 */
.callback = dmi_matched,
- .ident = "Acer TravelMate 370",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 370"),
@@ -790,8 +780,8 @@ static struct dmi_system_id dmi_ids[] __initdata = {
.driver_data = keymap_acer_travelmate_380 /* keyboard minus 1 key */
},
{
+ /* Acer TravelMate 220 */
.callback = dmi_matched,
- .ident = "Acer TravelMate 220",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 220"),
@@ -799,8 +789,8 @@ static struct dmi_system_id dmi_ids[] __initdata = {
.driver_data = keymap_acer_travelmate_220
},
{
+ /* Acer TravelMate 260 */
.callback = dmi_matched,
- .ident = "Acer TravelMate 260",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 260"),
@@ -808,8 +798,8 @@ static struct dmi_system_id dmi_ids[] __initdata = {
.driver_data = keymap_acer_travelmate_220
},
{
+ /* Acer TravelMate 230 */
.callback = dmi_matched,
- .ident = "Acer TravelMate 230",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 230"),
@@ -818,8 +808,8 @@ static struct dmi_system_id dmi_ids[] __initdata = {
.driver_data = keymap_acer_travelmate_230
},
{
+ /* Acer TravelMate 280 */
.callback = dmi_matched,
- .ident = "Acer TravelMate 280",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 280"),
@@ -827,8 +817,8 @@ static struct dmi_system_id dmi_ids[] __initdata = {
.driver_data = keymap_acer_travelmate_230
},
{
+ /* Acer TravelMate 240 */
.callback = dmi_matched,
- .ident = "Acer TravelMate 240",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 240"),
@@ -836,8 +826,8 @@ static struct dmi_system_id dmi_ids[] __initdata = {
.driver_data = keymap_acer_travelmate_240
},
{
+ /* Acer TravelMate 250 */
.callback = dmi_matched,
- .ident = "Acer TravelMate 250",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 250"),
@@ -845,8 +835,8 @@ static struct dmi_system_id dmi_ids[] __initdata = {
.driver_data = keymap_acer_travelmate_240
},
{
+ /* Acer TravelMate 2424NWXCi */
.callback = dmi_matched,
- .ident = "Acer TravelMate 2424NWXCi",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2420"),
@@ -854,8 +844,8 @@ static struct dmi_system_id dmi_ids[] __initdata = {
.driver_data = keymap_acer_travelmate_240
},
{
+ /* Acer TravelMate 350 */
.callback = dmi_matched,
- .ident = "Acer TravelMate 350",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 350"),
@@ -863,8 +853,8 @@ static struct dmi_system_id dmi_ids[] __initdata = {
.driver_data = keymap_acer_travelmate_350
},
{
+ /* Acer TravelMate 360 */
.callback = dmi_matched,
- .ident = "Acer TravelMate 360",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"),
@@ -872,8 +862,8 @@ static struct dmi_system_id dmi_ids[] __initdata = {
.driver_data = keymap_acer_travelmate_360
},
{
+ /* Acer TravelMate 610 */
.callback = dmi_matched,
- .ident = "Acer TravelMate 610",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "ACER"),
DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 610"),
@@ -881,8 +871,8 @@ static struct dmi_system_id dmi_ids[] __initdata = {
.driver_data = keymap_acer_travelmate_610
},
{
+ /* Acer TravelMate 620 */
.callback = dmi_matched,
- .ident = "Acer TravelMate 620",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 620"),
@@ -890,8 +880,8 @@ static struct dmi_system_id dmi_ids[] __initdata = {
.driver_data = keymap_acer_travelmate_630
},
{
+ /* Acer TravelMate 630 */
.callback = dmi_matched,
- .ident = "Acer TravelMate 630",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 630"),
@@ -899,8 +889,8 @@ static struct dmi_system_id dmi_ids[] __initdata = {
.driver_data = keymap_acer_travelmate_630
},
{
+ /* AOpen 1559AS */
.callback = dmi_matched,
- .ident = "AOpen 1559AS",
.matches = {
DMI_MATCH(DMI_PRODUCT_NAME, "E2U"),
DMI_MATCH(DMI_BOARD_NAME, "E2U"),
@@ -908,8 +898,8 @@ static struct dmi_system_id dmi_ids[] __initdata = {
.driver_data = keymap_aopen_1559as
},
{
+ /* Medion MD 9783 */
.callback = dmi_matched,
- .ident = "Medion MD 9783",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "MEDIONNB"),
DMI_MATCH(DMI_PRODUCT_NAME, "MD 9783"),
@@ -917,8 +907,8 @@ static struct dmi_system_id dmi_ids[] __initdata = {
.driver_data = keymap_wistron_ms2111
},
{
+ /* Medion MD 40100 */
.callback = dmi_matched,
- .ident = "Medion MD 40100",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "MEDIONNB"),
DMI_MATCH(DMI_PRODUCT_NAME, "WID2000"),
@@ -926,8 +916,8 @@ static struct dmi_system_id dmi_ids[] __initdata = {
.driver_data = keymap_wistron_md40100
},
{
+ /* Medion MD 2900 */
.callback = dmi_matched,
- .ident = "Medion MD 2900",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "MEDIONNB"),
DMI_MATCH(DMI_PRODUCT_NAME, "WIM 2000"),
@@ -935,8 +925,8 @@ static struct dmi_system_id dmi_ids[] __initdata = {
.driver_data = keymap_wistron_md2900
},
{
+ /* Medion MD 42200 */
.callback = dmi_matched,
- .ident = "Medion MD 42200",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Medion"),
DMI_MATCH(DMI_PRODUCT_NAME, "WIM 2030"),
@@ -944,8 +934,8 @@ static struct dmi_system_id dmi_ids[] __initdata = {
.driver_data = keymap_fs_amilo_pro_v2000
},
{
+ /* Medion MD 96500 */
.callback = dmi_matched,
- .ident = "Medion MD 96500",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "MEDIONPC"),
DMI_MATCH(DMI_PRODUCT_NAME, "WIM 2040"),
@@ -953,8 +943,8 @@ static struct dmi_system_id dmi_ids[] __initdata = {
.driver_data = keymap_wistron_md96500
},
{
+ /* Medion MD 95400 */
.callback = dmi_matched,
- .ident = "Medion MD 95400",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "MEDIONPC"),
DMI_MATCH(DMI_PRODUCT_NAME, "WIM 2050"),
@@ -962,8 +952,8 @@ static struct dmi_system_id dmi_ids[] __initdata = {
.driver_data = keymap_wistron_md96500
},
{
+ /* Fujitsu Siemens Amilo D7820 */
.callback = dmi_matched,
- .ident = "Fujitsu Siemens Amilo D7820",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), /* not sure */
DMI_MATCH(DMI_PRODUCT_NAME, "Amilo D"),
@@ -971,8 +961,8 @@ static struct dmi_system_id dmi_ids[] __initdata = {
.driver_data = keymap_fs_amilo_d88x0
},
{
+ /* Fujitsu Siemens Amilo D88x0 */
.callback = dmi_matched,
- .ident = "Fujitsu Siemens Amilo D88x0",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
DMI_MATCH(DMI_PRODUCT_NAME, "AMILO D"),
@@ -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;
@@ -1263,7 +1207,7 @@ static int __devinit setup_input_dev(void)
if (!wistron_idev)
return -ENOMEM;
- wistron_idev->flush = wistron_flush;
+ wistron_idev->open = wistron_flush;
wistron_idev->poll = wistron_poll;
wistron_idev->poll_interval = POLL_INTERVAL_DEFAULT;
@@ -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();