1 /* keyboard.c: Sun keyboard driver.
3 * Copyright (C) 1995, 1996, 1997 David S. Miller (davem@caip.rutgers.edu)
5 * Added vuid event generation and /dev/kbd device for SunOS
6 * compatibility - Miguel (miguel@nuclecu.unam.mx)
8 * Added PCI 8042 controller support -DaveM
9 * Added Magic SysRq support -MJ
12 #include <linux/config.h>
13 #include <linux/kernel.h>
14 #include <linux/sched.h>
15 #include <linux/tty.h>
16 #include <linux/tty_flip.h>
18 #include <linux/ptrace.h>
19 #include <linux/signal.h>
20 #include <linux/string.h>
21 #include <linux/fcntl.h>
22 #include <linux/poll.h>
23 #include <linux/random.h>
24 #include <linux/delay.h>
25 #include <linux/init.h>
26 #include <linux/sysrq.h>
29 #include <asm/vuid_event.h>
30 #include <asm/bitops.h>
31 #include <asm/oplib.h>
32 #include <asm/uaccess.h>
34 #include <linux/kbd_kern.h>
35 #include <linux/kbd_diacr.h>
36 #include <linux/vt_kern.h>
39 #include <linux/pci.h>
46 #define SIZE(x) (sizeof(x)/sizeof((x)[0]))
48 /* Define this one if you are making a new frame buffer driver */
49 /* it will not block the keyboard */
50 /* #define CODING_NEW_DRIVER */
52 /* KBD device number, temporal */
55 #define KBD_REPORT_ERR
56 #define KBD_REPORT_UNKN
59 #define KBD_DEFMODE ((1 << VC_REPEAT) | (1 << VC_META))
64 * Some laptops take the 789uiojklm,. keys as number pad when NumLock
65 * is on. This seems a good reason to start with NumLock off.
74 extern void poke_blanked_console(void);
75 extern void ctrl_alt_del(void);
76 extern void reset_vc(unsigned int new_console
);
77 extern void scrollback(int);
78 extern void scrollfront(int);
80 struct l1a_kbd_state l1a_state
= { 0, 0 };
82 /* Dummy function for now, we need it to link. -DaveM */
83 void kbd_reset_setup(char *str
, int *ints
)
88 struct wait_queue
* keypress_wait
= NULL
;
91 int keyboard_wait_for_keypress(struct console
*co
)
93 sleep_on(&keypress_wait
);
98 * global state includes the following, and various static variables
99 * in this module: prev_scancode, shift_state, diacr, npadch, dead_key_next.
100 * (last_console is now a global variable)
103 /* shift state counters.. */
104 static unsigned char k_down
[NR_SHIFT
] = {0, };
105 /* keyboard key bitmap */
106 static unsigned long key_down
[256/BITS_PER_LONG
] = { 0, };
108 void push_kbd (int scan
);
109 int kbd_redirected
= 0;
111 static int dead_key_next
= 0;
113 * In order to retrieve the shift_state (for the mouse server), either
114 * the variable must be global, or a new procedure must be created to
115 * return the value. I chose the former way.
118 /*static*/ int shift_state
= 0;
120 static int npadch
= -1; /* -1 or number assembled on pad */
121 static unsigned char diacr
= 0;
122 static char rep
= 0; /* flag telling character repeat */
123 struct kbd_struct kbd_table
[MAX_NR_CONSOLES
];
124 static struct tty_struct
**ttytab
;
125 static struct kbd_struct
* kbd
= kbd_table
;
126 static struct tty_struct
* tty
= NULL
;
127 static int compose_led_on
= 0;
128 static int kbd_delay_ticks
= HZ
/ 5;
129 static int kbd_rate_ticks
= HZ
/ 20;
131 void sun_compute_shiftstate(void);
133 typedef void (*k_hand
)(unsigned char value
, char up_flag
);
134 typedef void (k_handfn
)(unsigned char value
, char up_flag
);
137 do_self
, do_fn
, do_spec
, do_pad
, do_dead
, do_cons
, do_cur
, do_shift
,
138 do_meta
, do_ascii
, do_lock
, do_lowercase
, do_ignore
;
140 static k_hand key_handler
[16] = {
141 do_self
, do_fn
, do_spec
, do_pad
, do_dead
, do_cons
, do_cur
, do_shift
,
142 do_meta
, do_ascii
, do_lock
, do_lowercase
,
143 do_ignore
, do_ignore
, do_ignore
, do_ignore
146 typedef void (*void_fnp
)(void);
147 typedef void (void_fn
)(void);
149 static void_fn do_null
, enter
, show_ptregs
, send_intr
, lastcons
, caps_toggle
,
150 num
, hold
, scroll_forw
, scroll_back
, boot_it
, caps_on
, compose
,
151 SAK
, decr_console
, incr_console
, spawn_console
, bare_num
;
153 static void_fnp spec_fn_table
[] = {
154 do_null
, enter
, show_ptregs
, show_mem
,
155 show_state
, send_intr
, lastcons
, caps_toggle
,
156 num
, hold
, scroll_forw
, scroll_back
,
157 boot_it
, caps_on
, compose
, SAK
,
158 decr_console
, incr_console
, spawn_console
, bare_num
161 /* maximum values each key_handler can handle */
163 const int max_vals
[] = {
164 255, SIZE(func_table
) - 1, SIZE(spec_fn_table
) - 1, NR_PAD
- 1,
165 NR_DEAD
- 1, 255, 3, NR_SHIFT
- 1,
166 255, NR_ASCII
- 1, NR_LOCK
- 1, 255,
170 const int NR_TYPES
= SIZE(max_vals
);
173 static void put_queue(int);
174 static unsigned char handle_diacr(unsigned char);
176 /* pt_regs - set by keyboard_interrupt(), used by show_ptregs() */
177 static struct pt_regs
* pt_regs
;
179 #ifdef CONFIG_MAGIC_SYSRQ
180 unsigned char sun_sysrq_xlate
[128] =
181 "\0\0\0\0\0\201\202\212\203\213\204\214\205\0\206\0" /* 0x00 - 0x0f */
182 "\207\210\211\0\0\0\0\0\0\0\0\0\0\03312" /* 0x10 - 0x1f */
183 "34567890-=`\177\0=/*" /* 0x20 - 0x2f */
184 "\0\0.\0\0\011qwertyuiop" /* 0x30 - 0x3f */
185 "[]\177\000789-\0\0\0\0\0asd" /* 0x40 - 0x4f */
186 "fghjkl;'\\\015\0154560\0" /* 0x50 - 0x5f */
187 "\0\0\0\0zxcvbnm,./\0\012" /* 0x60 - 0x6f */
188 "123\0\0\0\0\0\0 \0\0\0\0\0\0"; /* 0x70 - 0x7f */
191 volatile unsigned char sunkbd_layout
;
192 volatile unsigned char sunkbd_type
;
193 #define SUNKBD_TYPE2 0x02
194 #define SUNKBD_TYPE3 0x03
195 #define SUNKBD_TYPE4 0x04
197 #define SUNKBD_LOUT_TYP4 0x00
198 #define SUNKBD_LOUT_TYP5_MASK 0x20
200 volatile int kbd_reset_pending
;
201 volatile int kbd_layout_pending
;
204 #define SKBDCMD_RESET 0x1
205 #define SKBDCMD_GLAYOUT 0xf
206 #define SKBDCMD_BELLON 0x2
207 #define SKBDCMD_BELLOFF 0x3
208 #define SKBDCMD_SETLED 0xe
209 #define SKBDCMD_NOCLICK 0xb
210 #define SKBDCMD_CLICK 0xa
212 static unsigned char sunkbd_clickp
;
214 /* The led set commands require sending the SETLED byte then
215 * a byte encoding which led's to have set. Here are the bit
216 * values, a bit set = led-on.
218 #define LED_NLOCK 0x1 /* Num-lock */
219 #define LED_CMPOSE 0x2 /* Compose */
220 #define LED_SCRLCK 0x4 /* Scroll-lock */
221 #define LED_CLOCK 0x8 /* Caps-lock */
223 /* Special state characters */
224 #define SKBD_RESET 0xff
225 #define SKBD_ALLUP 0x7f
226 #define SKBD_LYOUT 0xfe
228 /* On the Sparc the keyboard could be one of two things.
229 * It could be a real keyboard speaking over one of the
230 * channels of the second zs8530 chip (other channel is
231 * used by the Sun mouse). Else we have serial console
232 * going, and thus the other zs8530 chip is who we speak
233 * to. Either way, we communicate through the zs8530
234 * driver for all our I/O.
237 #define SUNKBD_UBIT 0x80 /* If set, key went up */
238 #define SUNKBD_KMASK 0x7f /* Other bits are the keycode */
240 #define KEY_LSHIFT 0x81
241 #define KEY_RSHIFT 0x82
242 #define KEY_CONTROL 0x83
243 #define KEY_NILL 0x84
244 #define KEY_CAPSLOCK 0x85
248 /* Do to sun_kbd_init() being called before rs_init(), and sun_kbd_init() doing:
250 * init_bh(KEYBOARD_BH, kbd_bh);
251 * mark_bh(KEYBOARD_BH);
253 * this might well be called before some driver has claimed interest in
254 * handling the keyboard input/output. So we need to assign an initial nop.
256 * Otherwise this would lead to the following (DaveM might want to look at):
258 * sparc64_dtlb_refbit_catch(),
259 * do_sparc64_fault(),
260 * kernel NULL pointer dereference at do_sparc64_fault + 0x2c0 ;-(
262 static void nop_kbd_put_char(unsigned char c
) { }
263 static void (*kbd_put_char
)(unsigned char) = nop_kbd_put_char
;
265 static inline void send_cmd(unsigned char c
)
270 /* kbd_bh() calls this to send the SKBDCMD_SETLED to the sun keyboard
271 * with the proper bit pattern for the leds to be set. It basically
272 * converts the kbd->ledflagstate values to corresponding sun kbd led
275 static inline unsigned char vcleds_to_sunkbd(unsigned char vcleds
)
277 unsigned char retval
= 0;
279 if(vcleds
& (1<<VC_SCROLLOCK
))
280 retval
|= LED_SCRLCK
;
281 if(vcleds
& (1<<VC_NUMLOCK
))
283 if(vcleds
& (1<<VC_CAPSLOCK
))
286 retval
|= LED_CMPOSE
;
291 * Translation of escaped scancodes to keycodes.
292 * This is now user-settable.
293 * The keycodes 1-88,96-111,119 are fairly standard, and
294 * should probably not be changed - changing might confuse X.
295 * X also interprets scancode 0x5d (KEY_Begin).
297 * For 1-88 keycode equals scancode.
300 #define E0_KPENTER 96
302 #define E0_KPSLASH 98
305 #define E0_BREAK 101 /* (control-pause) */
320 * The keycodes below are randomly located in 89-95,112-118,120-127.
321 * They could be thrown away (and all occurrences below replaced by 0),
322 * but that would force many users to use the `setkeycodes' utility, where
323 * they needed not before. It does not matter that there are duplicates, as
324 * long as no duplication occurs for any single keyboard.
328 #define FOCUS_PF1 85 /* actual code! */
336 #define FOCUS_PF9 120
337 #define FOCUS_PF10 121
338 #define FOCUS_PF11 122
339 #define FOCUS_PF12 123
342 /* tfj@olivia.ping.dk:
343 * The four keys are located over the numeric keypad, and are
344 * labelled A1-A4. It's an rc930 keyboard, from
345 * Regnecentralen/RC International, Now ICL.
346 * Scancodes: 59, 5a, 5b, 5c.
353 static unsigned char high_keys
[128 - SC_LIM
] = {
354 RGN1
, RGN2
, RGN3
, RGN4
, 0, 0, 0, /* 0x59-0x5f */
355 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60-0x67 */
356 0, 0, 0, 0, 0, FOCUS_PF11
, 0, FOCUS_PF12
, /* 0x68-0x6f */
357 0, 0, 0, FOCUS_PF2
, FOCUS_PF9
, 0, 0, FOCUS_PF3
, /* 0x70-0x77 */
358 FOCUS_PF4
, FOCUS_PF5
, FOCUS_PF6
, FOCUS_PF7
, /* 0x78-0x7b */
359 FOCUS_PF8
, JAP_86
, FOCUS_PF10
, 0 /* 0x7c-0x7f */
370 #define E0_KPMINPLUS 118
372 * My OmniKey generates e0 4c for the "OMNI" key and the
373 * right alt key does nada. [kkoller@nyx10.cs.du.edu]
377 * New microsoft keyboard is rumoured to have
378 * e0 5b (left window button), e0 5c (right window button),
379 * e0 5d (menu button). [or: LBANNER, RBANNER, RMENU]
380 * [or: Windows_L, Windows_R, TaskMan]
386 static unsigned char e0_keys
[128] = {
387 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00-0x07 */
388 0, 0, 0, 0, 0, 0, 0, 0, /* 0x08-0x0f */
389 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10-0x17 */
390 0, 0, 0, 0, E0_KPENTER
, E0_RCTRL
, 0, 0, /* 0x18-0x1f */
391 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20-0x27 */
392 0, 0, 0, 0, 0, 0, 0, 0, /* 0x28-0x2f */
393 0, 0, 0, 0, 0, E0_KPSLASH
, 0, E0_PRSCR
, /* 0x30-0x37 */
394 E0_RALT
, 0, 0, 0, 0, E0_F13
, E0_F14
, E0_HELP
, /* 0x38-0x3f */
395 E0_DO
, E0_F17
, 0, 0, 0, 0, E0_BREAK
, E0_HOME
, /* 0x40-0x47 */
396 E0_UP
, E0_PGUP
, 0, E0_LEFT
, E0_OK
, E0_RIGHT
, E0_KPMINPLUS
, E0_END
,/* 0x48-0x4f */
397 E0_DOWN
, E0_PGDN
, E0_INS
, E0_DEL
, 0, 0, 0, 0, /* 0x50-0x57 */
398 0, 0, 0, E0_MSLW
, E0_MSRW
, E0_MSTM
, 0, 0, /* 0x58-0x5f */
399 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60-0x67 */
400 0, 0, 0, 0, 0, 0, 0, E0_MACRO
, /* 0x68-0x6f */
401 0, 0, 0, 0, 0, 0, 0, 0, /* 0x70-0x77 */
402 0, 0, 0, 0, 0, 0, 0, 0 /* 0x78-0x7f */
405 /* we use this map to determine if a particular key should not be
406 autorepeated. We don't autorepeat CONTROL, LSHIFT, CAPS,
407 ALT, LMETA, RSHIFT, RMETA, ALTG and COMPOSE */
408 static unsigned char norepeat_keys
[128] = {
409 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, /* 0x00-0x0f */
410 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10-0x1f */
411 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20-0x2f */
412 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x30-0x3f */
413 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, /* 0x40-0x4f */
414 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x50-0x5f */
415 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, /* 0x60-0x6f */
416 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, /* 0x70-0x7f */
420 int sun_setkeycode(unsigned int scancode
, unsigned int keycode
)
422 if (scancode
< SC_LIM
|| scancode
> 255 || keycode
> 127)
425 high_keys
[scancode
- SC_LIM
] = keycode
;
427 e0_keys
[scancode
- 128] = keycode
;
431 int sun_getkeycode(unsigned int scancode
)
434 (scancode
< SC_LIM
|| scancode
> 255) ? -EINVAL
:
435 (scancode
< 128) ? high_keys
[scancode
- SC_LIM
] :
436 e0_keys
[scancode
- 128];
439 void sunkbd_inchar(unsigned char ch
, struct pt_regs
*regs
);
440 static void keyboard_timer (unsigned long ignored
);
442 static struct timer_list
443 auto_repeat_timer
= { NULL
, NULL
, 0, 0, keyboard_timer
};
445 /* Keeps track of the last pressed key */
446 static unsigned char last_keycode
;
449 keyboard_timer (unsigned long ignored
)
453 save_flags(flags
); cli();
455 /* Auto repeat: send regs = 0 to indicate autorepeat */
456 sunkbd_inchar (last_keycode
, 0);
457 del_timer (&auto_repeat_timer
);
458 if (kbd_rate_ticks
) {
459 auto_repeat_timer
.expires
= jiffies
+ kbd_rate_ticks
;
460 add_timer (&auto_repeat_timer
);
462 restore_flags(flags
);
465 /* #define SKBD_DEBUG */
466 /* This is our keyboard 'interrupt' routine. */
467 void sunkbd_inchar(unsigned char ch
, struct pt_regs
*regs
)
469 unsigned char keycode
;
470 char up_flag
; /* 0 or SUNKBD_UBIT */
473 if(ch
== SKBD_RESET
) {
474 kbd_reset_pending
= 1;
477 if(ch
== SKBD_LYOUT
) {
478 kbd_layout_pending
= 1;
481 if(kbd_reset_pending
) {
483 kbd_reset_pending
= 0;
484 if(ch
== SUNKBD_TYPE4
)
485 send_cmd(SKBDCMD_GLAYOUT
);
487 } else if(kbd_layout_pending
) {
489 kbd_layout_pending
= 0;
491 } else if(ch
== SKBD_ALLUP
) {
492 del_timer (&auto_repeat_timer
);
493 memset(key_down
, 0, sizeof(key_down
));
494 sun_compute_shiftstate();
499 printk("KBD<ALL KEYS UP>");
501 printk("KBD<%x %s>", ch
,
502 ((ch
&0x80) ? "UP" : "DOWN"));
505 /* Whee, a real character. */
508 last_keycode
= keycode
= ch
;
513 do_poke_blanked_console
= 1;
515 add_keyboard_randomness(keycode
);
517 kbd
= kbd_table
+ fg_console
;
518 tty
= ttytab
[fg_console
];
519 if((raw_mode
= (kbd
->kbdmode
== VC_RAW
))) {
520 if (kbd_redirected
== fg_console
+1)
524 /* we do not return yet, because we want to maintain
525 * the key_down array, so that we have the correct
526 * values when finishing RAW mode or when changing VT's.
529 up_flag
= (keycode
& SUNKBD_UBIT
); /* The 'up' bit */
530 keycode
&= SUNKBD_KMASK
; /* all the rest */
531 del_timer (&auto_repeat_timer
);
534 clear_bit(keycode
, key_down
);
536 if (!norepeat_keys
[keycode
]) {
537 if (kbd_rate_ticks
) {
538 auto_repeat_timer
.expires
=
539 jiffies
+ kbd_delay_ticks
;
540 add_timer (&auto_repeat_timer
);
543 rep
= test_and_set_bit(keycode
, key_down
);
546 #ifdef CONFIG_MAGIC_SYSRQ /* Handle the SysRq hack */
547 if (l1a_state
.l1_down
) {
549 handle_sysrq(sun_sysrq_xlate
[keycode
], pt_regs
, kbd
, tty
);
557 if(kbd
->kbdmode
== VC_MEDIUMRAW
) {
558 put_queue(keycode
+ up_flag
);
563 * Small change in philosophy: earlier we defined repetition by
564 * rep = keycode == prev_keycode;
565 * prev_keycode = keycode;
566 * but now by the fact that the depressed key was down already.
567 * Does this ever make a difference? Yes.
571 * Repeat a key only if the input buffers are empty or the
572 * characters get echoed locally. This makes key repeat usable
573 * with slow applications and under heavy loads.
576 (vc_kbd_mode(kbd
,VC_REPEAT
) && tty
&&
577 (L_ECHO(tty
) || (tty
->driver
.chars_in_buffer(tty
) == 0)))) {
581 /* the XOR below used to be an OR */
582 int shift_final
= shift_state
^ kbd
->lockstate
^ kbd
->slockstate
;
583 ushort
*key_map
= key_maps
[shift_final
];
585 if (key_map
!= NULL
) {
586 keysym
= key_map
[keycode
];
591 if (type
== KT_LETTER
) {
593 if (vc_kbd_led(kbd
, VC_CAPSLOCK
)) {
594 key_map
= key_maps
[shift_final
^ (1<<KG_SHIFT
)];
596 keysym
= key_map
[keycode
];
599 (*key_handler
[type
])(keysym
& 0xff, up_flag
);
600 if (type
!= KT_SLOCK
)
605 /* we have at least to update shift_state */
606 sun_compute_shiftstate();
610 mark_bh(KEYBOARD_BH
);
613 static void put_queue(int ch
)
615 wake_up(&keypress_wait
);
617 tty_insert_flip_char(tty
, ch
, 0);
618 tty_schedule_flip(tty
);
622 static void puts_queue(char *cp
)
624 wake_up(&keypress_wait
);
629 tty_insert_flip_char(tty
, *cp
, 0);
632 tty_schedule_flip(tty
);
635 static void applkey(int key
, char mode
)
637 static char buf
[] = { 0x1b, 'O', 0x00, 0x00 };
639 buf
[1] = (mode
? 'O' : '[');
644 static void enter(void)
647 if (vc_kbd_mode(kbd
,VC_CRLF
))
651 static void caps_toggle(void)
655 chg_vc_kbd_led(kbd
, VC_CAPSLOCK
);
658 static void caps_on(void)
662 set_vc_kbd_led(kbd
, VC_CAPSLOCK
);
665 static void show_ptregs(void)
671 static void hold(void)
677 * Note: SCROLLOCK will be set (cleared) by stop_tty (start_tty);
678 * these routines are also activated by ^S/^Q.
679 * (And SCROLLOCK can also be set by the ioctl KDSKBLED.)
687 static void num(void)
689 if (vc_kbd_mode(kbd
,VC_APPLIC
))
696 * Bind this to Shift-NumLock if you work in application keypad mode
697 * but want to be able to change the NumLock flag.
698 * Bind this to NumLock if you prefer that the NumLock key always
699 * changes the NumLock flag.
701 static void bare_num(void)
704 chg_vc_kbd_led(kbd
,VC_NUMLOCK
);
707 static void lastcons(void)
709 /* switch to the last used console, ChN */
710 set_console(last_console
);
713 static void decr_console(void)
717 for (i
= fg_console
-1; i
!= fg_console
; i
--) {
719 i
= MAX_NR_CONSOLES
-1;
720 if (vc_cons_allocated(i
))
726 static void incr_console(void)
730 for (i
= fg_console
+1; i
!= fg_console
; i
++) {
731 if (i
== MAX_NR_CONSOLES
)
733 if (vc_cons_allocated(i
))
739 static void send_intr(void)
743 tty_insert_flip_char(tty
, 0, TTY_BREAK
);
744 tty_schedule_flip(tty
);
747 static void scroll_forw(void)
752 static void scroll_back(void)
757 static void boot_it(void)
759 extern int obp_system_intr(void);
761 if (!obp_system_intr())
763 /* sigh.. attempt to prevent multiple entry */
768 static void compose(void)
775 int spawnpid
, spawnsig
;
777 static void spawn_console(void)
780 if(kill_proc(spawnpid
, spawnsig
, 1))
784 static void SAK(void)
789 * Need to fix SAK handling to fix up RAW/MEDIUM_RAW and
790 * vt_cons modes before we can enable RAW/MEDIUM_RAW SAK
793 * We should do this some day --- the whole point of a secure
794 * attention key is that it should be guaranteed to always
797 reset_vc(fg_console
);
798 do_unblank_screen(); /* not in interrupt routine? */
802 static void do_ignore(unsigned char value
, char up_flag
)
806 static void do_null()
808 sun_compute_shiftstate();
811 static void do_spec(unsigned char value
, char up_flag
)
815 if (value
>= SIZE(spec_fn_table
))
817 spec_fn_table
[value
]();
820 static void do_lowercase(unsigned char value
, char up_flag
)
822 printk("keyboard.c: do_lowercase was called - impossible\n");
825 static void do_self(unsigned char value
, char up_flag
)
828 return; /* no action, if this is a key release */
831 value
= handle_diacr(value
);
851 static unsigned char ret_diacr
[NR_DEAD
] =
852 {A_GRAVE
, A_ACUTE
, A_CFLEX
, A_TILDE
, A_DIAER
, A_CEDIL
};
854 /* If a dead key pressed twice, output a character corresponding to it, */
855 /* otherwise just remember the dead key. */
857 static void do_dead(unsigned char value
, char up_flag
)
862 value
= ret_diacr
[value
];
863 if (diacr
== value
) { /* pressed twice */
872 /* If space is pressed, return the character corresponding the pending */
873 /* dead key, otherwise try to combine the two. */
875 unsigned char handle_diacr(unsigned char ch
)
884 for (i
= 0; i
< accent_table_size
; i
++) {
885 if (accent_table
[i
].diacr
== d
&& accent_table
[i
].base
== ch
)
886 return accent_table
[i
].result
;
893 static void do_cons(unsigned char value
, char up_flag
)
900 static void do_fn(unsigned char value
, char up_flag
)
904 if (value
< SIZE(func_table
)) {
905 if (func_table
[value
])
906 puts_queue(func_table
[value
]);
908 printk("do_fn called with value=%d\n", value
);
911 static void do_pad(unsigned char value
, char up_flag
)
913 static const char *pad_chars
= "0123456789+-*/\015,.?";
914 static const char *app_map
= "pqrstuvwxylSRQMnn?";
917 return; /* no action, if this is a key release */
919 /* kludge... shift forces cursor/number keys */
920 if (vc_kbd_mode(kbd
,VC_APPLIC
) && !k_down
[KG_SHIFT
]) {
921 applkey(app_map
[value
], 1);
925 if (!vc_kbd_led(kbd
,VC_NUMLOCK
))
929 do_fn(KVAL(K_REMOVE
), 0);
932 do_fn(KVAL(K_INSERT
), 0);
935 do_fn(KVAL(K_SELECT
), 0);
938 do_cur(KVAL(K_DOWN
), 0);
941 do_fn(KVAL(K_PGDN
), 0);
944 do_cur(KVAL(K_LEFT
), 0);
947 do_cur(KVAL(K_RIGHT
), 0);
950 do_fn(KVAL(K_FIND
), 0);
953 do_cur(KVAL(K_UP
), 0);
956 do_fn(KVAL(K_PGUP
), 0);
959 applkey('G', vc_kbd_mode(kbd
, VC_APPLIC
));
963 put_queue(pad_chars
[value
]);
964 if (value
== KVAL(K_PENTER
) && vc_kbd_mode(kbd
, VC_CRLF
))
968 static void do_cur(unsigned char value
, char up_flag
)
970 static const char *cur_chars
= "BDCA";
974 applkey(cur_chars
[value
], vc_kbd_mode(kbd
,VC_CKMODE
));
977 static void do_shift(unsigned char value
, char up_flag
)
979 int old_state
= shift_state
;
985 a CapsShift key acts like Shift but undoes CapsLock */
986 if (value
== KVAL(K_CAPSSHIFT
)) {
987 value
= KVAL(K_SHIFT
);
989 clr_vc_kbd_led(kbd
, VC_CAPSLOCK
);
993 /* handle the case that two shift or control
994 keys are depressed simultaneously */
1001 shift_state
|= (1 << value
);
1003 shift_state
&= ~ (1 << value
);
1005 /* kludge, no joke... */
1006 if (up_flag
&& shift_state
!= old_state
&& npadch
!= -1) {
1007 put_queue(npadch
& 0xff);
1012 /* called after returning from RAW mode or when changing consoles -
1013 recompute k_down[] and shift_state from key_down[] */
1014 /* maybe called when keymap is undefined, so that shiftkey release is seen */
1015 void sun_compute_shiftstate(void)
1017 int i
, j
, k
, sym
, val
;
1020 for(i
=0; i
< SIZE(k_down
); i
++)
1023 for(i
=0; i
< SIZE(key_down
); i
++)
1024 if(key_down
[i
]) { /* skip this word if not a single bit on */
1025 k
= i
*BITS_PER_LONG
;
1026 for(j
=0; j
<BITS_PER_LONG
; j
++,k
++)
1027 if(test_bit(k
, key_down
)) {
1028 sym
= U(plain_map
[k
]);
1029 if(KTYP(sym
) == KT_SHIFT
) {
1031 if (val
== KVAL(K_CAPSSHIFT
))
1032 val
= KVAL(K_SHIFT
);
1034 shift_state
|= (1<<val
);
1040 static void do_meta(unsigned char value
, char up_flag
)
1045 if (vc_kbd_mode(kbd
, VC_META
)) {
1049 put_queue(value
| 0x80);
1052 static void do_ascii(unsigned char value
, char up_flag
)
1059 if (value
< 10) /* decimal input of code, while Alt depressed */
1061 else { /* hexadecimal input of code, while AltGr depressed */
1069 npadch
= npadch
* base
+ value
;
1072 static void do_lock(unsigned char value
, char up_flag
)
1076 chg_vc_kbd_lock(kbd
, value
);
1080 * The leds display either (i) the status of NumLock, CapsLock, ScrollLock,
1081 * or (ii) whatever pattern of lights people want to show using KDSETLED,
1082 * or (iii) specified bits of specified words in kernel memory.
1085 static unsigned char ledstate
= 0xff; /* undefined */
1086 static unsigned char sunkbd_ledstate
= 0xff; /* undefined */
1087 static unsigned char ledioctl
;
1089 unsigned char sun_getledstate(void) {
1093 void sun_setledstate(struct kbd_struct
*kbd
, unsigned int led
) {
1096 kbd
->ledmode
= LED_SHOW_IOCTL
;
1098 kbd
->ledmode
= LED_SHOW_FLAGS
;
1102 static struct ledptr
{
1105 unsigned char valid
:1;
1108 void register_leds(int console
, unsigned int led
,
1109 unsigned int *addr
, unsigned int mask
) {
1110 struct kbd_struct
*kbd
= kbd_table
+ console
;
1112 ledptrs
[led
].addr
= addr
;
1113 ledptrs
[led
].mask
= mask
;
1114 ledptrs
[led
].valid
= 1;
1115 kbd
->ledmode
= LED_SHOW_MEM
;
1117 kbd
->ledmode
= LED_SHOW_FLAGS
;
1120 static inline unsigned char getleds(void){
1121 struct kbd_struct
*kbd
= kbd_table
+ fg_console
;
1124 if (kbd
->ledmode
== LED_SHOW_IOCTL
)
1126 leds
= kbd
->ledflagstate
;
1127 if (kbd
->ledmode
== LED_SHOW_MEM
) {
1128 if (ledptrs
[0].valid
) {
1129 if (*ledptrs
[0].addr
& ledptrs
[0].mask
)
1134 if (ledptrs
[1].valid
) {
1135 if (*ledptrs
[1].addr
& ledptrs
[1].mask
)
1140 if (ledptrs
[2].valid
) {
1141 if (*ledptrs
[2].addr
& ledptrs
[2].mask
)
1151 * This routine is the bottom half of the keyboard interrupt
1152 * routine, and runs with all interrupts enabled. It does
1153 * console changing, led setting and copy_to_cooked, which can
1154 * take a reasonably long time.
1156 * Aside from timing (which isn't really that important for
1157 * keyboard interrupts as they happen often), using the software
1158 * interrupt routines for this thing allows us to easily mask
1159 * this when we don't want any of the above to happen. Not yet
1160 * used, but this allows for easy and efficient race-condition
1161 * prevention later on.
1163 static void kbd_bh(void)
1165 unsigned char leds
= getleds();
1166 unsigned char kbd_leds
= vcleds_to_sunkbd(leds
);
1168 if (kbd_leds
!= sunkbd_ledstate
) {
1170 sunkbd_ledstate
= kbd_leds
;
1171 send_cmd(SKBDCMD_SETLED
);
1176 /* Support for keyboard "beeps". */
1178 /* Timer routine to turn off the beep after the interval expires. */
1179 static void sunkbd_kd_nosound(unsigned long __unused
)
1181 send_cmd(SKBDCMD_BELLOFF
);
1185 * Initiate a keyboard beep. If the frequency is zero, then we stop
1186 * the beep. Any other frequency will start a monotone beep. The beep
1187 * will be stopped by a timer after "ticks" jiffies. If ticks is 0,
1188 * then we do not start a timer.
1190 static void sunkbd_kd_mksound(unsigned int hz
, unsigned int ticks
)
1192 unsigned long flags
;
1193 static struct timer_list sound_timer
= { NULL
, NULL
, 0, 0,
1194 sunkbd_kd_nosound
};
1199 del_timer(&sound_timer
);
1202 send_cmd(SKBDCMD_BELLON
);
1204 sound_timer
.expires
= jiffies
+ ticks
;
1205 add_timer(&sound_timer
);
1208 send_cmd(SKBDCMD_BELLOFF
);
1210 restore_flags(flags
);
1213 extern void (*kd_mksound
)(unsigned int hz
, unsigned int ticks
);
1215 __initfunc(int sun_kbd_init(void))
1218 struct kbd_struct kbd0
;
1219 extern struct tty_driver console_driver
;
1221 kbd0
.ledflagstate
= kbd0
.default_ledflagstate
= KBD_DEFLEDS
;
1222 kbd0
.ledmode
= LED_SHOW_FLAGS
;
1223 kbd0
.lockstate
= KBD_DEFLOCK
;
1224 kbd0
.slockstate
= 0;
1225 kbd0
.modeflags
= KBD_DEFMODE
;
1226 kbd0
.kbdmode
= VC_XLATE
;
1228 for (i
= 0 ; i
< MAX_NR_CONSOLES
; i
++)
1229 kbd_table
[i
] = kbd0
;
1231 ttytab
= console_driver
.table
;
1233 kd_mksound
= sunkbd_kd_mksound
;
1235 /* XXX Check keyboard-click? property in 'options' PROM node XXX */
1236 if(sparc_cpu_model
!= sun4
) {
1237 opt_node
= prom_getchild(prom_root_node
);
1238 opt_node
= prom_searchsiblings(opt_node
, "options");
1239 i
= prom_getintdefault(opt_node
, "keyboard-click?", -1);
1247 init_bh(KEYBOARD_BH
, kbd_bh
);
1248 mark_bh(KEYBOARD_BH
);
1252 /* /dev/kbd support */
1254 #define KBD_QSIZE 32
1255 static Firm_event kbd_queue
[KBD_QSIZE
];
1256 static int kbd_head
, kbd_tail
;
1258 static int kbd_active
= 0;
1259 static struct wait_queue
*kbd_wait
;
1260 static struct fasync_struct
*kb_fasync
;
1265 int next
= (kbd_head
+ 1) % KBD_QSIZE
;
1267 if (scan
== KBD_IDLE
)
1269 if (next
!= kbd_tail
){
1270 kbd_queue
[kbd_head
].id
= scan
& KBD_KEYMASK
;
1271 kbd_queue
[kbd_head
].value
=scan
& KBD_UP
? VKEY_UP
: VKEY_DOWN
;
1272 kbd_queue
[kbd_head
].time
= xtime
;
1276 kill_fasync (kb_fasync
, SIGIO
);
1277 wake_up_interruptible (&kbd_wait
);
1281 kbd_read (struct file
*f
, char *buffer
, size_t count
, loff_t
*ppos
)
1283 struct wait_queue wait
= { current
, NULL
};
1286 /* Return EWOULDBLOCK, because this is what the X server expects */
1287 if (kbd_head
== kbd_tail
){
1288 if (f
->f_flags
& O_NONBLOCK
)
1289 return -EWOULDBLOCK
;
1290 add_wait_queue (&kbd_wait
, &wait
);
1291 while (kbd_head
== kbd_tail
&& !signal_pending(current
)) {
1292 current
->state
= TASK_INTERRUPTIBLE
;
1295 current
->state
= TASK_RUNNING
;
1296 remove_wait_queue (&kbd_wait
, &wait
);
1298 /* There is data in the keyboard, fill the user buffer */
1301 for (; p
< end
&& kbd_head
!= kbd_tail
;){
1302 #ifdef CONFIG_SPARC32_COMPAT
1303 if (current
->tss
.flags
& SPARC_FLAG_32BIT
) {
1304 copy_to_user_ret((Firm_event
*)p
, &kbd_queue
[kbd_tail
],
1305 sizeof(Firm_event
)-sizeof(struct timeval
), -EFAULT
);
1306 p
+= sizeof(Firm_event
)-sizeof(struct timeval
);
1307 __put_user_ret(kbd_queue
[kbd_tail
].time
.tv_sec
, (u32
*)p
, -EFAULT
);
1309 __put_user_ret(kbd_queue
[kbd_tail
].time
.tv_usec
, (u32
*)p
, -EFAULT
);
1314 copy_to_user_ret((Firm_event
*)p
, &kbd_queue
[kbd_tail
],
1315 sizeof(Firm_event
), -EFAULT
);
1316 p
+= sizeof (Firm_event
);
1319 printk ("[%s]", kbd_queue
[kbd_tail
].value
== VKEY_UP
? "UP" : "DOWN");
1322 kbd_tail
%= KBD_QSIZE
;
1328 static int kbd_fasync (struct file
*filp
, int on
)
1332 retval
= fasync_helper (filp
, on
, &kb_fasync
);
1338 static unsigned int kbd_poll (struct file
*f
, poll_table
*wait
)
1340 poll_wait(f
, &kbd_wait
, wait
);
1341 if (kbd_head
!= kbd_tail
)
1342 return POLLIN
| POLLRDNORM
;
1347 kbd_ioctl (struct inode
*i
, struct file
*f
, unsigned int cmd
, unsigned long arg
)
1350 unsigned char leds
= 0;
1354 case KIOCTYPE
: /* return keyboard type */
1355 put_user_ret(sunkbd_type
, (int *) arg
, -EFAULT
);
1358 put_user_ret(TR_UNTRANS_EVENT
, (int *) arg
, -EFAULT
);
1361 get_user_ret(value
, (int *) arg
, -EFAULT
);
1362 if (value
!= TR_UNTRANS_EVENT
)
1366 put_user_ret(sunkbd_layout
, (int *) arg
, -EFAULT
);
1369 #ifndef CODING_NEW_DRIVER
1370 get_user_ret(value
, (int *) arg
, -EFAULT
);
1372 kbd_redirected
= fg_console
+ 1;
1375 kbd_table
[fg_console
].kbdmode
= kbd_redirected
? VC_RAW
: VC_XLATE
;
1379 get_user_ret(value
, (int *) arg
, -EFAULT
);
1380 c
= (unsigned char) value
;
1383 case SKBDCMD_NOCLICK
:
1386 case SKBDCMD_BELLON
:
1389 case SKBDCMD_BELLOFF
:
1396 get_user_ret(c
, (unsigned char *) arg
, -EFAULT
);
1398 if (c
& LED_SCRLCK
) leds
|= (1 << VC_SCROLLOCK
);
1399 if (c
& LED_NLOCK
) leds
|= (1 << VC_NUMLOCK
);
1400 if (c
& LED_CLOCK
) leds
|= (1 << VC_CAPSLOCK
);
1401 compose_led_on
= !!(c
& LED_CMPOSE
);
1402 sun_setledstate(kbd_table
+ fg_console
, leds
);
1405 put_user_ret(vcleds_to_sunkbd(getleds()), (unsigned char *) arg
, -EFAULT
);
1409 struct kbd_rate rate
;
1411 rate
.delay
= kbd_delay_ticks
;
1413 rate
.rate
= HZ
/ kbd_rate_ticks
;
1417 copy_to_user_ret((struct kbd_rate
*)arg
, &rate
,
1418 sizeof(struct kbd_rate
), -EFAULT
);
1424 struct kbd_rate rate
;
1426 if (verify_area(VERIFY_READ
, (void *)arg
,
1427 sizeof(struct kbd_rate
)))
1429 copy_from_user(&rate
, (struct kbd_rate
*)arg
,
1430 sizeof(struct kbd_rate
));
1437 kbd_rate_ticks
= HZ
/ rate
.rate
;
1438 kbd_delay_ticks
= rate
.delay
;
1442 case FIONREAD
: /* return number of bytes in kbd queue */
1446 count
= kbd_head
- kbd_tail
;
1447 put_user_ret((count
< 0) ? KBD_QSIZE
- count
: count
, (int *) arg
, -EFAULT
);
1451 printk ("Unknown Keyboard ioctl: %8.8x\n", cmd
);
1458 kbd_open (struct inode
*i
, struct file
*f
)
1465 kbd_opened
= fg_console
+ 1;
1466 kbd_head
= kbd_tail
= 0;
1471 kbd_close (struct inode
*i
, struct file
*f
)
1477 kbd_table
[kbd_opened
-1].kbdmode
= VC_XLATE
;
1487 file_operations kbd_fops
=
1490 kbd_read
, /* read */
1493 kbd_poll
, /* poll */
1494 kbd_ioctl
, /* ioctl */
1496 kbd_open
, /* open */
1498 kbd_close
, /* close */
1500 kbd_fasync
, /* fasync */
1501 NULL
, /* check_media_change */
1502 NULL
, /* revalidate */
1505 __initfunc(void keyboard_zsinit(void (*put_char
)(unsigned char)))
1509 kbd_put_char
= put_char
;
1511 panic("keyboard_zsinit: no put_char parameter");
1513 /* Test out the leds */
1517 send_cmd(SKBDCMD_RESET
);
1518 send_cmd(SKBDCMD_RESET
);
1519 while((sunkbd_type
==255) && timeout
++ < 25000) {
1524 if(timeout
>=25000) {
1525 printk("keyboard: not present\n");
1529 if(sunkbd_type
!= SUNKBD_TYPE4
) {
1530 printk("Sun TYPE %d keyboard detected ", sunkbd_type
);
1533 while((sunkbd_layout
==0) && timeout
++ < 10000) {
1537 printk("Sun TYPE %d keyboard detected ",
1538 ((sunkbd_layout
& SUNKBD_LOUT_TYP5_MASK
) ? 5 : 4));
1540 if(sunkbd_type
== SUNKBD_TYPE2
)
1544 send_cmd(SKBDCMD_CLICK
);
1545 printk("with keyclick\n");
1547 send_cmd(SKBDCMD_NOCLICK
);
1548 printk("without keyclick\n");
1551 /* Dork with led lights, then turn them all off */
1552 send_cmd(SKBDCMD_SETLED
); send_cmd(0xf); /* All on */
1553 send_cmd(SKBDCMD_SETLED
); send_cmd(0x0); /* All off */
1555 /* Register the /dev/kbd interface */
1556 if (register_chrdev (KBD_MAJOR
, "kbd", &kbd_fops
)){
1557 printk ("Could not register /dev/kbd device\n");