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_input_keyboard_interrupt_hook) (unsigned char, char);
41
42void (*atari_input_mouse_interrupt_hook) (char *);
43EXPORT_SYMBOL(atari_input_keyboard_interrupt_hook);
44EXPORT_SYMBOL(atari_input_mouse_interrupt_hook);
45
46
47
48
49static volatile int ikbd_self_test;
50
51static volatile unsigned long self_test_last_rcv;
52
53static unsigned long broken_keys[128/(sizeof(unsigned long)*8)] = { 0, };
54
55#define BREAK_MASK (0x80)
56
57
58
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
103typedef enum kb_state_t {
104 KEYBOARD, AMOUSE, RMOUSE, JOYSTICK, CLOCK, RESYNC
105} KB_STATE_T;
106
107#define IS_SYNC_CODE(sc) ((sc) >= 0x04 && (sc) <= 0xfb)
108
109typedef struct keyboard_state {
110 unsigned char buf[6];
111 int len;
112 KB_STATE_T state;
113} KEYBOARD_STATE;
114
115KEYBOARD_STATE kb_state;
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134static irqreturn_t atari_keyboard_interrupt(int irq, void *dummy)
135{
136 u_char acia_stat;
137 int scancode;
138 int break_flag;
139
140repeat:
141 if (acia.mid_ctrl & ACIA_IRQ)
142 if (atari_MIDI_interrupt_hook)
143 atari_MIDI_interrupt_hook();
144 acia_stat = acia.key_ctrl;
145
146 if (!((acia_stat | acia.mid_ctrl) & ACIA_IRQ))
147 return IRQ_HANDLED;
148
149 if (acia_stat & ACIA_OVRN) {
150
151
152 pr_debug("Keyboard overrun\n");
153 scancode = acia.key_data;
154 if (ikbd_self_test)
155
156 goto interpret_scancode;
157 else if (IS_SYNC_CODE(scancode)) {
158
159
160 kb_state.state = KEYBOARD;
161 goto interpret_scancode;
162 } else {
163
164 kb_state.state = RESYNC;
165 kb_state.len = 1;
166 goto repeat;
167 }
168 }
169
170 if (acia_stat & ACIA_RDRF) {
171
172 scancode = acia.key_data;
173 interpret_scancode:
174 switch (kb_state.state) {
175 case KEYBOARD:
176 switch (scancode) {
177 case 0xF7:
178 kb_state.state = AMOUSE;
179 kb_state.len = 0;
180 break;
181
182 case 0xF8:
183 case 0xF9:
184 case 0xFA:
185 case 0xFB:
186 kb_state.state = RMOUSE;
187 kb_state.len = 1;
188 kb_state.buf[0] = scancode;
189 break;
190
191 case 0xFC:
192 kb_state.state = CLOCK;
193 kb_state.len = 0;
194 break;
195
196 case 0xFE:
197 case 0xFF:
198 kb_state.state = JOYSTICK;
199 kb_state.len = 1;
200 kb_state.buf[0] = scancode;
201 break;
202
203 case 0xF1:
204
205 if (ikbd_self_test) {
206 ++ikbd_self_test;
207 self_test_last_rcv = jiffies;
208 break;
209 }
210 fallthrough;
211
212 default:
213 break_flag = scancode & BREAK_MASK;
214 scancode &= ~BREAK_MASK;
215 if (ikbd_self_test) {
216
217
218
219
220
221
222 int keyval, keytyp;
223
224 set_bit(scancode, broken_keys);
225 self_test_last_rcv = jiffies;
226
227 keyval = scancode;
228 keytyp = KTYP(keyval) - 0xf0;
229 keyval = KVAL(keyval);
230
231 pr_warn("Key with scancode %d ", scancode);
232 if (keytyp == KT_LATIN || keytyp == KT_LETTER) {
233 if (keyval < ' ')
234 pr_cont("('^%c') ", keyval + '@');
235 else
236 pr_cont("('%c') ", keyval);
237 }
238 pr_cont("is broken -- will be ignored.\n");
239 break;
240 } else if (test_bit(scancode, broken_keys))
241 break;
242
243 if (atari_input_keyboard_interrupt_hook)
244 atari_input_keyboard_interrupt_hook((unsigned char)scancode, !break_flag);
245 break;
246 }
247 break;
248
249 case AMOUSE:
250 kb_state.buf[kb_state.len++] = scancode;
251 if (kb_state.len == 5) {
252 kb_state.state = KEYBOARD;
253
254
255 }
256 break;
257
258 case RMOUSE:
259 kb_state.buf[kb_state.len++] = scancode;
260 if (kb_state.len == 3) {
261 kb_state.state = KEYBOARD;
262 if (atari_input_mouse_interrupt_hook)
263 atari_input_mouse_interrupt_hook(kb_state.buf);
264 }
265 break;
266
267 case JOYSTICK:
268 kb_state.buf[1] = scancode;
269 kb_state.state = KEYBOARD;
270#ifdef FIXED_ATARI_JOYSTICK
271 atari_joystick_interrupt(kb_state.buf);
272#endif
273 break;
274
275 case CLOCK:
276 kb_state.buf[kb_state.len++] = scancode;
277 if (kb_state.len == 6) {
278 kb_state.state = KEYBOARD;
279
280
281
282
283 }
284 break;
285
286 case RESYNC:
287 if (kb_state.len <= 0 || IS_SYNC_CODE(scancode)) {
288 kb_state.state = KEYBOARD;
289 goto interpret_scancode;
290 }
291 kb_state.len--;
292 break;
293 }
294 }
295
296#if 0
297 if (acia_stat & ACIA_CTS)
298 ;
299#endif
300
301 if (acia_stat & (ACIA_FE | ACIA_PE)) {
302 pr_err("Error in keyboard communication\n");
303 }
304
305
306
307
308 goto repeat;
309}
310
311
312
313
314
315
316
317
318
319void ikbd_write(const char *str, int len)
320{
321 u_char acia_stat;
322
323 if ((len < 1) || (len > 7))
324 panic("ikbd: maximum string length exceeded");
325 while (len) {
326 acia_stat = acia.key_ctrl;
327 if (acia_stat & ACIA_TDRE) {
328 acia.key_data = *str++;
329 len--;
330 }
331 }
332}
333
334
335void ikbd_reset(void)
336{
337 static const char cmd[2] = { 0x80, 0x01 };
338
339 ikbd_write(cmd, 2);
340
341
342
343
344
345}
346
347
348void ikbd_mouse_button_action(int mode)
349{
350 char cmd[2] = { 0x07, mode };
351
352 ikbd_write(cmd, 2);
353}
354
355
356void ikbd_mouse_rel_pos(void)
357{
358 static const char cmd[1] = { 0x08 };
359
360 ikbd_write(cmd, 1);
361}
362EXPORT_SYMBOL(ikbd_mouse_rel_pos);
363
364
365void ikbd_mouse_abs_pos(int xmax, int ymax)
366{
367 char cmd[5] = { 0x09, xmax>>8, xmax&0xFF, ymax>>8, ymax&0xFF };
368
369 ikbd_write(cmd, 5);
370}
371
372
373void ikbd_mouse_kbd_mode(int dx, int dy)
374{
375 char cmd[3] = { 0x0A, dx, dy };
376
377 ikbd_write(cmd, 3);
378}
379
380
381void ikbd_mouse_thresh(int x, int y)
382{
383 char cmd[3] = { 0x0B, x, y };
384
385 ikbd_write(cmd, 3);
386}
387EXPORT_SYMBOL(ikbd_mouse_thresh);
388
389
390void ikbd_mouse_scale(int x, int y)
391{
392 char cmd[3] = { 0x0C, x, y };
393
394 ikbd_write(cmd, 3);
395}
396
397
398void ikbd_mouse_pos_get(int *x, int *y)
399{
400 static const char cmd[1] = { 0x0D };
401
402 ikbd_write(cmd, 1);
403
404
405}
406
407
408void ikbd_mouse_pos_set(int x, int y)
409{
410 char cmd[6] = { 0x0E, 0x00, x>>8, x&0xFF, y>>8, y&0xFF };
411
412 ikbd_write(cmd, 6);
413}
414
415
416void ikbd_mouse_y0_bot(void)
417{
418 static const char cmd[1] = { 0x0F };
419
420 ikbd_write(cmd, 1);
421}
422
423
424void ikbd_mouse_y0_top(void)
425{
426 static const char cmd[1] = { 0x10 };
427
428 ikbd_write(cmd, 1);
429}
430EXPORT_SYMBOL(ikbd_mouse_y0_top);
431
432
433void ikbd_mouse_disable(void)
434{
435 static const char cmd[1] = { 0x12 };
436
437 ikbd_write(cmd, 1);
438}
439EXPORT_SYMBOL(ikbd_mouse_disable);
440
441
442void ikbd_joystick_event_on(void)
443{
444 static const char cmd[1] = { 0x14 };
445
446 ikbd_write(cmd, 1);
447}
448
449
450void ikbd_joystick_event_off(void)
451{
452 static const char cmd[1] = { 0x15 };
453
454 ikbd_write(cmd, 1);
455}
456
457
458void ikbd_joystick_get_state(void)
459{
460 static const char cmd[1] = { 0x16 };
461
462 ikbd_write(cmd, 1);
463}
464
465#if 0
466
467
468void ikbd_joystick_monitor(int rate)
469{
470 static const char cmd[2] = { 0x17, rate };
471
472 ikbd_write(cmd, 2);
473
474 kb_state.state = JOYSTICK_MONITOR;
475}
476#endif
477
478
479
480
481void ikbd_joystick_disable(void)
482{
483 static const char cmd[1] = { 0x1A };
484
485 ikbd_write(cmd, 1);
486}
487
488
489
490
491
492
493
494
495static int atari_keyb_done = 0;
496
497int atari_keyb_init(void)
498{
499 int error;
500
501 if (atari_keyb_done)
502 return 0;
503
504 kb_state.state = KEYBOARD;
505 kb_state.len = 0;
506
507 error = request_irq(IRQ_MFP_ACIA, atari_keyboard_interrupt, 0,
508 "keyboard,mouse,MIDI", atari_keyboard_interrupt);
509 if (error)
510 return error;
511
512 atari_turnoff_irq(IRQ_MFP_ACIA);
513 do {
514
515 acia.key_ctrl = ACIA_RESET |
516 ((atari_switches & ATARI_SWITCH_IKBD) ?
517 ACIA_RHTID : 0);
518 (void)acia.key_ctrl;
519 (void)acia.key_data;
520
521
522 acia.mid_ctrl = ACIA_RESET |
523 ((atari_switches & ATARI_SWITCH_MIDI) ?
524 ACIA_RHTID : 0);
525 (void)acia.mid_ctrl;
526 (void)acia.mid_data;
527
528
529
530
531
532 acia.key_ctrl = (ACIA_DIV64|ACIA_D8N1S|ACIA_RIE) |
533 ((atari_switches & ATARI_SWITCH_IKBD) ?
534 ACIA_RHTID : ACIA_RLTID);
535
536 acia.mid_ctrl = ACIA_DIV16 | ACIA_D8N1S |
537 ((atari_switches & ATARI_SWITCH_MIDI) ?
538 ACIA_RHTID : 0);
539
540
541 } while ((st_mfp.par_dt_reg & 0x10) == 0);
542
543
544 st_mfp.active_edge &= ~0x10;
545 atari_turnon_irq(IRQ_MFP_ACIA);
546
547 ikbd_self_test = 1;
548 ikbd_reset();
549
550
551 self_test_last_rcv = jiffies;
552 while (time_before(jiffies, self_test_last_rcv + HZ/4))
553 barrier();
554
555 if (ikbd_self_test == 1)
556 pr_err("Keyboard self test failed!\n");
557 ikbd_self_test = 0;
558
559 ikbd_mouse_disable();
560 ikbd_joystick_disable();
561
562#ifdef FIXED_ATARI_JOYSTICK
563 atari_joystick_init();
564#endif
565
566
567 atari_keyb_done = 1;
568 return 0;
569}
570EXPORT_SYMBOL_GPL(atari_keyb_init);
571