wistron_btns.c (389679d8faa38bb6d069d9e1805f15e3cb9a6d7f) wistron_btns.c (c2554c91425a86e5d0409a76b7ddcb328362f08b)
1/*
2 * Wistron laptop button driver
3 * Copyright (C) 2005 Miloslav Trmac <mitr@volny.cz>
4 * Copyright (C) 2005 Bernhard Rosenkraenzer <bero@arklinux.org>
5 * Copyright (C) 2005 Dmitry Torokhov <dtor@mail.ru>
6 *
7 * You can redistribute and/or modify this program under the terms of the
8 * GNU General Public License version 2 as published by the Free Software

--- 6 unchanged lines hidden (view full) ---

15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 59 Temple Place Suite 330, Boston, MA 02111-1307, USA.
19 */
20#include <linux/io.h>
21#include <linux/dmi.h>
22#include <linux/init.h>
1/*
2 * Wistron laptop button driver
3 * Copyright (C) 2005 Miloslav Trmac <mitr@volny.cz>
4 * Copyright (C) 2005 Bernhard Rosenkraenzer <bero@arklinux.org>
5 * Copyright (C) 2005 Dmitry Torokhov <dtor@mail.ru>
6 *
7 * You can redistribute and/or modify this program under the terms of the
8 * GNU General Public License version 2 as published by the Free Software

--- 6 unchanged lines hidden (view full) ---

15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 59 Temple Place Suite 330, Boston, MA 02111-1307, USA.
19 */
20#include <linux/io.h>
21#include <linux/dmi.h>
22#include <linux/init.h>
23#include <linux/input.h>
23#include <linux/input-polldev.h>
24#include <linux/interrupt.h>
25#include <linux/jiffies.h>
26#include <linux/kernel.h>
27#include <linux/mc146818rtc.h>
28#include <linux/module.h>
29#include <linux/preempt.h>
30#include <linux/string.h>
24#include <linux/interrupt.h>
25#include <linux/jiffies.h>
26#include <linux/kernel.h>
27#include <linux/mc146818rtc.h>
28#include <linux/module.h>
29#include <linux/preempt.h>
30#include <linux/string.h>
31#include <linux/timer.h>
32#include <linux/types.h>
33#include <linux/platform_device.h>
34#include <linux/leds.h>
35
31#include <linux/types.h>
32#include <linux/platform_device.h>
33#include <linux/leds.h>
34
36/*
37 * Number of attempts to read data from queue per poll;
38 * the queue can hold up to 31 entries
39 */
40#define MAX_POLL_ITERATIONS 64
35/* How often we poll keys - msecs */
36#define POLL_INTERVAL_DEFAULT 500 /* when idle */
37#define POLL_INTERVAL_BURST 100 /* when a key was recently pressed */
41
38
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
49/* BIOS subsystem IDs */
50#define WIFI 0x35
51#define BLUETOOTH 0x34
52#define MAIL_LED 0x31
53
54MODULE_AUTHOR("Miloslav Trmac <mitr@volny.cz>");
55MODULE_DESCRIPTION("Wistron laptop button driver");
56MODULE_LICENSE("GPL v2");

--- 911 unchanged lines hidden (view full) ---

968 keymap = keymap_empty;
969 }
970
971 return copy_keymap();
972}
973
974 /* Input layer interface */
975
39/* BIOS subsystem IDs */
40#define WIFI 0x35
41#define BLUETOOTH 0x34
42#define MAIL_LED 0x31
43
44MODULE_AUTHOR("Miloslav Trmac <mitr@volny.cz>");
45MODULE_DESCRIPTION("Wistron laptop button driver");
46MODULE_LICENSE("GPL v2");

--- 911 unchanged lines hidden (view full) ---

958 keymap = keymap_empty;
959 }
960
961 return copy_keymap();
962}
963
964 /* Input layer interface */
965
976static struct input_dev *input_dev;
966static struct input_polled_dev *wistron_idev;
967static unsigned long jiffies_last_press;
968static int wifi_enabled;
969static int bluetooth_enabled;
977
970
978static int __devinit setup_input_dev(void)
971static void report_key(struct input_dev *dev, unsigned int keycode)
979{
972{
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;
973 input_report_key(dev, keycode, 1);
974 input_sync(dev);
975 input_report_key(dev, keycode, 0);
976 input_sync(dev);
1022}
1023
977}
978
1024static void report_key(unsigned keycode)
979static void report_switch(struct input_dev *dev, unsigned int code, int value)
1025{
980{
1026 input_report_key(input_dev, keycode, 1);
1027 input_sync(input_dev);
1028 input_report_key(input_dev, keycode, 0);
1029 input_sync(input_dev);
981 input_report_switch(dev, code, value);
982 input_sync(dev);
1030}
1031
983}
984
1032static void report_switch(unsigned code, int value)
1033{
1034 input_report_switch(input_dev, code, value);
1035 input_sync(input_dev);
1036}
1037
985
1038
1039 /* led management */
1040static void wistron_mail_led_set(struct led_classdev *led_cdev,
1041 enum led_brightness value)
1042{
1043 bios_set_state(MAIL_LED, (value != LED_OFF) ? 1 : 0);
1044}
1045
1046/* same as setting up wifi card, but for laptops on which the led is managed */

--- 60 unchanged lines hidden (view full) ---

1107{
1108 if (have_leds & FE_MAIL_LED)
1109 led_classdev_resume(&wistron_mail_led);
1110
1111 if (have_leds & FE_WIFI_LED)
1112 led_classdev_resume(&wistron_wifi_led);
1113}
1114
986 /* led management */
987static void wistron_mail_led_set(struct led_classdev *led_cdev,
988 enum led_brightness value)
989{
990 bios_set_state(MAIL_LED, (value != LED_OFF) ? 1 : 0);
991}
992
993/* same as setting up wifi card, but for laptops on which the led is managed */

--- 60 unchanged lines hidden (view full) ---

1054{
1055 if (have_leds & FE_MAIL_LED)
1056 led_classdev_resume(&wistron_mail_led);
1057
1058 if (have_leds & FE_WIFI_LED)
1059 led_classdev_resume(&wistron_wifi_led);
1060}
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)
1125{
1126 const struct key_entry *key;
1127
1128 for (key = keymap; key->type != KE_END; key++) {
1129 if (code == key->code) {
1130 switch (key->type) {
1131 case KE_KEY:
1062static void handle_key(u8 code)
1063{
1064 const struct key_entry *key;
1065
1066 for (key = keymap; key->type != KE_END; key++) {
1067 if (code == key->code) {
1068 switch (key->type) {
1069 case KE_KEY:
1132 report_key(key->keycode);
1070 report_key(wistron_idev->input, key->keycode);
1133 break;
1134
1135 case KE_SW:
1071 break;
1072
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;
1138
1139 case KE_WIFI:
1140 if (have_wifi) {
1141 wifi_enabled = !wifi_enabled;
1142 bios_set_state(WIFI, wifi_enabled);
1143 }
1144 break;
1145
1146 case KE_BLUETOOTH:
1147 if (have_bluetooth) {
1148 bluetooth_enabled = !bluetooth_enabled;
1149 bios_set_state(BLUETOOTH, bluetooth_enabled);
1150 }
1151 break;
1152
1153 case KE_END:
1154 break;
1076 break;
1077
1078 case KE_WIFI:
1079 if (have_wifi) {
1080 wifi_enabled = !wifi_enabled;
1081 bios_set_state(WIFI, wifi_enabled);
1082 }
1083 break;
1084
1085 case KE_BLUETOOTH:
1086 if (have_bluetooth) {
1087 bluetooth_enabled = !bluetooth_enabled;
1088 bios_set_state(BLUETOOTH, bluetooth_enabled);
1089 }
1090 break;
1091
1092 case KE_END:
1093 break;
1094
1155 default:
1156 BUG();
1157 }
1095 default:
1096 BUG();
1097 }
1098 jiffies_last_press = jiffies;
1158 return;
1159 }
1160 }
1161 printk(KERN_NOTICE "wistron_btns: Unknown key code %02X\n", code);
1162}
1163
1099 return;
1100 }
1101 }
1102 printk(KERN_NOTICE "wistron_btns: Unknown key code %02X\n", code);
1103}
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;
1169 u16 val;
1170
1171 for (;;) {
1172 qlen = CMOS_READ(cmos_address);
1173 if (qlen == 0)
1174 break;
1175 val = bios_pop_queue();
1107 u8 qlen;
1108 u16 val;
1109
1110 for (;;) {
1111 qlen = CMOS_READ(cmos_address);
1112 if (qlen == 0)
1113 break;
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}
1181
1119
1182 /* Increase precision if user is currently pressing keys (< 2s ago) */
1183 if (time_after(jiffies_last_press, jiffies_now - (HZ * 2)))
1184 mod_timer(&poll_timer, jiffies_now + HZ / POLL_FREQUENCY_BURST);
1120static void wistron_flush(struct input_polled_dev *dev)
1121{
1122 /* Flush stale event queue */
1123 poll_bios(true);
1124}
1125
1126static void wistron_poll(struct input_polled_dev *dev)
1127{
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;
1187}
1188
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}
1188
1189/* Driver core */
1190
1189static int __devinit wistron_probe(struct platform_device *dev)
1190{
1191static int __devinit wistron_probe(struct platform_device *dev)
1192{
1191 int err = setup_input_dev();
1192 if (err)
1193 return err;
1193 int err;
1194
1195 bios_attach();
1196 cmos_address = bios_get_cmos_address();
1197
1198 if (have_wifi) {
1199 u16 wifi = bios_get_default_setting(WIFI);
1200 if (wifi & 1)
1201 wifi_enabled = (wifi & 2) ? 1 : 0;

--- 11 unchanged lines hidden (view full) ---

1213 else
1214 have_bluetooth = 0;
1215
1216 if (have_bluetooth)
1217 bios_set_state(BLUETOOTH, bluetooth_enabled);
1218 }
1219
1220 wistron_led_init(&dev->dev);
1194
1195 bios_attach();
1196 cmos_address = bios_get_cmos_address();
1197
1198 if (have_wifi) {
1199 u16 wifi = bios_get_default_setting(WIFI);
1200 if (wifi & 1)
1201 wifi_enabled = (wifi & 2) ? 1 : 0;

--- 11 unchanged lines hidden (view full) ---

1213 else
1214 have_bluetooth = 0;
1215
1216 if (have_bluetooth)
1217 bios_set_state(BLUETOOTH, bluetooth_enabled);
1218 }
1219
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
1223 return 0;
1224}
1225
1226static int __devexit wistron_remove(struct platform_device *dev)
1227{
1226
1227 return 0;
1228}
1229
1230static int __devexit wistron_remove(struct platform_device *dev)
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();
1232
1233 return 0;
1234}
1235
1236#ifdef CONFIG_PM
1237static int wistron_suspend(struct platform_device *dev, pm_message_t state)
1238{
1235 bios_detach();
1236
1237 return 0;
1238}
1239
1240#ifdef CONFIG_PM
1241static int wistron_suspend(struct platform_device *dev, pm_message_t state)
1242{
1239 del_timer_sync(&poll_timer);
1240
1241 if (have_wifi)
1242 bios_set_state(WIFI, 0);
1243
1244 if (have_bluetooth)
1245 bios_set_state(BLUETOOTH, 0);
1246
1247 wistron_led_suspend();
1248 return 0;
1249}
1250
1251static int wistron_resume(struct platform_device *dev)
1252{
1253 if (have_wifi)
1254 bios_set_state(WIFI, wifi_enabled);
1255
1256 if (have_bluetooth)
1257 bios_set_state(BLUETOOTH, bluetooth_enabled);
1258
1259 wistron_led_resume();
1243 if (have_wifi)
1244 bios_set_state(WIFI, 0);
1245
1246 if (have_bluetooth)
1247 bios_set_state(BLUETOOTH, 0);
1248
1249 wistron_led_suspend();
1250 return 0;
1251}
1252
1253static int wistron_resume(struct platform_device *dev)
1254{
1255 if (have_wifi)
1256 bios_set_state(WIFI, wifi_enabled);
1257
1258 if (have_bluetooth)
1259 bios_set_state(BLUETOOTH, bluetooth_enabled);
1260
1261 wistron_led_resume();
1260 poll_bios(1);
1262 poll_bios(true);
1261
1262 return 0;
1263}
1264#else
1265#define wistron_suspend NULL
1266#define wistron_resume NULL
1267#endif
1268

--- 59 unchanged lines hidden ---
1263
1264 return 0;
1265}
1266#else
1267#define wistron_suspend NULL
1268#define wistron_resume NULL
1269#endif
1270

--- 59 unchanged lines hidden ---