Loading drivers/input/misc/Kconfig +1 −0 Original line number Original line Diff line number Diff line Loading @@ -80,6 +80,7 @@ config INPUT_WISTRON_BTNS tristate "x86 Wistron laptop button interface" tristate "x86 Wistron laptop button interface" depends on X86 && !X86_64 depends on X86 && !X86_64 select INPUT_POLLDEV select INPUT_POLLDEV select INPUT_SPARSEKMAP select NEW_LEDS select NEW_LEDS select LEDS_CLASS select LEDS_CLASS select CHECK_SIGNATURE select CHECK_SIGNATURE Loading drivers/input/misc/wistron_btns.c +44 −134 Original line number Original line Diff line number Diff line Loading @@ -21,6 +21,7 @@ #include <linux/dmi.h> #include <linux/dmi.h> #include <linux/init.h> #include <linux/init.h> #include <linux/input-polldev.h> #include <linux/input-polldev.h> #include <linux/input/sparse-keymap.h> #include <linux/interrupt.h> #include <linux/interrupt.h> #include <linux/jiffies.h> #include <linux/jiffies.h> #include <linux/kernel.h> #include <linux/kernel.h> Loading Loading @@ -224,19 +225,8 @@ static void bios_set_state(u8 subsys, int enable) /* Hardware database */ /* Hardware database */ struct key_entry { #define KE_WIFI (KE_LAST + 1) char type; /* See KE_* below */ #define KE_BLUETOOTH (KE_LAST + 2) 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 FE_MAIL_LED 0x01 #define FE_MAIL_LED 0x01 #define FE_WIFI_LED 0x02 #define FE_WIFI_LED 0x02 Loading Loading @@ -1037,21 +1027,6 @@ static unsigned long jiffies_last_press; static bool wifi_enabled; static bool wifi_enabled; static bool bluetooth_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 */ /* led management */ static void wistron_mail_led_set(struct led_classdev *led_cdev, static void wistron_mail_led_set(struct led_classdev *led_cdev, enum led_brightness value) enum led_brightness value) Loading Loading @@ -1128,43 +1103,13 @@ static inline void wistron_led_resume(void) led_classdev_resume(&wistron_wifi_led); 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) 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) { if (key) { switch (key->type) { 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: case KE_WIFI: if (have_wifi) { if (have_wifi) { wifi_enabled = !wifi_enabled; wifi_enabled = !wifi_enabled; Loading @@ -1180,7 +1125,9 @@ static void handle_key(u8 code) break; break; default: default: BUG(); sparse_keymap_report_entry(wistron_idev->input, key, 1, true); break; } } jiffies_last_press = jiffies; jiffies_last_press = jiffies; } else } else Loading Loading @@ -1220,42 +1167,39 @@ static void wistron_poll(struct input_polled_dev *dev) dev->poll_interval = POLL_INTERVAL_DEFAULT; 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) { /* if wifi or bluetooth are not available, create normal keys */ *keycode = key->keycode; case KE_WIFI: return 0; if (!have_wifi) { entry->type = KE_KEY; entry->keycode = KEY_WLAN; } } break; return -EINVAL; case KE_BLUETOOTH: if (!have_bluetooth) { entry->type = KE_KEY; entry->keycode = KEY_BLUETOOTH; } } break; static int wistron_setkeycode(struct input_dev *dev, int scancode, int keycode) case KE_END: { if (entry->code & FE_UNTESTED) struct key_entry *key; printk(KERN_WARNING "Untested laptop multimedia keys, " int old_keycode; "please report success or failure to " "eric.piel@tremplin-utc.net\n"); if (keycode < 0 || keycode > KEY_MAX) break; 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; } } return -EINVAL; return 0; } } static int __devinit setup_input_dev(void) static int __devinit setup_input_dev(void) { { struct key_entry *key; struct input_dev *input_dev; struct input_dev *input_dev; int error; int error; Loading @@ -1273,58 +1217,23 @@ static int __devinit setup_input_dev(void) input_dev->id.bustype = BUS_HOST; input_dev->id.bustype = BUS_HOST; input_dev->dev.parent = &wistron_device->dev; input_dev->dev.parent = &wistron_device->dev; input_dev->getkeycode = wistron_getkeycode; error = sparse_keymap_setup(input_dev, keymap, wistron_setup_keymap); input_dev->setkeycode = wistron_setkeycode; if (error) goto err_free_dev; 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: error = input_register_polled_device(wistron_idev); break; if (error) } goto err_free_keymap; } /* reads information flags on KE_END */ return 0; 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 = input_register_polled_device(wistron_idev); err_free_keymap: if (error) { sparse_keymap_free(input_dev); err_free_dev: input_free_polled_device(wistron_idev); input_free_polled_device(wistron_idev); return error; return error; } } return 0; } /* Driver core */ /* Driver core */ static int __devinit wistron_probe(struct platform_device *dev) static int __devinit wistron_probe(struct platform_device *dev) Loading Loading @@ -1371,6 +1280,7 @@ static int __devexit wistron_remove(struct platform_device *dev) { { wistron_led_remove(); wistron_led_remove(); input_unregister_polled_device(wistron_idev); input_unregister_polled_device(wistron_idev); sparse_keymap_free(wistron_idev->input); input_free_polled_device(wistron_idev); input_free_polled_device(wistron_idev); bios_detach(); bios_detach(); Loading Loading
drivers/input/misc/Kconfig +1 −0 Original line number Original line Diff line number Diff line Loading @@ -80,6 +80,7 @@ config INPUT_WISTRON_BTNS tristate "x86 Wistron laptop button interface" tristate "x86 Wistron laptop button interface" depends on X86 && !X86_64 depends on X86 && !X86_64 select INPUT_POLLDEV select INPUT_POLLDEV select INPUT_SPARSEKMAP select NEW_LEDS select NEW_LEDS select LEDS_CLASS select LEDS_CLASS select CHECK_SIGNATURE select CHECK_SIGNATURE Loading
drivers/input/misc/wistron_btns.c +44 −134 Original line number Original line Diff line number Diff line Loading @@ -21,6 +21,7 @@ #include <linux/dmi.h> #include <linux/dmi.h> #include <linux/init.h> #include <linux/init.h> #include <linux/input-polldev.h> #include <linux/input-polldev.h> #include <linux/input/sparse-keymap.h> #include <linux/interrupt.h> #include <linux/interrupt.h> #include <linux/jiffies.h> #include <linux/jiffies.h> #include <linux/kernel.h> #include <linux/kernel.h> Loading Loading @@ -224,19 +225,8 @@ static void bios_set_state(u8 subsys, int enable) /* Hardware database */ /* Hardware database */ struct key_entry { #define KE_WIFI (KE_LAST + 1) char type; /* See KE_* below */ #define KE_BLUETOOTH (KE_LAST + 2) 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 FE_MAIL_LED 0x01 #define FE_MAIL_LED 0x01 #define FE_WIFI_LED 0x02 #define FE_WIFI_LED 0x02 Loading Loading @@ -1037,21 +1027,6 @@ static unsigned long jiffies_last_press; static bool wifi_enabled; static bool wifi_enabled; static bool bluetooth_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 */ /* led management */ static void wistron_mail_led_set(struct led_classdev *led_cdev, static void wistron_mail_led_set(struct led_classdev *led_cdev, enum led_brightness value) enum led_brightness value) Loading Loading @@ -1128,43 +1103,13 @@ static inline void wistron_led_resume(void) led_classdev_resume(&wistron_wifi_led); 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) 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) { if (key) { switch (key->type) { 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: case KE_WIFI: if (have_wifi) { if (have_wifi) { wifi_enabled = !wifi_enabled; wifi_enabled = !wifi_enabled; Loading @@ -1180,7 +1125,9 @@ static void handle_key(u8 code) break; break; default: default: BUG(); sparse_keymap_report_entry(wistron_idev->input, key, 1, true); break; } } jiffies_last_press = jiffies; jiffies_last_press = jiffies; } else } else Loading Loading @@ -1220,42 +1167,39 @@ static void wistron_poll(struct input_polled_dev *dev) dev->poll_interval = POLL_INTERVAL_DEFAULT; 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) { /* if wifi or bluetooth are not available, create normal keys */ *keycode = key->keycode; case KE_WIFI: return 0; if (!have_wifi) { entry->type = KE_KEY; entry->keycode = KEY_WLAN; } } break; return -EINVAL; case KE_BLUETOOTH: if (!have_bluetooth) { entry->type = KE_KEY; entry->keycode = KEY_BLUETOOTH; } } break; static int wistron_setkeycode(struct input_dev *dev, int scancode, int keycode) case KE_END: { if (entry->code & FE_UNTESTED) struct key_entry *key; printk(KERN_WARNING "Untested laptop multimedia keys, " int old_keycode; "please report success or failure to " "eric.piel@tremplin-utc.net\n"); if (keycode < 0 || keycode > KEY_MAX) break; 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; } } return -EINVAL; return 0; } } static int __devinit setup_input_dev(void) static int __devinit setup_input_dev(void) { { struct key_entry *key; struct input_dev *input_dev; struct input_dev *input_dev; int error; int error; Loading @@ -1273,58 +1217,23 @@ static int __devinit setup_input_dev(void) input_dev->id.bustype = BUS_HOST; input_dev->id.bustype = BUS_HOST; input_dev->dev.parent = &wistron_device->dev; input_dev->dev.parent = &wistron_device->dev; input_dev->getkeycode = wistron_getkeycode; error = sparse_keymap_setup(input_dev, keymap, wistron_setup_keymap); input_dev->setkeycode = wistron_setkeycode; if (error) goto err_free_dev; 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: error = input_register_polled_device(wistron_idev); break; if (error) } goto err_free_keymap; } /* reads information flags on KE_END */ return 0; 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 = input_register_polled_device(wistron_idev); err_free_keymap: if (error) { sparse_keymap_free(input_dev); err_free_dev: input_free_polled_device(wistron_idev); input_free_polled_device(wistron_idev); return error; return error; } } return 0; } /* Driver core */ /* Driver core */ static int __devinit wistron_probe(struct platform_device *dev) static int __devinit wistron_probe(struct platform_device *dev) Loading Loading @@ -1371,6 +1280,7 @@ static int __devexit wistron_remove(struct platform_device *dev) { { wistron_led_remove(); wistron_led_remove(); input_unregister_polled_device(wistron_idev); input_unregister_polled_device(wistron_idev); sparse_keymap_free(wistron_idev->input); input_free_polled_device(wistron_idev); input_free_polled_device(wistron_idev); bios_detach(); bios_detach(); Loading