Import 2.1.34
[davej-history.git] / drivers / sbus / char / sunkbd.c
blob6c22f6ed0bc44601ff7954909424c98c1568bf20
1 /* keyboard.c: Sun keyboard driver.
3 * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
4 * Added vuid event generation and /dev/kbd device for SunOS
5 * compatibility - Miguel (miguel@nuclecu.unam.mx)
6 */
8 #include <linux/kernel.h>
9 #include <linux/sched.h>
10 #include <linux/tty.h>
11 #include <linux/tty_flip.h>
12 #include <linux/mm.h>
13 #include <linux/ptrace.h>
14 #include <linux/signal.h>
15 #include <linux/string.h>
16 #include <linux/fcntl.h>
17 #include <linux/poll.h>
18 #include <linux/random.h>
19 #include <linux/init.h>
21 #include <asm/kbio.h>
22 #include <asm/vuid_event.h>
23 #include <asm/delay.h>
24 #include <asm/bitops.h>
25 #include <asm/oplib.h>
26 #include <asm/uaccess.h>
28 #include"../../char/kbd_kern.h"
29 #include"../../char/diacr.h"
30 #include"../../char/vt_kern.h"
32 #define SIZE(x) (sizeof(x)/sizeof((x)[0]))
34 /* Define this one if you are making a new frame buffer driver */
35 /* it will not block the keyboard */
36 /* #define CODING_NEW_DRIVER */
38 /* KBD device number, temporal */
39 #define KBD_MAJOR 11
41 #define KBD_REPORT_ERR
42 #define KBD_REPORT_UNKN
44 #ifndef KBD_DEFMODE
45 #define KBD_DEFMODE ((1 << VC_REPEAT) | (1 << VC_META))
46 #endif
48 #ifndef KBD_DEFLEDS
50 * Some laptops take the 789uiojklm,. keys as number pad when NumLock
51 * is on. This seems a good reason to start with NumLock off.
53 #define KBD_DEFLEDS 0
54 #endif
56 #ifndef KBD_DEFLOCK
57 #define KBD_DEFLOCK 0
58 #endif
60 externvoidpoke_blanked_console(void);
61 externvoidctrl_alt_del(void);
62 externvoidreset_vc(unsigned int new_console);
63 externvoidscrollback(int);
64 externvoidscrollfront(int);
66 unsigned char kbd_read_mask =0x01;/* modified by psaux.c */
67 unsigned char aux_device_present =0x00;/* To make kernel/ksyms.c happy */
69 struct wait_queue * keypress_wait = NULL;
71 voidkeyboard_wait_for_keypress(void)
73 sleep_on(&keypress_wait);
77 * global state includes the following, and various static variables
78 * in this module: prev_scancode, shift_state, diacr, npadch, dead_key_next.
79 * (last_console is now a global variable)
82 /* shift state counters.. */
83 static unsigned char k_down[NR_SHIFT] = {0, };
84 /* keyboard key bitmap */
85 #define BITS_PER_LONG (8*sizeof(unsigned long))
86 static unsigned long key_down[256/BITS_PER_LONG] = {0, };
88 voidpush_kbd(int scan);
89 int kbd_redirected =0;
91 static int dead_key_next =0;
92 /*
93 * In order to retrieve the shift_state (for the mouse server), either
94 * the variable must be global, or a new procedure must be created to
95 * return the value. I chose the former way.
97 /*static*/int shift_state =0;
98 static int npadch = -1;/* -1 or number assembled on pad */
99 static unsigned char diacr =0;
100 static char rep =0;/* flag telling character repeat */
101 struct kbd_struct kbd_table[MAX_NR_CONSOLES];
102 static struct tty_struct **ttytab;
103 static struct kbd_struct * kbd = kbd_table;
104 static struct tty_struct * tty = NULL;
105 static int compose_led_on =0;
106 static int kbd_delay_ticks = HZ /5;
107 static int kbd_rate_ticks = HZ /20;
109 externvoidcompute_shiftstate(void);
111 typedefvoid(*k_hand)(unsigned char value,char up_flag);
112 typedefvoid(k_handfn)(unsigned char value,char up_flag);
114 static k_handfn
115 do_self, do_fn, do_spec, do_pad, do_dead, do_cons, do_cur, do_shift,
116 do_meta, do_ascii, do_lock, do_lowercase, do_ignore;
118 static k_hand key_handler[16] = {
119 do_self, do_fn, do_spec, do_pad, do_dead, do_cons, do_cur, do_shift,
120 do_meta, do_ascii, do_lock, do_lowercase,
121 do_ignore, do_ignore, do_ignore, do_ignore
124 typedefvoid(*void_fnp)(void);
125 typedefvoid(void_fn)(void);
127 static void_fn do_null, enter, show_ptregs, send_intr, lastcons, caps_toggle,
128 num, hold, scroll_forw, scroll_back, boot_it, caps_on, compose,
129 SAK, decr_console, incr_console, spawn_console, bare_num;
131 static void_fnp spec_fn_table[] = {
132 do_null, enter, show_ptregs, show_mem,
133 show_state, send_intr, lastcons, caps_toggle,
134 num, hold, scroll_forw, scroll_back,
135 boot_it, caps_on, compose, SAK,
136 decr_console, incr_console, spawn_console, bare_num
139 /* maximum values each key_handler can handle */
140 const int max_vals[] = {
141 255,SIZE(func_table) -1,SIZE(spec_fn_table) -1, NR_PAD -1,
142 NR_DEAD -1,255,3, NR_SHIFT -1,
143 255, NR_ASCII -1, NR_LOCK -1,255
146 const int NR_TYPES =SIZE(max_vals);
148 static voidput_queue(int);
149 static unsigned charhandle_diacr(unsigned char);
151 /* pt_regs - set by keyboard_interrupt(), used by show_ptregs() */
152 static struct pt_regs * pt_regs;
154 volatileunsigned char sunkbd_layout;
155 volatileunsigned char sunkbd_type;
156 #define SUNKBD_TYPE2 0x02
157 #define SUNKBD_TYPE3 0x03
158 #define SUNKBD_TYPE4 0x04
160 #define SUNKBD_LOUT_TYP4 0x00
161 #define SUNKBD_LOUT_TYP5_MASK 0x20
163 volatileint kbd_reset_pending;
164 volatileint kbd_layout_pending;
166 /* commands */
167 #define SKBDCMD_RESET 0x1
168 #define SKBDCMD_GLAYOUT 0xf
169 #define SKBDCMD_BELLON 0x2
170 #define SKBDCMD_BELLOFF 0x3
171 #define SKBDCMD_SETLED 0xe
172 #define SKBDCMD_NOCLICK 0xb
173 #define SKBDCMD_CLICK 0xa
175 static unsigned char sunkbd_clickp;
177 /* The led set commands require sending the SETLED byte then
178 * a byte encoding which led's to have set. Here are the bit
179 * values, a bit set = led-on.
181 #define LED_NLOCK 0x1/* Num-lock */
182 #define LED_CMPOSE 0x2/* Compose */
183 #define LED_SCRLCK 0x4/* Scroll-lock */
184 #define LED_CLOCK 0x8/* Caps-lock */
186 /* Special state characters */
187 #define SKBD_RESET 0xff
188 #define SKBD_ALLUP 0x7f
189 #define SKBD_LYOUT 0xfe
191 /* On the Sparc the keyboard could be one of two things.
192 * It could be a real keyboard speaking over one of the
193 * channels of the second zs8530 chip (other channel is
194 * used by the Sun mouse). Else we have serial console
195 * going, and thus the other zs8530 chip is who we speak
196 * to. Either way, we communicate through the zs8530
197 * driver for all our I/O.
200 #define SUNKBD_UBIT 0x80/* If set, key went up */
201 #define SUNKBD_KMASK 0x7f/* Other bits are the keycode */
203 #define KEY_LSHIFT 0x81
204 #define KEY_RSHIFT 0x82
205 #define KEY_CONTROL 0x83
206 #define KEY_NILL 0x84
207 #define KEY_CAPSLOCK 0x85
208 #define KEY_ALT 0x86
209 #define KEY_L1 0x87
211 externvoidkbd_put_char(unsigned char ch);
212 staticinlinevoidsend_cmd(unsigned char c)
214 kbd_put_char(c);
217 /* kbd_bh() calls this to send the SKBDCMD_SETLED to the sun keyboard
218 * with the proper bit pattern for the leds to be set. It basically
219 * converts the kbd->ledflagstate values to corresponding sun kbd led
220 * bit value.
222 staticinlineunsigned charvcleds_to_sunkbd(unsigned char vcleds)
224 unsigned char retval =0;
226 if(vcleds & (1<<VC_SCROLLOCK))
227 retval |= LED_SCRLCK;
228 if(vcleds & (1<<VC_NUMLOCK))
229 retval |= LED_NLOCK;
230 if(vcleds & (1<<VC_CAPSLOCK))
231 retval |= LED_CLOCK;
232 if(compose_led_on)
233 retval |= LED_CMPOSE;
234 return retval;
238 * Translation of escaped scancodes to keycodes.
239 * This is now user-settable.
240 * The keycodes 1-88,96-111,119 are fairly standard, and
241 * should probably not be changed - changing might confuse X.
242 * X also interprets scancode 0x5d (KEY_Begin).
244 * For 1-88 keycode equals scancode.
247 #define E0_KPENTER 96
248 #define E0_RCTRL 97
249 #define E0_KPSLASH 98
250 #define E0_PRSCR 99
251 #define E0_RALT 100
252 #define E0_BREAK 101/* (control-pause) */
253 #define E0_HOME 102
254 #define E0_UP 103
255 #define E0_PGUP 104
256 #define E0_LEFT 105
257 #define E0_RIGHT 106
258 #define E0_END 107
259 #define E0_DOWN 108
260 #define E0_PGDN 109
261 #define E0_INS 110
262 #define E0_DEL 111
264 #define E1_PAUSE 119
267 * The keycodes below are randomly located in 89-95,112-118,120-127.
268 * They could be thrown away (and all occurrences below replaced by 0),
269 * but that would force many users to use the `setkeycodes' utility, where
270 * they needed not before. It does not matter that there are duplicates, as
271 * long as no duplication occurs for any single keyboard.
273 #define SC_LIM 89
275 #define FOCUS_PF1 85/* actual code! */
276 #define FOCUS_PF2 89
277 #define FOCUS_PF3 90
278 #define FOCUS_PF4 91
279 #define FOCUS_PF5 92
280 #define FOCUS_PF6 93
281 #define FOCUS_PF7 94
282 #define FOCUS_PF8 95
283 #define FOCUS_PF9 120
284 #define FOCUS_PF10 121
285 #define FOCUS_PF11 122
286 #define FOCUS_PF12 123
288 #define JAP_86 124
289 /* tfj@olivia.ping.dk:
290 * The four keys are located over the numeric keypad, and are
291 * labelled A1-A4. It's an rc930 keyboard, from
292 * Regnecentralen/RC International, Now ICL.
293 * Scancodes: 59, 5a, 5b, 5c.
295 #define RGN1 124
296 #define RGN2 125
297 #define RGN3 126
298 #define RGN4 127
300 static unsigned char high_keys[128- SC_LIM] = {
301 RGN1, RGN2, RGN3, RGN4,0,0,0,/* 0x59-0x5f */
302 0,0,0,0,0,0,0,0,/* 0x60-0x67 */
303 0,0,0,0,0, FOCUS_PF11,0, FOCUS_PF12,/* 0x68-0x6f */
304 0,0,0, FOCUS_PF2, FOCUS_PF9,0,0, FOCUS_PF3,/* 0x70-0x77 */
305 FOCUS_PF4, FOCUS_PF5, FOCUS_PF6, FOCUS_PF7,/* 0x78-0x7b */
306 FOCUS_PF8, JAP_86, FOCUS_PF10,0/* 0x7c-0x7f */
309 /* BTC */
310 #define E0_MACRO 112
311 /* LK450 */
312 #define E0_F13 113
313 #define E0_F14 114
314 #define E0_HELP 115
315 #define E0_DO 116
316 #define E0_F17 117
317 #define E0_KPMINPLUS 118
319 * My OmniKey generates e0 4c for the "OMNI" key and the
320 * right alt key does nada. [kkoller@nyx10.cs.du.edu]
322 #define E0_OK 124
324 * New microsoft keyboard is rumoured to have
325 * e0 5b (left window button), e0 5c (right window button),
326 * e0 5d (menu button). [or: LBANNER, RBANNER, RMENU]
327 * [or: Windows_L, Windows_R, TaskMan]
329 #define E0_MSLW 125
330 #define E0_MSRW 126
331 #define E0_MSTM 127
333 static unsigned char e0_keys[128] = {
334 0,0,0,0,0,0,0,0,/* 0x00-0x07 */
335 0,0,0,0,0,0,0,0,/* 0x08-0x0f */
336 0,0,0,0,0,0,0,0,/* 0x10-0x17 */
337 0,0,0,0, E0_KPENTER, E0_RCTRL,0,0,/* 0x18-0x1f */
338 0,0,0,0,0,0,0,0,/* 0x20-0x27 */
339 0,0,0,0,0,0,0,0,/* 0x28-0x2f */
340 0,0,0,0,0, E0_KPSLASH,0, E0_PRSCR,/* 0x30-0x37 */
341 E0_RALT,0,0,0,0, E0_F13, E0_F14, E0_HELP,/* 0x38-0x3f */
342 E0_DO, E0_F17,0,0,0,0, E0_BREAK, E0_HOME,/* 0x40-0x47 */
343 E0_UP, E0_PGUP,0, E0_LEFT, E0_OK, E0_RIGHT, E0_KPMINPLUS, E0_END,/* 0x48-0x4f */
344 E0_DOWN, E0_PGDN, E0_INS, E0_DEL,0,0,0,0,/* 0x50-0x57 */
345 0,0,0, E0_MSLW, E0_MSRW, E0_MSTM,0,0,/* 0x58-0x5f */
346 0,0,0,0,0,0,0,0,/* 0x60-0x67 */
347 0,0,0,0,0,0,0, E0_MACRO,/* 0x68-0x6f */
348 0,0,0,0,0,0,0,0,/* 0x70-0x77 */
349 0,0,0,0,0,0,0,0/* 0x78-0x7f */
352 /* we use this map to determine if a particular key should not be
353 autorepeated. We don't autorepeat CONTROL, LSHIFT, CAPS,
354 ALT, LMETA, RSHIFT, RMETA, ALTG and COMPOSE */
355 static unsigned char norepeat_keys[128] = {
356 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,/* 0x00-0x0f */
357 0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,/* 0x10-0x1f */
358 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,/* 0x20-0x2f */
359 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,/* 0x30-0x3f */
360 0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,/* 0x40-0x4f */
361 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,/* 0x50-0x5f */
362 0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,/* 0x60-0x6f */
363 0,0,0,0,0,0,0,1,1,0,1,0,0,0,0,0,/* 0x70-0x7f */
367 intsetkeycode(unsigned int scancode,unsigned int keycode)
369 if(scancode < SC_LIM || scancode >255|| keycode >127)
370 return-EINVAL;
371 if(scancode <128)
372 high_keys[scancode - SC_LIM] = keycode;
373 else
374 e0_keys[scancode -128] = keycode;
375 return0;
378 intgetkeycode(unsigned int scancode)
380 return
381 (scancode < SC_LIM || scancode >255) ? -EINVAL :
382 (scancode <128) ? high_keys[scancode - SC_LIM] :
383 e0_keys[scancode -128];
386 voidsunkbd_inchar(unsigned char ch,struct pt_regs *regs);
387 static voidkeyboard_timer(unsigned long ignored);
389 static struct timer_list
390 auto_repeat_timer = { NULL, NULL,0,0, keyboard_timer };
392 /* Keeps track of the last pressed key */
393 static unsigned char last_keycode;
395 static void
396 keyboard_timer(unsigned long ignored)
398 unsigned long flags;
400 save_flags(flags);cli();
402 /* Auto repeat: send regs = 0 to indicate autorepeat */
403 sunkbd_inchar(last_keycode,0);
404 del_timer(&auto_repeat_timer);
405 if(kbd_rate_ticks) {
406 auto_repeat_timer.expires = jiffies + kbd_rate_ticks;
407 add_timer(&auto_repeat_timer);
409 restore_flags(flags);
412 /* #define SKBD_DEBUG */
413 /* This is our keyboard 'interrupt' routine. */
414 voidsunkbd_inchar(unsigned char ch,struct pt_regs *regs)
416 unsigned char keycode;
417 char up_flag;/* 0 or SUNKBD_UBIT */
418 char raw_mode;
420 if(ch == SKBD_RESET) {
421 kbd_reset_pending =1;
422 return;
424 if(ch == SKBD_LYOUT) {
425 kbd_layout_pending =1;
426 return;
428 if(kbd_reset_pending) {
429 sunkbd_type = ch;
430 kbd_reset_pending =0;
431 if(ch == SUNKBD_TYPE4)
432 send_cmd(SKBDCMD_GLAYOUT);
433 return;
434 }else if(kbd_layout_pending) {
435 sunkbd_layout = ch;
436 kbd_layout_pending =0;
437 return;
438 }else if(ch == SKBD_ALLUP) {
439 del_timer(&auto_repeat_timer);
440 memset(key_down,0,sizeof(key_down));
441 compute_shiftstate();
442 return;
444 #ifdef SKBD_DEBUG
445 if(ch ==0x7f)
446 printk("KBD<ALL KEYS UP>");
447 else
448 printk("KBD<%x %s>", ch,
449 ((ch&0x80) ?"UP":"DOWN"));
450 #endif
452 /* Whee, a real character. */
453 if(regs) {
454 pt_regs = regs;
455 last_keycode = keycode = ch;
456 }else{
457 keycode = ch;
459 add_keyboard_randomness(keycode);
461 mark_bh(KEYBOARD_BH);
462 do_poke_blanked_console =1;
463 mark_bh(CONSOLE_BH);
464 kbd = kbd_table + fg_console;
465 tty = ttytab[fg_console];
466 if((raw_mode = (kbd->kbdmode == VC_RAW))) {
467 if(kbd_redirected == fg_console+1)
468 push_kbd(keycode);
469 else
470 put_queue(keycode);
471 /* we do not return yet, because we want to maintain
472 * the key_down array, so that we have the correct
473 * values when finishing RAW mode or when changing VT's.
476 up_flag = (keycode & SUNKBD_UBIT);/* The 'up' bit */
477 keycode &= SUNKBD_KMASK;/* all the rest */
478 del_timer(&auto_repeat_timer);
479 if(up_flag) {
480 rep =0;
481 clear_bit(keycode, key_down);
482 }else{
483 if(!norepeat_keys[keycode]) {
484 if(kbd_rate_ticks) {
485 auto_repeat_timer.expires =
486 jiffies + kbd_delay_ticks;
487 add_timer(&auto_repeat_timer);
490 rep =set_bit(keycode, key_down);
493 if(raw_mode)
494 return;
496 if(kbd->kbdmode == VC_MEDIUMRAW) {
497 put_queue(keycode + up_flag);
498 return;
502 * Small change in philosophy: earlier we defined repetition by
503 * rep = keycode == prev_keycode;
504 * prev_keycode = keycode;
505 * but now by the fact that the depressed key was down already.
506 * Does this ever make a difference? Yes.
510 * Repeat a key only if the input buffers are empty or the
511 * characters get echoed locally. This makes key repeat usable
512 * with slow applications and under heavy loads.
514 if(!rep ||
515 (vc_kbd_mode(kbd,VC_REPEAT) && tty &&
516 (L_ECHO(tty) || (tty->driver.chars_in_buffer(tty) ==0)))) {
517 u_short keysym;
518 u_char type;
520 /* the XOR below used to be an OR */
521 int shift_final = shift_state ^ kbd->lockstate;
522 ushort *key_map = key_maps[shift_final];
524 if(key_map != NULL) {
525 keysym = key_map[keycode];
526 type =KTYP(keysym);
528 if(type >=0xf0) {
529 type -=0xf0;
530 if(type == KT_LETTER) {
531 type = KT_LATIN;
532 if(vc_kbd_led(kbd, VC_CAPSLOCK)) {
533 key_map = key_maps[shift_final ^ (1<<KG_SHIFT)];
534 if(key_map)
535 keysym = key_map[keycode];
538 (*key_handler[type])(keysym &0xff, up_flag);
539 if(type != KT_SLOCK)
540 kbd->slockstate =0;
542 }else{
543 /* maybe beep? */
544 /* we have at least to update shift_state */
545 compute_shiftstate();
550 static voidput_queue(int ch)
552 wake_up(&keypress_wait);
553 if(tty) {
554 tty_insert_flip_char(tty, ch,0);
555 tty_schedule_flip(tty);
559 static voidputs_queue(char*cp)
561 wake_up(&keypress_wait);
562 if(!tty)
563 return;
565 while(*cp) {
566 tty_insert_flip_char(tty, *cp,0);
567 cp++;
569 tty_schedule_flip(tty);
572 static voidapplkey(int key,char mode)
574 static char buf[] = {0x1b,'O',0x00,0x00};
576 buf[1] = (mode ?'O':'[');
577 buf[2] = key;
578 puts_queue(buf);
581 static voidenter(void)
583 put_queue(13);
584 if(vc_kbd_mode(kbd,VC_CRLF))
585 put_queue(10);
588 static voidcaps_toggle(void)
590 if(rep)
591 return;
592 chg_vc_kbd_led(kbd, VC_CAPSLOCK);
595 static voidcaps_on(void)
597 if(rep)
598 return;
599 set_vc_kbd_led(kbd, VC_CAPSLOCK);
602 static voidshow_ptregs(void)
604 if(pt_regs)
605 show_regs(pt_regs);
608 static voidhold(void)
610 if(rep || !tty)
611 return;
614 * Note: SCROLLOCK will be set (cleared) by stop_tty (start_tty);
615 * these routines are also activated by ^S/^Q.
616 * (And SCROLLOCK can also be set by the ioctl KDSKBLED.)
618 if(tty->stopped)
619 start_tty(tty);
620 else
621 stop_tty(tty);
624 static voidnum(void)
626 if(vc_kbd_mode(kbd,VC_APPLIC))
627 applkey('P',1);
628 else
629 bare_num();
633 * Bind this to Shift-NumLock if you work in application keypad mode
634 * but want to be able to change the NumLock flag.
635 * Bind this to NumLock if you prefer that the NumLock key always
636 * changes the NumLock flag.
638 static voidbare_num(void)
640 if(!rep)
641 chg_vc_kbd_led(kbd,VC_NUMLOCK);
644 static voidlastcons(void)
646 /* switch to the last used console, ChN */
647 set_console(last_console);
650 static voiddecr_console(void)
652 int i;
654 for(i = fg_console-1; i != fg_console; i--) {
655 if(i == -1)
656 i = MAX_NR_CONSOLES-1;
657 if(vc_cons_allocated(i))
658 break;
660 set_console(i);
663 static voidincr_console(void)
665 int i;
667 for(i = fg_console+1; i != fg_console; i++) {
668 if(i == MAX_NR_CONSOLES)
669 i =0;
670 if(vc_cons_allocated(i))
671 break;
673 set_console(i);
676 static voidsend_intr(void)
678 if(!tty)
679 return;
680 tty_insert_flip_char(tty,0, TTY_BREAK);
681 tty_schedule_flip(tty);
684 static voidscroll_forw(void)
686 scrollfront(0);
689 static voidscroll_back(void)
691 scrollback(0);
694 static voidboot_it(void)
696 externintobp_system_intr(void);
698 if(!obp_system_intr())
699 ctrl_alt_del();
700 /* sigh.. attempt to prevent multiple entry */
701 last_keycode=1;
702 rep =0;
705 static voidcompose(void)
707 dead_key_next =1;
708 compose_led_on =1;
709 set_leds();
712 int spawnpid, spawnsig;
714 static voidspawn_console(void)
716 if(spawnpid)
717 if(kill_proc(spawnpid, spawnsig,1))
718 spawnpid =0;
721 static voidSAK(void)
723 do_SAK(tty);
724 #if 0
726 * Need to fix SAK handling to fix up RAW/MEDIUM_RAW and
727 * vt_cons modes before we can enable RAW/MEDIUM_RAW SAK
728 * handling.
730 * We should do this some day --- the whole point of a secure
731 * attention key is that it should be guaranteed to always
732 * work.
734 reset_vc(fg_console);
735 do_unblank_screen();/* not in interrupt routine? */
736 #endif
739 static voiddo_ignore(unsigned char value,char up_flag)
743 static voiddo_null()
745 compute_shiftstate();
748 static voiddo_spec(unsigned char value,char up_flag)
750 if(up_flag)
751 return;
752 if(value >=SIZE(spec_fn_table))
753 return;
754 spec_fn_table[value]();
757 static voiddo_lowercase(unsigned char value,char up_flag)
759 printk("keyboard.c: do_lowercase was called - impossible\n");
762 static voiddo_self(unsigned char value,char up_flag)
764 if(up_flag)
765 return;/* no action, if this is a key release */
767 if(diacr) {
768 value =handle_diacr(value);
769 compose_led_on =0;
770 set_leds();
773 if(dead_key_next) {
774 dead_key_next =0;
775 diacr = value;
776 return;
779 put_queue(value);
782 #define A_GRAVE'`'
783 #define A_ACUTE'\''
784 #define A_CFLEX'^'
785 #define A_TILDE'~'
786 #define A_DIAER'"'
787 #define A_CEDIL','
788 static unsigned char ret_diacr[NR_DEAD] =
789 {A_GRAVE, A_ACUTE, A_CFLEX, A_TILDE, A_DIAER, A_CEDIL };
791 /* If a dead key pressed twice, output a character corresponding to it, */
792 /* otherwise just remember the dead key. */
794 static voiddo_dead(unsigned char value,char up_flag)
796 if(up_flag)
797 return;
799 value = ret_diacr[value];
800 if(diacr == value) {/* pressed twice */
801 diacr =0;
802 put_queue(value);
803 return;
805 diacr = value;
809 /* If space is pressed, return the character corresponding the pending */
810 /* dead key, otherwise try to combine the two. */
812 unsigned charhandle_diacr(unsigned char ch)
814 int d = diacr;
815 int i;
817 diacr =0;
818 if(ch ==' ')
819 return d;
821 for(i =0; i < accent_table_size; i++) {
822 if(accent_table[i].diacr == d && accent_table[i].base == ch)
823 return accent_table[i].result;
826 put_queue(d);
827 return ch;
830 static voiddo_cons(unsigned char value,char up_flag)
832 if(up_flag)
833 return;
834 set_console(value);
837 static voiddo_fn(unsigned char value,char up_flag)
839 if(up_flag)
840 return;
841 if(value <SIZE(func_table)) {
842 if(func_table[value])
843 puts_queue(func_table[value]);
844 }else
845 printk("do_fn called with value=%d\n", value);
848 static voiddo_pad(unsigned char value,char up_flag)
850 static const char*pad_chars ="0123456789+-*/\015,.?";
851 static const char*app_map ="pqrstuvwxylSRQMnn?";
853 if(up_flag)
854 return;/* no action, if this is a key release */
856 /* kludge... shift forces cursor/number keys */
857 if(vc_kbd_mode(kbd,VC_APPLIC) && !k_down[KG_SHIFT]) {
858 applkey(app_map[value],1);
859 return;
862 if(!vc_kbd_led(kbd,VC_NUMLOCK))
863 switch(value) {
864 caseKVAL(K_PCOMMA):
865 caseKVAL(K_PDOT):
866 do_fn(KVAL(K_REMOVE),0);
867 return;
868 caseKVAL(K_P0):
869 do_fn(KVAL(K_INSERT),0);
870 return;
871 caseKVAL(K_P1):
872 do_fn(KVAL(K_SELECT),0);
873 return;
874 caseKVAL(K_P2):
875 do_cur(KVAL(K_DOWN),0);
876 return;
877 caseKVAL(K_P3):
878 do_fn(KVAL(K_PGDN),0);
879 return;
880 caseKVAL(K_P4):
881 do_cur(KVAL(K_LEFT),0);
882 return;
883 caseKVAL(K_P6):
884 do_cur(KVAL(K_RIGHT),0);
885 return;
886 caseKVAL(K_P7):
887 do_fn(KVAL(K_FIND),0);
888 return;
889 caseKVAL(K_P8):
890 do_cur(KVAL(K_UP),0);
891 return;
892 caseKVAL(K_P9):
893 do_fn(KVAL(K_PGUP),0);
894 return;
895 caseKVAL(K_P5):
896 applkey('G',vc_kbd_mode(kbd, VC_APPLIC));
897 return;
900 put_queue(pad_chars[value]);
901 if(value ==KVAL(K_PENTER) &&vc_kbd_mode(kbd, VC_CRLF))
902 put_queue(10);
905 static voiddo_cur(unsigned char value,char up_flag)
907 static const char*cur_chars ="BDCA";
908 if(up_flag)
909 return;
911 applkey(cur_chars[value],vc_kbd_mode(kbd,VC_CKMODE));
914 static voiddo_shift(unsigned char value,char up_flag)
916 int old_state = shift_state;
918 if(rep)
919 return;
921 /* Mimic typewriter:
922 a CapsShift key acts like Shift but undoes CapsLock */
923 if(value ==KVAL(K_CAPSSHIFT)) {
924 value =KVAL(K_SHIFT);
925 if(!up_flag)
926 clr_vc_kbd_led(kbd, VC_CAPSLOCK);
929 if(up_flag) {
930 /* handle the case that two shift or control
931 keys are depressed simultaneously */
932 if(k_down[value])
933 k_down[value]--;
934 }else
935 k_down[value]++;
937 if(k_down[value])
938 shift_state |= (1<< value);
939 else
940 shift_state &= ~ (1<< value);
942 /* kludge, no joke... */
943 if(up_flag && shift_state != old_state && npadch != -1) {
944 put_queue(npadch &0xff);
945 npadch = -1;
949 /* called after returning from RAW mode or when changing consoles -
950 recompute k_down[] and shift_state from key_down[] */
951 /* maybe called when keymap is undefined, so that shiftkey release is seen */
952 voidcompute_shiftstate(void)
954 int i, j, k, sym, val;
956 shift_state =0;
957 for(i=0; i <SIZE(k_down); i++)
958 k_down[i] =0;
960 for(i=0; i <SIZE(key_down); i++)
961 if(key_down[i]) {/* skip this word if not a single bit on */
962 k = i*BITS_PER_LONG;
963 for(j=0; j<BITS_PER_LONG; j++,k++)
964 if(test_bit(k, key_down)) {
965 sym =U(plain_map[k]);
966 if(KTYP(sym) == KT_SHIFT) {
967 val =KVAL(sym);
968 if(val ==KVAL(K_CAPSSHIFT))
969 val =KVAL(K_SHIFT);
970 k_down[val]++;
971 shift_state |= (1<<val);
977 static voiddo_meta(unsigned char value,char up_flag)
979 if(up_flag)
980 return;
982 if(vc_kbd_mode(kbd, VC_META)) {
983 put_queue('\033');
984 put_queue(value);
985 }else
986 put_queue(value |0x80);
989 static voiddo_ascii(unsigned char value,char up_flag)
991 int base;
993 if(up_flag)
994 return;
996 if(value <10)/* decimal input of code, while Alt depressed */
997 base =10;
998 else{/* hexadecimal input of code, while AltGr depressed */
999 value -=10;
1000 base =16;
1003 if(npadch == -1)
1004 npadch = value;
1005 else
1006 npadch = npadch * base + value;
1009 static voiddo_lock(unsigned char value,char up_flag)
1011 if(up_flag || rep)
1012 return;
1013 chg_vc_kbd_lock(kbd, value);
1017 * The leds display either (i) the status of NumLock, CapsLock, ScrollLock,
1018 * or (ii) whatever pattern of lights people want to show using KDSETLED,
1019 * or (iii) specified bits of specified words in kernel memory.
1022 static unsigned char ledstate =0xff;/* undefined */
1023 static unsigned char sunkbd_ledstate =0xff;/* undefined */
1024 static unsigned char ledioctl;
1026 unsigned chargetledstate(void) {
1027 return ledstate;
1030 voidsetledstate(struct kbd_struct *kbd,unsigned int led) {
1031 if(!(led & ~7)) {
1032 ledioctl = led;
1033 kbd->ledmode = LED_SHOW_IOCTL;
1034 }else
1035 kbd->ledmode = LED_SHOW_FLAGS;
1036 set_leds();
1039 static struct ledptr {
1040 unsigned int*addr;
1041 unsigned int mask;
1042 unsigned char valid:1;
1043 } ledptrs[3];
1045 voidregister_leds(int console,unsigned int led,
1046 unsigned int*addr,unsigned int mask) {
1047 struct kbd_struct *kbd = kbd_table + console;
1048 if(led <3) {
1049 ledptrs[led].addr = addr;
1050 ledptrs[led].mask = mask;
1051 ledptrs[led].valid =1;
1052 kbd->ledmode = LED_SHOW_MEM;
1053 }else
1054 kbd->ledmode = LED_SHOW_FLAGS;
1057 staticinlineunsigned chargetleds(void){
1058 struct kbd_struct *kbd = kbd_table + fg_console;
1059 unsigned char leds;
1061 if(kbd->ledmode == LED_SHOW_IOCTL)
1062 return ledioctl;
1063 leds = kbd->ledflagstate;
1064 if(kbd->ledmode == LED_SHOW_MEM) {
1065 if(ledptrs[0].valid) {
1066 if(*ledptrs[0].addr & ledptrs[0].mask)
1067 leds |=1;
1068 else
1069 leds &= ~1;
1071 if(ledptrs[1].valid) {
1072 if(*ledptrs[1].addr & ledptrs[1].mask)
1073 leds |=2;
1074 else
1075 leds &= ~2;
1077 if(ledptrs[2].valid) {
1078 if(*ledptrs[2].addr & ledptrs[2].mask)
1079 leds |=4;
1080 else
1081 leds &= ~4;
1084 return leds;
1088 * This routine is the bottom half of the keyboard interrupt
1089 * routine, and runs with all interrupts enabled. It does
1090 * console changing, led setting and copy_to_cooked, which can
1091 * take a reasonably long time.
1093 * Aside from timing (which isn't really that important for
1094 * keyboard interrupts as they happen often), using the software
1095 * interrupt routines for this thing allows us to easily mask
1096 * this when we don't want any of the above to happen. Not yet
1097 * used, but this allows for easy and efficient race-condition
1098 * prevention later on.
1100 static voidkbd_bh(void)
1102 unsigned char leds =getleds();
1103 unsigned char kbd_leds =vcleds_to_sunkbd(leds);
1105 if(kbd_leds != sunkbd_ledstate) {
1106 ledstate = leds;
1107 sunkbd_ledstate = kbd_leds;
1108 send_cmd(SKBDCMD_SETLED);
1109 send_cmd(kbd_leds);
1113 /* Support for keyboard "beeps". */
1115 /* Timer routine to turn off the beep after the interval expires. */
1116 static voidsunkbd_kd_nosound(unsigned long __unused)
1118 send_cmd(SKBDCMD_BELLOFF);
1122 * Initiate a keyboard beep. If the frequency is zero, then we stop
1123 * the beep. Any other frequency will start a monotone beep. The beep
1124 * will be stopped by a timer after "ticks" jiffies. If ticks is 0,
1125 * then we do not start a timer.
1127 static voidsunkbd_kd_mksound(unsigned int hz,unsigned int ticks)
1129 unsigned long flags;
1130 static struct timer_list sound_timer = { NULL, NULL,0,0,
1131 sunkbd_kd_nosound };
1133 save_flags(flags);
1134 cli();
1136 del_timer(&sound_timer);
1138 if(hz) {
1139 send_cmd(SKBDCMD_BELLON);
1140 if(ticks) {
1141 sound_timer.expires = jiffies + ticks;
1142 add_timer(&sound_timer);
1144 }else
1145 send_cmd(SKBDCMD_BELLOFF);
1147 restore_flags(flags);
1150 externvoid(*kd_mksound)(unsigned int hz,unsigned int ticks);
1152 intkbd_init(void)
1154 int i, opt_node;
1155 struct kbd_struct kbd0;
1156 externstruct tty_driver console_driver;
1158 kbd0.ledflagstate = kbd0.default_ledflagstate = KBD_DEFLEDS;
1159 kbd0.ledmode = LED_SHOW_FLAGS;
1160 kbd0.lockstate = KBD_DEFLOCK;
1161 kbd0.modeflags = KBD_DEFMODE;
1162 kbd0.kbdmode = VC_XLATE;
1164 for(i =0; i < MAX_NR_CONSOLES ; i++)
1165 kbd_table[i] = kbd0;
1167 ttytab = console_driver.table;
1169 kd_mksound = sunkbd_kd_mksound;
1171 /* XXX Check keyboard-click? property in 'options' PROM node XXX */
1172 if(sparc_cpu_model != sun4) {
1173 opt_node =prom_getchild(prom_root_node);
1174 opt_node =prom_searchsiblings(opt_node,"options");
1175 i =prom_getintdefault(opt_node,"keyboard-click?", -1);
1176 if(i != -1)
1177 sunkbd_clickp =1;
1178 else
1179 sunkbd_clickp =0;
1180 }else{
1181 sunkbd_clickp =0;
1183 init_bh(KEYBOARD_BH, kbd_bh);
1184 mark_bh(KEYBOARD_BH);
1185 return0;
1188 /* /dev/kbd support */
1190 #define KBD_QSIZE 32
1191 static Firm_event kbd_queue [KBD_QSIZE];
1192 static int kbd_head, kbd_tail;
1193 char kbd_opened;
1194 static int kbd_active =0;
1195 static struct wait_queue *kbd_wait;
1196 static struct fasync_struct *kb_fasync;
1198 void
1199 push_kbd(int scan)
1201 int next = (kbd_head +1) % KBD_QSIZE;
1203 if(scan == KBD_IDLE)
1204 return;
1205 if(next != kbd_tail){
1206 kbd_queue [kbd_head].id = scan & KBD_KEYMASK;
1207 kbd_queue [kbd_head].value=scan & KBD_UP ? VKEY_UP : VKEY_DOWN;
1208 kbd_queue [kbd_head].time = xtime;
1209 kbd_head = next;
1211 if(kb_fasync)
1212 kill_fasync(kb_fasync, SIGIO);
1213 wake_up_interruptible(&kbd_wait);
1216 static long
1217 kbd_read(struct inode *inode,struct file *f,char*buffer,unsigned long count)
1219 struct wait_queue wait = { current, NULL };
1220 char*end, *p;
1222 /* Return EWOULDBLOCK, because this is what the X server expects */
1223 if(kbd_head == kbd_tail){
1224 if(f->f_flags & O_NONBLOCK)
1225 return-EWOULDBLOCK;
1226 add_wait_queue(&kbd_wait, &wait);
1227 while(kbd_head == kbd_tail && !(current->signal & ~current->blocked)){
1228 current->state = TASK_INTERRUPTIBLE;
1229 schedule();
1231 current->state = TASK_RUNNING;
1232 remove_wait_queue(&kbd_wait, &wait);
1234 /* There is data in the keyboard, fill the user buffer */
1235 end = buffer+count;
1236 p = buffer;
1237 for(; p < end && kbd_head != kbd_tail; p +=sizeof(Firm_event)){
1238 copy_to_user_ret((Firm_event *)p, &kbd_queue [kbd_tail],sizeof(Firm_event), -EFAULT);
1239 #ifdef KBD_DEBUG
1240 printk("[%s]", kbd_queue [kbd_tail].value == VKEY_UP ?"UP":"DOWN");
1241 #endif
1242 kbd_tail++;
1243 kbd_tail %= KBD_QSIZE;
1245 return p-buffer;
1248 /* Needed by X */
1249 static int
1250 kbd_fasync(struct inode *inode,struct file *filp,int on)
1252 int retval;
1254 retval =fasync_helper(inode, filp, on, &kb_fasync);
1255 if(retval <0)
1256 return retval;
1257 return0;
1260 static unsigned intkbd_poll(struct file *f, poll_table *wait)
1262 poll_wait(&kbd_wait, wait);
1263 if(kbd_head != kbd_tail)
1264 return POLLIN | POLLRDNORM;
1265 return0;
1268 static int
1269 kbd_ioctl(struct inode *i,struct file *f,unsigned int cmd,unsigned long arg)
1271 unsigned char c;
1272 unsigned char leds =0;
1273 int value;
1275 switch(cmd){
1276 case KIOCTYPE:/* return keyboard type */
1277 put_user_ret(sunkbd_type, (int*) arg, -EFAULT);
1278 break;
1279 case KIOCGTRANS:
1280 put_user_ret(TR_UNTRANS_EVENT, (int*) arg, -EFAULT);
1281 break;
1282 case KIOCTRANS:
1283 get_user_ret(value, (int*) arg, -EFAULT);
1284 if(value != TR_UNTRANS_EVENT)
1285 return-EINVAL;
1286 break;
1287 case KIOCLAYOUT:
1288 put_user_ret(sunkbd_layout, (int*) arg, -EFAULT);
1289 break;
1290 case KIOCSDIRECT:
1291 #ifndef CODING_NEW_DRIVER
1292 get_user_ret(value, (int*) arg, -EFAULT);
1293 if(value)
1294 kbd_redirected = fg_console +1;
1295 else
1296 kbd_redirected =0;
1297 kbd_table [fg_console].kbdmode = kbd_redirected ? VC_RAW : VC_XLATE;
1298 #endif
1299 break;
1300 case KIOCCMD:
1301 get_user_ret(value, (int*) arg, -EFAULT);
1302 c = (unsigned char) value;
1303 switch(c) {
1304 case SKBDCMD_CLICK:
1305 case SKBDCMD_NOCLICK:
1306 send_cmd(c);
1307 return0;
1308 case SKBDCMD_BELLON:
1309 kd_mksound(1,0);
1310 return0;
1311 case SKBDCMD_BELLOFF:
1312 kd_mksound(0,0);
1313 return0;
1314 default:
1315 return-EINVAL;
1317 case KIOCSLED:
1318 get_user_ret(c, (unsigned char*) arg, -EFAULT);
1320 if(c & LED_SCRLCK) leds |= (1<< VC_SCROLLOCK);
1321 if(c & LED_NLOCK) leds |= (1<< VC_NUMLOCK);
1322 if(c & LED_CLOCK) leds |= (1<< VC_CAPSLOCK);
1323 compose_led_on = !!(c & LED_CMPOSE);
1324 setledstate(kbd_table + fg_console, leds);
1325 break;
1326 case KIOCGLED:
1327 put_user_ret(vcleds_to_sunkbd(getleds()), (unsigned char*) arg, -EFAULT);
1328 break;
1329 case KIOCGRATE:
1331 struct kbd_rate rate;
1333 rate.delay = kbd_delay_ticks;
1334 if(kbd_rate_ticks)
1335 rate.rate = HZ / kbd_rate_ticks;
1336 else
1337 rate.rate =0;
1339 copy_to_user_ret((struct kbd_rate *)arg, &rate,
1340 sizeof(struct kbd_rate), -EFAULT);
1342 return0;
1344 case KIOCSRATE:
1346 struct kbd_rate rate;
1348 if(verify_area(VERIFY_READ, (void*)arg,
1349 sizeof(struct kbd_rate)))
1350 return-EFAULT;
1351 copy_from_user(&rate, (struct kbd_rate *)arg,
1352 sizeof(struct kbd_rate));
1354 if(rate.rate >50)
1355 return-EINVAL;
1356 if(rate.rate ==0)
1357 kbd_rate_ticks =0;
1358 else
1359 kbd_rate_ticks = HZ / rate.rate;
1360 kbd_delay_ticks = rate.delay;
1362 return0;
1364 case FIONREAD:/* return number of bytes in kbd queue */
1366 int count;
1368 count = kbd_head - kbd_tail;
1369 put_user_ret((count <0) ? KBD_QSIZE - count : count, (int*) arg, -EFAULT);
1370 return0;
1372 default:
1373 printk("Unknown Keyboard ioctl: %8.8x\n", cmd);
1374 return-EINVAL;
1376 return0;
1379 static int
1380 kbd_open(struct inode *i,struct file *f)
1382 kbd_active++;
1384 if(kbd_opened)
1385 return0;
1387 kbd_opened = fg_console +1;
1388 kbd_head = kbd_tail =0;
1389 return0;
1392 static int
1393 kbd_close(struct inode *i,struct file *f)
1395 if(--kbd_active)
1396 return0;
1398 if(kbd_redirected)
1399 kbd_table [kbd_opened-1].kbdmode = VC_XLATE;
1401 kbd_redirected =0;
1402 kbd_opened =0;
1404 kbd_fasync(i, f,0);
1405 return0;
1408 static struct
1409 file_operations kbd_fops =
1411 NULL,/* seek */
1412 kbd_read,/* read */
1413 NULL,/* write */
1414 NULL,/* readdir */
1415 kbd_poll,/* poll */
1416 kbd_ioctl,/* ioctl */
1417 NULL,/* mmap */
1418 kbd_open,/* open */
1419 kbd_close,/* close */
1420 NULL,/* fsync */
1421 kbd_fasync,/* fasync */
1422 NULL,/* check_media_change */
1423 NULL,/* revalidate */
1426 __initfunc(voidkeyboard_zsinit(void))
1428 int timeout =0;
1430 /* Test out the leds */
1431 sunkbd_type =255;
1432 send_cmd(SKBDCMD_RESET);
1433 while((sunkbd_type==255) && timeout <500000) {
1434 udelay(100);
1435 timeout +=20;
1438 if(timeout>=500000) {
1439 printk("keyboard: not present\n");
1440 return;
1443 if(sunkbd_type != SUNKBD_TYPE4) {
1444 printk("Sun TYPE %d keyboard detected ", sunkbd_type);
1445 }else{
1446 udelay(200);
1447 timeout=0;
1448 while(timeout++ <500000)
1449 barrier();
1450 printk("Sun TYPE %d keyboard detected ",
1451 ((sunkbd_layout & SUNKBD_LOUT_TYP5_MASK) ?5:4));
1453 if(sunkbd_type == SUNKBD_TYPE2)
1454 sunkbd_clickp =0;
1456 if(sunkbd_clickp) {
1457 send_cmd(SKBDCMD_CLICK);
1458 printk("with keyclick\n");
1459 }else{
1460 send_cmd(SKBDCMD_NOCLICK);
1461 printk("without keyclick\n");
1464 /* Dork with led lights, then turn them all off */
1465 send_cmd(SKBDCMD_SETLED);send_cmd(0xf);/* All on */
1466 send_cmd(SKBDCMD_SETLED);send_cmd(0x0);/* All off */
1468 /* Register the /dev/kbd interface */
1469 if(register_chrdev(KBD_MAJOR,"kbd", &kbd_fops)){
1470 printk("Could not register /dev/kbd device\n");
1471 return;
1473 return;
close