1 /*
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
16 #include <linux/config.h>
17 #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_ll.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 static void atakeyb_rep( unsigned long ignore );
37 extern unsigned int keymap_count;
38
39 /* Hook for MIDI serial driver */
40 void (*atari_MIDI_interrupt_hook) (void);
41 /* Hook for mouse driver */
42 void (*atari_mouse_interrupt_hook) (char *);
43
44 /* variables for IKBD self test: */
45
46 /* state: 0: off; >0: in progress; >1: 0xf1 received */
47 static volatile int ikbd_self_test;
48 /* timestamp when last received a char */
49 static volatile unsigned long self_test_last_rcv;
50 /* bitmap of keys reported as broken */
51 static unsigned long broken_keys[128/(sizeof(unsigned long)*8)] = { 0, };
52
53 #define BREAK_MASK (0x80)
54
55 /*
56 * ++roman: The following changes were applied manually:
57 *
58 * - The Alt (= Meta) key works in combination with Shift and
59 * Control, e.g. Alt+Shift+a sends Meta-A (0xc1), Alt+Control+A sends
60 * Meta-Ctrl-A (0x81) ...
61 *
62 * - The parentheses on the keypad send '(' and ')' with all
63 * modifiers (as would do e.g. keypad '+'), but they cannot be used as
64 * application keys (i.e. sending Esc O c).
65 *
66 * - HELP and UNDO are mapped to be F21 and F24, resp, that send the
67 * codes "\E[M" and "\E[P". (This is better than the old mapping to
68 * F11 and F12, because these codes are on Shift+F1/2 anyway.) This
69 * way, applications that allow their own keyboard mappings
70 * (e.g. tcsh, X Windows) can be configured to use them in the way
71 * the label suggests (providing help or undoing).
72 *
73 * - Console switching is done with Alt+Fx (consoles 1..10) and
74 * Shift+Alt+Fx (consoles 11..20).
75 *
76 * - The misc. special function implemented in the kernel are mapped
77 * to the following key combinations:
78 *
79 * ClrHome -> Home/Find
80 * Shift + ClrHome -> End/Select
81 * Shift + Up -> Page Up
82 * Shift + Down -> Page Down
83 * Alt + Help -> show system status
84 * Shift + Help -> show memory info
85 * Ctrl + Help -> show registers
86 * Ctrl + Alt + Del -> Reboot
87 * Alt + Undo -> switch to last console
88 * Shift + Undo -> send interrupt
89 * Alt + Insert -> stop/start output (same as ^S/^Q)
90 * Alt + Up -> Scroll back console (if implemented)
91 * Alt + Down -> Scroll forward console (if implemented)
92 * Alt + CapsLock -> NumLock
93 *
94 * ++Andreas:
95 *
96 * - Help mapped to K_HELP
97 * - Undo mapped to K_UNDO (= K_F246)
98 * - Keypad Left/Right Parenthesis mapped to new K_PPAREN[LR]
99 */
100
101 static u_short ataplain_map[NR_KEYS] __initdata = {
102 0xf200, 0xf01b, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036,
103 0xf037, 0xf038, 0xf039, 0xf030, 0xf02d, 0xf03d, 0xf008, 0xf009,
104 0xfb71, 0xfb77, 0xfb65, 0xfb72, 0xfb74, 0xfb79, 0xfb75, 0xfb69,
105 0xfb6f, 0xfb70, 0xf05b, 0xf05d, 0xf201, 0xf702, 0xfb61, 0xfb73,
106 0xfb64, 0xfb66, 0xfb67, 0xfb68, 0xfb6a, 0xfb6b, 0xfb6c, 0xf03b,
107 0xf027, 0xf060, 0xf700, 0xf05c, 0xfb7a, 0xfb78, 0xfb63, 0xfb76,
108 0xfb62, 0xfb6e, 0xfb6d, 0xf02c, 0xf02e, 0xf02f, 0xf700, 0xf200,
109 0xf703, 0xf020, 0xf207, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104,
110 0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf200, 0xf200, 0xf114,
111 0xf603, 0xf200, 0xf30b, 0xf601, 0xf200, 0xf602, 0xf30a, 0xf200,
112 0xf600, 0xf200, 0xf115, 0xf07f, 0xf200, 0xf200, 0xf200, 0xf200,
113 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
114 0xf200, 0xf1ff, 0xf11b, 0xf312, 0xf313, 0xf30d, 0xf30c, 0xf307,
115 0xf308, 0xf309, 0xf304, 0xf305, 0xf306, 0xf301, 0xf302, 0xf303,
116 0xf300, 0xf310, 0xf30e, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
117 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200
118 };
119
120 static u_short atashift_map[NR_KEYS] __initdata = {
121 0xf200, 0xf01b, 0xf021, 0xf040, 0xf023, 0xf024, 0xf025, 0xf05e,
122 0xf026, 0xf02a, 0xf028, 0xf029, 0xf05f, 0xf02b, 0xf008, 0xf009,
123 0xfb51, 0xfb57, 0xfb45, 0xfb52, 0xfb54, 0xfb59, 0xfb55, 0xfb49,
124 0xfb4f, 0xfb50, 0xf07b, 0xf07d, 0xf201, 0xf702, 0xfb41, 0xfb53,
125 0xfb44, 0xfb46, 0xfb47, 0xfb48, 0xfb4a, 0xfb4b, 0xfb4c, 0xf03a,
126 0xf022, 0xf07e, 0xf700, 0xf07c, 0xfb5a, 0xfb58, 0xfb43, 0xfb56,
127 0xfb42, 0xfb4e, 0xfb4d, 0xf03c, 0xf03e, 0xf03f, 0xf700, 0xf200,
128 0xf703, 0xf020, 0xf207, 0xf10a, 0xf10b, 0xf10c, 0xf10d, 0xf10e,
129 0xf10f, 0xf110, 0xf111, 0xf112, 0xf113, 0xf200, 0xf200, 0xf117,
130 0xf118, 0xf200, 0xf30b, 0xf601, 0xf200, 0xf602, 0xf30a, 0xf200,
131 0xf119, 0xf200, 0xf115, 0xf07f, 0xf200, 0xf200, 0xf200, 0xf200,
132 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
133 0xf200, 0xf205, 0xf203, 0xf312, 0xf313, 0xf30d, 0xf30c, 0xf307,
134 0xf308, 0xf309, 0xf304, 0xf305, 0xf306, 0xf301, 0xf302, 0xf303,
135 0xf300, 0xf310, 0xf30e, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
136 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200
137 };
138
139 static u_short atactrl_map[NR_KEYS] __initdata = {
140 0xf200, 0xf200, 0xf200, 0xf000, 0xf01b, 0xf01c, 0xf01d, 0xf01e,
141 0xf01f, 0xf07f, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf008, 0xf200,
142 0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009,
143 0xf00f, 0xf010, 0xf01b, 0xf01d, 0xf201, 0xf702, 0xf001, 0xf013,
144 0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200,
145 0xf007, 0xf000, 0xf700, 0xf01c, 0xf01a, 0xf018, 0xf003, 0xf016,
146 0xf002, 0xf00e, 0xf00d, 0xf200, 0xf200, 0xf07f, 0xf700, 0xf200,
147 0xf703, 0xf000, 0xf207, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104,
148 0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf200, 0xf200, 0xf114,
149 0xf603, 0xf200, 0xf30b, 0xf601, 0xf200, 0xf602, 0xf30a, 0xf200,
150 0xf600, 0xf200, 0xf115, 0xf07f, 0xf200, 0xf200, 0xf200, 0xf200,
151 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
152 0xf200, 0xf1ff, 0xf202, 0xf312, 0xf313, 0xf30d, 0xf30c, 0xf307,
153 0xf308, 0xf309, 0xf304, 0xf305, 0xf306, 0xf301, 0xf302, 0xf303,
154 0xf300, 0xf310, 0xf30e, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
155 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200
156 };
157
158 static u_short atashift_ctrl_map[NR_KEYS] __initdata = {
159 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
160 0xf200, 0xf200, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf008, 0xf200,
161 0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009,
162 0xf00f, 0xf010, 0xf200, 0xf200, 0xf201, 0xf702, 0xf001, 0xf013,
163 0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200,
164 0xf200, 0xf200, 0xf700, 0xf200, 0xf01a, 0xf018, 0xf003, 0xf016,
165 0xf002, 0xf00e, 0xf00d, 0xf200, 0xf200, 0xf07f, 0xf700, 0xf200,
166 0xf703, 0xf200, 0xf207, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104,
167 0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf200, 0xf200, 0xf117,
168 0xf603, 0xf200, 0xf30b, 0xf601, 0xf200, 0xf602, 0xf30a, 0xf200,
169 0xf600, 0xf200, 0xf115, 0xf07f, 0xf200, 0xf200, 0xf200, 0xf200,
170 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
171 0xf200, 0xf1ff, 0xf11b, 0xf312, 0xf313, 0xf30d, 0xf30c, 0xf307,
172 0xf308, 0xf309, 0xf304, 0xf305, 0xf306, 0xf301, 0xf302, 0xf303,
173 0xf300, 0xf310, 0xf30e, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
174 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200
175 };
176
177 static u_short ataalt_map[NR_KEYS] __initdata = {
178 0xf200, 0xf81b, 0xf831, 0xf832, 0xf833, 0xf834, 0xf835, 0xf836,
179 0xf837, 0xf838, 0xf839, 0xf830, 0xf82d, 0xf83d, 0xf808, 0xf809,
180 0xf871, 0xf877, 0xf865, 0xf872, 0xf874, 0xf879, 0xf875, 0xf869,
181 0xf86f, 0xf870, 0xf85b, 0xf85d, 0xf80d, 0xf702, 0xf861, 0xf873,
182 0xf864, 0xf866, 0xf867, 0xf868, 0xf86a, 0xf86b, 0xf86c, 0xf83b,
183 0xf827, 0xf860, 0xf700, 0xf85c, 0xf87a, 0xf878, 0xf863, 0xf876,
184 0xf862, 0xf86e, 0xf86d, 0xf82c, 0xf82e, 0xf82f, 0xf700, 0xf200,
185 0xf703, 0xf820, 0xf208, 0xf500, 0xf501, 0xf502, 0xf503, 0xf504,
186 0xf505, 0xf506, 0xf507, 0xf508, 0xf509, 0xf200, 0xf200, 0xf114,
187 0xf20b, 0xf200, 0xf30b, 0xf601, 0xf200, 0xf602, 0xf30a, 0xf200,
188 0xf20a, 0xf200, 0xf209, 0xf87f, 0xf200, 0xf200, 0xf200, 0xf200,
189 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
190 0xf200, 0xf206, 0xf204, 0xf312, 0xf313, 0xf30d, 0xf30c, 0xf907,
191 0xf908, 0xf909, 0xf904, 0xf905, 0xf906, 0xf901, 0xf902, 0xf903,
192 0xf900, 0xf310, 0xf30e, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
193 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200
194 };
195
196 static u_short atashift_alt_map[NR_KEYS] __initdata = {
197 0xf200, 0xf81b, 0xf821, 0xf840, 0xf823, 0xf824, 0xf825, 0xf85e,
198 0xf826, 0xf82a, 0xf828, 0xf829, 0xf85f, 0xf82b, 0xf808, 0xf809,
199 0xf851, 0xf857, 0xf845, 0xf852, 0xf854, 0xf859, 0xf855, 0xf849,
200 0xf84f, 0xf850, 0xf87b, 0xf87d, 0xf201, 0xf702, 0xf841, 0xf853,
201 0xf844, 0xf846, 0xf847, 0xf848, 0xf84a, 0xf84b, 0xf84c, 0xf83a,
202 0xf822, 0xf87e, 0xf700, 0xf87c, 0xf85a, 0xf858, 0xf843, 0xf856,
203 0xf842, 0xf84e, 0xf84d, 0xf83c, 0xf83e, 0xf83f, 0xf700, 0xf200,
204 0xf703, 0xf820, 0xf207, 0xf50a, 0xf50b, 0xf50c, 0xf50d, 0xf50e,
205 0xf50f, 0xf510, 0xf511, 0xf512, 0xf513, 0xf200, 0xf200, 0xf117,
206 0xf118, 0xf200, 0xf30b, 0xf601, 0xf200, 0xf602, 0xf30a, 0xf200,
207 0xf119, 0xf200, 0xf115, 0xf87f, 0xf200, 0xf200, 0xf200, 0xf200,
208 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
209 0xf200, 0xf1ff, 0xf11b, 0xf312, 0xf313, 0xf30d, 0xf30c, 0xf307,
210 0xf308, 0xf309, 0xf304, 0xf305, 0xf306, 0xf301, 0xf302, 0xf303,
211 0xf300, 0xf310, 0xf30e, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
212 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200
213 };
214
215 static u_short atactrl_alt_map[NR_KEYS] __initdata = {
216 0xf200, 0xf200, 0xf200, 0xf800, 0xf81b, 0xf81c, 0xf81d, 0xf81e,
217 0xf81f, 0xf87f, 0xf200, 0xf200, 0xf81f, 0xf200, 0xf808, 0xf200,
218 0xf811, 0xf817, 0xf805, 0xf812, 0xf814, 0xf819, 0xf815, 0xf809,
219 0xf80f, 0xf810, 0xf81b, 0xf81d, 0xf201, 0xf702, 0xf801, 0xf813,
220 0xf804, 0xf806, 0xf807, 0xf808, 0xf80a, 0xf80b, 0xf80c, 0xf200,
221 0xf807, 0xf800, 0xf700, 0xf81c, 0xf81a, 0xf818, 0xf803, 0xf816,
222 0xf802, 0xf80e, 0xf80d, 0xf200, 0xf200, 0xf87f, 0xf700, 0xf200,
223 0xf703, 0xf800, 0xf207, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104,
224 0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf200, 0xf200, 0xf114,
225 0xf603, 0xf200, 0xf30b, 0xf601, 0xf200, 0xf602, 0xf30a, 0xf200,
226 0xf600, 0xf200, 0xf115, 0xf87f, 0xf200, 0xf200, 0xf200, 0xf200,
227 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
228 0xf200, 0xf1ff, 0xf202, 0xf312, 0xf313, 0xf30d, 0xf30c, 0xf307,
229 0xf308, 0xf309, 0xf304, 0xf305, 0xf306, 0xf301, 0xf302, 0xf303,
230 0xf300, 0xf310, 0xf30e, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
231 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200
232 };
233
234 static u_short atashift_ctrl_alt_map[NR_KEYS] = {
235 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
236 0xf200, 0xf200, 0xf200, 0xf200, 0xf81f, 0xf200, 0xf808, 0xf200,
237 0xf811, 0xf817, 0xf805, 0xf812, 0xf814, 0xf819, 0xf815, 0xf809,
238 0xf80f, 0xf810, 0xf200, 0xf200, 0xf201, 0xf702, 0xf801, 0xf813,
239 0xf804, 0xf806, 0xf807, 0xf808, 0xf80a, 0xf80b, 0xf80c, 0xf200,
240 0xf200, 0xf200, 0xf700, 0xf200, 0xf81a, 0xf818, 0xf803, 0xf816,
241 0xf802, 0xf80e, 0xf80d, 0xf200, 0xf200, 0xf87f, 0xf700, 0xf200,
242 0xf703, 0xf200, 0xf207, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104,
243 0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf200, 0xf200, 0xf117,
244 0xf603, 0xf200, 0xf30b, 0xf601, 0xf200, 0xf602, 0xf30a, 0xf200,
245 0xf600, 0xf200, 0xf115, 0xf87f, 0xf200, 0xf200, 0xf200, 0xf200,
246 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
247 0xf200, 0xf1ff, 0xf11b, 0xf312, 0xf313, 0xf30d, 0xf30c, 0xf307,
248 0xf308, 0xf309, 0xf304, 0xf305, 0xf306, 0xf301, 0xf302, 0xf303,
249 0xf300, 0xf310, 0xf30e, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
250 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200
251 };
252
253 typedef enum kb_state_t
254 {
255 KEYBOARD, AMOUSE, RMOUSE, JOYSTICK, CLOCK, RESYNC
256 } KB_STATE_T;
257
258 #define IS_SYNC_CODE(sc) ((sc) >= 0x04 && (sc) <= 0xfb)
259
260 typedef struct keyboard_state
261 {
262 unsigned char buf[6];
263 int len;
264 KB_STATE_T state;
265 } KEYBOARD_STATE;
266
267 KEYBOARD_STATE kb_state;
268
269 #define DEFAULT_KEYB_REP_DELAY (HZ/4)
270 #define DEFAULT_KEYB_REP_RATE (HZ/25)
271
272 /* These could be settable by some ioctl() in future... */
273 static unsigned int key_repeat_delay = DEFAULT_KEYB_REP_DELAY;
274 static unsigned int key_repeat_rate = DEFAULT_KEYB_REP_RATE;
275
276 static unsigned char rep_scancode;
277 static struct timer_list atakeyb_rep_timer = { function: atakeyb_rep };
278
atakeyb_rep(unsigned long ignore)279 static void atakeyb_rep( unsigned long ignore )
280
281 {
282 kbd_pt_regs = NULL;
283
284 /* Disable keyboard for the time we call handle_scancode(), else a race
285 * in the keyboard tty queue may happen */
286 atari_disable_irq( IRQ_MFP_ACIA );
287 del_timer( &atakeyb_rep_timer );
288
289 /* A keyboard int may have come in before we disabled the irq, so
290 * double-check whether rep_scancode is still != 0 */
291 if (rep_scancode) {
292 init_timer(&atakeyb_rep_timer);
293 atakeyb_rep_timer.expires = jiffies + key_repeat_rate;
294 add_timer( &atakeyb_rep_timer );
295
296 handle_scancode(rep_scancode, 1);
297 }
298
299 atari_enable_irq( IRQ_MFP_ACIA );
300 }
301
302
303 /* ++roman: If a keyboard overrun happened, we can't tell in general how much
304 * bytes have been lost and in which state of the packet structure we are now.
305 * This usually causes keyboards bytes to be interpreted as mouse movements
306 * and vice versa, which is very annoying. It seems better to throw away some
307 * bytes (that are usually mouse bytes) than to misinterpret them. Therefor I
308 * introduced the RESYNC state for IKBD data. In this state, the bytes up to
309 * one that really looks like a key event (0x04..0xf2) or the start of a mouse
310 * packet (0xf8..0xfb) are thrown away, but at most 2 bytes. This at least
311 * speeds up the resynchronization of the event structure, even if maybe a
312 * mouse movement is lost. However, nothing is perfect. For bytes 0x01..0x03,
313 * it's really hard to decide whether they're mouse or keyboard bytes. Since
314 * overruns usually occur when moving the Atari mouse rapidly, they're seen as
315 * mouse bytes here. If this is wrong, only a make code of the keyboard gets
316 * lost, which isn't too bad. Loosing a break code would be disastrous,
317 * because then the keyboard repeat strikes...
318 */
319
keyboard_interrupt(int irq,void * dummy,struct pt_regs * fp)320 static void keyboard_interrupt(int irq, void *dummy, struct pt_regs *fp)
321 {
322 u_char acia_stat;
323 int scancode;
324 int break_flag;
325
326 /* save frame for register dump */
327 kbd_pt_regs = fp;
328
329 repeat:
330 if (acia.mid_ctrl & ACIA_IRQ)
331 if (atari_MIDI_interrupt_hook)
332 atari_MIDI_interrupt_hook();
333 acia_stat = acia.key_ctrl;
334 /* check out if the interrupt came from this ACIA */
335 if (!((acia_stat | acia.mid_ctrl) & ACIA_IRQ))
336 return;
337
338 if (acia_stat & ACIA_OVRN)
339 {
340 /* a very fast typist or a slow system, give a warning */
341 /* ...happens often if interrupts were disabled for too long */
342 printk( KERN_DEBUG "Keyboard overrun\n" );
343 scancode = acia.key_data;
344 /* Turn off autorepeating in case a break code has been lost */
345 del_timer( &atakeyb_rep_timer );
346 rep_scancode = 0;
347 if (ikbd_self_test)
348 /* During self test, don't do resyncing, just process the code */
349 goto interpret_scancode;
350 else if (IS_SYNC_CODE(scancode)) {
351 /* This code seem already to be the start of a new packet or a
352 * single scancode */
353 kb_state.state = KEYBOARD;
354 goto interpret_scancode;
355 }
356 else {
357 /* Go to RESYNC state and skip this byte */
358 kb_state.state = RESYNC;
359 kb_state.len = 1; /* skip max. 1 another byte */
360 goto repeat;
361 }
362 }
363
364 if (acia_stat & ACIA_RDRF) /* received a character */
365 {
366 scancode = acia.key_data; /* get it or reset the ACIA, I'll get it! */
367 tasklet_schedule(&keyboard_tasklet);
368 interpret_scancode:
369 switch (kb_state.state)
370 {
371 case KEYBOARD:
372 switch (scancode)
373 {
374 case 0xF7:
375 kb_state.state = AMOUSE;
376 kb_state.len = 0;
377 break;
378
379 case 0xF8:
380 case 0xF9:
381 case 0xFA:
382 case 0xFB:
383 kb_state.state = RMOUSE;
384 kb_state.len = 1;
385 kb_state.buf[0] = scancode;
386 break;
387
388 case 0xFC:
389 kb_state.state = CLOCK;
390 kb_state.len = 0;
391 break;
392
393 case 0xFE:
394 case 0xFF:
395 kb_state.state = JOYSTICK;
396 kb_state.len = 1;
397 kb_state.buf[0] = scancode;
398 break;
399
400 case 0xF1:
401 /* during self-test, note that 0xf1 received */
402 if (ikbd_self_test) {
403 ++ikbd_self_test;
404 self_test_last_rcv = jiffies;
405 break;
406 }
407 /* FALL THROUGH */
408
409 default:
410 break_flag = scancode & BREAK_MASK;
411 scancode &= ~BREAK_MASK;
412
413 if (ikbd_self_test) {
414 /* Scancodes sent during the self-test stand for broken
415 * keys (keys being down). The code *should* be a break
416 * code, but nevertheless some AT keyboard interfaces send
417 * make codes instead. Therefore, simply ignore
418 * break_flag...
419 * */
420 int keyval = plain_map[scancode], keytyp;
421
422 set_bit( scancode, broken_keys );
423 self_test_last_rcv = jiffies;
424 keyval = plain_map[scancode];
425 keytyp = KTYP(keyval) - 0xf0;
426 keyval = KVAL(keyval);
427
428 printk( KERN_WARNING "Key with scancode %d ", scancode );
429 if (keytyp == KT_LATIN || keytyp == KT_LETTER) {
430 if (keyval < ' ')
431 printk( "('^%c') ", keyval + '@' );
432 else
433 printk( "('%c') ", keyval );
434 }
435 printk( "is broken -- will be ignored.\n" );
436 break;
437 }
438 else if (test_bit( scancode, broken_keys ))
439 break;
440
441 if (break_flag) {
442 del_timer( &atakeyb_rep_timer );
443 rep_scancode = 0;
444 }
445 else {
446 del_timer( &atakeyb_rep_timer );
447 rep_scancode = scancode;
448 atakeyb_rep_timer.expires = jiffies + key_repeat_delay;
449 add_timer( &atakeyb_rep_timer );
450 }
451
452 handle_scancode(scancode, !break_flag);
453 break;
454 }
455 break;
456
457 case AMOUSE:
458 kb_state.buf[kb_state.len++] = scancode;
459 if (kb_state.len == 5)
460 {
461 kb_state.state = KEYBOARD;
462 /* not yet used */
463 /* wake up someone waiting for this */
464 }
465 break;
466
467 case RMOUSE:
468 kb_state.buf[kb_state.len++] = scancode;
469 if (kb_state.len == 3)
470 {
471 kb_state.state = KEYBOARD;
472 if (atari_mouse_interrupt_hook)
473 atari_mouse_interrupt_hook(kb_state.buf);
474 }
475 break;
476
477 case JOYSTICK:
478 kb_state.buf[1] = scancode;
479 kb_state.state = KEYBOARD;
480 atari_joystick_interrupt(kb_state.buf);
481 break;
482
483 case CLOCK:
484 kb_state.buf[kb_state.len++] = scancode;
485 if (kb_state.len == 6)
486 {
487 kb_state.state = KEYBOARD;
488 /* wake up someone waiting for this.
489 But will this ever be used, as Linux keeps its own time.
490 Perhaps for synchronization purposes? */
491 /* wake_up_interruptible(&clock_wait); */
492 }
493 break;
494
495 case RESYNC:
496 if (kb_state.len <= 0 || IS_SYNC_CODE(scancode)) {
497 kb_state.state = KEYBOARD;
498 goto interpret_scancode;
499 }
500 kb_state.len--;
501 break;
502 }
503 }
504
505 #if 0
506 if (acia_stat & ACIA_CTS)
507 /* cannot happen */;
508 #endif
509
510 if (acia_stat & (ACIA_FE | ACIA_PE))
511 {
512 printk("Error in keyboard communication\n");
513 }
514
515 /* handle_scancode() can take a lot of time, so check again if
516 * some character arrived
517 */
518 goto repeat;
519 }
520
521 /*
522 * I write to the keyboard without using interrupts, I poll instead.
523 * This takes for the maximum length string allowed (7) at 7812.5 baud
524 * 8 data 1 start 1 stop bit: 9.0 ms
525 * If this takes too long for normal operation, interrupt driven writing
526 * is the solution. (I made a feeble attempt in that direction but I
527 * kept it simple for now.)
528 */
ikbd_write(const char * str,int len)529 void ikbd_write(const char *str, int len)
530 {
531 u_char acia_stat;
532
533 if ((len < 1) || (len > 7))
534 panic("ikbd: maximum string length exceeded");
535 while (len)
536 {
537 acia_stat = acia.key_ctrl;
538 if (acia_stat & ACIA_TDRE)
539 {
540 acia.key_data = *str++;
541 len--;
542 }
543 }
544 }
545
546 /* Reset (without touching the clock) */
ikbd_reset(void)547 void ikbd_reset(void)
548 {
549 static const char cmd[2] = { 0x80, 0x01 };
550
551 ikbd_write(cmd, 2);
552
553 /* if all's well code 0xF1 is returned, else the break codes of
554 all keys making contact */
555 }
556
557 /* Set mouse button action */
ikbd_mouse_button_action(int mode)558 void ikbd_mouse_button_action(int mode)
559 {
560 char cmd[2] = { 0x07, mode };
561
562 ikbd_write(cmd, 2);
563 }
564
565 /* Set relative mouse position reporting */
ikbd_mouse_rel_pos(void)566 void ikbd_mouse_rel_pos(void)
567 {
568 static const char cmd[1] = { 0x08 };
569
570 ikbd_write(cmd, 1);
571 }
572
573 /* Set absolute mouse position reporting */
ikbd_mouse_abs_pos(int xmax,int ymax)574 void ikbd_mouse_abs_pos(int xmax, int ymax)
575 {
576 char cmd[5] = { 0x09, xmax>>8, xmax&0xFF, ymax>>8, ymax&0xFF };
577
578 ikbd_write(cmd, 5);
579 }
580
581 /* Set mouse keycode mode */
ikbd_mouse_kbd_mode(int dx,int dy)582 void ikbd_mouse_kbd_mode(int dx, int dy)
583 {
584 char cmd[3] = { 0x0A, dx, dy };
585
586 ikbd_write(cmd, 3);
587 }
588
589 /* Set mouse threshold */
ikbd_mouse_thresh(int x,int y)590 void ikbd_mouse_thresh(int x, int y)
591 {
592 char cmd[3] = { 0x0B, x, y };
593
594 ikbd_write(cmd, 3);
595 }
596
597 /* Set mouse scale */
ikbd_mouse_scale(int x,int y)598 void ikbd_mouse_scale(int x, int y)
599 {
600 char cmd[3] = { 0x0C, x, y };
601
602 ikbd_write(cmd, 3);
603 }
604
605 /* Interrogate mouse position */
ikbd_mouse_pos_get(int * x,int * y)606 void ikbd_mouse_pos_get(int *x, int *y)
607 {
608 static const char cmd[1] = { 0x0D };
609
610 ikbd_write(cmd, 1);
611
612 /* wait for returning bytes */
613 }
614
615 /* Load mouse position */
ikbd_mouse_pos_set(int x,int y)616 void ikbd_mouse_pos_set(int x, int y)
617 {
618 char cmd[6] = { 0x0E, 0x00, x>>8, x&0xFF, y>>8, y&0xFF };
619
620 ikbd_write(cmd, 6);
621 }
622
623 /* Set Y=0 at bottom */
ikbd_mouse_y0_bot(void)624 void ikbd_mouse_y0_bot(void)
625 {
626 static const char cmd[1] = { 0x0F };
627
628 ikbd_write(cmd, 1);
629 }
630
631 /* Set Y=0 at top */
ikbd_mouse_y0_top(void)632 void ikbd_mouse_y0_top(void)
633 {
634 static const char cmd[1] = { 0x10 };
635
636 ikbd_write(cmd, 1);
637 }
638
639 /* Resume */
ikbd_resume(void)640 void ikbd_resume(void)
641 {
642 static const char cmd[1] = { 0x11 };
643
644 ikbd_write(cmd, 1);
645 }
646
647 /* Disable mouse */
ikbd_mouse_disable(void)648 void ikbd_mouse_disable(void)
649 {
650 static const char cmd[1] = { 0x12 };
651
652 ikbd_write(cmd, 1);
653 }
654
655 /* Pause output */
ikbd_pause(void)656 void ikbd_pause(void)
657 {
658 static const char cmd[1] = { 0x13 };
659
660 ikbd_write(cmd, 1);
661 }
662
663 /* Set joystick event reporting */
ikbd_joystick_event_on(void)664 void ikbd_joystick_event_on(void)
665 {
666 static const char cmd[1] = { 0x14 };
667
668 ikbd_write(cmd, 1);
669 }
670
671 /* Set joystick interrogation mode */
ikbd_joystick_event_off(void)672 void ikbd_joystick_event_off(void)
673 {
674 static const char cmd[1] = { 0x15 };
675
676 ikbd_write(cmd, 1);
677 }
678
679 /* Joystick interrogation */
ikbd_joystick_get_state(void)680 void ikbd_joystick_get_state(void)
681 {
682 static const char cmd[1] = { 0x16 };
683
684 ikbd_write(cmd, 1);
685 }
686
687 #if 0
688 /* This disables all other ikbd activities !!!! */
689 /* Set joystick monitoring */
690 void ikbd_joystick_monitor(int rate)
691 {
692 static const char cmd[2] = { 0x17, rate };
693
694 ikbd_write(cmd, 2);
695
696 kb_state.state = JOYSTICK_MONITOR;
697 }
698 #endif
699
700 /* some joystick routines not in yet (0x18-0x19) */
701
702 /* Disable joysticks */
ikbd_joystick_disable(void)703 void ikbd_joystick_disable(void)
704 {
705 static const char cmd[1] = { 0x1A };
706
707 ikbd_write(cmd, 1);
708 }
709
710 /* Time-of-day clock set */
ikbd_clock_set(int year,int month,int day,int hour,int minute,int second)711 void ikbd_clock_set(int year, int month, int day, int hour, int minute, int second)
712 {
713 char cmd[7] = { 0x1B, year, month, day, hour, minute, second };
714
715 ikbd_write(cmd, 7);
716 }
717
718 /* Interrogate time-of-day clock */
ikbd_clock_get(int * year,int * month,int * day,int * hour,int * minute,int second)719 void ikbd_clock_get(int *year, int *month, int *day, int *hour, int *minute, int second)
720 {
721 static const char cmd[1] = { 0x1C };
722
723 ikbd_write(cmd, 1);
724 }
725
726 /* Memory load */
ikbd_mem_write(int address,int size,char * data)727 void ikbd_mem_write(int address, int size, char *data)
728 {
729 panic("Attempt to write data into keyboard memory");
730 }
731
732 /* Memory read */
ikbd_mem_read(int address,char data[6])733 void ikbd_mem_read(int address, char data[6])
734 {
735 char cmd[3] = { 0x21, address>>8, address&0xFF };
736
737 ikbd_write(cmd, 3);
738
739 /* receive data and put it in data */
740 }
741
742 /* Controller execute */
ikbd_exec(int address)743 void ikbd_exec(int address)
744 {
745 char cmd[3] = { 0x22, address>>8, address&0xFF };
746
747 ikbd_write(cmd, 3);
748 }
749
750 /* Status inquiries (0x87-0x9A) not yet implemented */
751
752 /* Set the state of the caps lock led. */
atari_kbd_leds(unsigned int leds)753 void atari_kbd_leds (unsigned int leds)
754 {
755 char cmd[6] = {32, 0, 4, 1, 254 + ((leds & 4) != 0), 0};
756 ikbd_write(cmd, 6);
757 }
758
759 /*
760 * The original code sometimes left the interrupt line of
761 * the ACIAs low forever. I hope, it is fixed now.
762 *
763 * Martin Rogge, 20 Aug 1995
764 */
765
atari_keyb_init(void)766 int __init atari_keyb_init(void)
767 {
768 /* setup key map */
769 memcpy(key_maps[0], ataplain_map, sizeof(plain_map));
770 memcpy(key_maps[1], atashift_map, sizeof(plain_map));
771 memcpy(key_maps[4], atactrl_map, sizeof(plain_map));
772 memcpy(key_maps[5], atashift_ctrl_map, sizeof(plain_map));
773 memcpy(key_maps[8], ataalt_map, sizeof(plain_map));
774 /* Atari doesn't have an altgr_map, so we can reuse its memory for
775 atashift_alt_map */
776 memcpy(key_maps[2], atashift_alt_map, sizeof(plain_map));
777 key_maps[9] = key_maps[2];
778 key_maps[2] = 0; /* ataaltgr_map */
779 memcpy(key_maps[12], atactrl_alt_map, sizeof(plain_map));
780 key_maps[13] = atashift_ctrl_alt_map;
781 keymap_count = 8;
782
783 /* say that we don't have an AltGr key */
784 keyboard_type = KB_84;
785
786 kb_state.state = KEYBOARD;
787 kb_state.len = 0;
788
789 request_irq(IRQ_MFP_ACIA, keyboard_interrupt, IRQ_TYPE_SLOW,
790 "keyboard/mouse/MIDI", keyboard_interrupt);
791
792 atari_turnoff_irq(IRQ_MFP_ACIA);
793 do {
794 /* reset IKBD ACIA */
795 acia.key_ctrl = ACIA_RESET |
796 (atari_switches & ATARI_SWITCH_IKBD) ? ACIA_RHTID : 0;
797 (void)acia.key_ctrl;
798 (void)acia.key_data;
799
800 /* reset MIDI ACIA */
801 acia.mid_ctrl = ACIA_RESET |
802 (atari_switches & ATARI_SWITCH_MIDI) ? ACIA_RHTID : 0;
803 (void)acia.mid_ctrl;
804 (void)acia.mid_data;
805
806 /* divide 500kHz by 64 gives 7812.5 baud */
807 /* 8 data no parity 1 start 1 stop bit */
808 /* receive interrupt enabled */
809 /* RTS low (except if switch selected), transmit interrupt disabled */
810 acia.key_ctrl = (ACIA_DIV64|ACIA_D8N1S|ACIA_RIE) |
811 ((atari_switches & ATARI_SWITCH_IKBD) ?
812 ACIA_RHTID : ACIA_RLTID);
813
814 acia.mid_ctrl = ACIA_DIV16 | ACIA_D8N1S |
815 (atari_switches & ATARI_SWITCH_MIDI) ? ACIA_RHTID : 0;
816 }
817 /* make sure the interrupt line is up */
818 while ((mfp.par_dt_reg & 0x10) == 0);
819
820 /* enable ACIA Interrupts */
821 mfp.active_edge &= ~0x10;
822 atari_turnon_irq(IRQ_MFP_ACIA);
823
824 ikbd_self_test = 1;
825 ikbd_reset();
826 /* wait for a period of inactivity (here: 0.25s), then assume the IKBD's
827 * self-test is finished */
828 self_test_last_rcv = jiffies;
829 while (time_before(jiffies, self_test_last_rcv + HZ/4))
830 barrier();
831 /* if not incremented: no 0xf1 received */
832 if (ikbd_self_test == 1)
833 printk( KERN_ERR "WARNING: keyboard self test failed!\n" );
834 ikbd_self_test = 0;
835
836 ikbd_mouse_disable();
837 ikbd_joystick_disable();
838
839 atari_joystick_init();
840
841 return 0;
842 }
843
844
atari_kbdrate(struct kbd_repeat * k)845 int atari_kbdrate( struct kbd_repeat *k )
846
847 {
848 if (k->delay > 0) {
849 /* convert from msec to jiffies */
850 key_repeat_delay = (k->delay * HZ + 500) / 1000;
851 if (key_repeat_delay < 1)
852 key_repeat_delay = 1;
853 }
854 if (k->rate > 0) {
855 key_repeat_rate = (k->rate * HZ + 500) / 1000;
856 if (key_repeat_rate < 1)
857 key_repeat_rate = 1;
858 }
859
860 k->delay = key_repeat_delay * 1000 / HZ;
861 k->rate = key_repeat_rate * 1000 / HZ;
862
863 return( 0 );
864 }
865
atari_kbd_translate(unsigned char keycode,unsigned char * keycodep,char raw_mode)866 int atari_kbd_translate(unsigned char keycode, unsigned char *keycodep, char raw_mode)
867 {
868 #ifdef CONFIG_MAGIC_SYSRQ
869 /* ALT+HELP pressed? */
870 if ((keycode == 98) && ((shift_state & 0xff) == 8))
871 *keycodep = 0xff;
872 else
873 #endif
874 *keycodep = keycode;
875 return 1;
876 }
877
878