aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/platform
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2010-08-05 01:30:19 -0400
committerMatthew Garrett <mjg@redhat.com>2010-10-21 09:36:43 -0400
commit384a7cd9ace5b37a17ffea436f09170cdf671c88 (patch)
treeeb76ae01c26465ae4c3d96f57de2abfb73810929 /drivers/platform
parent4d291ed7217d617dacbf54b4bd35819b0d08b981 (diff)
toshiba-acpi - switch to using sparse keymap
Instead of implementing its own version of keymap hanlding switch over to using sparse keymap library. Also, install notify handler only after we allocated input device, otherwise we may risk getting event too early and crash. Similarly, notify handler should be removed before we unregister input device. Signed-off-by: Dmitry Torokhov <dtor@mail.ru> Signed-off-by: Matthew Garrett <mjg@redhat.com>
Diffstat (limited to 'drivers/platform')
-rw-r--r--drivers/platform/x86/Kconfig2
-rw-r--r--drivers/platform/x86/toshiba_acpi.c191
2 files changed, 66 insertions, 127 deletions
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index 1ca392f5c826..b96db80fad99 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -496,6 +496,8 @@ config ACPI_TOSHIBA
496 depends on INPUT 496 depends on INPUT
497 depends on RFKILL || RFKILL = n 497 depends on RFKILL || RFKILL = n
498 select INPUT_POLLDEV 498 select INPUT_POLLDEV
499 select INPUT_SPARSEKMAP
500 select BACKLIGHT_CLASS_DEVICE
499 ---help--- 501 ---help---
500 This driver adds support for access to certain system settings 502 This driver adds support for access to certain system settings
501 on "legacy free" Toshiba laptops. These laptops can be recognized by 503 on "legacy free" Toshiba laptops. These laptops can be recognized by
diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c
index 7d67a45bb2b0..06f304f46e02 100644
--- a/drivers/platform/x86/toshiba_acpi.c
+++ b/drivers/platform/x86/toshiba_acpi.c
@@ -48,6 +48,7 @@
48#include <linux/platform_device.h> 48#include <linux/platform_device.h>
49#include <linux/rfkill.h> 49#include <linux/rfkill.h>
50#include <linux/input.h> 50#include <linux/input.h>
51#include <linux/input/sparse-keymap.h>
51#include <linux/leds.h> 52#include <linux/leds.h>
52#include <linux/slab.h> 53#include <linux/slab.h>
53 54
@@ -121,36 +122,28 @@ static const struct acpi_device_id toshiba_device_ids[] = {
121}; 122};
122MODULE_DEVICE_TABLE(acpi, toshiba_device_ids); 123MODULE_DEVICE_TABLE(acpi, toshiba_device_ids);
123 124
124struct key_entry { 125static const struct key_entry toshiba_acpi_keymap[] __initconst = {
125 char type; 126 { KE_KEY, 0x101, { KEY_MUTE } },
126 u16 code; 127 { KE_KEY, 0x102, { KEY_ZOOMOUT } },
127 u16 keycode; 128 { KE_KEY, 0x103, { KEY_ZOOMIN } },
128}; 129 { KE_KEY, 0x13b, { KEY_COFFEE } },
129 130 { KE_KEY, 0x13c, { KEY_BATTERY } },
130enum {KE_KEY, KE_END}; 131 { KE_KEY, 0x13d, { KEY_SLEEP } },
131 132 { KE_KEY, 0x13e, { KEY_SUSPEND } },
132static struct key_entry toshiba_acpi_keymap[] = { 133 { KE_KEY, 0x13f, { KEY_SWITCHVIDEOMODE } },
133 {KE_KEY, 0x101, KEY_MUTE}, 134 { KE_KEY, 0x140, { KEY_BRIGHTNESSDOWN } },
134 {KE_KEY, 0x102, KEY_ZOOMOUT}, 135 { KE_KEY, 0x141, { KEY_BRIGHTNESSUP } },
135 {KE_KEY, 0x103, KEY_ZOOMIN}, 136 { KE_KEY, 0x142, { KEY_WLAN } },
136 {KE_KEY, 0x13b, KEY_COFFEE}, 137 { KE_KEY, 0x143, { KEY_PROG1 } },
137 {KE_KEY, 0x13c, KEY_BATTERY}, 138 { KE_KEY, 0xb05, { KEY_PROG2 } },
138 {KE_KEY, 0x13d, KEY_SLEEP}, 139 { KE_KEY, 0xb06, { KEY_WWW } },
139 {KE_KEY, 0x13e, KEY_SUSPEND}, 140 { KE_KEY, 0xb07, { KEY_MAIL } },
140 {KE_KEY, 0x13f, KEY_SWITCHVIDEOMODE}, 141 { KE_KEY, 0xb30, { KEY_STOP } },
141 {KE_KEY, 0x140, KEY_BRIGHTNESSDOWN}, 142 { KE_KEY, 0xb31, { KEY_PREVIOUSSONG } },
142 {KE_KEY, 0x141, KEY_BRIGHTNESSUP}, 143 { KE_KEY, 0xb32, { KEY_NEXTSONG } },
143 {KE_KEY, 0x142, KEY_WLAN}, 144 { KE_KEY, 0xb33, { KEY_PLAYPAUSE } },
144 {KE_KEY, 0x143, KEY_PROG1}, 145 { KE_KEY, 0xb5a, { KEY_MEDIA } },
145 {KE_KEY, 0xb05, KEY_PROG2}, 146 { KE_END, 0 },
146 {KE_KEY, 0xb06, KEY_WWW},
147 {KE_KEY, 0xb07, KEY_MAIL},
148 {KE_KEY, 0xb30, KEY_STOP},
149 {KE_KEY, 0xb31, KEY_PREVIOUSSONG},
150 {KE_KEY, 0xb32, KEY_NEXTSONG},
151 {KE_KEY, 0xb33, KEY_PLAYPAUSE},
152 {KE_KEY, 0xb5a, KEY_MEDIA},
153 {KE_END, 0, 0},
154}; 147};
155 148
156/* utility 149/* utility
@@ -852,64 +845,9 @@ static struct backlight_ops toshiba_backlight_data = {
852 .update_status = set_lcd_status, 845 .update_status = set_lcd_status,
853}; 846};
854 847
855static struct key_entry *toshiba_acpi_get_entry_by_scancode(unsigned int code)
856{
857 struct key_entry *key;
858
859 for (key = toshiba_acpi_keymap; key->type != KE_END; key++)
860 if (code == key->code)
861 return key;
862
863 return NULL;
864}
865
866static struct key_entry *toshiba_acpi_get_entry_by_keycode(unsigned int code)
867{
868 struct key_entry *key;
869
870 for (key = toshiba_acpi_keymap; key->type != KE_END; key++)
871 if (code == key->keycode && key->type == KE_KEY)
872 return key;
873
874 return NULL;
875}
876
877static int toshiba_acpi_getkeycode(struct input_dev *dev,
878 unsigned int scancode, unsigned int *keycode)
879{
880 struct key_entry *key = toshiba_acpi_get_entry_by_scancode(scancode);
881
882 if (key && key->type == KE_KEY) {
883 *keycode = key->keycode;
884 return 0;
885 }
886
887 return -EINVAL;
888}
889
890static int toshiba_acpi_setkeycode(struct input_dev *dev,
891 unsigned int scancode, unsigned int keycode)
892{
893 struct key_entry *key;
894 unsigned int old_keycode;
895
896 key = toshiba_acpi_get_entry_by_scancode(scancode);
897 if (key && key->type == KE_KEY) {
898 old_keycode = key->keycode;
899 key->keycode = keycode;
900 set_bit(keycode, dev->keybit);
901 if (!toshiba_acpi_get_entry_by_keycode(old_keycode))
902 clear_bit(old_keycode, dev->keybit);
903 return 0;
904 }
905
906 return -EINVAL;
907}
908
909static void toshiba_acpi_notify(acpi_handle handle, u32 event, void *context) 848static void toshiba_acpi_notify(acpi_handle handle, u32 event, void *context)
910{ 849{
911 u32 hci_result, value; 850 u32 hci_result, value;
912 struct key_entry *key;
913 851
914 if (event != 0x80) 852 if (event != 0x80)
915 return; 853 return;
@@ -922,19 +860,11 @@ static void toshiba_acpi_notify(acpi_handle handle, u32 event, void *context)
922 if (value & 0x80) 860 if (value & 0x80)
923 continue; 861 continue;
924 862
925 key = toshiba_acpi_get_entry_by_scancode 863 if (!sparse_keymap_report_event(toshiba_acpi.hotkey_dev,
926 (value); 864 value, 1, true)) {
927 if (!key) {
928 printk(MY_INFO "Unknown key %x\n", 865 printk(MY_INFO "Unknown key %x\n",
929 value); 866 value);
930 continue;
931 } 867 }
932 input_report_key(toshiba_acpi.hotkey_dev,
933 key->keycode, 1);
934 input_sync(toshiba_acpi.hotkey_dev);
935 input_report_key(toshiba_acpi.hotkey_dev,
936 key->keycode, 0);
937 input_sync(toshiba_acpi.hotkey_dev);
938 } else if (hci_result == HCI_NOT_SUPPORTED) { 868 } else if (hci_result == HCI_NOT_SUPPORTED) {
939 /* This is a workaround for an unresolved issue on 869 /* This is a workaround for an unresolved issue on
940 * some machines where system events sporadically 870 * some machines where system events sporadically
@@ -945,34 +875,17 @@ static void toshiba_acpi_notify(acpi_handle handle, u32 event, void *context)
945 } while (hci_result != HCI_EMPTY); 875 } while (hci_result != HCI_EMPTY);
946} 876}
947 877
948static int toshiba_acpi_setup_keyboard(char *device) 878static int __init toshiba_acpi_setup_keyboard(char *device)
949{ 879{
950 acpi_status status; 880 acpi_status status;
951 acpi_handle handle; 881 int error;
952 int result;
953 const struct key_entry *key;
954 882
955 status = acpi_get_handle(NULL, device, &handle); 883 status = acpi_get_handle(NULL, device, &toshiba_acpi.handle);
956 if (ACPI_FAILURE(status)) { 884 if (ACPI_FAILURE(status)) {
957 printk(MY_INFO "Unable to get notification device\n"); 885 printk(MY_INFO "Unable to get notification device\n");
958 return -ENODEV; 886 return -ENODEV;
959 } 887 }
960 888
961 toshiba_acpi.handle = handle;
962
963 status = acpi_evaluate_object(handle, "ENAB", NULL, NULL);
964 if (ACPI_FAILURE(status)) {
965 printk(MY_INFO "Unable to enable hotkeys\n");
966 return -ENODEV;
967 }
968
969 status = acpi_install_notify_handler(handle, ACPI_DEVICE_NOTIFY,
970 toshiba_acpi_notify, NULL);
971 if (ACPI_FAILURE(status)) {
972 printk(MY_INFO "Unable to install hotkey notification\n");
973 return -ENODEV;
974 }
975
976 toshiba_acpi.hotkey_dev = input_allocate_device(); 889 toshiba_acpi.hotkey_dev = input_allocate_device();
977 if (!toshiba_acpi.hotkey_dev) { 890 if (!toshiba_acpi.hotkey_dev) {
978 printk(MY_INFO "Unable to register input device\n"); 891 printk(MY_INFO "Unable to register input device\n");
@@ -982,27 +895,54 @@ static int toshiba_acpi_setup_keyboard(char *device)
982 toshiba_acpi.hotkey_dev->name = "Toshiba input device"; 895 toshiba_acpi.hotkey_dev->name = "Toshiba input device";
983 toshiba_acpi.hotkey_dev->phys = device; 896 toshiba_acpi.hotkey_dev->phys = device;
984 toshiba_acpi.hotkey_dev->id.bustype = BUS_HOST; 897 toshiba_acpi.hotkey_dev->id.bustype = BUS_HOST;
985 toshiba_acpi.hotkey_dev->getkeycode = toshiba_acpi_getkeycode;
986 toshiba_acpi.hotkey_dev->setkeycode = toshiba_acpi_setkeycode;
987 898
988 for (key = toshiba_acpi_keymap; key->type != KE_END; key++) { 899 error = sparse_keymap_setup(toshiba_acpi.hotkey_dev,
989 set_bit(EV_KEY, toshiba_acpi.hotkey_dev->evbit); 900 toshiba_acpi_keymap, NULL);
990 set_bit(key->keycode, toshiba_acpi.hotkey_dev->keybit); 901 if (error)
902 goto err_free_dev;
903
904 status = acpi_install_notify_handler(toshiba_acpi.handle,
905 ACPI_DEVICE_NOTIFY, toshiba_acpi_notify, NULL);
906 if (ACPI_FAILURE(status)) {
907 printk(MY_INFO "Unable to install hotkey notification\n");
908 error = -ENODEV;
909 goto err_free_keymap;
910 }
911
912 status = acpi_evaluate_object(toshiba_acpi.handle, "ENAB", NULL, NULL);
913 if (ACPI_FAILURE(status)) {
914 printk(MY_INFO "Unable to enable hotkeys\n");
915 error = -ENODEV;
916 goto err_remove_notify;
991 } 917 }
992 918
993 result = input_register_device(toshiba_acpi.hotkey_dev); 919 error = input_register_device(toshiba_acpi.hotkey_dev);
994 if (result) { 920 if (error) {
995 printk(MY_INFO "Unable to register input device\n"); 921 printk(MY_INFO "Unable to register input device\n");
996 return result; 922 goto err_remove_notify;
997 } 923 }
998 924
999 return 0; 925 return 0;
926
927 err_remove_notify:
928 acpi_remove_notify_handler(toshiba_acpi.handle,
929 ACPI_DEVICE_NOTIFY, toshiba_acpi_notify);
930 err_free_keymap:
931 sparse_keymap_free(toshiba_acpi.hotkey_dev);
932 err_free_dev:
933 input_free_device(toshiba_acpi.hotkey_dev);
934 toshiba_acpi.hotkey_dev = NULL;
935 return error;
1000} 936}
1001 937
1002static void toshiba_acpi_exit(void) 938static void toshiba_acpi_exit(void)
1003{ 939{
1004 if (toshiba_acpi.hotkey_dev) 940 if (toshiba_acpi.hotkey_dev) {
941 acpi_remove_notify_handler(toshiba_acpi.handle,
942 ACPI_DEVICE_NOTIFY, toshiba_acpi_notify);
943 sparse_keymap_free(toshiba_acpi.hotkey_dev);
1005 input_unregister_device(toshiba_acpi.hotkey_dev); 944 input_unregister_device(toshiba_acpi.hotkey_dev);
945 }
1006 946
1007 if (toshiba_acpi.bt_rfk) { 947 if (toshiba_acpi.bt_rfk) {
1008 rfkill_unregister(toshiba_acpi.bt_rfk); 948 rfkill_unregister(toshiba_acpi.bt_rfk);
@@ -1017,9 +957,6 @@ static void toshiba_acpi_exit(void)
1017 if (toshiba_proc_dir) 957 if (toshiba_proc_dir)
1018 remove_proc_entry(PROC_TOSHIBA, acpi_root_dir); 958 remove_proc_entry(PROC_TOSHIBA, acpi_root_dir);
1019 959
1020 acpi_remove_notify_handler(toshiba_acpi.handle, ACPI_DEVICE_NOTIFY,
1021 toshiba_acpi_notify);
1022
1023 if (toshiba_acpi.illumination_installed) 960 if (toshiba_acpi.illumination_installed)
1024 led_classdev_unregister(&toshiba_led); 961 led_classdev_unregister(&toshiba_led);
1025 962