Linux 2.2.0
[davej-history.git] / drivers / char / pc_keyb.c
blobb20d517b616ded123ce1a5243945a80c0dada8b3
1 /*
2 * linux/drivers/char/pc_keyb.c
4 * Separation of the PC low-level part by Geert Uytterhoeven, May 1997
5 * See keyboard.c for the whole history.
7 * Major cleanup by Martin Mares, May 1997
9 * Combined the keyboard and PS/2 mouse handling into one file,
10 * because they share the same hardware.
11 * Johan Myreen <jem@iki.fi> 1998-10-08.
15 #include <linux/config.h>
17 #include <asm/spinlock.h>
18 #include <linux/sched.h>
19 #include <linux/interrupt.h>
20 #include <linux/tty.h>
21 #include <linux/mm.h>
22 #include <linux/signal.h>
23 #include <linux/ioport.h>
24 #include <linux/init.h>
25 #include <linux/kbd_ll.h>
26 #include <linux/delay.h>
27 #include <linux/random.h>
28 #include <linux/poll.h>
29 #include <linux/miscdevice.h>
30 #include <linux/malloc.h>
32 #include <asm/keyboard.h>
33 #include <asm/bitops.h>
34 #include <asm/io.h>
35 #include <asm/uaccess.h>
36 #include <asm/irq.h>
37 #include <asm/system.h>
38 #include <asm/irq.h>
40 /* Some configuration switches are present in the include file... */
42 #include "pc_keyb.h"
44 /* Simple translation table for the SysRq keys */
46 #ifdef CONFIG_MAGIC_SYSRQ
47 unsigned char pckbd_sysrq_xlate[128] =
48 "\000\0331234567890-=\177\t" /* 0x00 - 0x0f */
49 "qwertyuiop[]\r\000as" /* 0x10 - 0x1f */
50 "dfghjkl;'`\000\\zxcv" /* 0x20 - 0x2f */
51 "bnm,./\000*\000 \000\201\202\203\204\205" /* 0x30 - 0x3f */
52 "\206\207\210\211\212\000\000789-456+1" /* 0x40 - 0x4f */
53 "230\177\000\000\213\214\000\000\000\000\000\000\000\000\000\000" /* 0x50 - 0x5f */
54 "\r\000/"; /* 0x60 - 0x6f */
55 #endif
57 static void kbd_write(int address, int data);
58 static unsigned char handle_kbd_event(void);
60 spinlock_t kbd_controller_lock = SPIN_LOCK_UNLOCKED;
62 /* used only by send_data - set by keyboard_interrupt */
63 static volatile unsigned char reply_expected = 0;
64 static volatile unsigned char acknowledge = 0;
65 static volatile unsigned char resend = 0;
68 #if defined CONFIG_PSMOUSE
70 * PS/2 Auxiliary Device
73 static int __init psaux_init(void);
75 static struct aux_queue *queue; /* Mouse data buffer. */
76 static int aux_count = 0;
78 #define AUX_INTS_OFF (KBD_MODE_KCC | KBD_MODE_DISABLE_MOUSE | KBD_MODE_SYS | KBD_MODE_KBD_INT)
79 #define AUX_INTS_ON (KBD_MODE_KCC | KBD_MODE_SYS | KBD_MODE_MOUSE_INT | KBD_MODE_KBD_INT)
81 #define MAX_RETRIES 60 /* some aux operations take long time*/
83 #ifndef AUX_IRQ
84 # define AUX_IRQ 12
85 #endif
87 #endif /* CONFIG_PSMOUSE */
90 * Wait for keyboard controller input buffer to drain.
92 * Don't use 'jiffies' so that we don't depend on
93 * interrupts..
95 * Quote from PS/2 System Reference Manual:
97 * "Address hex 0060 and address hex 0064 should be written only when
98 * the input-buffer-full bit and output-buffer-full bit in the
99 * Controller Status register are set 0."
102 static inline void kb_wait(void)
104 unsigned long timeout = KBC_TIMEOUT;
106 do {
108 * "handle_kbd_event()" will handle any incoming events
109 * while we wait - keypresses or mouse movement.
111 unsigned char status = handle_kbd_event();
113 if (! (status & KBD_STAT_IBF))
114 return;
115 mdelay(1);
116 timeout--;
117 } while (timeout);
118 #ifdef KBD_REPORT_TIMEOUTS
119 printk(KERN_WARNING "Keyboard timed out[1]\n");
120 #endif
124 * Translation of escaped scancodes to keycodes.
125 * This is now user-settable.
126 * The keycodes 1-88,96-111,119 are fairly standard, and
127 * should probably not be changed - changing might confuse X.
128 * X also interprets scancode 0x5d (KEY_Begin).
130 * For 1-88 keycode equals scancode.
133 #define E0_KPENTER 96
134 #define E0_RCTRL 97
135 #define E0_KPSLASH 98
136 #define E0_PRSCR 99
137 #define E0_RALT 100
138 #define E0_BREAK 101 /* (control-pause) */
139 #define E0_HOME 102
140 #define E0_UP 103
141 #define E0_PGUP 104
142 #define E0_LEFT 105
143 #define E0_RIGHT 106
144 #define E0_END 107
145 #define E0_DOWN 108
146 #define E0_PGDN 109
147 #define E0_INS 110
148 #define E0_DEL 111
150 #define E1_PAUSE 119
153 * The keycodes below are randomly located in 89-95,112-118,120-127.
154 * They could be thrown away (and all occurrences below replaced by 0),
155 * but that would force many users to use the `setkeycodes' utility, where
156 * they needed not before. It does not matter that there are duplicates, as
157 * long as no duplication occurs for any single keyboard.
159 #define SC_LIM 89
161 #define FOCUS_PF1 85 /* actual code! */
162 #define FOCUS_PF2 89
163 #define FOCUS_PF3 90
164 #define FOCUS_PF4 91
165 #define FOCUS_PF5 92
166 #define FOCUS_PF6 93
167 #define FOCUS_PF7 94
168 #define FOCUS_PF8 95
169 #define FOCUS_PF9 120
170 #define FOCUS_PF10 121
171 #define FOCUS_PF11 122
172 #define FOCUS_PF12 123
174 #define JAP_86 124
175 /* tfj@olivia.ping.dk:
176 * The four keys are located over the numeric keypad, and are
177 * labelled A1-A4. It's an rc930 keyboard, from
178 * Regnecentralen/RC International, Now ICL.
179 * Scancodes: 59, 5a, 5b, 5c.
181 #define RGN1 124
182 #define RGN2 125
183 #define RGN3 126
184 #define RGN4 127
186 static unsigned char high_keys[128 - SC_LIM] = {
187 RGN1, RGN2, RGN3, RGN4, 0, 0, 0, /* 0x59-0x5f */
188 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60-0x67 */
189 0, 0, 0, 0, 0, FOCUS_PF11, 0, FOCUS_PF12, /* 0x68-0x6f */
190 0, 0, 0, FOCUS_PF2, FOCUS_PF9, 0, 0, FOCUS_PF3, /* 0x70-0x77 */
191 FOCUS_PF4, FOCUS_PF5, FOCUS_PF6, FOCUS_PF7, /* 0x78-0x7b */
192 FOCUS_PF8, JAP_86, FOCUS_PF10, 0 /* 0x7c-0x7f */
195 /* BTC */
196 #define E0_MACRO 112
197 /* LK450 */
198 #define E0_F13 113
199 #define E0_F14 114
200 #define E0_HELP 115
201 #define E0_DO 116
202 #define E0_F17 117
203 #define E0_KPMINPLUS 118
205 * My OmniKey generates e0 4c for the "OMNI" key and the
206 * right alt key does nada. [kkoller@nyx10.cs.du.edu]
208 #define E0_OK 124
210 * New microsoft keyboard is rumoured to have
211 * e0 5b (left window button), e0 5c (right window button),
212 * e0 5d (menu button). [or: LBANNER, RBANNER, RMENU]
213 * [or: Windows_L, Windows_R, TaskMan]
215 #define E0_MSLW 125
216 #define E0_MSRW 126
217 #define E0_MSTM 127
219 static unsigned char e0_keys[128] = {
220 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00-0x07 */
221 0, 0, 0, 0, 0, 0, 0, 0, /* 0x08-0x0f */
222 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10-0x17 */
223 0, 0, 0, 0, E0_KPENTER, E0_RCTRL, 0, 0, /* 0x18-0x1f */
224 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20-0x27 */
225 0, 0, 0, 0, 0, 0, 0, 0, /* 0x28-0x2f */
226 0, 0, 0, 0, 0, E0_KPSLASH, 0, E0_PRSCR, /* 0x30-0x37 */
227 E0_RALT, 0, 0, 0, 0, E0_F13, E0_F14, E0_HELP, /* 0x38-0x3f */
228 E0_DO, E0_F17, 0, 0, 0, 0, E0_BREAK, E0_HOME, /* 0x40-0x47 */
229 E0_UP, E0_PGUP, 0, E0_LEFT, E0_OK, E0_RIGHT, E0_KPMINPLUS, E0_END,/* 0x48-0x4f */
230 E0_DOWN, E0_PGDN, E0_INS, E0_DEL, 0, 0, 0, 0, /* 0x50-0x57 */
231 0, 0, 0, E0_MSLW, E0_MSRW, E0_MSTM, 0, 0, /* 0x58-0x5f */
232 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60-0x67 */
233 0, 0, 0, 0, 0, 0, 0, E0_MACRO, /* 0x68-0x6f */
234 0, 0, 0, 0, 0, 0, 0, 0, /* 0x70-0x77 */
235 0, 0, 0, 0, 0, 0, 0, 0 /* 0x78-0x7f */
238 static unsigned int prev_scancode = 0; /* remember E0, E1 */
240 int pckbd_setkeycode(unsigned int scancode, unsigned int keycode)
242 if (scancode < SC_LIM || scancode > 255 || keycode > 127)
243 return -EINVAL;
244 if (scancode < 128)
245 high_keys[scancode - SC_LIM] = keycode;
246 else
247 e0_keys[scancode - 128] = keycode;
248 return 0;
251 int pckbd_getkeycode(unsigned int scancode)
253 return
254 (scancode < SC_LIM || scancode > 255) ? -EINVAL :
255 (scancode < 128) ? high_keys[scancode - SC_LIM] :
256 e0_keys[scancode - 128];
259 static int do_acknowledge(unsigned char scancode)
261 if (reply_expected) {
262 /* Unfortunately, we must recognise these codes only if we know they
263 * are known to be valid (i.e., after sending a command), because there
264 * are some brain-damaged keyboards (yes, FOCUS 9000 again) which have
265 * keys with such codes :(
267 if (scancode == KBD_REPLY_ACK) {
268 acknowledge = 1;
269 reply_expected = 0;
270 return 0;
271 } else if (scancode == KBD_REPLY_RESEND) {
272 resend = 1;
273 reply_expected = 0;
274 return 0;
276 /* Should not happen... */
277 #if 0
278 printk(KERN_DEBUG "keyboard reply expected - got %02x\n",
279 scancode);
280 #endif
282 if (scancode == 0) {
283 #ifdef KBD_REPORT_ERR
284 printk(KERN_INFO "Keyboard buffer overflow\n");
285 #endif
286 prev_scancode = 0;
287 return 0;
289 return 1;
292 int pckbd_pretranslate(unsigned char scancode, char raw_mode)
294 if (scancode == 0xff) {
295 /* in scancode mode 1, my ESC key generates 0xff */
296 /* the calculator keys on a FOCUS 9000 generate 0xff */
297 #ifndef KBD_IS_FOCUS_9000
298 #ifdef KBD_REPORT_ERR
299 if (!raw_mode)
300 printk(KERN_DEBUG "Keyboard error\n");
301 #endif
302 #endif
303 prev_scancode = 0;
304 return 0;
307 if (scancode == 0xe0 || scancode == 0xe1) {
308 prev_scancode = scancode;
309 return 0;
311 return 1;
314 int pckbd_translate(unsigned char scancode, unsigned char *keycode,
315 char raw_mode)
317 if (prev_scancode) {
319 * usually it will be 0xe0, but a Pause key generates
320 * e1 1d 45 e1 9d c5 when pressed, and nothing when released
322 if (prev_scancode != 0xe0) {
323 if (prev_scancode == 0xe1 && scancode == 0x1d) {
324 prev_scancode = 0x100;
325 return 0;
326 } else if (prev_scancode == 0x100 && scancode == 0x45) {
327 *keycode = E1_PAUSE;
328 prev_scancode = 0;
329 } else {
330 #ifdef KBD_REPORT_UNKN
331 if (!raw_mode)
332 printk(KERN_INFO "keyboard: unknown e1 escape sequence\n");
333 #endif
334 prev_scancode = 0;
335 return 0;
337 } else {
338 prev_scancode = 0;
340 * The keyboard maintains its own internal caps lock and
341 * num lock statuses. In caps lock mode E0 AA precedes make
342 * code and E0 2A follows break code. In num lock mode,
343 * E0 2A precedes make code and E0 AA follows break code.
344 * We do our own book-keeping, so we will just ignore these.
347 * For my keyboard there is no caps lock mode, but there are
348 * both Shift-L and Shift-R modes. The former mode generates
349 * E0 2A / E0 AA pairs, the latter E0 B6 / E0 36 pairs.
350 * So, we should also ignore the latter. - aeb@cwi.nl
352 if (scancode == 0x2a || scancode == 0x36)
353 return 0;
355 if (e0_keys[scancode])
356 *keycode = e0_keys[scancode];
357 else {
358 #ifdef KBD_REPORT_UNKN
359 if (!raw_mode)
360 printk(KERN_INFO "keyboard: unknown scancode e0 %02x\n",
361 scancode);
362 #endif
363 return 0;
366 } else if (scancode >= SC_LIM) {
367 /* This happens with the FOCUS 9000 keyboard
368 Its keys PF1..PF12 are reported to generate
369 55 73 77 78 79 7a 7b 7c 74 7e 6d 6f
370 Moreover, unless repeated, they do not generate
371 key-down events, so we have to zero up_flag below */
372 /* Also, Japanese 86/106 keyboards are reported to
373 generate 0x73 and 0x7d for \ - and \ | respectively. */
374 /* Also, some Brazilian keyboard is reported to produce
375 0x73 and 0x7e for \ ? and KP-dot, respectively. */
377 *keycode = high_keys[scancode - SC_LIM];
379 if (!*keycode) {
380 if (!raw_mode) {
381 #ifdef KBD_REPORT_UNKN
382 printk(KERN_INFO "keyboard: unrecognized scancode (%02x)"
383 " - ignored\n", scancode);
384 #endif
386 return 0;
388 } else
389 *keycode = scancode;
390 return 1;
393 char pckbd_unexpected_up(unsigned char keycode)
395 /* unexpected, but this can happen: maybe this was a key release for a
396 FOCUS 9000 PF key; if we want to see it, we have to clear up_flag */
397 if (keycode >= SC_LIM || keycode == 85)
398 return 0;
399 else
400 return 0200;
404 * This reads the keyboard status port, and does the
405 * appropriate action.
407 * It requires that we hold the keyboard controller
408 * spinlock.
410 static unsigned char handle_kbd_event(void)
412 unsigned char status = inb(KBD_STATUS_REG);
414 while (status & KBD_STAT_OBF) {
415 unsigned char scancode;
417 scancode = inb(KBD_DATA_REG);
419 if (status & KBD_STAT_MOUSE_OBF) {
420 #ifdef CONFIG_PSMOUSE
421 /* Mouse data. */
422 if (aux_count) {
423 int head = queue->head;
424 queue->buf[head] = scancode;
425 add_mouse_randomness(scancode);
426 head = (head + 1) & (AUX_BUF_SIZE-1);
427 if (head != queue->tail) {
428 queue->head = head;
429 if (queue->fasync)
430 kill_fasync(queue->fasync, SIGIO);
431 wake_up_interruptible(&queue->proc_list);
434 #endif
435 } else {
436 if (do_acknowledge(scancode))
437 handle_scancode(scancode);
438 mark_bh(KEYBOARD_BH);
441 status = inb(KBD_STATUS_REG);
444 return status;
448 static void keyboard_interrupt(int irq, void *dev_id, struct pt_regs *regs)
450 unsigned long flags;
452 kbd_pt_regs = regs;
454 spin_lock_irqsave(&kbd_controller_lock, flags);
455 handle_kbd_event();
456 spin_unlock_irqrestore(&kbd_controller_lock, flags);
460 * send_data sends a character to the keyboard and waits
461 * for an acknowledge, possibly retrying if asked to. Returns
462 * the success status.
464 * Don't use 'jiffies', so that we don't depend on interrupts
466 static int send_data(unsigned char data)
468 int retries = 3;
470 do {
471 unsigned long timeout = KBD_TIMEOUT;
473 acknowledge = 0; /* Set by interrupt routine on receipt of ACK. */
474 resend = 0;
475 reply_expected = 1;
476 kbd_write(KBD_DATA_REG, data);
477 for (;;) {
478 if (acknowledge)
479 return 1;
480 if (resend)
481 break;
482 mdelay(1);
483 if (!--timeout) {
484 #ifdef KBD_REPORT_TIMEOUTS
485 printk(KERN_WARNING "Keyboard timeout[2]\n");
486 #endif
487 return 0;
490 } while (retries-- > 0);
491 #ifdef KBD_REPORT_TIMEOUTS
492 printk(KERN_WARNING "keyboard: Too many NACKs -- noisy kbd cable?\n");
493 #endif
494 return 0;
497 void pckbd_leds(unsigned char leds)
499 if (!send_data(KBD_CMD_SET_LEDS) || !send_data(leds))
500 send_data(KBD_CMD_ENABLE); /* re-enable kbd if any errors */
504 * In case we run on a non-x86 hardware we need to initialize both the
505 * keyboard controller and the keyboard. On a x86, the BIOS will
506 * already have initialized them.
508 * Some x86 BIOSes do not correctly initialize the keyboard, so the
509 * "kbd-reset" command line options can be given to force a reset.
510 * [Ranger]
512 #ifdef __i386__
513 int kbd_startup_reset __initdata = 0;
514 #else
515 int kbd_startup_reset __initdata = 1;
516 #endif
518 /* for "kbd-reset" cmdline param */
519 void __init kbd_reset_setup(char *str, int *ints)
521 kbd_startup_reset = 1;
524 #define KBD_NO_DATA (-1) /* No data */
525 #define KBD_BAD_DATA (-2) /* Parity or other error */
527 static int __init kbd_read_input(void)
529 int retval = KBD_NO_DATA;
530 unsigned char status;
532 status = inb(KBD_STATUS_REG);
533 if (status & KBD_STAT_OBF) {
534 unsigned char data = inb(KBD_DATA_REG);
536 retval = data;
537 if (status & (KBD_STAT_GTO | KBD_STAT_PERR))
538 retval = KBD_BAD_DATA;
540 return retval;
543 static void __init kbd_clear_input(void)
545 int maxread = 100; /* Random number */
547 do {
548 if (kbd_read_input() == KBD_NO_DATA)
549 break;
550 } while (--maxread);
553 static int __init kbd_wait_for_input(void)
555 long timeout = KBD_INIT_TIMEOUT;
557 do {
558 int retval = kbd_read_input();
559 if (retval >= 0)
560 return retval;
561 mdelay(1);
562 } while (--timeout);
563 return -1;
566 static void kbd_write(int address, int data)
568 unsigned long flags;
570 spin_lock_irqsave(&kbd_controller_lock, flags);
571 kb_wait();
572 outb(data, address);
573 spin_unlock_irqrestore(&kbd_controller_lock, flags);
576 #if defined CONFIG_PSMOUSE
577 static void kbd_write_cmd(int cmd)
579 unsigned long flags;
581 spin_lock_irqsave(&kbd_controller_lock, flags);
582 kb_wait();
583 outb(KBD_CCMD_WRITE_MODE, KBD_CNTL_REG);
584 kb_wait();
585 outb(cmd, KBD_DATA_REG);
586 spin_unlock_irqrestore(&kbd_controller_lock, flags);
588 #endif /* CONFIG_PSMOUSE */
590 static char * __init initialize_kbd(void)
592 int status;
595 * Test the keyboard interface.
596 * This seems to be the only way to get it going.
597 * If the test is successful a x55 is placed in the input buffer.
599 kbd_write(KBD_CNTL_REG, KBD_CCMD_SELF_TEST);
600 if (kbd_wait_for_input() != 0x55)
601 return "Keyboard failed self test";
604 * Perform a keyboard interface test. This causes the controller
605 * to test the keyboard clock and data lines. The results of the
606 * test are placed in the input buffer.
608 kbd_write(KBD_CNTL_REG, KBD_CCMD_KBD_TEST);
609 if (kbd_wait_for_input() != 0x00)
610 return "Keyboard interface failed self test";
613 * Enable the keyboard by allowing the keyboard clock to run.
615 kbd_write(KBD_CNTL_REG, KBD_CCMD_KBD_ENABLE);
618 * Reset keyboard. If the read times out
619 * then the assumption is that no keyboard is
620 * plugged into the machine.
621 * This defaults the keyboard to scan-code set 2.
623 * Set up to try again if the keyboard asks for RESEND.
625 do {
626 kbd_write(KBD_DATA_REG, KBD_CMD_RESET);
627 status = kbd_wait_for_input();
628 if (status == KBD_REPLY_ACK)
629 break;
630 if (status != KBD_REPLY_RESEND)
631 return "Keyboard reset failed, no ACK";
632 } while (1);
634 if (kbd_wait_for_input() != KBD_REPLY_POR)
635 return "Keyboard reset failed, no POR";
638 * Set keyboard controller mode. During this, the keyboard should be
639 * in the disabled state.
641 * Set up to try again if the keyboard asks for RESEND.
643 do {
644 kbd_write(KBD_DATA_REG, KBD_CMD_DISABLE);
645 status = kbd_wait_for_input();
646 if (status == KBD_REPLY_ACK)
647 break;
648 if (status != KBD_REPLY_RESEND)
649 return "Disable keyboard: no ACK";
650 } while (1);
652 kbd_write(KBD_CNTL_REG, KBD_CCMD_WRITE_MODE);
653 kbd_write(KBD_DATA_REG, KBD_MODE_KBD_INT
654 | KBD_MODE_SYS
655 | KBD_MODE_DISABLE_MOUSE
656 | KBD_MODE_KCC);
658 /* ibm powerpc portables need this to use scan-code set 1 -- Cort */
659 kbd_write(KBD_CNTL_REG, KBD_CCMD_READ_MODE);
660 if (!(kbd_wait_for_input() & KBD_MODE_KCC)) {
662 * If the controller does not support conversion,
663 * Set the keyboard to scan-code set 1.
665 kbd_write(KBD_DATA_REG, 0xF0);
666 kbd_wait_for_input();
667 kbd_write(KBD_DATA_REG, 0x01);
668 kbd_wait_for_input();
672 kbd_write(KBD_DATA_REG, KBD_CMD_ENABLE);
673 if (kbd_wait_for_input() != KBD_REPLY_ACK)
674 return "Enable keyboard: no ACK";
677 * Finally, set the typematic rate to maximum.
679 kbd_write(KBD_DATA_REG, KBD_CMD_SET_RATE);
680 if (kbd_wait_for_input() != KBD_REPLY_ACK)
681 return "Set rate: no ACK";
682 kbd_write(KBD_DATA_REG, 0x00);
683 if (kbd_wait_for_input() != KBD_REPLY_ACK)
684 return "Set rate: no ACK";
686 return NULL;
689 void __init pckbd_init_hw(void)
691 /* Get the keyboard controller registers (incomplete decode) */
692 request_region(0x60, 16, "keyboard");
694 /* Flush any pending input. */
695 kbd_clear_input();
697 if (kbd_startup_reset) {
698 char *msg = initialize_kbd();
699 if (msg)
700 printk(KERN_WARNING "initialize_kbd: %s\n", msg);
703 #if defined CONFIG_PSMOUSE
704 psaux_init();
705 #endif
707 /* Ok, finally allocate the IRQ, and off we go.. */
708 request_irq(KEYBOARD_IRQ, keyboard_interrupt, 0, "keyboard", NULL);
711 #if defined CONFIG_PSMOUSE
714 * Check if this is a dual port controller.
716 static int __init detect_auxiliary_port(void)
718 unsigned long flags;
719 unsigned char status;
720 unsigned char val;
721 int loops = 5;
722 int retval = 0;
724 spin_lock_irqsave(&kbd_controller_lock, flags);
726 /* Put the value 0x5A in the output buffer using the "Write
727 * Auxiliary Device Output Buffer" command (0xD3). Poll the
728 * Status Register for a while to see if the value really
729 * turns up in the Data Register. If the KBD_STAT_MOUSE_OBF
730 * bit is also set to 1 in the Status Register, we assume this
731 * controller has an Auxiliary Port (a.k.a. Mouse Port).
733 kb_wait();
734 outb(KBD_CCMD_WRITE_AUX_OBUF, KBD_CNTL_REG);
736 kb_wait();
737 outb(0x5a, KBD_DATA_REG); /* 0x5a is a random dummy value. */
739 status = inb(KBD_STATUS_REG);
740 while (!(status & KBD_STAT_OBF) && loops--) {
741 mdelay(1);
742 status = inb(KBD_STATUS_REG);
745 if (status & KBD_STAT_OBF) {
746 val = inb(KBD_DATA_REG);
747 if (status & KBD_STAT_MOUSE_OBF) {
748 printk(KERN_INFO "Detected PS/2 Mouse Port.\n");
749 retval = 1;
753 spin_unlock_irqrestore(&kbd_controller_lock, flags);
755 return retval;
759 * Send a byte to the mouse.
761 static void aux_write_dev(int val)
763 unsigned long flags;
765 spin_lock_irqsave(&kbd_controller_lock, flags);
766 kb_wait();
767 outb(KBD_CCMD_WRITE_MOUSE, KBD_CNTL_REG);
768 kb_wait();
769 outb(val, KBD_DATA_REG);
770 spin_unlock_irqrestore(&kbd_controller_lock, flags);
773 static unsigned int get_from_queue(void)
775 unsigned int result;
776 unsigned long flags;
778 save_flags(flags);
779 cli();
780 result = queue->buf[queue->tail];
781 queue->tail = (queue->tail + 1) & (AUX_BUF_SIZE-1);
782 restore_flags(flags);
783 return result;
787 static inline int queue_empty(void)
789 return queue->head == queue->tail;
792 static int fasync_aux(int fd, struct file *filp, int on)
794 int retval;
796 retval = fasync_helper(fd, filp, on, &queue->fasync);
797 if (retval < 0)
798 return retval;
799 return 0;
804 * Random magic cookie for the aux device
806 #define AUX_DEV ((void *)queue)
808 static int release_aux(struct inode * inode, struct file * file)
810 fasync_aux(-1, file, 0);
811 if (--aux_count)
812 return 0;
813 kbd_write_cmd(AUX_INTS_OFF); /* Disable controller ints */
814 kbd_write(KBD_CNTL_REG, KBD_CCMD_MOUSE_DISABLE);
815 free_irq(AUX_IRQ, AUX_DEV);
816 return 0;
820 * Install interrupt handler.
821 * Enable auxiliary device.
824 static int open_aux(struct inode * inode, struct file * file)
826 if (aux_count++) {
827 return 0;
829 queue->head = queue->tail = 0; /* Flush input queue */
830 if (request_irq(AUX_IRQ, keyboard_interrupt, SA_SHIRQ, "PS/2 Mouse", AUX_DEV)) {
831 aux_count--;
832 return -EBUSY;
834 kbd_write(KBD_CNTL_REG, KBD_CCMD_MOUSE_ENABLE); /* Enable the
835 auxiliary port on
836 controller. */
837 aux_write_dev(AUX_ENABLE_DEV); /* Enable aux device */
838 kbd_write_cmd(AUX_INTS_ON); /* Enable controller ints */
840 return 0;
844 * Put bytes from input queue to buffer.
847 static ssize_t read_aux(struct file * file, char * buffer,
848 size_t count, loff_t *ppos)
850 struct wait_queue wait = { current, NULL };
851 ssize_t i = count;
852 unsigned char c;
854 if (queue_empty()) {
855 if (file->f_flags & O_NONBLOCK)
856 return -EAGAIN;
857 add_wait_queue(&queue->proc_list, &wait);
858 repeat:
859 current->state = TASK_INTERRUPTIBLE;
860 if (queue_empty() && !signal_pending(current)) {
861 schedule();
862 goto repeat;
864 current->state = TASK_RUNNING;
865 remove_wait_queue(&queue->proc_list, &wait);
867 while (i > 0 && !queue_empty()) {
868 c = get_from_queue();
869 put_user(c, buffer++);
870 i--;
872 if (count-i) {
873 file->f_dentry->d_inode->i_atime = CURRENT_TIME;
874 return count-i;
876 if (signal_pending(current))
877 return -ERESTARTSYS;
878 return 0;
882 * Write to the aux device.
885 static ssize_t write_aux(struct file * file, const char * buffer,
886 size_t count, loff_t *ppos)
888 ssize_t retval = 0;
890 if (count) {
891 ssize_t written = 0;
893 if (count > 32)
894 count = 32; /* Limit to 32 bytes. */
895 do {
896 char c;
897 get_user(c, buffer++);
898 aux_write_dev(c);
899 written++;
900 } while (--count);
901 retval = -EIO;
902 if (written) {
903 retval = written;
904 file->f_dentry->d_inode->i_mtime = CURRENT_TIME;
908 return retval;
911 static unsigned int aux_poll(struct file *file, poll_table * wait)
913 poll_wait(file, &queue->proc_list, wait);
914 if (!queue_empty())
915 return POLLIN | POLLRDNORM;
916 return 0;
919 struct file_operations psaux_fops = {
920 NULL, /* seek */
921 read_aux,
922 write_aux,
923 NULL, /* readdir */
924 aux_poll,
925 NULL, /* ioctl */
926 NULL, /* mmap */
927 open_aux,
928 NULL, /* flush */
929 release_aux,
930 NULL,
931 fasync_aux,
935 * Initialize driver.
937 static struct miscdevice psaux_mouse = {
938 PSMOUSE_MINOR, "psaux", &psaux_fops
941 static int __init psaux_init(void)
943 if (!detect_auxiliary_port())
944 return -EIO;
946 misc_register(&psaux_mouse);
947 queue = (struct aux_queue *) kmalloc(sizeof(*queue), GFP_KERNEL);
948 memset(queue, 0, sizeof(*queue));
949 queue->head = queue->tail = 0;
950 queue->proc_list = NULL;
952 #ifdef INITIALIZE_MOUSE
953 kbd_write(KBD_CNTL_REG, KBD_CCMD_MOUSE_ENABLE); /* Enable Aux. */
954 aux_write_dev(AUX_SET_SAMPLE);
955 aux_write_dev(100); /* 100 samples/sec */
956 aux_write_dev(AUX_SET_RES);
957 aux_write_dev(3); /* 8 counts per mm */
958 aux_write_dev(AUX_SET_SCALE21); /* 2:1 scaling */
959 #endif /* INITIALIZE_MOUSE */
960 kbd_write(KBD_CNTL_REG, KBD_CCMD_MOUSE_DISABLE); /* Disable aux device. */
961 kbd_write_cmd(AUX_INTS_OFF); /* Disable controller ints. */
963 return 0;
966 #endif /* CONFIG_PSMOUSE */