aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/misc
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2009-12-04 13:22:24 -0500
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2009-12-07 12:26:49 -0500
commite97af4cbbe500e6a3f4e189fe9324c5b99192dd6 (patch)
tree9c0840313afd06cff11c16cf6d5010a1cd5c874f /drivers/input/misc
parent36203c4f3d091b5f6c082663bd1f74273798043a (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/Kconfig1
-rw-r--r--drivers/input/misc/wistron_btns.c178
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
227struct 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
239enum { 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;
1037static bool wifi_enabled; 1027static bool wifi_enabled;
1038static bool bluetooth_enabled; 1028static bool bluetooth_enabled;
1039 1029
1040static 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
1048static 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 */
1056static void wistron_mail_led_set(struct led_classdev *led_cdev, 1031static 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
1131static 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
1142static 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
1153static void handle_key(u8 code) 1106static 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
1223static int wistron_getkeycode(struct input_dev *dev, int scancode, int *keycode) 1170static 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
1235static 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
1256static int __devinit setup_input_dev(void) 1201static 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