1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17#include <linux/module.h>
18#include <linux/sched.h>
19#include <linux/kernel.h>
20#include <linux/interrupt.h>
21#include <linux/errno.h>
22#include <linux/keyboard.h>
23#include <linux/delay.h>
24#include <linux/timer.h>
25#include <linux/kd.h>
26#include <linux/random.h>
27#include <linux/init.h>
28#include <linux/kbd_kern.h>
29
30#include <asm/atariints.h>
31#include <asm/atarihw.h>
32#include <asm/atarikb.h>
33#include <asm/atari_joystick.h>
34#include <asm/irq.h>
35
36
37
38void (*atari_MIDI_interrupt_hook) (void);
39
40void (*atari_mouse_interrupt_hook) (char *);
41
42void (*atari_input_keyboard_interrupt_hook) (unsigned char, char);
43
44void (*atari_input_mouse_interrupt_hook) (char *);
45EXPORT_SYMBOL(atari_mouse_interrupt_hook);
46EXPORT_SYMBOL(atari_input_keyboard_interrupt_hook);
47EXPORT_SYMBOL(atari_input_mouse_interrupt_hook);
48
49
50
51
52static volatile int ikbd_self_test;
53
54static volatile unsigned long self_test_last_rcv;
55
56static unsigned long broken_keys[128/(sizeof(unsigned long)*8)] = { 0, };
57
58#define BREAK_MASK (0x80)
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106typedef enum kb_state_t {
107 KEYBOARD, AMOUSE, RMOUSE, JOYSTICK, CLOCK, RESYNC
108} KB_STATE_T;
109
110#define IS_SYNC_CODE(sc) ((sc) >= 0x04 && (sc) <= 0xfb)
111
112typedef struct keyboard_state {
113 unsigned char buf[6];
114 int len;
115 KB_STATE_T state;
116} KEYBOARD_STATE;
117
118KEYBOARD_STATE kb_state;
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137static irqreturn_t atari_keyboard_interrupt(int irq, void *dummy)
138{
139 u_char acia_stat;
140 int scancode;
141 int break_flag;
142
143repeat:
144 if (acia.mid_ctrl & ACIA_IRQ)
145 if (atari_MIDI_interrupt_hook)
146 atari_MIDI_interrupt_hook();
147 acia_stat = acia.key_ctrl;
148
149 if (!((acia_stat | acia.mid_ctrl) & ACIA_IRQ))
150 return IRQ_HANDLED;
151
152 if (acia_stat & ACIA_OVRN) {
153
154
155 printk(KERN_DEBUG "Keyboard overrun\n");
156 scancode = acia.key_data;
157 if (ikbd_self_test)
158
159 goto interpret_scancode;
160 else if (IS_SYNC_CODE(scancode)) {
161
162
163 kb_state.state = KEYBOARD;
164 goto interpret_scancode;
165 } else {
166
167 kb_state.state = RESYNC;
168 kb_state.len = 1;
169 goto repeat;
170 }
171 }
172
173 if (acia_stat & ACIA_RDRF) {
174
175 scancode = acia.key_data;
176 tasklet_schedule(&keyboard_tasklet);
177 interpret_scancode:
178 switch (kb_state.state) {
179 case KEYBOARD:
180 switch (scancode) {
181 case 0xF7:
182 kb_state.state = AMOUSE;
183 kb_state.len = 0;
184 break;
185
186 case 0xF8:
187 case 0xF9:
188 case 0xFA:
189 case 0xFB:
190 kb_state.state = RMOUSE;
191 kb_state.len = 1;
192 kb_state.buf[0] = scancode;
193 break;
194
195 case 0xFC:
196 kb_state.state = CLOCK;
197 kb_state.len = 0;
198 break;
199
200 case 0xFE:
201 case 0xFF:
202 kb_state.state = JOYSTICK;
203 kb_state.len = 1;
204 kb_state.buf[0] = scancode;
205 break;
206
207 case 0xF1:
208
209 if (ikbd_self_test) {
210 ++ikbd_self_test;
211 self_test_last_rcv = jiffies;
212 break;
213 }
214
215
216 default:
217 break_flag = scancode & BREAK_MASK;
218 scancode &= ~BREAK_MASK;
219 if (ikbd_self_test) {
220
221
222
223
224
225
226 int keyval, keytyp;
227
228 set_bit(scancode, broken_keys);
229 self_test_last_rcv = jiffies;
230
231 keyval = scancode;
232 keytyp = KTYP(keyval) - 0xf0;
233 keyval = KVAL(keyval);
234
235 printk(KERN_WARNING "Key with scancode %d ", scancode);
236 if (keytyp == KT_LATIN || keytyp == KT_LETTER) {
237 if (keyval < ' ')
238 printk("('^%c') ", keyval + '@');
239 else
240 printk("('%c') ", keyval);
241 }
242 printk("is broken -- will be ignored.\n");
243 break;
244 } else if (test_bit(scancode, broken_keys))
245 break;
246
247 if (atari_input_keyboard_interrupt_hook)
248 atari_input_keyboard_interrupt_hook((unsigned char)scancode, !break_flag);
249 break;
250 }
251 break;
252
253 case AMOUSE:
254 kb_state.buf[kb_state.len++] = scancode;
255 if (kb_state.len == 5) {
256 kb_state.state = KEYBOARD;
257
258
259 }
260 break;
261
262 case RMOUSE:
263 kb_state.buf[kb_state.len++] = scancode;
264 if (kb_state.len == 3) {
265 kb_state.state = KEYBOARD;
266 if (atari_mouse_interrupt_hook)
267 atari_mouse_interrupt_hook(kb_state.buf);
268 }
269 break;
270
271 case JOYSTICK:
272 kb_state.buf[1] = scancode;
273 kb_state.state = KEYBOARD;
274#ifdef FIXED_ATARI_JOYSTICK
275 atari_joystick_interrupt(kb_state.buf);
276#endif
277 break;
278
279 case CLOCK:
280 kb_state.buf[kb_state.len++] = scancode;
281 if (kb_state.len == 6) {
282 kb_state.state = KEYBOARD;
283
284
285
286
287 }
288 break;
289
290 case RESYNC:
291 if (kb_state.len <= 0 || IS_SYNC_CODE(scancode)) {
292 kb_state.state = KEYBOARD;
293 goto interpret_scancode;
294 }
295 kb_state.len--;
296 break;
297 }
298 }
299
300#if 0
301 if (acia_stat & ACIA_CTS)
302 ;
303#endif
304
305 if (acia_stat & (ACIA_FE | ACIA_PE)) {
306 printk("Error in keyboard communication\n");
307 }
308
309
310
311
312 goto repeat;
313}
314
315
316
317
318
319
320
321
322
323void ikbd_write(const char *str, int len)
324{
325 u_char acia_stat;
326
327 if ((len < 1) || (len > 7))
328 panic("ikbd: maximum string length exceeded");
329 while (len) {
330 acia_stat = acia.key_ctrl;
331 if (acia_stat & ACIA_TDRE) {
332 acia.key_data = *str++;
333 len--;
334 }
335 }
336}
337
338
339void ikbd_reset(void)
340{
341 static const char cmd[2] = { 0x80, 0x01 };
342
343 ikbd_write(cmd, 2);
344
345
346
347
348
349}
350
351
352void ikbd_mouse_button_action(int mode)
353{
354 char cmd[2] = { 0x07, mode };
355
356 ikbd_write(cmd, 2);
357}
358
359
360void ikbd_mouse_rel_pos(void)
361{
362 static const char cmd[1] = { 0x08 };
363
364 ikbd_write(cmd, 1);
365}
366EXPORT_SYMBOL(ikbd_mouse_rel_pos);
367
368
369void ikbd_mouse_abs_pos(int xmax, int ymax)
370{
371 char cmd[5] = { 0x09, xmax>>8, xmax&0xFF, ymax>>8, ymax&0xFF };
372
373 ikbd_write(cmd, 5);
374}
375
376
377void ikbd_mouse_kbd_mode(int dx, int dy)
378{
379 char cmd[3] = { 0x0A, dx, dy };
380
381 ikbd_write(cmd, 3);
382}
383
384
385void ikbd_mouse_thresh(int x, int y)
386{
387 char cmd[3] = { 0x0B, x, y };
388
389 ikbd_write(cmd, 3);
390}
391EXPORT_SYMBOL(ikbd_mouse_thresh);
392
393
394void ikbd_mouse_scale(int x, int y)
395{
396 char cmd[3] = { 0x0C, x, y };
397
398 ikbd_write(cmd, 3);
399}
400
401
402void ikbd_mouse_pos_get(int *x, int *y)
403{
404 static const char cmd[1] = { 0x0D };
405
406 ikbd_write(cmd, 1);
407
408
409}
410
411
412void ikbd_mouse_pos_set(int x, int y)
413{
414 char cmd[6] = { 0x0E, 0x00, x>>8, x&0xFF, y>>8, y&0xFF };
415
416 ikbd_write(cmd, 6);
417}
418
419
420void ikbd_mouse_y0_bot(void)
421{
422 static const char cmd[1] = { 0x0F };
423
424 ikbd_write(cmd, 1);
425}
426
427
428void ikbd_mouse_y0_top(void)
429{
430 static const char cmd[1] = { 0x10 };
431
432 ikbd_write(cmd, 1);
433}
434EXPORT_SYMBOL(ikbd_mouse_y0_top);
435
436
437void ikbd_resume(void)
438{
439 static const char cmd[1] = { 0x11 };
440
441 ikbd_write(cmd, 1);
442}
443
444
445void ikbd_mouse_disable(void)
446{
447 static const char cmd[1] = { 0x12 };
448
449 ikbd_write(cmd, 1);
450}
451EXPORT_SYMBOL(ikbd_mouse_disable);
452
453
454void ikbd_pause(void)
455{
456 static const char cmd[1] = { 0x13 };
457
458 ikbd_write(cmd, 1);
459}
460
461
462void ikbd_joystick_event_on(void)
463{
464 static const char cmd[1] = { 0x14 };
465
466 ikbd_write(cmd, 1);
467}
468
469
470void ikbd_joystick_event_off(void)
471{
472 static const char cmd[1] = { 0x15 };
473
474 ikbd_write(cmd, 1);
475}
476
477
478void ikbd_joystick_get_state(void)
479{
480 static const char cmd[1] = { 0x16 };
481
482 ikbd_write(cmd, 1);
483}
484
485#if 0
486
487
488void ikbd_joystick_monitor(int rate)
489{
490 static const char cmd[2] = { 0x17, rate };
491
492 ikbd_write(cmd, 2);
493
494 kb_state.state = JOYSTICK_MONITOR;
495}
496#endif
497
498
499
500
501void ikbd_joystick_disable(void)
502{
503 static const char cmd[1] = { 0x1A };
504
505 ikbd_write(cmd, 1);
506}
507
508
509void ikbd_clock_set(int year, int month, int day, int hour, int minute, int second)
510{
511 char cmd[7] = { 0x1B, year, month, day, hour, minute, second };
512
513 ikbd_write(cmd, 7);
514}
515
516
517void ikbd_clock_get(int *year, int *month, int *day, int *hour, int *minute, int second)
518{
519 static const char cmd[1] = { 0x1C };
520
521 ikbd_write(cmd, 1);
522}
523
524
525void ikbd_mem_write(int address, int size, char *data)
526{
527 panic("Attempt to write data into keyboard memory");
528}
529
530
531void ikbd_mem_read(int address, char data[6])
532{
533 char cmd[3] = { 0x21, address>>8, address&0xFF };
534
535 ikbd_write(cmd, 3);
536
537
538}
539
540
541void ikbd_exec(int address)
542{
543 char cmd[3] = { 0x22, address>>8, address&0xFF };
544
545 ikbd_write(cmd, 3);
546}
547
548
549
550
551void atari_kbd_leds(unsigned int leds)
552{
553 char cmd[6] = {32, 0, 4, 1, 254 + ((leds & 4) != 0), 0};
554
555 ikbd_write(cmd, 6);
556}
557
558
559
560
561
562
563
564
565static int atari_keyb_done = 0;
566
567int atari_keyb_init(void)
568{
569 int error;
570
571 if (atari_keyb_done)
572 return 0;
573
574 kb_state.state = KEYBOARD;
575 kb_state.len = 0;
576
577 error = request_irq(IRQ_MFP_ACIA, atari_keyboard_interrupt,
578 IRQ_TYPE_SLOW, "keyboard/mouse/MIDI",
579 atari_keyboard_interrupt);
580 if (error)
581 return error;
582
583 atari_turnoff_irq(IRQ_MFP_ACIA);
584 do {
585
586 acia.key_ctrl = ACIA_RESET |
587 ((atari_switches & ATARI_SWITCH_IKBD) ?
588 ACIA_RHTID : 0);
589 (void)acia.key_ctrl;
590 (void)acia.key_data;
591
592
593 acia.mid_ctrl = ACIA_RESET |
594 ((atari_switches & ATARI_SWITCH_MIDI) ?
595 ACIA_RHTID : 0);
596 (void)acia.mid_ctrl;
597 (void)acia.mid_data;
598
599
600
601
602
603 acia.key_ctrl = (ACIA_DIV64|ACIA_D8N1S|ACIA_RIE) |
604 ((atari_switches & ATARI_SWITCH_IKBD) ?
605 ACIA_RHTID : ACIA_RLTID);
606
607 acia.mid_ctrl = ACIA_DIV16 | ACIA_D8N1S |
608 ((atari_switches & ATARI_SWITCH_MIDI) ?
609 ACIA_RHTID : 0);
610
611
612 } while ((st_mfp.par_dt_reg & 0x10) == 0);
613
614
615 st_mfp.active_edge &= ~0x10;
616 atari_turnon_irq(IRQ_MFP_ACIA);
617
618 ikbd_self_test = 1;
619 ikbd_reset();
620
621
622 self_test_last_rcv = jiffies;
623 while (time_before(jiffies, self_test_last_rcv + HZ/4))
624 barrier();
625
626 if (ikbd_self_test == 1)
627 printk(KERN_ERR "WARNING: keyboard self test failed!\n");
628 ikbd_self_test = 0;
629
630 ikbd_mouse_disable();
631 ikbd_joystick_disable();
632
633#ifdef FIXED_ATARI_JOYSTICK
634 atari_joystick_init();
635#endif
636
637
638 atari_keyb_done = 1;
639 return 0;
640}
641EXPORT_SYMBOL_GPL(atari_keyb_init);
642