aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDmitry Torokhov <dtor@insightbb.com>2007-06-14 23:31:45 -0400
committerDmitry Torokhov <dtor@insightbb.com>2007-07-10 00:35:17 -0400
commitd63219a10126b878abbbffdf4c5bcf29ef756b7f (patch)
treecdd5e16aecd568c2b94fcd8a14dd20a817203cbc /drivers
parentc2554c91425a86e5d0409a76b7ddcb328362f08b (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')
-rw-r--r--drivers/input/misc/wistron_btns.c121
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
245static const struct key_entry *keymap; /* = NULL; Current key map */ 245static struct key_entry *keymap; /* = NULL; Current key map */
246static int have_wifi; 246static int have_wifi;
247static int have_bluetooth; 247static int have_bluetooth;
248static int have_leds; 248static 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
1062static void handle_key(u8 code) 1062static 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: 1073static 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: 1084static 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
1105static void poll_bios(bool discard) 1122static 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
1154static 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
1166static 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
1137static int __devinit setup_input_dev(void) 1187static 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) {