2 * linux/atari/atakeyb.c
4 * Atari Keyboard driver for 680x0 Linux
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file COPYING in the main directory of this archive
12 * Atari support by Robert de Vries
13 * enhanced by Bjoern Brauel and Roman Hodek
16 #include <linux/sched.h>
17 #include <linux/kernel.h>
18 #include <linux/interrupt.h>
19 #include <linux/errno.h>
20 #include <linux/keyboard.h>
21 #include <linux/delay.h>
22 #include <linux/timer.h>
24 #include <linux/random.h>
25 #include <linux/init.h>
26 #include <linux/kbd_kern.h>
28 #include <asm/atariints.h>
29 #include <asm/atarihw.h>
30 #include <asm/atarikb.h>
31 #include <asm/atari_joystick.h>
34 static void atakeyb_rep(unsigned long ignore);
35 extern unsigned int keymap_count;
37 /* Hook for MIDI serial driver */
38 void (*atari_MIDI_interrupt_hook) (void);
39 /* Hook for mouse driver */
40 void (*atari_mouse_interrupt_hook) (char *);
41 /* Hook for keyboard inputdev driver */
42 void (*atari_input_keyboard_interrupt_hook) (unsigned char, char);
43 /* Hook for mouse inputdev driver */
44 void (*atari_input_mouse_interrupt_hook) (char *);
46 /* variables for IKBD self test: */
48 /* state: 0: off; >0: in progress; >1: 0xf1 received */
49 static volatile int ikbd_self_test;
50 /* timestamp when last received a char */
51 static volatile unsigned long self_test_last_rcv;
52 /* bitmap of keys reported as broken */
53 static unsigned long broken_keys[128/(sizeof(unsigned long)*8)] = { 0, };
55 #define BREAK_MASK (0x80)
58 * ++roman: The following changes were applied manually:
60 * - The Alt (= Meta) key works in combination with Shift and
61 * Control, e.g. Alt+Shift+a sends Meta-A (0xc1), Alt+Control+A sends
62 * Meta-Ctrl-A (0x81) ...
64 * - The parentheses on the keypad send '(' and ')' with all
65 * modifiers (as would do e.g. keypad '+'), but they cannot be used as
66 * application keys (i.e. sending Esc O c).
68 * - HELP and UNDO are mapped to be F21 and F24, resp, that send the
69 * codes "\E[M" and "\E[P". (This is better than the old mapping to
70 * F11 and F12, because these codes are on Shift+F1/2 anyway.) This
71 * way, applications that allow their own keyboard mappings
72 * (e.g. tcsh, X Windows) can be configured to use them in the way
73 * the label suggests (providing help or undoing).
75 * - Console switching is done with Alt+Fx (consoles 1..10) and
76 * Shift+Alt+Fx (consoles 11..20).
78 * - The misc. special function implemented in the kernel are mapped
79 * to the following key combinations:
81 * ClrHome -> Home/Find
82 * Shift + ClrHome -> End/Select
83 * Shift + Up -> Page Up
84 * Shift + Down -> Page Down
85 * Alt + Help -> show system status
86 * Shift + Help -> show memory info
87 * Ctrl + Help -> show registers
88 * Ctrl + Alt + Del -> Reboot
89 * Alt + Undo -> switch to last console
90 * Shift + Undo -> send interrupt
91 * Alt + Insert -> stop/start output (same as ^S/^Q)
92 * Alt + Up -> Scroll back console (if implemented)
93 * Alt + Down -> Scroll forward console (if implemented)
94 * Alt + CapsLock -> NumLock
98 * - Help mapped to K_HELP
99 * - Undo mapped to K_UNDO (= K_F246)
100 * - Keypad Left/Right Parenthesis mapped to new K_PPAREN[LR]
103 static u_short ataplain_map[NR_KEYS] __initdata = {
104 0xf200, 0xf01b, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036,
105 0xf037, 0xf038, 0xf039, 0xf030, 0xf02d, 0xf03d, 0xf008, 0xf009,
106 0xfb71, 0xfb77, 0xfb65, 0xfb72, 0xfb74, 0xfb79, 0xfb75, 0xfb69,
107 0xfb6f, 0xfb70, 0xf05b, 0xf05d, 0xf201, 0xf702, 0xfb61, 0xfb73,
108 0xfb64, 0xfb66, 0xfb67, 0xfb68, 0xfb6a, 0xfb6b, 0xfb6c, 0xf03b,
109 0xf027, 0xf060, 0xf700, 0xf05c, 0xfb7a, 0xfb78, 0xfb63, 0xfb76,
110 0xfb62, 0xfb6e, 0xfb6d, 0xf02c, 0xf02e, 0xf02f, 0xf700, 0xf200,
111 0xf703, 0xf020, 0xf207, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104,
112 0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf200, 0xf200, 0xf114,
113 0xf603, 0xf200, 0xf30b, 0xf601, 0xf200, 0xf602, 0xf30a, 0xf200,
114 0xf600, 0xf200, 0xf115, 0xf07f, 0xf200, 0xf200, 0xf200, 0xf200,
115 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
116 0xf200, 0xf1ff, 0xf11b, 0xf312, 0xf313, 0xf30d, 0xf30c, 0xf307,
117 0xf308, 0xf309, 0xf304, 0xf305, 0xf306, 0xf301, 0xf302, 0xf303,
118 0xf300, 0xf310, 0xf30e, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
119 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200
122 typedef enum kb_state_t {
123 KEYBOARD, AMOUSE, RMOUSE, JOYSTICK, CLOCK, RESYNC
126 #define IS_SYNC_CODE(sc) ((sc) >= 0x04 && (sc) <= 0xfb)
128 typedef struct keyboard_state {
129 unsigned char buf[6];
134 KEYBOARD_STATE kb_state;
136 #define DEFAULT_KEYB_REP_DELAY (HZ/4)
137 #define DEFAULT_KEYB_REP_RATE (HZ/25)
139 /* These could be settable by some ioctl() in future... */
140 static unsigned int key_repeat_delay = DEFAULT_KEYB_REP_DELAY;
141 static unsigned int key_repeat_rate = DEFAULT_KEYB_REP_RATE;
143 static unsigned char rep_scancode;
144 static struct timer_list atakeyb_rep_timer = {
145 .function = atakeyb_rep,
148 static void atakeyb_rep(unsigned long ignore)
150 /* Disable keyboard for the time we call handle_scancode(), else a race
151 * in the keyboard tty queue may happen */
152 atari_disable_irq(IRQ_MFP_ACIA);
153 del_timer(&atakeyb_rep_timer);
155 /* A keyboard int may have come in before we disabled the irq, so
156 * double-check whether rep_scancode is still != 0 */
158 init_timer(&atakeyb_rep_timer);
159 atakeyb_rep_timer.expires = jiffies + key_repeat_rate;
160 add_timer(&atakeyb_rep_timer);
162 //handle_scancode(rep_scancode, 1);
163 if (atari_input_keyboard_interrupt_hook)
164 atari_input_keyboard_interrupt_hook(rep_scancode, 1);
167 atari_enable_irq(IRQ_MFP_ACIA);
171 /* ++roman: If a keyboard overrun happened, we can't tell in general how much
172 * bytes have been lost and in which state of the packet structure we are now.
173 * This usually causes keyboards bytes to be interpreted as mouse movements
174 * and vice versa, which is very annoying. It seems better to throw away some
175 * bytes (that are usually mouse bytes) than to misinterpret them. Therefor I
176 * introduced the RESYNC state for IKBD data. In this state, the bytes up to
177 * one that really looks like a key event (0x04..0xf2) or the start of a mouse
178 * packet (0xf8..0xfb) are thrown away, but at most 2 bytes. This at least
179 * speeds up the resynchronization of the event structure, even if maybe a
180 * mouse movement is lost. However, nothing is perfect. For bytes 0x01..0x03,
181 * it's really hard to decide whether they're mouse or keyboard bytes. Since
182 * overruns usually occur when moving the Atari mouse rapidly, they're seen as
183 * mouse bytes here. If this is wrong, only a make code of the keyboard gets
184 * lost, which isn't too bad. Loosing a break code would be disastrous,
185 * because then the keyboard repeat strikes...
188 static irqreturn_t atari_keyboard_interrupt(int irq, void *dummy)
195 if (acia.mid_ctrl & ACIA_IRQ)
196 if (atari_MIDI_interrupt_hook)
197 atari_MIDI_interrupt_hook();
198 acia_stat = acia.key_ctrl;
199 /* check out if the interrupt came from this ACIA */
200 if (!((acia_stat | acia.mid_ctrl) & ACIA_IRQ))
203 if (acia_stat & ACIA_OVRN) {
204 /* a very fast typist or a slow system, give a warning */
205 /* ...happens often if interrupts were disabled for too long */
206 printk(KERN_DEBUG "Keyboard overrun\n");
207 scancode = acia.key_data;
208 /* Turn off autorepeating in case a break code has been lost */
209 del_timer(&atakeyb_rep_timer);
212 /* During self test, don't do resyncing, just process the code */
213 goto interpret_scancode;
214 else if (IS_SYNC_CODE(scancode)) {
215 /* This code seem already to be the start of a new packet or a
217 kb_state.state = KEYBOARD;
218 goto interpret_scancode;
220 /* Go to RESYNC state and skip this byte */
221 kb_state.state = RESYNC;
222 kb_state.len = 1; /* skip max. 1 another byte */
227 if (acia_stat & ACIA_RDRF) {
228 /* received a character */
229 scancode = acia.key_data; /* get it or reset the ACIA, I'll get it! */
230 tasklet_schedule(&keyboard_tasklet);
232 switch (kb_state.state) {
236 kb_state.state = AMOUSE;
244 kb_state.state = RMOUSE;
246 kb_state.buf[0] = scancode;
250 kb_state.state = CLOCK;
256 kb_state.state = JOYSTICK;
258 kb_state.buf[0] = scancode;
262 /* during self-test, note that 0xf1 received */
263 if (ikbd_self_test) {
265 self_test_last_rcv = jiffies;
271 break_flag = scancode & BREAK_MASK;
272 scancode &= ~BREAK_MASK;
273 if (ikbd_self_test) {
274 /* Scancodes sent during the self-test stand for broken
275 * keys (keys being down). The code *should* be a break
276 * code, but nevertheless some AT keyboard interfaces send
277 * make codes instead. Therefore, simply ignore
280 int keyval = plain_map[scancode], keytyp;
282 set_bit(scancode, broken_keys);
283 self_test_last_rcv = jiffies;
284 keyval = plain_map[scancode];
285 keytyp = KTYP(keyval) - 0xf0;
286 keyval = KVAL(keyval);
288 printk(KERN_WARNING "Key with scancode %d ", scancode);
289 if (keytyp == KT_LATIN || keytyp == KT_LETTER) {
291 printk("('^%c') ", keyval + '@');
293 printk("('%c') ", keyval);
295 printk("is broken -- will be ignored.\n");
297 } else if (test_bit(scancode, broken_keys))
300 #if 0 // FIXME; hangs at boot
302 del_timer(&atakeyb_rep_timer);
305 del_timer(&atakeyb_rep_timer);
306 rep_scancode = scancode;
307 atakeyb_rep_timer.expires = jiffies + key_repeat_delay;
308 add_timer(&atakeyb_rep_timer);
312 // handle_scancode(scancode, !break_flag);
313 if (atari_input_keyboard_interrupt_hook)
314 atari_input_keyboard_interrupt_hook((unsigned char)scancode, !break_flag);
320 kb_state.buf[kb_state.len++] = scancode;
321 if (kb_state.len == 5) {
322 kb_state.state = KEYBOARD;
324 /* wake up someone waiting for this */
329 kb_state.buf[kb_state.len++] = scancode;
330 if (kb_state.len == 3) {
331 kb_state.state = KEYBOARD;
332 if (atari_mouse_interrupt_hook)
333 atari_mouse_interrupt_hook(kb_state.buf);
338 kb_state.buf[1] = scancode;
339 kb_state.state = KEYBOARD;
340 #ifdef FIXED_ATARI_JOYSTICK
341 atari_joystick_interrupt(kb_state.buf);
346 kb_state.buf[kb_state.len++] = scancode;
347 if (kb_state.len == 6) {
348 kb_state.state = KEYBOARD;
349 /* wake up someone waiting for this.
350 But will this ever be used, as Linux keeps its own time.
351 Perhaps for synchronization purposes? */
352 /* wake_up_interruptible(&clock_wait); */
357 if (kb_state.len <= 0 || IS_SYNC_CODE(scancode)) {
358 kb_state.state = KEYBOARD;
359 goto interpret_scancode;
367 if (acia_stat & ACIA_CTS)
371 if (acia_stat & (ACIA_FE | ACIA_PE)) {
372 printk("Error in keyboard communication\n");
375 /* handle_scancode() can take a lot of time, so check again if
376 * some character arrived
382 * I write to the keyboard without using interrupts, I poll instead.
383 * This takes for the maximum length string allowed (7) at 7812.5 baud
384 * 8 data 1 start 1 stop bit: 9.0 ms
385 * If this takes too long for normal operation, interrupt driven writing
386 * is the solution. (I made a feeble attempt in that direction but I
387 * kept it simple for now.)
389 void ikbd_write(const char *str, int len)
393 if ((len < 1) || (len > 7))
394 panic("ikbd: maximum string length exceeded");
396 acia_stat = acia.key_ctrl;
397 if (acia_stat & ACIA_TDRE) {
398 acia.key_data = *str++;
404 /* Reset (without touching the clock) */
405 void ikbd_reset(void)
407 static const char cmd[2] = { 0x80, 0x01 };
412 * if all's well code 0xF1 is returned, else the break codes of
413 * all keys making contact
417 /* Set mouse button action */
418 void ikbd_mouse_button_action(int mode)
420 char cmd[2] = { 0x07, mode };
425 /* Set relative mouse position reporting */
426 void ikbd_mouse_rel_pos(void)
428 static const char cmd[1] = { 0x08 };
433 /* Set absolute mouse position reporting */
434 void ikbd_mouse_abs_pos(int xmax, int ymax)
436 char cmd[5] = { 0x09, xmax>>8, xmax&0xFF, ymax>>8, ymax&0xFF };
441 /* Set mouse keycode mode */
442 void ikbd_mouse_kbd_mode(int dx, int dy)
444 char cmd[3] = { 0x0A, dx, dy };
449 /* Set mouse threshold */
450 void ikbd_mouse_thresh(int x, int y)
452 char cmd[3] = { 0x0B, x, y };
457 /* Set mouse scale */
458 void ikbd_mouse_scale(int x, int y)
460 char cmd[3] = { 0x0C, x, y };
465 /* Interrogate mouse position */
466 void ikbd_mouse_pos_get(int *x, int *y)
468 static const char cmd[1] = { 0x0D };
472 /* wait for returning bytes */
475 /* Load mouse position */
476 void ikbd_mouse_pos_set(int x, int y)
478 char cmd[6] = { 0x0E, 0x00, x>>8, x&0xFF, y>>8, y&0xFF };
483 /* Set Y=0 at bottom */
484 void ikbd_mouse_y0_bot(void)
486 static const char cmd[1] = { 0x0F };
492 void ikbd_mouse_y0_top(void)
494 static const char cmd[1] = { 0x10 };
500 void ikbd_resume(void)
502 static const char cmd[1] = { 0x11 };
508 void ikbd_mouse_disable(void)
510 static const char cmd[1] = { 0x12 };
516 void ikbd_pause(void)
518 static const char cmd[1] = { 0x13 };
523 /* Set joystick event reporting */
524 void ikbd_joystick_event_on(void)
526 static const char cmd[1] = { 0x14 };
531 /* Set joystick interrogation mode */
532 void ikbd_joystick_event_off(void)
534 static const char cmd[1] = { 0x15 };
539 /* Joystick interrogation */
540 void ikbd_joystick_get_state(void)
542 static const char cmd[1] = { 0x16 };
548 /* This disables all other ikbd activities !!!! */
549 /* Set joystick monitoring */
550 void ikbd_joystick_monitor(int rate)
552 static const char cmd[2] = { 0x17, rate };
556 kb_state.state = JOYSTICK_MONITOR;
560 /* some joystick routines not in yet (0x18-0x19) */
562 /* Disable joysticks */
563 void ikbd_joystick_disable(void)
565 static const char cmd[1] = { 0x1A };
570 /* Time-of-day clock set */
571 void ikbd_clock_set(int year, int month, int day, int hour, int minute, int second)
573 char cmd[7] = { 0x1B, year, month, day, hour, minute, second };
578 /* Interrogate time-of-day clock */
579 void ikbd_clock_get(int *year, int *month, int *day, int *hour, int *minute, int second)
581 static const char cmd[1] = { 0x1C };
587 void ikbd_mem_write(int address, int size, char *data)
589 panic("Attempt to write data into keyboard memory");
593 void ikbd_mem_read(int address, char data[6])
595 char cmd[3] = { 0x21, address>>8, address&0xFF };
599 /* receive data and put it in data */
602 /* Controller execute */
603 void ikbd_exec(int address)
605 char cmd[3] = { 0x22, address>>8, address&0xFF };
610 /* Status inquiries (0x87-0x9A) not yet implemented */
612 /* Set the state of the caps lock led. */
613 void atari_kbd_leds(unsigned int leds)
615 char cmd[6] = {32, 0, 4, 1, 254 + ((leds & 4) != 0), 0};
621 * The original code sometimes left the interrupt line of
622 * the ACIAs low forever. I hope, it is fixed now.
624 * Martin Rogge, 20 Aug 1995
627 static int atari_keyb_done = 0;
629 int __init atari_keyb_init(void)
635 memcpy(key_maps[0], ataplain_map, sizeof(plain_map));
637 kb_state.state = KEYBOARD;
640 request_irq(IRQ_MFP_ACIA, atari_keyboard_interrupt, IRQ_TYPE_SLOW,
641 "keyboard/mouse/MIDI", atari_keyboard_interrupt);
643 atari_turnoff_irq(IRQ_MFP_ACIA);
645 /* reset IKBD ACIA */
646 acia.key_ctrl = ACIA_RESET |
647 (atari_switches & ATARI_SWITCH_IKBD) ? ACIA_RHTID : 0;
651 /* reset MIDI ACIA */
652 acia.mid_ctrl = ACIA_RESET |
653 (atari_switches & ATARI_SWITCH_MIDI) ? ACIA_RHTID : 0;
657 /* divide 500kHz by 64 gives 7812.5 baud */
658 /* 8 data no parity 1 start 1 stop bit */
659 /* receive interrupt enabled */
660 /* RTS low (except if switch selected), transmit interrupt disabled */
661 acia.key_ctrl = (ACIA_DIV64|ACIA_D8N1S|ACIA_RIE) |
662 ((atari_switches & ATARI_SWITCH_IKBD) ?
663 ACIA_RHTID : ACIA_RLTID);
665 acia.mid_ctrl = ACIA_DIV16 | ACIA_D8N1S |
666 (atari_switches & ATARI_SWITCH_MIDI) ? ACIA_RHTID : 0;
668 /* make sure the interrupt line is up */
669 } while ((mfp.par_dt_reg & 0x10) == 0);
671 /* enable ACIA Interrupts */
672 mfp.active_edge &= ~0x10;
673 atari_turnon_irq(IRQ_MFP_ACIA);
677 /* wait for a period of inactivity (here: 0.25s), then assume the IKBD's
678 * self-test is finished */
679 self_test_last_rcv = jiffies;
680 while (time_before(jiffies, self_test_last_rcv + HZ/4))
682 /* if not incremented: no 0xf1 received */
683 if (ikbd_self_test == 1)
684 printk(KERN_ERR "WARNING: keyboard self test failed!\n");
687 ikbd_mouse_disable();
688 ikbd_joystick_disable();
690 #ifdef FIXED_ATARI_JOYSTICK
691 atari_joystick_init();
700 int atari_kbdrate(struct kbd_repeat *k)
703 /* convert from msec to jiffies */
704 key_repeat_delay = (k->delay * HZ + 500) / 1000;
705 if (key_repeat_delay < 1)
706 key_repeat_delay = 1;
709 key_repeat_rate = (k->period * HZ + 500) / 1000;
710 if (key_repeat_rate < 1)
714 k->delay = key_repeat_delay * 1000 / HZ;
715 k->period = key_repeat_rate * 1000 / HZ;
720 int atari_kbd_translate(unsigned char keycode, unsigned char *keycodep, char raw_mode)
722 #ifdef CONFIG_MAGIC_SYSRQ
723 /* ALT+HELP pressed? */
724 if ((keycode == 98) && ((shift_state & 0xff) == 8))