diff options
author | Dmitry Torokhov <dtor@insightbb.com> | 2007-06-14 23:31:45 -0400 |
---|---|---|
committer | Dmitry Torokhov <dtor@insightbb.com> | 2007-07-10 00:35:17 -0400 |
commit | d63219a10126b878abbbffdf4c5bcf29ef756b7f (patch) | |
tree | cdd5e16aecd568c2b94fcd8a14dd20a817203cbc /drivers/input/misc/wistron_btns.c | |
parent | c2554c91425a86e5d0409a76b7ddcb328362f08b (diff) |
Input: wistron - add support for querying/changing keymap
Implement getkeycode and setkeycode methods for the device so
EVIOCGKEYCODE and EVIOCSKEYCODE ioctls will work.
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/input/misc/wistron_btns.c')
-rw-r--r-- | drivers/input/misc/wistron_btns.c | 121 |
1 files changed, 87 insertions, 34 deletions
diff --git a/drivers/input/misc/wistron_btns.c b/drivers/input/misc/wistron_btns.c index 622630f051a5..60121f10f8d9 100644 --- a/drivers/input/misc/wistron_btns.c +++ b/drivers/input/misc/wistron_btns.c | |||
@@ -242,7 +242,7 @@ enum { KE_END, KE_KEY, KE_SW, KE_WIFI, KE_BLUETOOTH }; | |||
242 | #define FE_WIFI_LED 0x02 | 242 | #define FE_WIFI_LED 0x02 |
243 | #define FE_UNTESTED 0x80 | 243 | #define FE_UNTESTED 0x80 |
244 | 244 | ||
245 | static const struct key_entry *keymap; /* = NULL; Current key map */ | 245 | static struct key_entry *keymap; /* = NULL; Current key map */ |
246 | static int have_wifi; | 246 | static int have_wifi; |
247 | static int have_bluetooth; | 247 | static int have_bluetooth; |
248 | static int have_leds; | 248 | static int have_leds; |
@@ -1059,47 +1059,64 @@ static inline void wistron_led_resume(void) | |||
1059 | led_classdev_resume(&wistron_wifi_led); | 1059 | led_classdev_resume(&wistron_wifi_led); |
1060 | } | 1060 | } |
1061 | 1061 | ||
1062 | static void handle_key(u8 code) | 1062 | static struct key_entry *wistron_get_entry_by_scancode(int code) |
1063 | { | 1063 | { |
1064 | const struct key_entry *key; | 1064 | struct key_entry *key; |
1065 | 1065 | ||
1066 | for (key = keymap; key->type != KE_END; key++) { | 1066 | for (key = keymap; key->type != KE_END; key++) |
1067 | if (code == key->code) { | 1067 | if (code == key->code) |
1068 | switch (key->type) { | 1068 | return key; |
1069 | case KE_KEY: | ||
1070 | report_key(wistron_idev->input, key->keycode); | ||
1071 | break; | ||
1072 | 1069 | ||
1073 | case KE_SW: | 1070 | return NULL; |
1074 | report_switch(wistron_idev->input, | 1071 | } |
1075 | key->sw.code, key->sw.value); | ||
1076 | break; | ||
1077 | 1072 | ||
1078 | case KE_WIFI: | 1073 | static struct key_entry *wistron_get_entry_by_keycode(int keycode) |
1079 | if (have_wifi) { | 1074 | { |
1080 | wifi_enabled = !wifi_enabled; | 1075 | struct key_entry *key; |
1081 | bios_set_state(WIFI, wifi_enabled); | ||
1082 | } | ||
1083 | break; | ||
1084 | 1076 | ||
1085 | case KE_BLUETOOTH: | 1077 | for (key = keymap; key->type != KE_END; key++) |
1086 | if (have_bluetooth) { | 1078 | if (key->type == KE_KEY && keycode == key->keycode) |
1087 | bluetooth_enabled = !bluetooth_enabled; | 1079 | return key; |
1088 | bios_set_state(BLUETOOTH, bluetooth_enabled); | ||
1089 | } | ||
1090 | break; | ||
1091 | 1080 | ||
1092 | case KE_END: | 1081 | return NULL; |
1093 | break; | 1082 | } |
1094 | 1083 | ||
1095 | default: | 1084 | static void handle_key(u8 code) |
1096 | BUG(); | 1085 | { |
1086 | const struct key_entry *key = wistron_get_entry_by_scancode(code); | ||
1087 | |||
1088 | if (key) { | ||
1089 | switch (key->type) { | ||
1090 | case KE_KEY: | ||
1091 | report_key(wistron_idev->input, key->keycode); | ||
1092 | break; | ||
1093 | |||
1094 | case KE_SW: | ||
1095 | report_switch(wistron_idev->input, | ||
1096 | key->sw.code, key->sw.value); | ||
1097 | break; | ||
1098 | |||
1099 | case KE_WIFI: | ||
1100 | if (have_wifi) { | ||
1101 | wifi_enabled = !wifi_enabled; | ||
1102 | bios_set_state(WIFI, wifi_enabled); | ||
1103 | } | ||
1104 | break; | ||
1105 | |||
1106 | case KE_BLUETOOTH: | ||
1107 | if (have_bluetooth) { | ||
1108 | bluetooth_enabled = !bluetooth_enabled; | ||
1109 | bios_set_state(BLUETOOTH, bluetooth_enabled); | ||
1097 | } | 1110 | } |
1098 | jiffies_last_press = jiffies; | 1111 | break; |
1099 | return; | 1112 | |
1113 | default: | ||
1114 | BUG(); | ||
1100 | } | 1115 | } |
1101 | } | 1116 | jiffies_last_press = jiffies; |
1102 | printk(KERN_NOTICE "wistron_btns: Unknown key code %02X\n", code); | 1117 | } else |
1118 | printk(KERN_NOTICE | ||
1119 | "wistron_btns: Unknown key code %02X\n", code); | ||
1103 | } | 1120 | } |
1104 | 1121 | ||
1105 | static void poll_bios(bool discard) | 1122 | static void poll_bios(bool discard) |
@@ -1134,6 +1151,39 @@ static void wistron_poll(struct input_polled_dev *dev) | |||
1134 | dev->poll_interval = POLL_INTERVAL_DEFAULT; | 1151 | dev->poll_interval = POLL_INTERVAL_DEFAULT; |
1135 | } | 1152 | } |
1136 | 1153 | ||
1154 | static int wistron_getkeycode(struct input_dev *dev, int scancode, int *keycode) | ||
1155 | { | ||
1156 | const struct key_entry *key = wistron_get_entry_by_scancode(scancode); | ||
1157 | |||
1158 | if (key && key->type == KE_KEY) { | ||
1159 | *keycode = key->keycode; | ||
1160 | return 0; | ||
1161 | } | ||
1162 | |||
1163 | return -EINVAL; | ||
1164 | } | ||
1165 | |||
1166 | static int wistron_setkeycode(struct input_dev *dev, int scancode, int keycode) | ||
1167 | { | ||
1168 | struct key_entry *key; | ||
1169 | int old_keycode; | ||
1170 | |||
1171 | if (keycode < 0 || keycode > KEY_MAX) | ||
1172 | return -EINVAL; | ||
1173 | |||
1174 | key = wistron_get_entry_by_scancode(scancode); | ||
1175 | if (key && key->type == KE_KEY) { | ||
1176 | old_keycode = key->keycode; | ||
1177 | key->keycode = keycode; | ||
1178 | set_bit(keycode, dev->keybit); | ||
1179 | if (!wistron_get_entry_by_keycode(old_keycode)) | ||
1180 | clear_bit(old_keycode, dev->keybit); | ||
1181 | return 0; | ||
1182 | } | ||
1183 | |||
1184 | return -EINVAL; | ||
1185 | } | ||
1186 | |||
1137 | static int __devinit setup_input_dev(void) | 1187 | static int __devinit setup_input_dev(void) |
1138 | { | 1188 | { |
1139 | const struct key_entry *key; | 1189 | const struct key_entry *key; |
@@ -1152,7 +1202,10 @@ static int __devinit setup_input_dev(void) | |||
1152 | input_dev->name = "Wistron laptop buttons"; | 1202 | input_dev->name = "Wistron laptop buttons"; |
1153 | input_dev->phys = "wistron/input0"; | 1203 | input_dev->phys = "wistron/input0"; |
1154 | input_dev->id.bustype = BUS_HOST; | 1204 | input_dev->id.bustype = BUS_HOST; |
1155 | input_dev->cdev.dev = &wistron_device->dev; | 1205 | input_dev->dev.parent = &wistron_device->dev; |
1206 | |||
1207 | input_dev->getkeycode = wistron_getkeycode; | ||
1208 | input_dev->setkeycode = wistron_setkeycode; | ||
1156 | 1209 | ||
1157 | for (key = keymap; key->type != KE_END; key++) { | 1210 | for (key = keymap; key->type != KE_END; key++) { |
1158 | switch (key->type) { | 1211 | switch (key->type) { |