]> Pileus Git - ~andy/linux/blob - drivers/input/misc/wistron_btns.c
Input: wistron - convert to dynamic input_dev allocation
[~andy/linux] / drivers / input / misc / wistron_btns.c
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  *
6  * You can redistribute and/or modify this program under the terms of the
7  * GNU General Public License version 2 as published by the Free Software
8  * Foundation.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
13  * Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 59 Temple Place Suite 330, Boston, MA 02111-1307, USA.
18  */
19 #include <asm/io.h>
20 #include <linux/dmi.h>
21 #include <linux/init.h>
22 #include <linux/input.h>
23 #include <linux/interrupt.h>
24 #include <linux/kernel.h>
25 #include <linux/mc146818rtc.h>
26 #include <linux/module.h>
27 #include <linux/preempt.h>
28 #include <linux/string.h>
29 #include <linux/timer.h>
30 #include <linux/types.h>
31
32 /*
33  * Number of attempts to read data from queue per poll;
34  * the queue can hold up to 31 entries
35  */
36 #define MAX_POLL_ITERATIONS 64
37
38 #define POLL_FREQUENCY 10 /* Number of polls per second */
39
40 #if POLL_FREQUENCY > HZ
41 #error "POLL_FREQUENCY too high"
42 #endif
43
44 /* BIOS subsystem IDs */
45 #define WIFI            0x35
46 #define BLUETOOTH       0x34
47
48 MODULE_AUTHOR("Miloslav Trmac <mitr@volny.cz>");
49 MODULE_DESCRIPTION("Wistron laptop button driver");
50 MODULE_LICENSE("GPL v2");
51 MODULE_VERSION("0.1");
52
53 static int force; /* = 0; */
54 module_param(force, bool, 0);
55 MODULE_PARM_DESC(force, "Load even if computer is not in database");
56
57 static char *keymap_name; /* = NULL; */
58 module_param_named(keymap, keymap_name, charp, 0);
59 MODULE_PARM_DESC(keymap, "Keymap name, if it can't be autodetected");
60
61  /* BIOS interface implementation */
62
63 static void __iomem *bios_entry_point; /* BIOS routine entry point */
64 static void __iomem *bios_code_map_base;
65 static void __iomem *bios_data_map_base;
66
67 static u8 cmos_address;
68
69 struct regs {
70         u32 eax, ebx, ecx;
71 };
72
73 static void call_bios(struct regs *regs)
74 {
75         unsigned long flags;
76
77         preempt_disable();
78         local_irq_save(flags);
79         asm volatile ("pushl %%ebp;"
80                       "movl %7, %%ebp;"
81                       "call *%6;"
82                       "popl %%ebp"
83                       : "=a" (regs->eax), "=b" (regs->ebx), "=c" (regs->ecx)
84                       : "0" (regs->eax), "1" (regs->ebx), "2" (regs->ecx),
85                         "m" (bios_entry_point), "m" (bios_data_map_base)
86                       : "edx", "edi", "esi", "memory");
87         local_irq_restore(flags);
88         preempt_enable();
89 }
90
91 static size_t __init locate_wistron_bios(void __iomem *base)
92 {
93         static const unsigned char __initdata signature[] =
94                 { 0x42, 0x21, 0x55, 0x30 };
95         size_t offset;
96
97         for (offset = 0; offset < 0x10000; offset += 0x10) {
98                 if (check_signature(base + offset, signature,
99                                     sizeof(signature)) != 0)
100                         return offset;
101         }
102         return -1;
103 }
104
105 static int __init map_bios(void)
106 {
107         void __iomem *base;
108         size_t offset;
109         u32 entry_point;
110
111         base = ioremap(0xF0000, 0x10000); /* Can't fail */
112         offset = locate_wistron_bios(base);
113         if (offset < 0) {
114                 printk(KERN_ERR "wistron_btns: BIOS entry point not found\n");
115                 iounmap(base);
116                 return -ENODEV;
117         }
118
119         entry_point = readl(base + offset + 5);
120         printk(KERN_DEBUG
121                 "wistron_btns: BIOS signature found at %p, entry point %08X\n",
122                 base + offset, entry_point);
123
124         if (entry_point >= 0xF0000) {
125                 bios_code_map_base = base;
126                 bios_entry_point = bios_code_map_base + (entry_point & 0xFFFF);
127         } else {
128                 iounmap(base);
129                 bios_code_map_base = ioremap(entry_point & ~0x3FFF, 0x4000);
130                 if (bios_code_map_base == NULL) {
131                         printk(KERN_ERR
132                                 "wistron_btns: Can't map BIOS code at %08X\n",
133                                 entry_point & ~0x3FFF);
134                         goto err;
135                 }
136                 bios_entry_point = bios_code_map_base + (entry_point & 0x3FFF);
137         }
138         /* The Windows driver maps 0x10000 bytes, we keep only one page... */
139         bios_data_map_base = ioremap(0x400, 0xc00);
140         if (bios_data_map_base == NULL) {
141                 printk(KERN_ERR "wistron_btns: Can't map BIOS data\n");
142                 goto err_code;
143         }
144         return 0;
145
146 err_code:
147         iounmap(bios_code_map_base);
148 err:
149         return -ENOMEM;
150 }
151
152 static inline void unmap_bios(void)
153 {
154         iounmap(bios_code_map_base);
155         iounmap(bios_data_map_base);
156 }
157
158  /* BIOS calls */
159
160 static u16 bios_pop_queue(void)
161 {
162         struct regs regs;
163
164         memset(&regs, 0, sizeof (regs));
165         regs.eax = 0x9610;
166         regs.ebx = 0x061C;
167         regs.ecx = 0x0000;
168         call_bios(&regs);
169
170         return regs.eax;
171 }
172
173 static void __init bios_attach(void)
174 {
175         struct regs regs;
176
177         memset(&regs, 0, sizeof (regs));
178         regs.eax = 0x9610;
179         regs.ebx = 0x012E;
180         call_bios(&regs);
181 }
182
183 static void bios_detach(void)
184 {
185         struct regs regs;
186
187         memset(&regs, 0, sizeof (regs));
188         regs.eax = 0x9610;
189         regs.ebx = 0x002E;
190         call_bios(&regs);
191 }
192
193 static u8 __init bios_get_cmos_address(void)
194 {
195         struct regs regs;
196
197         memset(&regs, 0, sizeof (regs));
198         regs.eax = 0x9610;
199         regs.ebx = 0x051C;
200         call_bios(&regs);
201
202         return regs.ecx;
203 }
204
205 static u16 __init bios_get_default_setting(u8 subsys)
206 {
207         struct regs regs;
208
209         memset(&regs, 0, sizeof (regs));
210         regs.eax = 0x9610;
211         regs.ebx = 0x0200 | subsys;
212         call_bios(&regs);
213
214         return regs.eax;
215 }
216
217 static void bios_set_state(u8 subsys, int enable)
218 {
219         struct regs regs;
220
221         memset(&regs, 0, sizeof (regs));
222         regs.eax = 0x9610;
223         regs.ebx = (enable ? 0x0100 : 0x0000) | subsys;
224         call_bios(&regs);
225 }
226
227 /* Hardware database */
228
229 struct key_entry {
230         char type;              /* See KE_* below */
231         u8 code;
232         unsigned keycode;       /* For KE_KEY */
233 };
234
235 enum { KE_END, KE_KEY, KE_WIFI, KE_BLUETOOTH };
236
237 static const struct key_entry *keymap; /* = NULL; Current key map */
238 static int have_wifi;
239 static int have_bluetooth;
240
241 static int __init dmi_matched(struct dmi_system_id *dmi)
242 {
243         const struct key_entry *key;
244
245         keymap = dmi->driver_data;
246         for (key = keymap; key->type != KE_END; key++) {
247                 if (key->type == KE_WIFI) {
248                         have_wifi = 1;
249                         break;
250                 } else if (key->type == KE_BLUETOOTH) {
251                         have_bluetooth = 1;
252                         break;
253                 }
254         }
255         return 1;
256 }
257
258 static struct key_entry keymap_empty[] = {
259         { KE_END, 0 }
260 };
261
262 static struct key_entry keymap_fs_amilo_pro_v2000[] = {
263         { KE_KEY,  0x01, KEY_HELP },
264         { KE_KEY,  0x11, KEY_PROG1 },
265         { KE_KEY,  0x12, KEY_PROG2 },
266         { KE_WIFI, 0x30, 0 },
267         { KE_KEY,  0x31, KEY_MAIL },
268         { KE_KEY,  0x36, KEY_WWW },
269         { KE_END,  0 }
270 };
271
272 static struct key_entry keymap_wistron_ms2141[] = {
273         { KE_KEY,  0x11, KEY_PROG1 },
274         { KE_KEY,  0x12, KEY_PROG2 },
275         { KE_WIFI, 0x30, 0 },
276         { KE_KEY,  0x22, KEY_REWIND },
277         { KE_KEY,  0x23, KEY_FORWARD },
278         { KE_KEY,  0x24, KEY_PLAYPAUSE },
279         { KE_KEY,  0x25, KEY_STOPCD },
280         { KE_KEY,  0x31, KEY_MAIL },
281         { KE_KEY,  0x36, KEY_WWW },
282         { KE_END,  0 }
283 };
284
285 static struct key_entry keymap_acer_aspire_1500[] = {
286         { KE_KEY, 0x11, KEY_PROG1 },
287         { KE_KEY, 0x12, KEY_PROG2 },
288         { KE_WIFI, 0x30, 0 },
289         { KE_KEY, 0x31, KEY_MAIL },
290         { KE_KEY, 0x36, KEY_WWW },
291         { KE_BLUETOOTH, 0x44, 0 },
292         { KE_END, 0 }
293 };
294
295 /*
296  * If your machine is not here (which is currently rather likely), please send
297  * a list of buttons and their key codes (reported when loading this module
298  * with force=1) and the output of dmidecode to $MODULE_AUTHOR.
299  */
300 static struct dmi_system_id dmi_ids[] = {
301         {
302                 .callback = dmi_matched,
303                 .ident = "Fujitsu-Siemens Amilo Pro V2000",
304                 .matches = {
305                         DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
306                         DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pro V2000"),
307                 },
308                 .driver_data = keymap_fs_amilo_pro_v2000
309         },
310         {
311                 .callback = dmi_matched,
312                 .ident = "Acer Aspire 1500",
313                 .matches = {
314                         DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
315                         DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1500"),
316                 },
317                 .driver_data = keymap_acer_aspire_1500
318         },
319         { 0, }
320 };
321
322 static int __init select_keymap(void)
323 {
324         if (keymap_name != NULL) {
325                 if (strcmp (keymap_name, "1557/MS2141") == 0)
326                         keymap = keymap_wistron_ms2141;
327                 else {
328                         printk(KERN_ERR "wistron_btns: Keymap unknown\n");
329                         return -EINVAL;
330                 }
331         }
332         dmi_check_system(dmi_ids);
333         if (keymap == NULL) {
334                 if (!force) {
335                         printk(KERN_ERR "wistron_btns: System unknown\n");
336                         return -ENODEV;
337                 }
338                 keymap = keymap_empty;
339         }
340         return 0;
341 }
342
343  /* Input layer interface */
344
345 static struct input_dev *input_dev;
346
347 static int __init setup_input_dev(void)
348 {
349         const struct key_entry *key;
350         int error;
351
352         input_dev = input_allocate_device();
353         if (!input_dev)
354                 return -ENOMEM;
355
356         input_dev->name = "Wistron laptop buttons";
357         input_dev->phys = "wistron/input0";
358         input_dev->id.bustype = BUS_HOST;
359
360         for (key = keymap; key->type != KE_END; key++) {
361                 if (key->type == KE_KEY) {
362                         input_dev->evbit[LONG(EV_KEY)] = BIT(EV_KEY);
363                         set_bit(key->keycode, input_dev->keybit);
364                 }
365         }
366
367         error = input_register_device(input_dev);
368         if (error) {
369                 input_free_device(input_dev);
370                 return error;
371         }
372
373         return 0;
374 }
375
376 static void report_key(unsigned keycode)
377 {
378         input_report_key(input_dev, keycode, 1);
379         input_sync(input_dev);
380         input_report_key(input_dev, keycode, 0);
381         input_sync(input_dev);
382 }
383
384  /* Driver core */
385
386 static int wifi_enabled;
387 static int bluetooth_enabled;
388
389 static void poll_bios(unsigned long);
390
391 static struct timer_list poll_timer = TIMER_INITIALIZER(poll_bios, 0, 0);
392
393 static void handle_key(u8 code)
394 {
395         const struct key_entry *key;
396
397         for (key = keymap; key->type != KE_END; key++) {
398                 if (code == key->code) {
399                         switch (key->type) {
400                         case KE_KEY:
401                                 report_key(key->keycode);
402                                 break;
403
404                         case KE_WIFI:
405                                 if (have_wifi) {
406                                         wifi_enabled = !wifi_enabled;
407                                         bios_set_state(WIFI, wifi_enabled);
408                                 }
409                                 break;
410
411                         case KE_BLUETOOTH:
412                                 if (have_bluetooth) {
413                                         bluetooth_enabled = !bluetooth_enabled;
414                                         bios_set_state(BLUETOOTH, bluetooth_enabled);
415                                 }
416                                 break;
417
418                         case KE_END:
419                         default:
420                                 BUG();
421                         }
422                         return;
423                 }
424         }
425         printk(KERN_NOTICE "wistron_btns: Unknown key code %02X\n", code);
426 }
427
428 static void poll_bios(unsigned long discard)
429 {
430         u8 qlen;
431         u16 val;
432
433         for (;;) {
434                 qlen = CMOS_READ(cmos_address);
435                 if (qlen == 0)
436                         break;
437                 val = bios_pop_queue();
438                 if (val != 0 && !discard)
439                         handle_key((u8)val);
440         }
441
442         mod_timer(&poll_timer, jiffies + HZ / POLL_FREQUENCY);
443 }
444
445 static int __init wb_module_init(void)
446 {
447         int err;
448
449         err = select_keymap();
450         if (err)
451                 return err;
452
453         err = map_bios();
454         if (err)
455                 return err;
456
457         bios_attach();
458         cmos_address = bios_get_cmos_address();
459
460         if (have_wifi) {
461                 u16 wifi = bios_get_default_setting(WIFI);
462                 if (wifi & 1)
463                         wifi_enabled = (wifi & 2) ? 1 : 0;
464                 else
465                         have_wifi = 0;
466
467                 if (have_wifi)
468                         bios_set_state(WIFI, wifi_enabled);
469         }
470
471         if (have_bluetooth) {
472                 u16 bt = bios_get_default_setting(BLUETOOTH);
473                 if (bt & 1)
474                         bluetooth_enabled = (bt & 2) ? 1 : 0;
475                 else
476                         have_bluetooth = 0;
477
478                 if (have_bluetooth)
479                         bios_set_state(BLUETOOTH, bluetooth_enabled);
480         }
481
482         err = setup_input_dev();
483         if (err) {
484                 bios_detach();
485                 unmap_bios();
486                 return err;
487         }
488
489         poll_bios(1); /* Flush stale event queue and arm timer */
490
491         return 0;
492 }
493
494 static void __exit wb_module_exit(void)
495 {
496         del_timer_sync(&poll_timer);
497         input_unregister_device(input_dev);
498         bios_detach();
499         unmap_bios();
500 }
501
502 module_init(wb_module_init);
503 module_exit(wb_module_exit);