1 /*
2 * drivers/char/mac_keyb.c
3 *
4 * Keyboard driver for Power Macintosh computers.
5 *
6 * Adapted from drivers/char/keyboard.c by Paul Mackerras
7 * (see that file for its authors and contributors).
8 *
9 * Copyright (C) 1996 Paul Mackerras.
10 *
11 * Adapted to ADB changes and support for more devices by
12 * Benjamin Herrenschmidt. Adapted from code in MkLinux
13 * and reworked.
14 *
15 * Supported devices:
16 *
17 * - Standard 1 button mouse
18 * - All standard Apple Extended protocol (handler ID 4)
19 * - mouseman and trackman mice & trackballs
20 * - PowerBook Trackpad (default setup: enable tapping)
21 * - MicroSpeed mouse & trackball (needs testing)
22 * - CH Products Trackball Pro (needs testing)
23 * - Contour Design (Contour Mouse)
24 * - Hunter digital (NoHandsMouse)
25 * - Kensignton TurboMouse 5 (needs testing)
26 * - Mouse Systems A3 mice and trackballs <aidan@kublai.com>
27 * - MacAlly 2-buttons mouse (needs testing) <pochini@denise.shiny.it>
28 *
29 * To do:
30 *
31 * Improve Kensignton support, add MacX support as a dynamic
32 * option (not a compile-time option).
33 */
34
35 #include <linux/sched.h>
36 #include <linux/interrupt.h>
37 #include <linux/tty.h>
38 #include <linux/mm.h>
39 #include <linux/signal.h>
40 #include <linux/ioport.h>
41 #include <linux/init.h>
42 #include <linux/tty_flip.h>
43 #include <linux/config.h>
44 #include <linux/notifier.h>
45
46 #include <asm/bitops.h>
47
48 #include <linux/adb.h>
49 #include <linux/cuda.h>
50 #include <linux/pmu.h>
51 #include <linux/kbd_kern.h>
52 #include <linux/kbd_ll.h>
53
54 #ifdef CONFIG_PMAC_BACKLIGHT
55 #include <asm/backlight.h>
56 #endif
57
58 #define KEYB_KEYREG 0 /* register # for key up/down data */
59 #define KEYB_LEDREG 2 /* register # for leds on ADB keyboard */
60 #define MOUSE_DATAREG 0 /* reg# for movement/button codes from mouse */
61
62 static int adb_message_handler(struct notifier_block *, unsigned long, void *);
63 static struct notifier_block mackeyb_adb_notifier = {
64 adb_message_handler,
65 NULL,
66 0
67 };
68
69 /* this map indicates which keys shouldn't autorepeat. */
70 static unsigned char dont_repeat[128] = {
71 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
72 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
73 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
74 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* esc...option */
75 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, /* fn, num lock */
76 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
77 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, /* scroll lock */
78 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, /* R modifiers */
79 };
80
81 /* Simple translation table for the SysRq keys */
82
83 #ifdef CONFIG_MAGIC_SYSRQ
84 unsigned char mackbd_sysrq_xlate[128] =
85 "asdfhgzxcv\000bqwer" /* 0x00 - 0x0f */
86 "yt123465=97-80o]" /* 0x10 - 0x1f */
87 "u[ip\rlj'k;\\,/nm." /* 0x20 - 0x2f */
88 "\t `\177\000\033\000\000\000\000\000\000\000\000\000\000"
89 /* 0x30 - 0x3f */
90 "\000\000\000*\000+\000\000\000\000\000/\r\000-\000"
91 /* 0x40 - 0x4f */
92 "\000\0000123456789\000\000\000" /* 0x50 - 0x5f */
93 "\205\206\207\203\210\211\000\213\000\215\000\000\000\000\000\212\000\214";
94 /* 0x60 - 0x6f */
95 #endif
96
97 static u_short macplain_map[NR_KEYS] __initdata = {
98 0xfb61, 0xfb73, 0xfb64, 0xfb66, 0xfb68, 0xfb67, 0xfb7a, 0xfb78,
99 0xfb63, 0xfb76, 0xf200, 0xfb62, 0xfb71, 0xfb77, 0xfb65, 0xfb72,
100 0xfb79, 0xfb74, 0xf031, 0xf032, 0xf033, 0xf034, 0xf036, 0xf035,
101 0xf03d, 0xf039, 0xf037, 0xf02d, 0xf038, 0xf030, 0xf05d, 0xfb6f,
102 0xfb75, 0xf05b, 0xfb69, 0xfb70, 0xf201, 0xfb6c, 0xfb6a, 0xf027,
103 0xfb6b, 0xf03b, 0xf05c, 0xf02c, 0xf02f, 0xfb6e, 0xfb6d, 0xf02e,
104 0xf009, 0xf020, 0xf060, 0xf07f, 0xf200, 0xf01b, 0xf702, 0xf703,
105 0xf700, 0xf207, 0xf701, 0xf601, 0xf602, 0xf600, 0xf603, 0xf200,
106 0xf200, 0xf310, 0xf200, 0xf30c, 0xf200, 0xf30a, 0xf200, 0xf208,
107 0xf200, 0xf200, 0xf200, 0xf30d, 0xf30e, 0xf200, 0xf30b, 0xf200,
108 0xf200, 0xf200, 0xf300, 0xf301, 0xf302, 0xf303, 0xf304, 0xf305,
109 0xf306, 0xf307, 0xf200, 0xf308, 0xf309, 0xf200, 0xf200, 0xf200,
110 0xf104, 0xf105, 0xf106, 0xf102, 0xf107, 0xf108, 0xf200, 0xf10a,
111 0xf200, 0xf10c, 0xf200, 0xf209, 0xf200, 0xf109, 0xf200, 0xf10b,
112 0xf200, 0xf11d, 0xf115, 0xf114, 0xf118, 0xf116, 0xf103, 0xf117,
113 0xf101, 0xf119, 0xf100, 0xf700, 0xf701, 0xf702, 0xf200, 0xf200,
114 };
115
116 static u_short macshift_map[NR_KEYS] __initdata = {
117 0xfb41, 0xfb53, 0xfb44, 0xfb46, 0xfb48, 0xfb47, 0xfb5a, 0xfb58,
118 0xfb43, 0xfb56, 0xf200, 0xfb42, 0xfb51, 0xfb57, 0xfb45, 0xfb52,
119 0xfb59, 0xfb54, 0xf021, 0xf040, 0xf023, 0xf024, 0xf05e, 0xf025,
120 0xf02b, 0xf028, 0xf026, 0xf05f, 0xf02a, 0xf029, 0xf07d, 0xfb4f,
121 0xfb55, 0xf07b, 0xfb49, 0xfb50, 0xf201, 0xfb4c, 0xfb4a, 0xf022,
122 0xfb4b, 0xf03a, 0xf07c, 0xf03c, 0xf03f, 0xfb4e, 0xfb4d, 0xf03e,
123 0xf009, 0xf020, 0xf07e, 0xf07f, 0xf200, 0xf01b, 0xf702, 0xf703,
124 0xf700, 0xf207, 0xf701, 0xf601, 0xf602, 0xf600, 0xf603, 0xf200,
125 0xf200, 0xf310, 0xf200, 0xf30c, 0xf200, 0xf30a, 0xf200, 0xf208,
126 0xf200, 0xf200, 0xf200, 0xf30d, 0xf30e, 0xf200, 0xf30b, 0xf200,
127 0xf200, 0xf200, 0xf300, 0xf301, 0xf302, 0xf303, 0xf304, 0xf305,
128 0xf306, 0xf307, 0xf200, 0xf308, 0xf309, 0xf200, 0xf200, 0xf200,
129 0xf10e, 0xf10f, 0xf110, 0xf10c, 0xf111, 0xf112, 0xf200, 0xf10a,
130 0xf200, 0xf10c, 0xf200, 0xf203, 0xf200, 0xf113, 0xf200, 0xf10b,
131 0xf200, 0xf11d, 0xf115, 0xf114, 0xf20b, 0xf116, 0xf10d, 0xf117,
132 0xf10b, 0xf20a, 0xf10a, 0xf700, 0xf701, 0xf702, 0xf200, 0xf200,
133 };
134
135 static u_short macaltgr_map[NR_KEYS] __initdata = {
136 0xf914, 0xfb73, 0xf917, 0xf919, 0xfb68, 0xfb67, 0xfb7a, 0xfb78,
137 0xf916, 0xfb76, 0xf200, 0xf915, 0xfb71, 0xfb77, 0xf918, 0xfb72,
138 0xfb79, 0xfb74, 0xf200, 0xf040, 0xf200, 0xf024, 0xf200, 0xf200,
139 0xf200, 0xf05d, 0xf07b, 0xf05c, 0xf05b, 0xf07d, 0xf07e, 0xfb6f,
140 0xfb75, 0xf200, 0xfb69, 0xfb70, 0xf201, 0xfb6c, 0xfb6a, 0xf200,
141 0xfb6b, 0xf200, 0xf200, 0xf200, 0xf200, 0xfb6e, 0xfb6d, 0xf200,
142 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf702, 0xf703,
143 0xf700, 0xf207, 0xf701, 0xf601, 0xf602, 0xf600, 0xf603, 0xf200,
144 0xf200, 0xf310, 0xf200, 0xf30c, 0xf200, 0xf30a, 0xf200, 0xf208,
145 0xf200, 0xf200, 0xf200, 0xf30d, 0xf30e, 0xf200, 0xf30b, 0xf200,
146 0xf200, 0xf200, 0xf90a, 0xf90b, 0xf90c, 0xf90d, 0xf90e, 0xf90f,
147 0xf910, 0xf911, 0xf200, 0xf912, 0xf913, 0xf200, 0xf200, 0xf200,
148 0xf510, 0xf511, 0xf512, 0xf50e, 0xf513, 0xf514, 0xf200, 0xf516,
149 0xf200, 0xf10c, 0xf200, 0xf202, 0xf200, 0xf515, 0xf200, 0xf517,
150 0xf200, 0xf11d, 0xf115, 0xf114, 0xf118, 0xf116, 0xf50f, 0xf117,
151 0xf50d, 0xf119, 0xf50c, 0xf700, 0xf701, 0xf702, 0xf200, 0xf200,
152 };
153
154 static u_short macctrl_map[NR_KEYS] __initdata = {
155 0xf001, 0xf013, 0xf004, 0xf006, 0xf008, 0xf007, 0xf01a, 0xf018,
156 0xf003, 0xf016, 0xf200, 0xf002, 0xf011, 0xf017, 0xf005, 0xf012,
157 0xf019, 0xf014, 0xf200, 0xf000, 0xf01b, 0xf01c, 0xf01e, 0xf01d,
158 0xf200, 0xf200, 0xf01f, 0xf01f, 0xf07f, 0xf200, 0xf01d, 0xf00f,
159 0xf015, 0xf01b, 0xf009, 0xf010, 0xf201, 0xf00c, 0xf00a, 0xf007,
160 0xf00b, 0xf200, 0xf01c, 0xf200, 0xf07f, 0xf00e, 0xf00d, 0xf20e,
161 0xf200, 0xf000, 0xf000, 0xf008, 0xf200, 0xf200, 0xf702, 0xf703,
162 0xf700, 0xf207, 0xf701, 0xf601, 0xf602, 0xf600, 0xf603, 0xf200,
163 0xf200, 0xf310, 0xf200, 0xf30c, 0xf200, 0xf30a, 0xf200, 0xf208,
164 0xf200, 0xf200, 0xf200, 0xf30d, 0xf30e, 0xf200, 0xf30b, 0xf200,
165 0xf200, 0xf200, 0xf300, 0xf301, 0xf302, 0xf303, 0xf304, 0xf305,
166 0xf306, 0xf307, 0xf200, 0xf308, 0xf309, 0xf200, 0xf200, 0xf200,
167 0xf104, 0xf105, 0xf106, 0xf102, 0xf107, 0xf108, 0xf200, 0xf10a,
168 0xf200, 0xf10c, 0xf200, 0xf204, 0xf200, 0xf109, 0xf200, 0xf10b,
169 0xf200, 0xf11d, 0xf115, 0xf114, 0xf118, 0xf116, 0xf103, 0xf117,
170 0xf101, 0xf119, 0xf100, 0xf700, 0xf701, 0xf702, 0xf200, 0xf200,
171 };
172
173 static u_short macshift_ctrl_map[NR_KEYS] __initdata = {
174 0xf001, 0xf013, 0xf004, 0xf006, 0xf008, 0xf007, 0xf01a, 0xf018,
175 0xf003, 0xf016, 0xf200, 0xf002, 0xf011, 0xf017, 0xf005, 0xf012,
176 0xf019, 0xf014, 0xf200, 0xf000, 0xf200, 0xf200, 0xf200, 0xf200,
177 0xf200, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf200, 0xf200, 0xf00f,
178 0xf015, 0xf200, 0xf009, 0xf010, 0xf201, 0xf00c, 0xf00a, 0xf200,
179 0xf00b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf00e, 0xf00d, 0xf200,
180 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf702, 0xf703,
181 0xf700, 0xf207, 0xf701, 0xf601, 0xf602, 0xf600, 0xf603, 0xf200,
182 0xf200, 0xf310, 0xf200, 0xf30c, 0xf200, 0xf30a, 0xf200, 0xf208,
183 0xf200, 0xf200, 0xf200, 0xf30d, 0xf30e, 0xf200, 0xf30b, 0xf200,
184 0xf200, 0xf200, 0xf300, 0xf301, 0xf302, 0xf303, 0xf304, 0xf305,
185 0xf306, 0xf307, 0xf200, 0xf308, 0xf309, 0xf200, 0xf200, 0xf200,
186 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
187 0xf200, 0xf10c, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
188 0xf200, 0xf11d, 0xf115, 0xf114, 0xf118, 0xf116, 0xf200, 0xf117,
189 0xf200, 0xf119, 0xf200, 0xf700, 0xf701, 0xf702, 0xf200, 0xf20c,
190 };
191
192 static u_short macalt_map[NR_KEYS] __initdata = {
193 0xf861, 0xf873, 0xf864, 0xf866, 0xf868, 0xf867, 0xf87a, 0xf878,
194 0xf863, 0xf876, 0xf200, 0xf862, 0xf871, 0xf877, 0xf865, 0xf872,
195 0xf879, 0xf874, 0xf831, 0xf832, 0xf833, 0xf834, 0xf836, 0xf835,
196 0xf83d, 0xf839, 0xf837, 0xf82d, 0xf838, 0xf830, 0xf85d, 0xf86f,
197 0xf875, 0xf85b, 0xf869, 0xf870, 0xf80d, 0xf86c, 0xf86a, 0xf827,
198 0xf86b, 0xf83b, 0xf85c, 0xf82c, 0xf82f, 0xf86e, 0xf86d, 0xf82e,
199 0xf809, 0xf820, 0xf860, 0xf87f, 0xf200, 0xf81b, 0xf702, 0xf703,
200 0xf700, 0xf207, 0xf701, 0xf210, 0xf211, 0xf600, 0xf603, 0xf200,
201 0xf200, 0xf310, 0xf200, 0xf30c, 0xf200, 0xf30a, 0xf200, 0xf208,
202 0xf200, 0xf200, 0xf200, 0xf30d, 0xf30e, 0xf200, 0xf30b, 0xf200,
203 0xf200, 0xf200, 0xf900, 0xf901, 0xf902, 0xf903, 0xf904, 0xf905,
204 0xf906, 0xf907, 0xf200, 0xf908, 0xf909, 0xf200, 0xf200, 0xf200,
205 0xf504, 0xf505, 0xf506, 0xf502, 0xf507, 0xf508, 0xf200, 0xf50a,
206 0xf200, 0xf10c, 0xf200, 0xf209, 0xf200, 0xf509, 0xf200, 0xf50b,
207 0xf200, 0xf11d, 0xf115, 0xf114, 0xf118, 0xf116, 0xf503, 0xf117,
208 0xf501, 0xf119, 0xf500, 0xf700, 0xf701, 0xf702, 0xf200, 0xf200,
209 };
210
211 static u_short macctrl_alt_map[NR_KEYS] __initdata = {
212 0xf801, 0xf813, 0xf804, 0xf806, 0xf808, 0xf807, 0xf81a, 0xf818,
213 0xf803, 0xf816, 0xf200, 0xf802, 0xf811, 0xf817, 0xf805, 0xf812,
214 0xf819, 0xf814, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
215 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf80f,
216 0xf815, 0xf200, 0xf809, 0xf810, 0xf201, 0xf80c, 0xf80a, 0xf200,
217 0xf80b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf80e, 0xf80d, 0xf200,
218 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf702, 0xf703,
219 0xf700, 0xf207, 0xf701, 0xf601, 0xf602, 0xf600, 0xf603, 0xf200,
220 0xf200, 0xf310, 0xf200, 0xf30c, 0xf200, 0xf30a, 0xf200, 0xf208,
221 0xf200, 0xf200, 0xf200, 0xf30d, 0xf30e, 0xf200, 0xf30b, 0xf200,
222 0xf200, 0xf200, 0xf300, 0xf301, 0xf302, 0xf303, 0xf304, 0xf305,
223 0xf306, 0xf307, 0xf200, 0xf308, 0xf309, 0xf200, 0xf200, 0xf200,
224 0xf504, 0xf505, 0xf506, 0xf502, 0xf507, 0xf508, 0xf200, 0xf50a,
225 0xf200, 0xf10c, 0xf200, 0xf200, 0xf200, 0xf509, 0xf200, 0xf50b,
226 0xf200, 0xf11d, 0xf115, 0xf114, 0xf118, 0xf116, 0xf503, 0xf117,
227 0xf501, 0xf119, 0xf500, 0xf700, 0xf701, 0xf702, 0xf200, 0xf200,
228 };
229
230
231 static void kbd_repeat(unsigned long);
232 static struct timer_list repeat_timer = { function: kbd_repeat };
233 static int last_keycode;
234
235 static void mackeyb_probe(void);
236
237 static void keyboard_input(unsigned char *, int, struct pt_regs *, int);
238 static void input_keycode(int, int);
239 static void leds_done(struct adb_request *);
240 static void mac_put_queue(int);
241
242 static void buttons_input(unsigned char *, int, struct pt_regs *, int);
243
244 static void init_trackpad(int id);
245 static void init_trackball(int id);
246 static void init_turbomouse(int id);
247 static void init_microspeed(int id);
248 static void init_ms_a3(int id);
249
250 #ifdef CONFIG_ADBMOUSE
251 /* XXX: Hook for mouse driver */
252 void (*adb_mouse_interrupt_hook)(unsigned char *, int);
253 int adb_emulate_buttons = 0;
254 int adb_button2_keycode = 0x7d; /* right control key */
255 int adb_button3_keycode = 0x7c; /* right option key */
256 #endif
257
258 extern struct kbd_struct kbd_table[];
259
260 extern void handle_scancode(unsigned char, int);
261
262 static struct adb_ids keyboard_ids;
263 static struct adb_ids mouse_ids;
264 static struct adb_ids buttons_ids;
265
266 /* Kind of mouse */
267 #define ADBMOUSE_STANDARD_100 0 /* Standard 100cpi mouse (handler 1) */
268 #define ADBMOUSE_STANDARD_200 1 /* Standard 200cpi mouse (handler 2) */
269 #define ADBMOUSE_EXTENDED 2 /* Apple Extended mouse (handler 4) */
270 #define ADBMOUSE_TRACKBALL 3 /* TrackBall (handler 4) */
271 #define ADBMOUSE_TRACKPAD 4 /* Apple's PowerBook trackpad (handler 4) */
272 #define ADBMOUSE_TURBOMOUSE5 5 /* Turbomouse 5 (previously req. mousehack) */
273 #define ADBMOUSE_MICROSPEED 6 /* Microspeed mouse (&trackball ?), MacPoint */
274 #define ADBMOUSE_TRACKBALLPRO 7 /* Trackball Pro (special buttons) */
275 #define ADBMOUSE_MS_A3 8 /* Mouse systems A3 trackball (handler 3) */
276 #define ADBMOUSE_MACALLY2 9 /* MacAlly 2-button mouse */
277
278 static int adb_mouse_kinds[16];
279
mackbd_setkeycode(unsigned int scancode,unsigned int keycode)280 int mackbd_setkeycode(unsigned int scancode, unsigned int keycode)
281 {
282 return -EINVAL;
283 }
284
mackbd_getkeycode(unsigned int scancode)285 int mackbd_getkeycode(unsigned int scancode)
286 {
287 return -EINVAL;
288 }
289
mackbd_translate(unsigned char keycode,unsigned char * keycodep,char raw_mode)290 int mackbd_translate(unsigned char keycode, unsigned char *keycodep,
291 char raw_mode)
292 {
293 if (!raw_mode) {
294 /*
295 * Convert R-shift/control/option to L version.
296 */
297 switch (keycode) {
298 case 0x7b: keycode = 0x38; break; /* R-shift */
299 case 0x7c: keycode = 0x3a; break; /* R-option */
300 case 0x7d: keycode = 0x36; break; /* R-control */
301 }
302 }
303 *keycodep = keycode;
304 return 1;
305 }
306
mackbd_unexpected_up(unsigned char keycode)307 char mackbd_unexpected_up(unsigned char keycode)
308 {
309 return 0x80;
310 }
311
312 static void
keyboard_input(unsigned char * data,int nb,struct pt_regs * regs,int apoll)313 keyboard_input(unsigned char *data, int nb, struct pt_regs *regs, int apoll)
314 {
315 /* first check this is from register 0 */
316 if (nb != 3 || (data[0] & 3) != KEYB_KEYREG)
317 return; /* ignore it */
318 kbd_pt_regs = regs;
319 input_keycode(data[1], 0);
320 if (!(data[2] == 0xff || (data[2] == 0x7f && data[1] == 0x7f)))
321 input_keycode(data[2], 0);
322 }
323
324 static void
input_keycode(int keycode,int repeat)325 input_keycode(int keycode, int repeat)
326 {
327 struct kbd_struct *kbd;
328 int up_flag;
329
330 kbd = kbd_table + fg_console;
331 up_flag = (keycode & 0x80);
332 keycode &= 0x7f;
333
334 /* on the powerbook 3400, the power key gives code 0x7e */
335 if (keycode == 0x7e)
336 keycode = 0x7f;
337 /* remap the "Fn" key of the PowerBook G3 Series to 0x48
338 to avoid conflict with button emulation */
339 if (keycode == 0x3f)
340 keycode = 0x48;
341
342 if (!repeat)
343 del_timer(&repeat_timer);
344
345 #ifdef CONFIG_ADBMOUSE
346 /*
347 * XXX: Add mouse button 2+3 fake codes here if mouse open.
348 * Keep track of 'button' states here as we only send
349 * single up/down events!
350 * Really messy; might need to check if keyboard is in
351 * VC_RAW mode.
352 * Might also want to know how many buttons need to be emulated.
353 * -> hide this as function in arch/m68k/mac ?
354 */
355 if (adb_emulate_buttons
356 && (keycode == adb_button2_keycode
357 || keycode == adb_button3_keycode)
358 && (adb_mouse_interrupt_hook || console_loglevel == 10)) {
359 int button;
360 /* faked ADB packet */
361 static unsigned char data[4] = { 0, 0x80, 0x80, 0x80 };
362
363 button = keycode == adb_button2_keycode? 2: 3;
364 if (data[button] != up_flag) {
365 /* send a fake mouse packet */
366 data[button] = up_flag;
367 if (console_loglevel >= 8)
368 printk("fake mouse event: %x %x %x\n",
369 data[1], data[2], data[3]);
370 if (adb_mouse_interrupt_hook)
371 adb_mouse_interrupt_hook(data, 4);
372 }
373 return;
374 }
375 #endif /* CONFIG_ADBMOUSE */
376
377 if (kbd->kbdmode != VC_RAW) {
378 if (!up_flag && !dont_repeat[keycode]) {
379 last_keycode = keycode;
380 repeat_timer.expires = jiffies + (repeat? HZ/15: HZ/2);
381 add_timer(&repeat_timer);
382 }
383
384 /*
385 * adb kludge!! Imitate pc caps lock behaviour by
386 * generating an up/down event for each time caps
387 * is pressed/released. Also, makes sure that the
388 * LED are handled. atong@uiuc.edu
389 */
390 switch (keycode) {
391 /*case 0xb9:*/
392 case 0x39:
393 handle_scancode(0x39, 1);
394 handle_scancode(0x39, 0);
395 tasklet_schedule(&keyboard_tasklet);
396 return;
397 case 0x47:
398 /*case 0xc7:*/
399 tasklet_schedule(&keyboard_tasklet);
400 break;
401 }
402 }
403
404 handle_scancode(keycode, !up_flag);
405 tasklet_schedule(&keyboard_tasklet);
406 }
407
408 static void
kbd_repeat(unsigned long xxx)409 kbd_repeat(unsigned long xxx)
410 {
411 unsigned long flags;
412
413 save_flags(flags);
414 cli();
415 input_keycode(last_keycode, 1);
416 restore_flags(flags);
417 }
418
mac_put_queue(int ch)419 static void mac_put_queue(int ch)
420 {
421 extern struct tty_driver console_driver;
422 struct tty_struct *tty;
423
424 tty = console_driver.table? console_driver.table[fg_console]: NULL;
425 if (tty) {
426 tty_insert_flip_char(tty, ch, 0);
427 con_schedule_flip(tty);
428 }
429 }
430
431 #ifdef CONFIG_ADBMOUSE
432 static void
mouse_input(unsigned char * data,int nb,struct pt_regs * regs,int autopoll)433 mouse_input(unsigned char *data, int nb, struct pt_regs *regs, int autopoll)
434 {
435 /* [ACA:23-Mar-97] Three button mouse support. This is designed to
436 function with MkLinux DR-2.1 style X servers. It only works with
437 three-button mice that conform to Apple's multi-button mouse
438 protocol. */
439
440 /*
441 The X server for MkLinux DR2.1 uses the following unused keycodes to
442 read the mouse:
443
444 0x7e This indicates that the next two keycodes should be interpreted
445 as mouse information. The first following byte's high bit
446 represents the state of the left button. The lower seven bits
447 represent the x-axis acceleration. The lower seven bits of the
448 second byte represent y-axis acceleration.
449
450 0x3f The x server interprets this keycode as a middle button
451 release.
452
453 0xbf The x server interprets this keycode as a middle button
454 depress.
455
456 0x40 The x server interprets this keycode as a right button
457 release.
458
459 0xc0 The x server interprets this keycode as a right button
460 depress.
461
462 NOTES: There should be a better way of handling mice in the X server.
463 The MOUSE_ESCAPE code (0x7e) should be followed by three bytes instead
464 of two. The three mouse buttons should then, in the X server, be read
465 as the high-bits of all three bytes. The x and y motions can still be
466 in the first two bytes. Maybe I'll do this...
467 */
468
469 /*
470 Handler 1 -- 100cpi original Apple mouse protocol.
471 Handler 2 -- 200cpi original Apple mouse protocol.
472
473 For Apple's standard one-button mouse protocol the data array will
474 contain the following values:
475
476 BITS COMMENTS
477 data[0] = dddd 1100 ADB command: Talk, register 0, for device dddd.
478 data[1] = bxxx xxxx First button and x-axis motion.
479 data[2] = byyy yyyy Second button and y-axis motion.
480
481 Handler 4 -- Apple Extended mouse protocol.
482
483 For Apple's 3-button mouse protocol the data array will contain the
484 following values:
485
486 BITS COMMENTS
487 data[0] = dddd 1100 ADB command: Talk, register 0, for device dddd.
488 data[1] = bxxx xxxx Left button and x-axis motion.
489 data[2] = byyy yyyy Second button and y-axis motion.
490 data[3] = byyy bxxx Third button and fourth button. Y is additional
491 high bits of y-axis motion. XY is additional
492 high bits of x-axis motion.
493
494 MacAlly 2-button mouse protocol.
495
496 For MacAlly 2-button mouse protocol the data array will contain the
497 following values:
498
499 BITS COMMENTS
500 data[0] = dddd 1100 ADB command: Talk, register 0, for device dddd.
501 data[1] = bxxx xxxx Left button and x-axis motion.
502 data[2] = byyy yyyy Right button and y-axis motion.
503 data[3] = ???? ???? unknown
504 data[4] = ???? ???? unknown
505
506 */
507 struct kbd_struct *kbd;
508
509 /* If it's a trackpad, we alias the second button to the first.
510 NOTE: Apple sends an ADB flush command to the trackpad when
511 the first (the real) button is released. We could do
512 this here using async flush requests.
513 */
514 switch (adb_mouse_kinds[(data[0]>>4) & 0xf])
515 {
516 case ADBMOUSE_TRACKPAD:
517 data[1] = (data[1] & 0x7f) | ((data[1] & data[2]) & 0x80);
518 data[2] = data[2] | 0x80;
519 break;
520 case ADBMOUSE_MICROSPEED:
521 data[1] = (data[1] & 0x7f) | ((data[3] & 0x01) << 7);
522 data[2] = (data[2] & 0x7f) | ((data[3] & 0x02) << 6);
523 data[3] = (data[3] & 0x77) | ((data[3] & 0x04) << 5)
524 | (data[3] & 0x08);
525 break;
526 case ADBMOUSE_TRACKBALLPRO:
527 data[1] = (data[1] & 0x7f) | (((data[3] & 0x04) << 5)
528 & ((data[3] & 0x08) << 4));
529 data[2] = (data[2] & 0x7f) | ((data[3] & 0x01) << 7);
530 data[3] = (data[3] & 0x77) | ((data[3] & 0x02) << 6);
531 break;
532 case ADBMOUSE_MS_A3:
533 data[1] = (data[1] & 0x7f) | ((data[3] & 0x01) << 7);
534 data[2] = (data[2] & 0x7f) | ((data[3] & 0x02) << 6);
535 data[3] = ((data[3] & 0x04) << 5);
536 break;
537 case ADBMOUSE_MACALLY2:
538 data[3] = (data[2] & 0x80) ? 0x80 : 0x00;
539 data[2] |= 0x80; /* Right button is mapped as button 3 */
540 nb=4;
541 break;
542 }
543
544 if (adb_mouse_interrupt_hook)
545 adb_mouse_interrupt_hook(data, nb);
546
547 kbd = kbd_table + fg_console;
548
549 /* Only send mouse codes when keyboard is in raw mode. */
550 if (kbd->kbdmode == VC_RAW) {
551 static unsigned char uch_ButtonStateSecond = 0x80;
552 unsigned char uchButtonSecond;
553
554 /* Send first button, second button and movement. */
555 mac_put_queue(0x7e);
556 mac_put_queue(data[1]);
557 mac_put_queue(data[2]);
558
559 /* [ACA: Are there any two-button ADB mice that use handler 1 or 2?] */
560
561 /* Store the button state. */
562 uchButtonSecond = (data[2] & 0x80);
563
564 /* Send second button. */
565 if (uchButtonSecond != uch_ButtonStateSecond) {
566 mac_put_queue(0x3f | uchButtonSecond);
567 uch_ButtonStateSecond = uchButtonSecond;
568 }
569
570 /* Macintosh 3-button mouse (handler 4). */
571 if (nb >= 4) {
572 static unsigned char uch_ButtonStateThird = 0x80;
573 unsigned char uchButtonThird;
574
575 /* Store the button state for speed. */
576 uchButtonThird = (data[3] & 0x80);
577
578 /* Send third button. */
579 if (uchButtonThird != uch_ButtonStateThird) {
580 mac_put_queue(0x40 | uchButtonThird);
581 uch_ButtonStateThird = uchButtonThird;
582 }
583 }
584 }
585 }
586 #endif /* CONFIG_ADBMOUSE */
587
588 static void
buttons_input(unsigned char * data,int nb,struct pt_regs * regs,int autopoll)589 buttons_input(unsigned char *data, int nb, struct pt_regs *regs, int autopoll)
590 {
591 #ifdef CONFIG_PMAC_BACKLIGHT
592 int backlight = get_backlight_level();
593
594 /*
595 * XXX: Where is the contrast control for the passive?
596 * -- Cort
597 */
598
599 /* Ignore data from register other than 0 */
600 if ((data[0] & 0x3) || (nb < 2))
601 return;
602
603 switch (data[1]) {
604 case 0x8: /* mute */
605 break;
606
607 case 0x7: /* contrast decrease */
608 break;
609
610 case 0x6: /* contrast increase */
611 break;
612
613 case 0xa: /* brightness decrease */
614 if (backlight < 0)
615 break;
616 if (backlight > BACKLIGHT_OFF)
617 set_backlight_level(backlight-1);
618 else
619 set_backlight_level(BACKLIGHT_OFF);
620 break;
621
622 case 0x9: /* brightness increase */
623 if (backlight < 0)
624 break;
625 if (backlight < BACKLIGHT_MAX)
626 set_backlight_level(backlight+1);
627 else
628 set_backlight_level(BACKLIGHT_MAX);
629 break;
630 }
631 #endif /* CONFIG_PMAC_BACKLIGHT */
632 }
633
634 /* Map led flags as defined in kbd_kern.h to bits for Apple keyboard. */
635 static unsigned char mac_ledmap[8] = {
636 0, /* none */
637 4, /* scroll lock */
638 1, /* num lock */
639 5, /* scroll + num lock */
640 2, /* caps lock */
641 6, /* caps + scroll lock */
642 3, /* caps + num lock */
643 7, /* caps + num + scroll lock */
644 };
645
646 static struct adb_request led_request;
647 static int leds_pending[16];
648 static int pending_devs[16];
649 static int pending_led_start=0;
650 static int pending_led_end=0;
651
real_mackbd_leds(unsigned char leds,int device)652 static void real_mackbd_leds(unsigned char leds, int device)
653 {
654 if (led_request.complete) {
655 adb_request(&led_request, leds_done, 0, 3,
656 ADB_WRITEREG(device, KEYB_LEDREG), 0xff,
657 ~mac_ledmap[leds]);
658 } else {
659 if (!(leds_pending[device] & 0x100)) {
660 pending_devs[pending_led_end] = device;
661 pending_led_end++;
662 pending_led_end = (pending_led_end < 16) ? pending_led_end : 0;
663 }
664 leds_pending[device] = leds | 0x100;
665 }
666 }
667
mackbd_leds(unsigned char leds)668 void mackbd_leds(unsigned char leds)
669 {
670 int i;
671
672 for(i = 0; i < keyboard_ids.nids; i++)
673 real_mackbd_leds(leds,keyboard_ids.id[i]);
674 }
675
leds_done(struct adb_request * req)676 static void leds_done(struct adb_request *req)
677 {
678 int leds,device;
679
680 if (pending_led_start != pending_led_end) {
681 device = pending_devs[pending_led_start];
682 leds = leds_pending[device] & 0xff;
683 leds_pending[device] = 0;
684 pending_led_start++;
685 pending_led_start = (pending_led_start < 16) ? pending_led_start : 0;
686 real_mackbd_leds(leds,device);
687 }
688
689 }
690
mackbd_init_hw(void)691 void __init mackbd_init_hw(void)
692 {
693 #ifdef CONFIG_PPC
694 if ( (_machine != _MACH_chrp) && (_machine != _MACH_Pmac) )
695 return;
696 #endif
697 #ifdef CONFIG_MAC
698 if (!MACH_IS_MAC)
699 return;
700 #endif
701
702 /* setup key map */
703 memcpy(key_maps[0], macplain_map, sizeof(plain_map));
704 memcpy(key_maps[1], macshift_map, sizeof(plain_map));
705 memcpy(key_maps[2], macaltgr_map, sizeof(plain_map));
706 memcpy(key_maps[4], macctrl_map, sizeof(plain_map));
707 memcpy(key_maps[5], macshift_ctrl_map, sizeof(plain_map));
708 memcpy(key_maps[8], macalt_map, sizeof(plain_map));
709 memcpy(key_maps[12], macctrl_alt_map, sizeof(plain_map));
710
711 #ifdef CONFIG_ADBMOUSE
712 /* initialize mouse interrupt hook */
713 adb_mouse_interrupt_hook = NULL;
714 #endif
715
716 led_request.complete = 1;
717
718 mackeyb_probe();
719
720 notifier_chain_register(&adb_client_list, &mackeyb_adb_notifier);
721 }
722
723 static int
adb_message_handler(struct notifier_block * this,unsigned long code,void * x)724 adb_message_handler(struct notifier_block *this, unsigned long code, void *x)
725 {
726 unsigned long flags;
727
728 switch (code) {
729 case ADB_MSG_PRE_RESET:
730 case ADB_MSG_POWERDOWN:
731 /* Stop the repeat timer. Autopoll is already off at this point */
732 save_flags(flags);
733 cli();
734 del_timer(&repeat_timer);
735 restore_flags(flags);
736
737 /* Stop pending led requests */
738 while(!led_request.complete)
739 adb_poll();
740 break;
741
742 case ADB_MSG_POST_RESET:
743 mackeyb_probe();
744 break;
745 }
746 return NOTIFY_DONE;
747 }
748
749 static void
mackeyb_probe(void)750 mackeyb_probe(void)
751 {
752 struct adb_request req;
753 int i;
754
755 #ifdef CONFIG_ADBMOUSE
756 adb_register(ADB_MOUSE, 0, &mouse_ids, mouse_input);
757 #endif /* CONFIG_ADBMOUSE */
758
759 adb_register(ADB_KEYBOARD, 0, &keyboard_ids, keyboard_input);
760 adb_register(0x07, 0x1F, &buttons_ids, buttons_input);
761
762 for (i = 0; i < keyboard_ids.nids; i++) {
763 int id = keyboard_ids.id[i];
764
765 /* turn off all leds */
766 adb_request(&req, NULL, ADBREQ_SYNC, 3,
767 ADB_WRITEREG(id, KEYB_LEDREG), 0xff, 0xff);
768
769 /* Enable full feature set of the keyboard
770 ->get it to send separate codes for left and right shift,
771 control, option keys */
772 #if 0 /* handler 5 doesn't send separate codes for R modifiers */
773 if (adb_try_handler_change(id, 5))
774 printk("ADB keyboard at %d, handler set to 5\n", id);
775 else
776 #endif
777 if (adb_try_handler_change(id, 3))
778 printk("ADB keyboard at %d, handler set to 3\n", id);
779 else
780 printk("ADB keyboard at %d, handler 1\n", id);
781 }
782
783 /* Try to switch all mice to handler 4, or 2 for three-button
784 mode and full resolution. */
785 for (i = 0; i < mouse_ids.nids; i++) {
786 int id = mouse_ids.id[i];
787 if (adb_try_handler_change(id, 4)) {
788 printk("ADB mouse at %d, handler set to 4", id);
789 adb_mouse_kinds[id] = ADBMOUSE_EXTENDED;
790 }
791 else if (adb_try_handler_change(id, 0x2F)) {
792 printk("ADB mouse at %d, handler set to 0x2F", id);
793 adb_mouse_kinds[id] = ADBMOUSE_MICROSPEED;
794 }
795 else if (adb_try_handler_change(id, 0x42)) {
796 printk("ADB mouse at %d, handler set to 0x42", id);
797 adb_mouse_kinds[id] = ADBMOUSE_TRACKBALLPRO;
798 }
799 else if (adb_try_handler_change(id, 0x66)) {
800 printk("ADB mouse at %d, handler set to 0x66", id);
801 adb_mouse_kinds[id] = ADBMOUSE_MICROSPEED;
802 }
803 else if (adb_try_handler_change(id, 0x5F)) {
804 printk("ADB mouse at %d, handler set to 0x5F", id);
805 adb_mouse_kinds[id] = ADBMOUSE_MICROSPEED;
806 }
807 else if (adb_try_handler_change(id, 3)) {
808 printk("ADB mouse at %d, handler set to 3", id);
809 adb_mouse_kinds[id] = ADBMOUSE_MS_A3;
810 }
811 else if (adb_try_handler_change(id, 2)) {
812 printk("ADB mouse at %d, handler set to 2", id);
813 adb_mouse_kinds[id] = ADBMOUSE_STANDARD_200;
814 }
815 else {
816 printk("ADB mouse at %d, handler 1", id);
817 adb_mouse_kinds[id] = ADBMOUSE_STANDARD_100;
818 }
819
820 if ((adb_mouse_kinds[id] == ADBMOUSE_TRACKBALLPRO)
821 || (adb_mouse_kinds[id] == ADBMOUSE_MICROSPEED)) {
822 init_microspeed(id);
823 } else if (adb_mouse_kinds[id] == ADBMOUSE_MS_A3) {
824 init_ms_a3(id);
825 } else if (adb_mouse_kinds[id] == ADBMOUSE_EXTENDED) {
826 /*
827 * Register 1 is usually used for device
828 * identification. Here, we try to identify
829 * a known device and call the appropriate
830 * init function.
831 */
832 adb_request(&req, NULL, ADBREQ_SYNC | ADBREQ_REPLY, 1,
833 ADB_READREG(id, 1));
834
835 if ((req.reply_len) &&
836 (req.reply[1] == 0x9a) && ((req.reply[2] == 0x21)
837 || (req.reply[2] == 0x20)))
838 init_trackball(id);
839 else if ((req.reply_len >= 4) &&
840 (req.reply[1] == 0x74) && (req.reply[2] == 0x70) &&
841 (req.reply[3] == 0x61) && (req.reply[4] == 0x64))
842 init_trackpad(id);
843 else if ((req.reply_len >= 4) &&
844 (req.reply[1] == 0x4b) && (req.reply[2] == 0x4d) &&
845 (req.reply[3] == 0x4c) && (req.reply[4] == 0x31))
846 init_turbomouse(id);
847 else if ((req.reply_len == 9) &&
848 (req.reply[1] == 0x4b) && (req.reply[2] == 0x4f) &&
849 (req.reply[3] == 0x49) && (req.reply[4] == 0x54)){
850 if (adb_try_handler_change(id, 0x42)) {
851 printk("\nADB MacAlly 2-button mouse at %d, handler set to 0x42", id);
852 adb_mouse_kinds[id] = ADBMOUSE_MACALLY2;
853 }
854 }
855 }
856 printk("\n");
857 }
858 }
859
860 static void
init_trackpad(int id)861 init_trackpad(int id)
862 {
863 struct adb_request req;
864 unsigned char r1_buffer[8];
865
866 printk(" (trackpad)");
867
868 adb_mouse_kinds[id] = ADBMOUSE_TRACKPAD;
869
870 adb_request(&req, NULL, ADBREQ_SYNC | ADBREQ_REPLY, 1,
871 ADB_READREG(id,1));
872 if (req.reply_len < 8)
873 printk("bad length for reg. 1\n");
874 else
875 {
876 memcpy(r1_buffer, &req.reply[1], 8);
877 adb_request(&req, NULL, ADBREQ_SYNC, 9,
878 ADB_WRITEREG(id,1),
879 r1_buffer[0],
880 r1_buffer[1],
881 r1_buffer[2],
882 r1_buffer[3],
883 r1_buffer[4],
884 r1_buffer[5],
885 0x0d, /*r1_buffer[6],*/
886 r1_buffer[7]);
887
888 adb_request(&req, NULL, ADBREQ_SYNC, 9,
889 ADB_WRITEREG(id,2),
890 0x99,
891 0x94,
892 0x19,
893 0xff,
894 0xb2,
895 0x8a,
896 0x1b,
897 0x50);
898
899 adb_request(&req, NULL, ADBREQ_SYNC, 9,
900 ADB_WRITEREG(id,1),
901 r1_buffer[0],
902 r1_buffer[1],
903 r1_buffer[2],
904 r1_buffer[3],
905 r1_buffer[4],
906 r1_buffer[5],
907 0x03, /*r1_buffer[6],*/
908 r1_buffer[7]);
909
910 /* Without this flush, the trackpad may be locked up */
911 adb_request(&req, NULL, ADBREQ_SYNC, 1, ADB_FLUSH(id));
912 }
913 }
914
915 static void
init_trackball(int id)916 init_trackball(int id)
917 {
918 struct adb_request req;
919
920 printk(" (trackman/mouseman)");
921
922 adb_mouse_kinds[id] = ADBMOUSE_TRACKBALL;
923
924 adb_request(&req, NULL, ADBREQ_SYNC, 3,
925 ADB_WRITEREG(id,1), 00,0x81);
926
927 adb_request(&req, NULL, ADBREQ_SYNC, 3,
928 ADB_WRITEREG(id,1), 01,0x81);
929
930 adb_request(&req, NULL, ADBREQ_SYNC, 3,
931 ADB_WRITEREG(id,1), 02,0x81);
932
933 adb_request(&req, NULL, ADBREQ_SYNC, 3,
934 ADB_WRITEREG(id,1), 03,0x38);
935
936 adb_request(&req, NULL, ADBREQ_SYNC, 3,
937 ADB_WRITEREG(id,1), 00,0x81);
938
939 adb_request(&req, NULL, ADBREQ_SYNC, 3,
940 ADB_WRITEREG(id,1), 01,0x81);
941
942 adb_request(&req, NULL, ADBREQ_SYNC, 3,
943 ADB_WRITEREG(id,1), 02,0x81);
944
945 adb_request(&req, NULL, ADBREQ_SYNC, 3,
946 ADB_WRITEREG(id,1), 03,0x38);
947 }
948
949 static void
init_turbomouse(int id)950 init_turbomouse(int id)
951 {
952 struct adb_request req;
953
954 printk(" (TurboMouse 5)");
955
956 adb_mouse_kinds[id] = ADBMOUSE_TURBOMOUSE5;
957
958 adb_request(&req, NULL, ADBREQ_SYNC, 1, ADB_FLUSH(id));
959
960 adb_request(&req, NULL, ADBREQ_SYNC, 1, ADB_FLUSH(3));
961
962 adb_request(&req, NULL, ADBREQ_SYNC, 9,
963 ADB_WRITEREG(3,2),
964 0xe7,
965 0x8c,
966 0,
967 0,
968 0,
969 0xff,
970 0xff,
971 0x94);
972
973 adb_request(&req, NULL, ADBREQ_SYNC, 1, ADB_FLUSH(3));
974
975 adb_request(&req, NULL, ADBREQ_SYNC, 9,
976 ADB_WRITEREG(3,2),
977 0xa5,
978 0x14,
979 0,
980 0,
981 0x69,
982 0xff,
983 0xff,
984 0x27);
985 }
986
987 static void
init_microspeed(int id)988 init_microspeed(int id)
989 {
990 struct adb_request req;
991
992 printk(" (Microspeed/MacPoint or compatible)");
993
994 adb_request(&req, NULL, ADBREQ_SYNC, 1, ADB_FLUSH(id));
995
996 /* This will initialize mice using the Microspeed, MacPoint and
997 other compatible firmware. Bit 12 enables extended protocol.
998
999 Register 1 Listen (4 Bytes)
1000 0 - 3 Button is mouse (set also for double clicking!!!)
1001 4 - 7 Button is locking (affects change speed also)
1002 8 - 11 Button changes speed
1003 12 1 = Extended mouse mode, 0 = normal mouse mode
1004 13 - 15 unused 0
1005 16 - 23 normal speed
1006 24 - 31 changed speed
1007
1008 Register 1 talk holds version and product identification information.
1009 Register 1 Talk (4 Bytes):
1010 0 - 7 Product code
1011 8 - 23 undefined, reserved
1012 24 - 31 Version number
1013
1014 Speed 0 is max. 1 to 255 set speed in increments of 1/256 of max.
1015 */
1016 adb_request(&req, NULL, ADBREQ_SYNC, 5,
1017 ADB_WRITEREG(id,1),
1018 0x20, /* alt speed = 0x20 (rather slow) */
1019 0x00, /* norm speed = 0x00 (fastest) */
1020 0x10, /* extended protocol, no speed change */
1021 0x07); /* all buttons enabled as mouse buttons, no locking */
1022
1023
1024 adb_request(&req, NULL, ADBREQ_SYNC, 1, ADB_FLUSH(id));
1025 }
1026
1027 static void
init_ms_a3(int id)1028 init_ms_a3(int id)
1029 {
1030 struct adb_request req;
1031
1032 printk(" (Mouse Systems A3 Mouse, or compatible)");
1033 adb_request(&req, NULL, ADBREQ_SYNC, 3,
1034 ADB_WRITEREG(id, 0x2),
1035 0x00,
1036 0x07);
1037
1038 adb_request(&req, NULL, ADBREQ_SYNC, 1, ADB_FLUSH(id));
1039 }
1040
1041