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