blob: 2b5f64726a2e88ff851c4c02119f5729e7947d80 [file] [log] [blame]
Michael Schmitzc04cb852007-05-01 22:32:38 +02001/*
2 * linux/atari/atakeyb.c
3 *
4 * Atari Keyboard driver for 680x0 Linux
5 *
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
8 * for more details.
9 */
10
11/*
12 * Atari support by Robert de Vries
13 * enhanced by Bjoern Brauel and Roman Hodek
14 */
15
Al Viro88f8bb7802007-07-20 04:33:18 +010016#include <linux/module.h>
Michael Schmitzc04cb852007-05-01 22:32:38 +020017#include <linux/sched.h>
18#include <linux/kernel.h>
19#include <linux/interrupt.h>
20#include <linux/errno.h>
21#include <linux/keyboard.h>
22#include <linux/delay.h>
23#include <linux/timer.h>
24#include <linux/kd.h>
25#include <linux/random.h>
26#include <linux/init.h>
27#include <linux/kbd_kern.h>
28
29#include <asm/atariints.h>
30#include <asm/atarihw.h>
31#include <asm/atarikb.h>
32#include <asm/atari_joystick.h>
33#include <asm/irq.h>
34
35static void atakeyb_rep(unsigned long ignore);
36extern unsigned int keymap_count;
37
38/* Hook for MIDI serial driver */
39void (*atari_MIDI_interrupt_hook) (void);
40/* Hook for mouse driver */
41void (*atari_mouse_interrupt_hook) (char *);
42/* Hook for keyboard inputdev driver */
43void (*atari_input_keyboard_interrupt_hook) (unsigned char, char);
44/* Hook for mouse inputdev driver */
45void (*atari_input_mouse_interrupt_hook) (char *);
Al Viro88f8bb7802007-07-20 04:33:18 +010046EXPORT_SYMBOL(atari_mouse_interrupt_hook);
47EXPORT_SYMBOL(atari_input_keyboard_interrupt_hook);
48EXPORT_SYMBOL(atari_input_mouse_interrupt_hook);
Michael Schmitzc04cb852007-05-01 22:32:38 +020049
50/* variables for IKBD self test: */
51
52/* state: 0: off; >0: in progress; >1: 0xf1 received */
53static volatile int ikbd_self_test;
54/* timestamp when last received a char */
55static volatile unsigned long self_test_last_rcv;
56/* bitmap of keys reported as broken */
57static unsigned long broken_keys[128/(sizeof(unsigned long)*8)] = { 0, };
58
59#define BREAK_MASK (0x80)
60
61/*
62 * ++roman: The following changes were applied manually:
63 *
64 * - The Alt (= Meta) key works in combination with Shift and
65 * Control, e.g. Alt+Shift+a sends Meta-A (0xc1), Alt+Control+A sends
66 * Meta-Ctrl-A (0x81) ...
67 *
68 * - The parentheses on the keypad send '(' and ')' with all
69 * modifiers (as would do e.g. keypad '+'), but they cannot be used as
70 * application keys (i.e. sending Esc O c).
71 *
72 * - HELP and UNDO are mapped to be F21 and F24, resp, that send the
73 * codes "\E[M" and "\E[P". (This is better than the old mapping to
74 * F11 and F12, because these codes are on Shift+F1/2 anyway.) This
75 * way, applications that allow their own keyboard mappings
76 * (e.g. tcsh, X Windows) can be configured to use them in the way
77 * the label suggests (providing help or undoing).
78 *
79 * - Console switching is done with Alt+Fx (consoles 1..10) and
80 * Shift+Alt+Fx (consoles 11..20).
81 *
82 * - The misc. special function implemented in the kernel are mapped
83 * to the following key combinations:
84 *
85 * ClrHome -> Home/Find
86 * Shift + ClrHome -> End/Select
87 * Shift + Up -> Page Up
88 * Shift + Down -> Page Down
89 * Alt + Help -> show system status
90 * Shift + Help -> show memory info
91 * Ctrl + Help -> show registers
92 * Ctrl + Alt + Del -> Reboot
93 * Alt + Undo -> switch to last console
94 * Shift + Undo -> send interrupt
95 * Alt + Insert -> stop/start output (same as ^S/^Q)
96 * Alt + Up -> Scroll back console (if implemented)
97 * Alt + Down -> Scroll forward console (if implemented)
98 * Alt + CapsLock -> NumLock
99 *
100 * ++Andreas:
101 *
102 * - Help mapped to K_HELP
103 * - Undo mapped to K_UNDO (= K_F246)
104 * - Keypad Left/Right Parenthesis mapped to new K_PPAREN[LR]
105 */
106
107static u_short ataplain_map[NR_KEYS] __initdata = {
108 0xf200, 0xf01b, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036,
109 0xf037, 0xf038, 0xf039, 0xf030, 0xf02d, 0xf03d, 0xf008, 0xf009,
110 0xfb71, 0xfb77, 0xfb65, 0xfb72, 0xfb74, 0xfb79, 0xfb75, 0xfb69,
111 0xfb6f, 0xfb70, 0xf05b, 0xf05d, 0xf201, 0xf702, 0xfb61, 0xfb73,
112 0xfb64, 0xfb66, 0xfb67, 0xfb68, 0xfb6a, 0xfb6b, 0xfb6c, 0xf03b,
113 0xf027, 0xf060, 0xf700, 0xf05c, 0xfb7a, 0xfb78, 0xfb63, 0xfb76,
114 0xfb62, 0xfb6e, 0xfb6d, 0xf02c, 0xf02e, 0xf02f, 0xf700, 0xf200,
115 0xf703, 0xf020, 0xf207, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104,
116 0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf200, 0xf200, 0xf114,
117 0xf603, 0xf200, 0xf30b, 0xf601, 0xf200, 0xf602, 0xf30a, 0xf200,
118 0xf600, 0xf200, 0xf115, 0xf07f, 0xf200, 0xf200, 0xf200, 0xf200,
119 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
120 0xf200, 0xf1ff, 0xf11b, 0xf312, 0xf313, 0xf30d, 0xf30c, 0xf307,
121 0xf308, 0xf309, 0xf304, 0xf305, 0xf306, 0xf301, 0xf302, 0xf303,
122 0xf300, 0xf310, 0xf30e, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
123 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200
124};
125
126typedef enum kb_state_t {
127 KEYBOARD, AMOUSE, RMOUSE, JOYSTICK, CLOCK, RESYNC
128} KB_STATE_T;
129
130#define IS_SYNC_CODE(sc) ((sc) >= 0x04 && (sc) <= 0xfb)
131
132typedef struct keyboard_state {
133 unsigned char buf[6];
134 int len;
135 KB_STATE_T state;
136} KEYBOARD_STATE;
137
138KEYBOARD_STATE kb_state;
139
140#define DEFAULT_KEYB_REP_DELAY (HZ/4)
141#define DEFAULT_KEYB_REP_RATE (HZ/25)
142
143/* These could be settable by some ioctl() in future... */
144static unsigned int key_repeat_delay = DEFAULT_KEYB_REP_DELAY;
145static unsigned int key_repeat_rate = DEFAULT_KEYB_REP_RATE;
146
147static unsigned char rep_scancode;
148static struct timer_list atakeyb_rep_timer = {
149 .function = atakeyb_rep,
150};
151
152static void atakeyb_rep(unsigned long ignore)
153{
154 /* Disable keyboard for the time we call handle_scancode(), else a race
155 * in the keyboard tty queue may happen */
156 atari_disable_irq(IRQ_MFP_ACIA);
157 del_timer(&atakeyb_rep_timer);
158
159 /* A keyboard int may have come in before we disabled the irq, so
160 * double-check whether rep_scancode is still != 0 */
161 if (rep_scancode) {
162 init_timer(&atakeyb_rep_timer);
163 atakeyb_rep_timer.expires = jiffies + key_repeat_rate;
164 add_timer(&atakeyb_rep_timer);
165
166 //handle_scancode(rep_scancode, 1);
167 if (atari_input_keyboard_interrupt_hook)
168 atari_input_keyboard_interrupt_hook(rep_scancode, 1);
169 }
170
171 atari_enable_irq(IRQ_MFP_ACIA);
172}
173
174
175/* ++roman: If a keyboard overrun happened, we can't tell in general how much
176 * bytes have been lost and in which state of the packet structure we are now.
177 * This usually causes keyboards bytes to be interpreted as mouse movements
178 * and vice versa, which is very annoying. It seems better to throw away some
179 * bytes (that are usually mouse bytes) than to misinterpret them. Therefor I
180 * introduced the RESYNC state for IKBD data. In this state, the bytes up to
181 * one that really looks like a key event (0x04..0xf2) or the start of a mouse
182 * packet (0xf8..0xfb) are thrown away, but at most 2 bytes. This at least
183 * speeds up the resynchronization of the event structure, even if maybe a
184 * mouse movement is lost. However, nothing is perfect. For bytes 0x01..0x03,
185 * it's really hard to decide whether they're mouse or keyboard bytes. Since
186 * overruns usually occur when moving the Atari mouse rapidly, they're seen as
187 * mouse bytes here. If this is wrong, only a make code of the keyboard gets
188 * lost, which isn't too bad. Loosing a break code would be disastrous,
189 * because then the keyboard repeat strikes...
190 */
191
192static irqreturn_t atari_keyboard_interrupt(int irq, void *dummy)
193{
194 u_char acia_stat;
195 int scancode;
196 int break_flag;
197
198repeat:
199 if (acia.mid_ctrl & ACIA_IRQ)
200 if (atari_MIDI_interrupt_hook)
201 atari_MIDI_interrupt_hook();
202 acia_stat = acia.key_ctrl;
203 /* check out if the interrupt came from this ACIA */
204 if (!((acia_stat | acia.mid_ctrl) & ACIA_IRQ))
205 return IRQ_HANDLED;
206
207 if (acia_stat & ACIA_OVRN) {
208 /* a very fast typist or a slow system, give a warning */
209 /* ...happens often if interrupts were disabled for too long */
210 printk(KERN_DEBUG "Keyboard overrun\n");
211 scancode = acia.key_data;
212 /* Turn off autorepeating in case a break code has been lost */
213 del_timer(&atakeyb_rep_timer);
214 rep_scancode = 0;
215 if (ikbd_self_test)
216 /* During self test, don't do resyncing, just process the code */
217 goto interpret_scancode;
218 else if (IS_SYNC_CODE(scancode)) {
219 /* This code seem already to be the start of a new packet or a
220 * single scancode */
221 kb_state.state = KEYBOARD;
222 goto interpret_scancode;
223 } else {
224 /* Go to RESYNC state and skip this byte */
225 kb_state.state = RESYNC;
226 kb_state.len = 1; /* skip max. 1 another byte */
227 goto repeat;
228 }
229 }
230
231 if (acia_stat & ACIA_RDRF) {
232 /* received a character */
233 scancode = acia.key_data; /* get it or reset the ACIA, I'll get it! */
234 tasklet_schedule(&keyboard_tasklet);
235 interpret_scancode:
236 switch (kb_state.state) {
237 case KEYBOARD:
238 switch (scancode) {
239 case 0xF7:
240 kb_state.state = AMOUSE;
241 kb_state.len = 0;
242 break;
243
244 case 0xF8:
245 case 0xF9:
246 case 0xFA:
247 case 0xFB:
248 kb_state.state = RMOUSE;
249 kb_state.len = 1;
250 kb_state.buf[0] = scancode;
251 break;
252
253 case 0xFC:
254 kb_state.state = CLOCK;
255 kb_state.len = 0;
256 break;
257
258 case 0xFE:
259 case 0xFF:
260 kb_state.state = JOYSTICK;
261 kb_state.len = 1;
262 kb_state.buf[0] = scancode;
263 break;
264
265 case 0xF1:
266 /* during self-test, note that 0xf1 received */
267 if (ikbd_self_test) {
268 ++ikbd_self_test;
269 self_test_last_rcv = jiffies;
270 break;
271 }
272 /* FALL THROUGH */
273
274 default:
275 break_flag = scancode & BREAK_MASK;
276 scancode &= ~BREAK_MASK;
277 if (ikbd_self_test) {
278 /* Scancodes sent during the self-test stand for broken
279 * keys (keys being down). The code *should* be a break
280 * code, but nevertheless some AT keyboard interfaces send
281 * make codes instead. Therefore, simply ignore
282 * break_flag...
283 */
284 int keyval = plain_map[scancode], keytyp;
285
286 set_bit(scancode, broken_keys);
287 self_test_last_rcv = jiffies;
288 keyval = plain_map[scancode];
289 keytyp = KTYP(keyval) - 0xf0;
290 keyval = KVAL(keyval);
291
292 printk(KERN_WARNING "Key with scancode %d ", scancode);
293 if (keytyp == KT_LATIN || keytyp == KT_LETTER) {
294 if (keyval < ' ')
295 printk("('^%c') ", keyval + '@');
296 else
297 printk("('%c') ", keyval);
298 }
299 printk("is broken -- will be ignored.\n");
300 break;
301 } else if (test_bit(scancode, broken_keys))
302 break;
303
304#if 0 // FIXME; hangs at boot
305 if (break_flag) {
306 del_timer(&atakeyb_rep_timer);
307 rep_scancode = 0;
308 } else {
309 del_timer(&atakeyb_rep_timer);
310 rep_scancode = scancode;
311 atakeyb_rep_timer.expires = jiffies + key_repeat_delay;
312 add_timer(&atakeyb_rep_timer);
313 }
314#endif
315
316 // handle_scancode(scancode, !break_flag);
317 if (atari_input_keyboard_interrupt_hook)
318 atari_input_keyboard_interrupt_hook((unsigned char)scancode, !break_flag);
319 break;
320 }
321 break;
322
323 case AMOUSE:
324 kb_state.buf[kb_state.len++] = scancode;
325 if (kb_state.len == 5) {
326 kb_state.state = KEYBOARD;
327 /* not yet used */
328 /* wake up someone waiting for this */
329 }
330 break;
331
332 case RMOUSE:
333 kb_state.buf[kb_state.len++] = scancode;
334 if (kb_state.len == 3) {
335 kb_state.state = KEYBOARD;
336 if (atari_mouse_interrupt_hook)
337 atari_mouse_interrupt_hook(kb_state.buf);
338 }
339 break;
340
341 case JOYSTICK:
342 kb_state.buf[1] = scancode;
343 kb_state.state = KEYBOARD;
344#ifdef FIXED_ATARI_JOYSTICK
345 atari_joystick_interrupt(kb_state.buf);
346#endif
347 break;
348
349 case CLOCK:
350 kb_state.buf[kb_state.len++] = scancode;
351 if (kb_state.len == 6) {
352 kb_state.state = KEYBOARD;
353 /* wake up someone waiting for this.
354 But will this ever be used, as Linux keeps its own time.
355 Perhaps for synchronization purposes? */
356 /* wake_up_interruptible(&clock_wait); */
357 }
358 break;
359
360 case RESYNC:
361 if (kb_state.len <= 0 || IS_SYNC_CODE(scancode)) {
362 kb_state.state = KEYBOARD;
363 goto interpret_scancode;
364 }
365 kb_state.len--;
366 break;
367 }
368 }
369
370#if 0
371 if (acia_stat & ACIA_CTS)
372 /* cannot happen */;
373#endif
374
375 if (acia_stat & (ACIA_FE | ACIA_PE)) {
376 printk("Error in keyboard communication\n");
377 }
378
379 /* handle_scancode() can take a lot of time, so check again if
380 * some character arrived
381 */
382 goto repeat;
383}
384
385/*
386 * I write to the keyboard without using interrupts, I poll instead.
387 * This takes for the maximum length string allowed (7) at 7812.5 baud
388 * 8 data 1 start 1 stop bit: 9.0 ms
389 * If this takes too long for normal operation, interrupt driven writing
390 * is the solution. (I made a feeble attempt in that direction but I
391 * kept it simple for now.)
392 */
393void ikbd_write(const char *str, int len)
394{
395 u_char acia_stat;
396
397 if ((len < 1) || (len > 7))
398 panic("ikbd: maximum string length exceeded");
399 while (len) {
400 acia_stat = acia.key_ctrl;
401 if (acia_stat & ACIA_TDRE) {
402 acia.key_data = *str++;
403 len--;
404 }
405 }
406}
407
408/* Reset (without touching the clock) */
409void ikbd_reset(void)
410{
411 static const char cmd[2] = { 0x80, 0x01 };
412
413 ikbd_write(cmd, 2);
414
415 /*
416 * if all's well code 0xF1 is returned, else the break codes of
417 * all keys making contact
418 */
419}
420
421/* Set mouse button action */
422void ikbd_mouse_button_action(int mode)
423{
424 char cmd[2] = { 0x07, mode };
425
426 ikbd_write(cmd, 2);
427}
428
429/* Set relative mouse position reporting */
430void ikbd_mouse_rel_pos(void)
431{
432 static const char cmd[1] = { 0x08 };
433
434 ikbd_write(cmd, 1);
435}
Al Viro88f8bb7802007-07-20 04:33:18 +0100436EXPORT_SYMBOL(ikbd_mouse_rel_pos);
Michael Schmitzc04cb852007-05-01 22:32:38 +0200437
438/* Set absolute mouse position reporting */
439void ikbd_mouse_abs_pos(int xmax, int ymax)
440{
441 char cmd[5] = { 0x09, xmax>>8, xmax&0xFF, ymax>>8, ymax&0xFF };
442
443 ikbd_write(cmd, 5);
444}
445
446/* Set mouse keycode mode */
447void ikbd_mouse_kbd_mode(int dx, int dy)
448{
449 char cmd[3] = { 0x0A, dx, dy };
450
451 ikbd_write(cmd, 3);
452}
453
454/* Set mouse threshold */
455void ikbd_mouse_thresh(int x, int y)
456{
457 char cmd[3] = { 0x0B, x, y };
458
459 ikbd_write(cmd, 3);
460}
Al Viro88f8bb7802007-07-20 04:33:18 +0100461EXPORT_SYMBOL(ikbd_mouse_thresh);
Michael Schmitzc04cb852007-05-01 22:32:38 +0200462
463/* Set mouse scale */
464void ikbd_mouse_scale(int x, int y)
465{
466 char cmd[3] = { 0x0C, x, y };
467
468 ikbd_write(cmd, 3);
469}
470
471/* Interrogate mouse position */
472void ikbd_mouse_pos_get(int *x, int *y)
473{
474 static const char cmd[1] = { 0x0D };
475
476 ikbd_write(cmd, 1);
477
478 /* wait for returning bytes */
479}
480
481/* Load mouse position */
482void ikbd_mouse_pos_set(int x, int y)
483{
484 char cmd[6] = { 0x0E, 0x00, x>>8, x&0xFF, y>>8, y&0xFF };
485
486 ikbd_write(cmd, 6);
487}
488
489/* Set Y=0 at bottom */
490void ikbd_mouse_y0_bot(void)
491{
492 static const char cmd[1] = { 0x0F };
493
494 ikbd_write(cmd, 1);
495}
496
497/* Set Y=0 at top */
498void ikbd_mouse_y0_top(void)
499{
500 static const char cmd[1] = { 0x10 };
501
502 ikbd_write(cmd, 1);
503}
Al Viro88f8bb7802007-07-20 04:33:18 +0100504EXPORT_SYMBOL(ikbd_mouse_y0_top);
Michael Schmitzc04cb852007-05-01 22:32:38 +0200505
506/* Resume */
507void ikbd_resume(void)
508{
509 static const char cmd[1] = { 0x11 };
510
511 ikbd_write(cmd, 1);
512}
513
514/* Disable mouse */
515void ikbd_mouse_disable(void)
516{
517 static const char cmd[1] = { 0x12 };
518
519 ikbd_write(cmd, 1);
520}
Al Viro88f8bb7802007-07-20 04:33:18 +0100521EXPORT_SYMBOL(ikbd_mouse_disable);
Michael Schmitzc04cb852007-05-01 22:32:38 +0200522
523/* Pause output */
524void ikbd_pause(void)
525{
526 static const char cmd[1] = { 0x13 };
527
528 ikbd_write(cmd, 1);
529}
530
531/* Set joystick event reporting */
532void ikbd_joystick_event_on(void)
533{
534 static const char cmd[1] = { 0x14 };
535
536 ikbd_write(cmd, 1);
537}
538
539/* Set joystick interrogation mode */
540void ikbd_joystick_event_off(void)
541{
542 static const char cmd[1] = { 0x15 };
543
544 ikbd_write(cmd, 1);
545}
546
547/* Joystick interrogation */
548void ikbd_joystick_get_state(void)
549{
550 static const char cmd[1] = { 0x16 };
551
552 ikbd_write(cmd, 1);
553}
554
555#if 0
556/* This disables all other ikbd activities !!!! */
557/* Set joystick monitoring */
558void ikbd_joystick_monitor(int rate)
559{
560 static const char cmd[2] = { 0x17, rate };
561
562 ikbd_write(cmd, 2);
563
564 kb_state.state = JOYSTICK_MONITOR;
565}
566#endif
567
568/* some joystick routines not in yet (0x18-0x19) */
569
570/* Disable joysticks */
571void ikbd_joystick_disable(void)
572{
573 static const char cmd[1] = { 0x1A };
574
575 ikbd_write(cmd, 1);
576}
577
578/* Time-of-day clock set */
579void ikbd_clock_set(int year, int month, int day, int hour, int minute, int second)
580{
581 char cmd[7] = { 0x1B, year, month, day, hour, minute, second };
582
583 ikbd_write(cmd, 7);
584}
585
586/* Interrogate time-of-day clock */
587void ikbd_clock_get(int *year, int *month, int *day, int *hour, int *minute, int second)
588{
589 static const char cmd[1] = { 0x1C };
590
591 ikbd_write(cmd, 1);
592}
593
594/* Memory load */
595void ikbd_mem_write(int address, int size, char *data)
596{
597 panic("Attempt to write data into keyboard memory");
598}
599
600/* Memory read */
601void ikbd_mem_read(int address, char data[6])
602{
603 char cmd[3] = { 0x21, address>>8, address&0xFF };
604
605 ikbd_write(cmd, 3);
606
607 /* receive data and put it in data */
608}
609
610/* Controller execute */
611void ikbd_exec(int address)
612{
613 char cmd[3] = { 0x22, address>>8, address&0xFF };
614
615 ikbd_write(cmd, 3);
616}
617
618/* Status inquiries (0x87-0x9A) not yet implemented */
619
620/* Set the state of the caps lock led. */
621void atari_kbd_leds(unsigned int leds)
622{
623 char cmd[6] = {32, 0, 4, 1, 254 + ((leds & 4) != 0), 0};
624
625 ikbd_write(cmd, 6);
626}
627
628/*
629 * The original code sometimes left the interrupt line of
630 * the ACIAs low forever. I hope, it is fixed now.
631 *
632 * Martin Rogge, 20 Aug 1995
633 */
634
635static int atari_keyb_done = 0;
636
637int __init atari_keyb_init(void)
638{
639 if (atari_keyb_done)
640 return 0;
641
642 /* setup key map */
643 memcpy(key_maps[0], ataplain_map, sizeof(plain_map));
644
645 kb_state.state = KEYBOARD;
646 kb_state.len = 0;
647
648 request_irq(IRQ_MFP_ACIA, atari_keyboard_interrupt, IRQ_TYPE_SLOW,
649 "keyboard/mouse/MIDI", atari_keyboard_interrupt);
650
651 atari_turnoff_irq(IRQ_MFP_ACIA);
652 do {
653 /* reset IKBD ACIA */
654 acia.key_ctrl = ACIA_RESET |
655 (atari_switches & ATARI_SWITCH_IKBD) ? ACIA_RHTID : 0;
656 (void)acia.key_ctrl;
657 (void)acia.key_data;
658
659 /* reset MIDI ACIA */
660 acia.mid_ctrl = ACIA_RESET |
661 (atari_switches & ATARI_SWITCH_MIDI) ? ACIA_RHTID : 0;
662 (void)acia.mid_ctrl;
663 (void)acia.mid_data;
664
665 /* divide 500kHz by 64 gives 7812.5 baud */
666 /* 8 data no parity 1 start 1 stop bit */
667 /* receive interrupt enabled */
668 /* RTS low (except if switch selected), transmit interrupt disabled */
669 acia.key_ctrl = (ACIA_DIV64|ACIA_D8N1S|ACIA_RIE) |
670 ((atari_switches & ATARI_SWITCH_IKBD) ?
671 ACIA_RHTID : ACIA_RLTID);
672
673 acia.mid_ctrl = ACIA_DIV16 | ACIA_D8N1S |
674 (atari_switches & ATARI_SWITCH_MIDI) ? ACIA_RHTID : 0;
675
676 /* make sure the interrupt line is up */
677 } while ((mfp.par_dt_reg & 0x10) == 0);
678
679 /* enable ACIA Interrupts */
680 mfp.active_edge &= ~0x10;
681 atari_turnon_irq(IRQ_MFP_ACIA);
682
683 ikbd_self_test = 1;
684 ikbd_reset();
685 /* wait for a period of inactivity (here: 0.25s), then assume the IKBD's
686 * self-test is finished */
687 self_test_last_rcv = jiffies;
688 while (time_before(jiffies, self_test_last_rcv + HZ/4))
689 barrier();
690 /* if not incremented: no 0xf1 received */
691 if (ikbd_self_test == 1)
692 printk(KERN_ERR "WARNING: keyboard self test failed!\n");
693 ikbd_self_test = 0;
694
695 ikbd_mouse_disable();
696 ikbd_joystick_disable();
697
698#ifdef FIXED_ATARI_JOYSTICK
699 atari_joystick_init();
700#endif
701
702 // flag init done
703 atari_keyb_done = 1;
704 return 0;
705}
706
Michael Schmitzc04cb852007-05-01 22:32:38 +0200707int atari_kbdrate(struct kbd_repeat *k)
708{
709 if (k->delay > 0) {
710 /* convert from msec to jiffies */
711 key_repeat_delay = (k->delay * HZ + 500) / 1000;
712 if (key_repeat_delay < 1)
713 key_repeat_delay = 1;
714 }
715 if (k->period > 0) {
716 key_repeat_rate = (k->period * HZ + 500) / 1000;
717 if (key_repeat_rate < 1)
718 key_repeat_rate = 1;
719 }
720
721 k->delay = key_repeat_delay * 1000 / HZ;
722 k->period = key_repeat_rate * 1000 / HZ;
723
724 return 0;
725}
726
727int atari_kbd_translate(unsigned char keycode, unsigned char *keycodep, char raw_mode)
728{
729#ifdef CONFIG_MAGIC_SYSRQ
730 /* ALT+HELP pressed? */
731 if ((keycode == 98) && ((shift_state & 0xff) == 8))
732 *keycodep = 0xff;
733 else
734#endif
735 *keycodep = keycode;
736 return 1;
737}