More Makefile cleanups, otherwise mainly noticeable are the netfilter fix
[davej-history.git] / arch / m68k / atari / atakeyb.c
blobf4f284a9adc731d564ecbfa4de74b42ab34ec224
1 /*
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
8 * for more details.
9 */
12 * Atari support by Robert de Vries
13 * enhanced by Bjoern Brauel and Roman Hodek
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>
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>
36 static void atakeyb_rep( unsigned long ignore );
37 extern unsigned int keymap_count;
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 *);
44 /* variables for IKBD self test: */
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, };
53 #define BREAK_MASK (0x80)
56 * ++roman: The following changes were applied manually:
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) ...
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).
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).
73 * - Console switching is done with Alt+Fx (consoles 1..10) and
74 * Shift+Alt+Fx (consoles 11..20).
76 * - The misc. special function implemented in the kernel are mapped
77 * to the following key combinations:
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
94 * ++Andreas:
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]
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
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
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
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
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
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
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
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
253 typedef enum kb_state_t
255 KEYBOARD, AMOUSE, RMOUSE, JOYSTICK, CLOCK, RESYNC
256 } KB_STATE_T;
258 #define IS_SYNC_CODE(sc) ((sc) >= 0x04 && (sc) <= 0xfb)
260 typedef struct keyboard_state
262 unsigned char buf[6];
263 int len;
264 KB_STATE_T state;
265 } KEYBOARD_STATE;
267 KEYBOARD_STATE kb_state;
269 #define DEFAULT_KEYB_REP_DELAY (HZ/4)
270 #define DEFAULT_KEYB_REP_RATE (HZ/25)
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;
276 static unsigned char rep_scancode;
277 static struct timer_list atakeyb_rep_timer = { function: atakeyb_rep };
279 static void atakeyb_rep( unsigned long ignore )
282 kbd_pt_regs = NULL;
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 );
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 );
296 handle_scancode(rep_scancode, 1);
299 atari_enable_irq( IRQ_MFP_ACIA );
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...
320 static void keyboard_interrupt(int irq, void *dummy, struct pt_regs *fp)
322 u_char acia_stat;
323 int scancode;
324 int break_flag;
326 /* save frame for register dump */
327 kbd_pt_regs = fp;
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;
338 if (acia_stat & ACIA_OVRN)
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;
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;
364 if (acia_stat & ACIA_RDRF) /* received a character */
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)
371 case KEYBOARD:
372 switch (scancode)
374 case 0xF7:
375 kb_state.state = AMOUSE;
376 kb_state.len = 0;
377 break;
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;
388 case 0xFC:
389 kb_state.state = CLOCK;
390 kb_state.len = 0;
391 break;
393 case 0xFE:
394 case 0xFF:
395 kb_state.state = JOYSTICK;
396 kb_state.len = 1;
397 kb_state.buf[0] = scancode;
398 break;
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;
407 /* FALL THROUGH */
409 default:
410 break_flag = scancode & BREAK_MASK;
411 scancode &= ~BREAK_MASK;
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;
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);
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 );
435 printk( "is broken -- will be ignored.\n" );
436 break;
438 else if (test_bit( scancode, broken_keys ))
439 break;
441 if (break_flag) {
442 del_timer( &atakeyb_rep_timer );
443 rep_scancode = 0;
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 );
452 handle_scancode(scancode, !break_flag);
453 break;
455 break;
457 case AMOUSE:
458 kb_state.buf[kb_state.len++] = scancode;
459 if (kb_state.len == 5)
461 kb_state.state = KEYBOARD;
462 /* not yet used */
463 /* wake up someone waiting for this */
465 break;
467 case RMOUSE:
468 kb_state.buf[kb_state.len++] = scancode;
469 if (kb_state.len == 3)
471 kb_state.state = KEYBOARD;
472 if (atari_mouse_interrupt_hook)
473 atari_mouse_interrupt_hook(kb_state.buf);
475 break;
477 case JOYSTICK:
478 kb_state.buf[1] = scancode;
479 kb_state.state = KEYBOARD;
480 atari_joystick_interrupt(kb_state.buf);
481 break;
483 case CLOCK:
484 kb_state.buf[kb_state.len++] = scancode;
485 if (kb_state.len == 6)
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); */
493 break;
495 case RESYNC:
496 if (kb_state.len <= 0 || IS_SYNC_CODE(scancode)) {
497 kb_state.state = KEYBOARD;
498 goto interpret_scancode;
500 kb_state.len--;
501 break;
505 #if 0
506 if (acia_stat & ACIA_CTS)
507 /* cannot happen */;
508 #endif
510 if (acia_stat & (ACIA_FE | ACIA_PE))
512 printk("Error in keyboard communication\n");
515 /* handle_scancode() can take a lot of time, so check again if
516 * some character arrived
518 goto repeat;
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.)
529 void ikbd_write(const char *str, int len)
531 u_char acia_stat;
533 if ((len < 1) || (len > 7))
534 panic("ikbd: maximum string length exceeded");
535 while (len)
537 acia_stat = acia.key_ctrl;
538 if (acia_stat & ACIA_TDRE)
540 acia.key_data = *str++;
541 len--;
546 /* Reset (without touching the clock) */
547 void ikbd_reset(void)
549 static const char cmd[2] = { 0x80, 0x01 };
551 ikbd_write(cmd, 2);
553 /* if all's well code 0xF1 is returned, else the break codes of
554 all keys making contact */
557 /* Set mouse button action */
558 void ikbd_mouse_button_action(int mode)
560 char cmd[2] = { 0x07, mode };
562 ikbd_write(cmd, 2);
565 /* Set relative mouse position reporting */
566 void ikbd_mouse_rel_pos(void)
568 static const char cmd[1] = { 0x08 };
570 ikbd_write(cmd, 1);
573 /* Set absolute mouse position reporting */
574 void ikbd_mouse_abs_pos(int xmax, int ymax)
576 char cmd[5] = { 0x09, xmax>>8, xmax&0xFF, ymax>>8, ymax&0xFF };
578 ikbd_write(cmd, 5);
581 /* Set mouse keycode mode */
582 void ikbd_mouse_kbd_mode(int dx, int dy)
584 char cmd[3] = { 0x0A, dx, dy };
586 ikbd_write(cmd, 3);
589 /* Set mouse threshold */
590 void ikbd_mouse_thresh(int x, int y)
592 char cmd[3] = { 0x0B, x, y };
594 ikbd_write(cmd, 3);
597 /* Set mouse scale */
598 void ikbd_mouse_scale(int x, int y)
600 char cmd[3] = { 0x0C, x, y };
602 ikbd_write(cmd, 3);
605 /* Interrogate mouse position */
606 void ikbd_mouse_pos_get(int *x, int *y)
608 static const char cmd[1] = { 0x0D };
610 ikbd_write(cmd, 1);
612 /* wait for returning bytes */
615 /* Load mouse position */
616 void ikbd_mouse_pos_set(int x, int y)
618 char cmd[6] = { 0x0E, 0x00, x>>8, x&0xFF, y>>8, y&0xFF };
620 ikbd_write(cmd, 6);
623 /* Set Y=0 at bottom */
624 void ikbd_mouse_y0_bot(void)
626 static const char cmd[1] = { 0x0F };
628 ikbd_write(cmd, 1);
631 /* Set Y=0 at top */
632 void ikbd_mouse_y0_top(void)
634 static const char cmd[1] = { 0x10 };
636 ikbd_write(cmd, 1);
639 /* Resume */
640 void ikbd_resume(void)
642 static const char cmd[1] = { 0x11 };
644 ikbd_write(cmd, 1);
647 /* Disable mouse */
648 void ikbd_mouse_disable(void)
650 static const char cmd[1] = { 0x12 };
652 ikbd_write(cmd, 1);
655 /* Pause output */
656 void ikbd_pause(void)
658 static const char cmd[1] = { 0x13 };
660 ikbd_write(cmd, 1);
663 /* Set joystick event reporting */
664 void ikbd_joystick_event_on(void)
666 static const char cmd[1] = { 0x14 };
668 ikbd_write(cmd, 1);
671 /* Set joystick interrogation mode */
672 void ikbd_joystick_event_off(void)
674 static const char cmd[1] = { 0x15 };
676 ikbd_write(cmd, 1);
679 /* Joystick interrogation */
680 void ikbd_joystick_get_state(void)
682 static const char cmd[1] = { 0x16 };
684 ikbd_write(cmd, 1);
687 #if 0
688 /* This disables all other ikbd activities !!!! */
689 /* Set joystick monitoring */
690 void ikbd_joystick_monitor(int rate)
692 static const char cmd[2] = { 0x17, rate };
694 ikbd_write(cmd, 2);
696 kb_state.state = JOYSTICK_MONITOR;
698 #endif
700 /* some joystick routines not in yet (0x18-0x19) */
702 /* Disable joysticks */
703 void ikbd_joystick_disable(void)
705 static const char cmd[1] = { 0x1A };
707 ikbd_write(cmd, 1);
710 /* Time-of-day clock set */
711 void ikbd_clock_set(int year, int month, int day, int hour, int minute, int second)
713 char cmd[7] = { 0x1B, year, month, day, hour, minute, second };
715 ikbd_write(cmd, 7);
718 /* Interrogate time-of-day clock */
719 void ikbd_clock_get(int *year, int *month, int *day, int *hour, int *minute, int second)
721 static const char cmd[1] = { 0x1C };
723 ikbd_write(cmd, 1);
726 /* Memory load */
727 void ikbd_mem_write(int address, int size, char *data)
729 panic("Attempt to write data into keyboard memory");
732 /* Memory read */
733 void ikbd_mem_read(int address, char data[6])
735 char cmd[3] = { 0x21, address>>8, address&0xFF };
737 ikbd_write(cmd, 3);
739 /* receive data and put it in data */
742 /* Controller execute */
743 void ikbd_exec(int address)
745 char cmd[3] = { 0x22, address>>8, address&0xFF };
747 ikbd_write(cmd, 3);
750 /* Status inquiries (0x87-0x9A) not yet implemented */
752 /* Set the state of the caps lock led. */
753 void atari_kbd_leds (unsigned int leds)
755 char cmd[6] = {32, 0, 4, 1, 254 + ((leds & 4) != 0), 0};
756 ikbd_write(cmd, 6);
760 * The original code sometimes left the interrupt line of
761 * the ACIAs low forever. I hope, it is fixed now.
763 * Martin Rogge, 20 Aug 1995
766 int __init atari_keyb_init(void)
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;
783 /* say that we don't have an AltGr key */
784 keyboard_type = KB_84;
786 kb_state.state = KEYBOARD;
787 kb_state.len = 0;
789 request_irq(IRQ_MFP_ACIA, keyboard_interrupt, IRQ_TYPE_SLOW,
790 "keyboard/mouse/MIDI", keyboard_interrupt);
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;
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;
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);
814 acia.mid_ctrl = ACIA_DIV16 | ACIA_D8N1S |
815 (atari_switches & ATARI_SWITCH_MIDI) ? ACIA_RHTID : 0;
817 /* make sure the interrupt line is up */
818 while ((mfp.par_dt_reg & 0x10) == 0);
820 /* enable ACIA Interrupts */
821 mfp.active_edge &= ~0x10;
822 atari_turnon_irq(IRQ_MFP_ACIA);
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;
836 ikbd_mouse_disable();
837 ikbd_joystick_disable();
839 atari_joystick_init();
841 return 0;
845 int atari_kbdrate( struct kbd_repeat *k )
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;
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;
860 k->delay = key_repeat_delay * 1000 / HZ;
861 k->rate = key_repeat_rate * 1000 / HZ;
863 return( 0 );
866 int atari_kbd_translate(unsigned char keycode, unsigned char *keycodep, char raw_mode)
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;