diff options
author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2009-12-04 13:22:24 -0500 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2009-12-07 12:26:49 -0500 |
commit | e97af4cbbe500e6a3f4e189fe9324c5b99192dd6 (patch) | |
tree | 9c0840313afd06cff11c16cf6d5010a1cd5c874f /drivers/input/misc | |
parent | 36203c4f3d091b5f6c082663bd1f74273798043a (diff) |
Input: wistron_btns - switch to using sparse keymap library
The keymap manipulation code was split into a library module,
so let's make us of it.
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/input/misc')
-rw-r--r-- | drivers/input/misc/Kconfig | 1 | ||||
-rw-r--r-- | drivers/input/misc/wistron_btns.c | 178 |
2 files changed, 45 insertions, 134 deletions
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index a9bb2544b2de..d25ecbb87bfc 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig | |||
@@ -80,6 +80,7 @@ config INPUT_WISTRON_BTNS | |||
80 | tristate "x86 Wistron laptop button interface" | 80 | tristate "x86 Wistron laptop button interface" |
81 | depends on X86 && !X86_64 | 81 | depends on X86 && !X86_64 |
82 | select INPUT_POLLDEV | 82 | select INPUT_POLLDEV |
83 | select INPUT_SPARSEKMAP | ||
83 | select NEW_LEDS | 84 | select NEW_LEDS |
84 | select LEDS_CLASS | 85 | select LEDS_CLASS |
85 | select CHECK_SIGNATURE | 86 | select CHECK_SIGNATURE |
diff --git a/drivers/input/misc/wistron_btns.c b/drivers/input/misc/wistron_btns.c index f9d2bc87b355..38da6ab04384 100644 --- a/drivers/input/misc/wistron_btns.c +++ b/drivers/input/misc/wistron_btns.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/dmi.h> | 21 | #include <linux/dmi.h> |
22 | #include <linux/init.h> | 22 | #include <linux/init.h> |
23 | #include <linux/input-polldev.h> | 23 | #include <linux/input-polldev.h> |
24 | #include <linux/input/sparse-keymap.h> | ||
24 | #include <linux/interrupt.h> | 25 | #include <linux/interrupt.h> |
25 | #include <linux/jiffies.h> | 26 | #include <linux/jiffies.h> |
26 | #include <linux/kernel.h> | 27 | #include <linux/kernel.h> |
@@ -224,19 +225,8 @@ static void bios_set_state(u8 subsys, int enable) | |||
224 | 225 | ||
225 | /* Hardware database */ | 226 | /* Hardware database */ |
226 | 227 | ||
227 | struct key_entry { | 228 | #define KE_WIFI (KE_LAST + 1) |
228 | char type; /* See KE_* below */ | 229 | #define KE_BLUETOOTH (KE_LAST + 2) |
229 | u8 code; | ||
230 | union { | ||
231 | u16 keycode; /* For KE_KEY */ | ||
232 | struct { /* For KE_SW */ | ||
233 | u8 code; | ||
234 | u8 value; | ||
235 | } sw; | ||
236 | }; | ||
237 | }; | ||
238 | |||
239 | enum { KE_END, KE_KEY, KE_SW, KE_WIFI, KE_BLUETOOTH }; | ||
240 | 230 | ||
241 | #define FE_MAIL_LED 0x01 | 231 | #define FE_MAIL_LED 0x01 |
242 | #define FE_WIFI_LED 0x02 | 232 | #define FE_WIFI_LED 0x02 |
@@ -1037,21 +1027,6 @@ static unsigned long jiffies_last_press; | |||
1037 | static bool wifi_enabled; | 1027 | static bool wifi_enabled; |
1038 | static bool bluetooth_enabled; | 1028 | static bool bluetooth_enabled; |
1039 | 1029 | ||
1040 | static void report_key(struct input_dev *dev, unsigned int keycode) | ||
1041 | { | ||
1042 | input_report_key(dev, keycode, 1); | ||
1043 | input_sync(dev); | ||
1044 | input_report_key(dev, keycode, 0); | ||
1045 | input_sync(dev); | ||
1046 | } | ||
1047 | |||
1048 | static void report_switch(struct input_dev *dev, unsigned int code, int value) | ||
1049 | { | ||
1050 | input_report_switch(dev, code, value); | ||
1051 | input_sync(dev); | ||
1052 | } | ||
1053 | |||
1054 | |||
1055 | /* led management */ | 1030 | /* led management */ |
1056 | static void wistron_mail_led_set(struct led_classdev *led_cdev, | 1031 | static void wistron_mail_led_set(struct led_classdev *led_cdev, |
1057 | enum led_brightness value) | 1032 | enum led_brightness value) |
@@ -1128,43 +1103,13 @@ static inline void wistron_led_resume(void) | |||
1128 | led_classdev_resume(&wistron_wifi_led); | 1103 | led_classdev_resume(&wistron_wifi_led); |
1129 | } | 1104 | } |
1130 | 1105 | ||
1131 | static struct key_entry *wistron_get_entry_by_scancode(int code) | ||
1132 | { | ||
1133 | struct key_entry *key; | ||
1134 | |||
1135 | for (key = keymap; key->type != KE_END; key++) | ||
1136 | if (code == key->code) | ||
1137 | return key; | ||
1138 | |||
1139 | return NULL; | ||
1140 | } | ||
1141 | |||
1142 | static struct key_entry *wistron_get_entry_by_keycode(int keycode) | ||
1143 | { | ||
1144 | struct key_entry *key; | ||
1145 | |||
1146 | for (key = keymap; key->type != KE_END; key++) | ||
1147 | if (key->type == KE_KEY && keycode == key->keycode) | ||
1148 | return key; | ||
1149 | |||
1150 | return NULL; | ||
1151 | } | ||
1152 | |||
1153 | static void handle_key(u8 code) | 1106 | static void handle_key(u8 code) |
1154 | { | 1107 | { |
1155 | const struct key_entry *key = wistron_get_entry_by_scancode(code); | 1108 | const struct key_entry *key = |
1109 | sparse_keymap_entry_from_scancode(wistron_idev->input, code); | ||
1156 | 1110 | ||
1157 | if (key) { | 1111 | if (key) { |
1158 | switch (key->type) { | 1112 | switch (key->type) { |
1159 | case KE_KEY: | ||
1160 | report_key(wistron_idev->input, key->keycode); | ||
1161 | break; | ||
1162 | |||
1163 | case KE_SW: | ||
1164 | report_switch(wistron_idev->input, | ||
1165 | key->sw.code, key->sw.value); | ||
1166 | break; | ||
1167 | |||
1168 | case KE_WIFI: | 1113 | case KE_WIFI: |
1169 | if (have_wifi) { | 1114 | if (have_wifi) { |
1170 | wifi_enabled = !wifi_enabled; | 1115 | wifi_enabled = !wifi_enabled; |
@@ -1180,7 +1125,9 @@ static void handle_key(u8 code) | |||
1180 | break; | 1125 | break; |
1181 | 1126 | ||
1182 | default: | 1127 | default: |
1183 | BUG(); | 1128 | sparse_keymap_report_entry(wistron_idev->input, |
1129 | key, 1, true); | ||
1130 | break; | ||
1184 | } | 1131 | } |
1185 | jiffies_last_press = jiffies; | 1132 | jiffies_last_press = jiffies; |
1186 | } else | 1133 | } else |
@@ -1220,42 +1167,39 @@ static void wistron_poll(struct input_polled_dev *dev) | |||
1220 | dev->poll_interval = POLL_INTERVAL_DEFAULT; | 1167 | dev->poll_interval = POLL_INTERVAL_DEFAULT; |
1221 | } | 1168 | } |
1222 | 1169 | ||
1223 | static int wistron_getkeycode(struct input_dev *dev, int scancode, int *keycode) | 1170 | static int __devinit wistron_setup_keymap(struct input_dev *dev, |
1171 | struct key_entry *entry) | ||
1224 | { | 1172 | { |
1225 | const struct key_entry *key = wistron_get_entry_by_scancode(scancode); | 1173 | switch (entry->type) { |
1226 | 1174 | ||
1227 | if (key && key->type == KE_KEY) { | 1175 | /* if wifi or bluetooth are not available, create normal keys */ |
1228 | *keycode = key->keycode; | 1176 | case KE_WIFI: |
1229 | return 0; | 1177 | if (!have_wifi) { |
1230 | } | 1178 | entry->type = KE_KEY; |
1231 | 1179 | entry->keycode = KEY_WLAN; | |
1232 | return -EINVAL; | 1180 | } |
1233 | } | 1181 | break; |
1234 | 1182 | ||
1235 | static int wistron_setkeycode(struct input_dev *dev, int scancode, int keycode) | 1183 | case KE_BLUETOOTH: |
1236 | { | 1184 | if (!have_bluetooth) { |
1237 | struct key_entry *key; | 1185 | entry->type = KE_KEY; |
1238 | int old_keycode; | 1186 | entry->keycode = KEY_BLUETOOTH; |
1239 | 1187 | } | |
1240 | if (keycode < 0 || keycode > KEY_MAX) | 1188 | break; |
1241 | return -EINVAL; | 1189 | |
1242 | 1190 | case KE_END: | |
1243 | key = wistron_get_entry_by_scancode(scancode); | 1191 | if (entry->code & FE_UNTESTED) |
1244 | if (key && key->type == KE_KEY) { | 1192 | printk(KERN_WARNING "Untested laptop multimedia keys, " |
1245 | old_keycode = key->keycode; | 1193 | "please report success or failure to " |
1246 | key->keycode = keycode; | 1194 | "eric.piel@tremplin-utc.net\n"); |
1247 | set_bit(keycode, dev->keybit); | 1195 | break; |
1248 | if (!wistron_get_entry_by_keycode(old_keycode)) | ||
1249 | clear_bit(old_keycode, dev->keybit); | ||
1250 | return 0; | ||
1251 | } | 1196 | } |
1252 | 1197 | ||
1253 | return -EINVAL; | 1198 | return 0; |
1254 | } | 1199 | } |
1255 | 1200 | ||
1256 | static int __devinit setup_input_dev(void) | 1201 | static int __devinit setup_input_dev(void) |
1257 | { | 1202 | { |
1258 | struct key_entry *key; | ||
1259 | struct input_dev *input_dev; | 1203 | struct input_dev *input_dev; |
1260 | int error; | 1204 | int error; |
1261 | 1205 | ||
@@ -1273,56 +1217,21 @@ static int __devinit setup_input_dev(void) | |||
1273 | input_dev->id.bustype = BUS_HOST; | 1217 | input_dev->id.bustype = BUS_HOST; |
1274 | input_dev->dev.parent = &wistron_device->dev; | 1218 | input_dev->dev.parent = &wistron_device->dev; |
1275 | 1219 | ||
1276 | input_dev->getkeycode = wistron_getkeycode; | 1220 | error = sparse_keymap_setup(input_dev, keymap, wistron_setup_keymap); |
1277 | input_dev->setkeycode = wistron_setkeycode; | 1221 | if (error) |
1278 | 1222 | goto err_free_dev; | |
1279 | for (key = keymap; key->type != KE_END; key++) { | ||
1280 | switch (key->type) { | ||
1281 | case KE_KEY: | ||
1282 | set_bit(EV_KEY, input_dev->evbit); | ||
1283 | set_bit(key->keycode, input_dev->keybit); | ||
1284 | break; | ||
1285 | |||
1286 | case KE_SW: | ||
1287 | set_bit(EV_SW, input_dev->evbit); | ||
1288 | set_bit(key->sw.code, input_dev->swbit); | ||
1289 | break; | ||
1290 | |||
1291 | /* if wifi or bluetooth are not available, create normal keys */ | ||
1292 | case KE_WIFI: | ||
1293 | if (!have_wifi) { | ||
1294 | key->type = KE_KEY; | ||
1295 | key->keycode = KEY_WLAN; | ||
1296 | key--; | ||
1297 | } | ||
1298 | break; | ||
1299 | |||
1300 | case KE_BLUETOOTH: | ||
1301 | if (!have_bluetooth) { | ||
1302 | key->type = KE_KEY; | ||
1303 | key->keycode = KEY_BLUETOOTH; | ||
1304 | key--; | ||
1305 | } | ||
1306 | break; | ||
1307 | |||
1308 | default: | ||
1309 | break; | ||
1310 | } | ||
1311 | } | ||
1312 | |||
1313 | /* reads information flags on KE_END */ | ||
1314 | if (key->code & FE_UNTESTED) | ||
1315 | printk(KERN_WARNING "Untested laptop multimedia keys, " | ||
1316 | "please report success or failure to eric.piel" | ||
1317 | "@tremplin-utc.net\n"); | ||
1318 | 1223 | ||
1319 | error = input_register_polled_device(wistron_idev); | 1224 | error = input_register_polled_device(wistron_idev); |
1320 | if (error) { | 1225 | if (error) |
1321 | input_free_polled_device(wistron_idev); | 1226 | goto err_free_keymap; |
1322 | return error; | ||
1323 | } | ||
1324 | 1227 | ||
1325 | return 0; | 1228 | return 0; |
1229 | |||
1230 | err_free_keymap: | ||
1231 | sparse_keymap_free(input_dev); | ||
1232 | err_free_dev: | ||
1233 | input_free_polled_device(wistron_idev); | ||
1234 | return error; | ||
1326 | } | 1235 | } |
1327 | 1236 | ||
1328 | /* Driver core */ | 1237 | /* Driver core */ |
@@ -1371,6 +1280,7 @@ static int __devexit wistron_remove(struct platform_device *dev) | |||
1371 | { | 1280 | { |
1372 | wistron_led_remove(); | 1281 | wistron_led_remove(); |
1373 | input_unregister_polled_device(wistron_idev); | 1282 | input_unregister_polled_device(wistron_idev); |
1283 | sparse_keymap_free(wistron_idev->input); | ||
1374 | input_free_polled_device(wistron_idev); | 1284 | input_free_polled_device(wistron_idev); |
1375 | bios_detach(); | 1285 | bios_detach(); |
1376 | 1286 | ||