aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/input/misc/Kconfig1
-rw-r--r--drivers/input/misc/wistron_btns.c200
2 files changed, 102 insertions, 99 deletions
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index 4326f536f849..9b26574f1466 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -65,6 +65,7 @@ config INPUT_COBALT_BTNS
65config INPUT_WISTRON_BTNS 65config INPUT_WISTRON_BTNS
66 tristate "x86 Wistron laptop button interface" 66 tristate "x86 Wistron laptop button interface"
67 depends on X86 && !X86_64 67 depends on X86 && !X86_64
68 select INPUT_POLLDEV
68 select NEW_LEDS 69 select NEW_LEDS
69 select LEDS_CLASS 70 select LEDS_CLASS
70 help 71 help
diff --git a/drivers/input/misc/wistron_btns.c b/drivers/input/misc/wistron_btns.c
index d58ddcab601f..622630f051a5 100644
--- a/drivers/input/misc/wistron_btns.c
+++ b/drivers/input/misc/wistron_btns.c
@@ -20,7 +20,7 @@
20#include <linux/io.h> 20#include <linux/io.h>
21#include <linux/dmi.h> 21#include <linux/dmi.h>
22#include <linux/init.h> 22#include <linux/init.h>
23#include <linux/input.h> 23#include <linux/input-polldev.h>
24#include <linux/interrupt.h> 24#include <linux/interrupt.h>
25#include <linux/jiffies.h> 25#include <linux/jiffies.h>
26#include <linux/kernel.h> 26#include <linux/kernel.h>
@@ -28,23 +28,13 @@
28#include <linux/module.h> 28#include <linux/module.h>
29#include <linux/preempt.h> 29#include <linux/preempt.h>
30#include <linux/string.h> 30#include <linux/string.h>
31#include <linux/timer.h>
32#include <linux/types.h> 31#include <linux/types.h>
33#include <linux/platform_device.h> 32#include <linux/platform_device.h>
34#include <linux/leds.h> 33#include <linux/leds.h>
35 34
36/* 35/* How often we poll keys - msecs */
37 * Number of attempts to read data from queue per poll; 36#define POLL_INTERVAL_DEFAULT 500 /* when idle */
38 * the queue can hold up to 31 entries 37#define POLL_INTERVAL_BURST 100 /* when a key was recently pressed */
39 */
40#define MAX_POLL_ITERATIONS 64
41
42#define POLL_FREQUENCY 2 /* Number of polls per second when idle */
43#define POLL_FREQUENCY_BURST 10 /* Polls per second when a key was recently pressed */
44
45#if POLL_FREQUENCY_BURST > HZ
46#error "POLL_FREQUENCY too high"
47#endif
48 38
49/* BIOS subsystem IDs */ 39/* BIOS subsystem IDs */
50#define WIFI 0x35 40#define WIFI 0x35
@@ -973,66 +963,23 @@ static int __init select_keymap(void)
973 963
974 /* Input layer interface */ 964 /* Input layer interface */
975 965
976static struct input_dev *input_dev; 966static struct input_polled_dev *wistron_idev;
977 967static unsigned long jiffies_last_press;
978static int __devinit setup_input_dev(void) 968static int wifi_enabled;
979{ 969static int bluetooth_enabled;
980 const struct key_entry *key;
981 int error;
982
983 input_dev = input_allocate_device();
984 if (!input_dev)
985 return -ENOMEM;
986
987 input_dev->name = "Wistron laptop buttons";
988 input_dev->phys = "wistron/input0";
989 input_dev->id.bustype = BUS_HOST;
990 input_dev->cdev.dev = &wistron_device->dev;
991
992 for (key = keymap; key->type != KE_END; key++) {
993 switch (key->type) {
994 case KE_KEY:
995 set_bit(EV_KEY, input_dev->evbit);
996 set_bit(key->keycode, input_dev->keybit);
997 break;
998
999 case KE_SW:
1000 set_bit(EV_SW, input_dev->evbit);
1001 set_bit(key->sw.code, input_dev->swbit);
1002 break;
1003
1004 default:
1005 ;
1006 }
1007 }
1008
1009 /* reads information flags on KE_END */
1010 if (key->code & FE_UNTESTED)
1011 printk(KERN_WARNING "Untested laptop multimedia keys, "
1012 "please report success or failure to eric.piel"
1013 "@tremplin-utc.net\n");
1014
1015 error = input_register_device(input_dev);
1016 if (error) {
1017 input_free_device(input_dev);
1018 return error;
1019 }
1020
1021 return 0;
1022}
1023 970
1024static void report_key(unsigned keycode) 971static void report_key(struct input_dev *dev, unsigned int keycode)
1025{ 972{
1026 input_report_key(input_dev, keycode, 1); 973 input_report_key(dev, keycode, 1);
1027 input_sync(input_dev); 974 input_sync(dev);
1028 input_report_key(input_dev, keycode, 0); 975 input_report_key(dev, keycode, 0);
1029 input_sync(input_dev); 976 input_sync(dev);
1030} 977}
1031 978
1032static void report_switch(unsigned code, int value) 979static void report_switch(struct input_dev *dev, unsigned int code, int value)
1033{ 980{
1034 input_report_switch(input_dev, code, value); 981 input_report_switch(dev, code, value);
1035 input_sync(input_dev); 982 input_sync(dev);
1036} 983}
1037 984
1038 985
@@ -1112,15 +1059,6 @@ static inline void wistron_led_resume(void)
1112 led_classdev_resume(&wistron_wifi_led); 1059 led_classdev_resume(&wistron_wifi_led);
1113} 1060}
1114 1061
1115 /* Driver core */
1116
1117static int wifi_enabled;
1118static int bluetooth_enabled;
1119
1120static void poll_bios(unsigned long);
1121
1122static struct timer_list poll_timer = TIMER_INITIALIZER(poll_bios, 0, 0);
1123
1124static void handle_key(u8 code) 1062static void handle_key(u8 code)
1125{ 1063{
1126 const struct key_entry *key; 1064 const struct key_entry *key;
@@ -1129,11 +1067,12 @@ static void handle_key(u8 code)
1129 if (code == key->code) { 1067 if (code == key->code) {
1130 switch (key->type) { 1068 switch (key->type) {
1131 case KE_KEY: 1069 case KE_KEY:
1132 report_key(key->keycode); 1070 report_key(wistron_idev->input, key->keycode);
1133 break; 1071 break;
1134 1072
1135 case KE_SW: 1073 case KE_SW:
1136 report_switch(key->sw.code, key->sw.value); 1074 report_switch(wistron_idev->input,
1075 key->sw.code, key->sw.value);
1137 break; 1076 break;
1138 1077
1139 case KE_WIFI: 1078 case KE_WIFI:
@@ -1152,19 +1091,19 @@ static void handle_key(u8 code)
1152 1091
1153 case KE_END: 1092 case KE_END:
1154 break; 1093 break;
1094
1155 default: 1095 default:
1156 BUG(); 1096 BUG();
1157 } 1097 }
1098 jiffies_last_press = jiffies;
1158 return; 1099 return;
1159 } 1100 }
1160 } 1101 }
1161 printk(KERN_NOTICE "wistron_btns: Unknown key code %02X\n", code); 1102 printk(KERN_NOTICE "wistron_btns: Unknown key code %02X\n", code);
1162} 1103}
1163 1104
1164static void poll_bios(unsigned long discard) 1105static void poll_bios(bool discard)
1165{ 1106{
1166 static unsigned long jiffies_last_press;
1167 unsigned long jiffies_now = jiffies;
1168 u8 qlen; 1107 u8 qlen;
1169 u16 val; 1108 u16 val;
1170 1109
@@ -1173,24 +1112,85 @@ static void poll_bios(unsigned long discard)
1173 if (qlen == 0) 1112 if (qlen == 0)
1174 break; 1113 break;
1175 val = bios_pop_queue(); 1114 val = bios_pop_queue();
1176 if (val != 0 && !discard) { 1115 if (val != 0 && !discard)
1177 handle_key((u8)val); 1116 handle_key((u8)val);
1178 jiffies_last_press = jiffies_now;
1179 }
1180 } 1117 }
1118}
1119
1120static void wistron_flush(struct input_polled_dev *dev)
1121{
1122 /* Flush stale event queue */
1123 poll_bios(true);
1124}
1181 1125
1182 /* Increase precision if user is currently pressing keys (< 2s ago) */ 1126static void wistron_poll(struct input_polled_dev *dev)
1183 if (time_after(jiffies_last_press, jiffies_now - (HZ * 2))) 1127{
1184 mod_timer(&poll_timer, jiffies_now + HZ / POLL_FREQUENCY_BURST); 1128 poll_bios(false);
1129
1130 /* Increase poll frequency if user is currently pressing keys (< 2s ago) */
1131 if (time_before(jiffies, jiffies_last_press + 2 * HZ))
1132 dev->poll_interval = POLL_INTERVAL_BURST;
1185 else 1133 else
1186 mod_timer(&poll_timer, jiffies_now + HZ / POLL_FREQUENCY); 1134 dev->poll_interval = POLL_INTERVAL_DEFAULT;
1135}
1136
1137static int __devinit setup_input_dev(void)
1138{
1139 const struct key_entry *key;
1140 struct input_dev *input_dev;
1141 int error;
1142
1143 wistron_idev = input_allocate_polled_device();
1144 if (!wistron_idev)
1145 return -ENOMEM;
1146
1147 wistron_idev->flush = wistron_flush;
1148 wistron_idev->poll = wistron_poll;
1149 wistron_idev->poll_interval = POLL_INTERVAL_DEFAULT;
1150
1151 input_dev = wistron_idev->input;
1152 input_dev->name = "Wistron laptop buttons";
1153 input_dev->phys = "wistron/input0";
1154 input_dev->id.bustype = BUS_HOST;
1155 input_dev->cdev.dev = &wistron_device->dev;
1156
1157 for (key = keymap; key->type != KE_END; key++) {
1158 switch (key->type) {
1159 case KE_KEY:
1160 set_bit(EV_KEY, input_dev->evbit);
1161 set_bit(key->keycode, input_dev->keybit);
1162 break;
1163
1164 case KE_SW:
1165 set_bit(EV_SW, input_dev->evbit);
1166 set_bit(key->sw.code, input_dev->swbit);
1167 break;
1168
1169 default:
1170 break;
1171 }
1172 }
1173
1174 /* reads information flags on KE_END */
1175 if (key->code & FE_UNTESTED)
1176 printk(KERN_WARNING "Untested laptop multimedia keys, "
1177 "please report success or failure to eric.piel"
1178 "@tremplin-utc.net\n");
1179
1180 error = input_register_polled_device(wistron_idev);
1181 if (error) {
1182 input_free_polled_device(wistron_idev);
1183 return error;
1184 }
1185
1186 return 0;
1187} 1187}
1188 1188
1189/* Driver core */
1190
1189static int __devinit wistron_probe(struct platform_device *dev) 1191static int __devinit wistron_probe(struct platform_device *dev)
1190{ 1192{
1191 int err = setup_input_dev(); 1193 int err;
1192 if (err)
1193 return err;
1194 1194
1195 bios_attach(); 1195 bios_attach();
1196 cmos_address = bios_get_cmos_address(); 1196 cmos_address = bios_get_cmos_address();
@@ -1218,16 +1218,20 @@ static int __devinit wistron_probe(struct platform_device *dev)
1218 } 1218 }
1219 1219
1220 wistron_led_init(&dev->dev); 1220 wistron_led_init(&dev->dev);
1221 poll_bios(1); /* Flush stale event queue and arm timer */ 1221 err = setup_input_dev();
1222 if (err) {
1223 bios_detach();
1224 return err;
1225 }
1222 1226
1223 return 0; 1227 return 0;
1224} 1228}
1225 1229
1226static int __devexit wistron_remove(struct platform_device *dev) 1230static int __devexit wistron_remove(struct platform_device *dev)
1227{ 1231{
1228 del_timer_sync(&poll_timer);
1229 wistron_led_remove(); 1232 wistron_led_remove();
1230 input_unregister_device(input_dev); 1233 input_unregister_polled_device(wistron_idev);
1234 input_free_polled_device(wistron_idev);
1231 bios_detach(); 1235 bios_detach();
1232 1236
1233 return 0; 1237 return 0;
@@ -1236,8 +1240,6 @@ static int __devexit wistron_remove(struct platform_device *dev)
1236#ifdef CONFIG_PM 1240#ifdef CONFIG_PM
1237static int wistron_suspend(struct platform_device *dev, pm_message_t state) 1241static int wistron_suspend(struct platform_device *dev, pm_message_t state)
1238{ 1242{
1239 del_timer_sync(&poll_timer);
1240
1241 if (have_wifi) 1243 if (have_wifi)
1242 bios_set_state(WIFI, 0); 1244 bios_set_state(WIFI, 0);
1243 1245
@@ -1257,7 +1259,7 @@ static int wistron_resume(struct platform_device *dev)
1257 bios_set_state(BLUETOOTH, bluetooth_enabled); 1259 bios_set_state(BLUETOOTH, bluetooth_enabled);
1258 1260
1259 wistron_led_resume(); 1261 wistron_led_resume();
1260 poll_bios(1); 1262 poll_bios(true);
1261 1263
1262 return 0; 1264 return 0;
1263} 1265}