2 * drivers/char/mac_keyb.c
4 * Keyboard driver for Power Macintosh computers.
6 * Adapted from drivers/char/keyboard.c by Paul Mackerras
7 * (see that file for its authors and contributors).
9 * Copyright (C) 1996 Paul Mackerras.
11 * Adapted to ADB changes and support for more devices by
12 * Benjamin Herrenschmidt. Adapted from code in MkLinux
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>
31 * Improve Kensignton support, add MacX support as a dynamic
32 * option (not a compile-time option).
35 #include <linux/sched.h>
36 #include <linux/interrupt.h>
37 #include <linux/tty.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>
46 #include <asm/bitops.h>
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>
54 #ifdef CONFIG_PMAC_BACKLIGHT
55 #include <asm/backlight.h>
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 */
62 static int adb_message_handler(struct notifier_block *, unsigned long, void *);
63 static struct notifier_block mackeyb_adb_notifier = {
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 */
81 /* Simple translation table for the SysRq keys */
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"
90 "\000\000\000*\000+\000\000\000\000\000/\r\000-\000"
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";
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,
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,
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,
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,
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,
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,
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,
231 static void kbd_repeat(unsigned long);
232 static struct timer_list repeat_timer = { function: kbd_repeat };
233 static int last_keycode;
235 static void mackeyb_probe(void);
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);
242 static void buttons_input(unsigned char *, int, struct pt_regs *, int);
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);
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 */
258 extern struct kbd_struct kbd_table[];
260 extern void handle_scancode(unsigned char, int);
262 static struct adb_ids keyboard_ids;
263 static struct adb_ids mouse_ids;
264 static struct adb_ids buttons_ids;
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 */
278 static int adb_mouse_kinds[16];
280 int mackbd_setkeycode(unsigned int scancode, unsigned int keycode)
285 int mackbd_getkeycode(unsigned int scancode)
290 int mackbd_translate(unsigned char keycode, unsigned char *keycodep,
295 * Convert R-shift/control/option to L version.
298 case 0x7b: keycode = 0x38; break; /* R-shift */
299 case 0x7c: keycode = 0x3a; break; /* R-option */
300 case 0x7d: keycode = 0x36; break; /* R-control */
307 char mackbd_unexpected_up(unsigned char keycode)
313 keyboard_input(unsigned char *data, int nb, struct pt_regs *regs, int apoll)
315 /* first check this is from register 0 */
316 if (nb != 3 || (data[0] & 3) != KEYB_KEYREG)
317 return; /* ignore it */
319 input_keycode(data[1], 0);
320 if (!(data[2] == 0xff || (data[2] == 0x7f && data[1] == 0x7f)))
321 input_keycode(data[2], 0);
325 input_keycode(int keycode, int repeat)
327 struct kbd_struct *kbd;
330 kbd = kbd_table + fg_console;
331 up_flag = (keycode & 0x80);
334 /* on the powerbook 3400, the power key gives code 0x7e */
337 /* remap the "Fn" key of the PowerBook G3 Series to 0x48
338 to avoid conflict with button emulation */
343 del_timer(&repeat_timer);
345 #ifdef CONFIG_ADBMOUSE
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
352 * Might also want to know how many buttons need to be emulated.
353 * -> hide this as function in arch/m68k/mac ?
355 if (adb_emulate_buttons
356 && (keycode == adb_button2_keycode
357 || keycode == adb_button3_keycode)
358 && (adb_mouse_interrupt_hook || console_loglevel == 10)) {
360 /* faked ADB packet */
361 static unsigned char data[4] = { 0, 0x80, 0x80, 0x80 };
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);
375 #endif /* CONFIG_ADBMOUSE */
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);
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
393 handle_scancode(0x39, 1);
394 handle_scancode(0x39, 0);
395 tasklet_schedule(&keyboard_tasklet);
399 tasklet_schedule(&keyboard_tasklet);
404 handle_scancode(keycode, !up_flag);
405 tasklet_schedule(&keyboard_tasklet);
409 kbd_repeat(unsigned long xxx)
415 input_keycode(last_keycode, 1);
416 restore_flags(flags);
419 static void mac_put_queue(int ch)
421 extern struct tty_driver console_driver;
422 struct tty_struct *tty;
424 tty = console_driver.table? console_driver.table[fg_console]: NULL;
426 tty_insert_flip_char(tty, ch, 0);
427 con_schedule_flip(tty);
431 #ifdef CONFIG_ADBMOUSE
433 mouse_input(unsigned char *data, int nb, struct pt_regs *regs, int autopoll)
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
441 The X server for MkLinux DR2.1 uses the following unused keycodes to
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.
450 0x3f The x server interprets this keycode as a middle button
453 0xbf The x server interprets this keycode as a middle button
456 0x40 The x server interprets this keycode as a right button
459 0xc0 The x server interprets this keycode as a right button
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...
470 Handler 1 -- 100cpi original Apple mouse protocol.
471 Handler 2 -- 200cpi original Apple mouse protocol.
473 For Apple's standard one-button mouse protocol the data array will
474 contain the following values:
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.
481 Handler 4 -- Apple Extended mouse protocol.
483 For Apple's 3-button mouse protocol the data array will contain the
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.
494 MacAlly 2-button mouse protocol.
496 For MacAlly 2-button mouse protocol the data array will contain the
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
507 struct kbd_struct *kbd;
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.
514 switch (adb_mouse_kinds[(data[0]>>4) & 0xf])
516 case ADBMOUSE_TRACKPAD:
517 data[1] = (data[1] & 0x7f) | ((data[1] & data[2]) & 0x80);
518 data[2] = data[2] | 0x80;
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)
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);
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);
537 case ADBMOUSE_MACALLY2:
538 data[3] = (data[2] & 0x80) ? 0x80 : 0x00;
539 data[2] |= 0x80; /* Right button is mapped as button 3 */
544 if (adb_mouse_interrupt_hook)
545 adb_mouse_interrupt_hook(data, nb);
547 kbd = kbd_table + fg_console;
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;
554 /* Send first button, second button and movement. */
556 mac_put_queue(data[1]);
557 mac_put_queue(data[2]);
559 /* [ACA: Are there any two-button ADB mice that use handler 1 or 2?] */
561 /* Store the button state. */
562 uchButtonSecond = (data[2] & 0x80);
564 /* Send second button. */
565 if (uchButtonSecond != uch_ButtonStateSecond) {
566 mac_put_queue(0x3f | uchButtonSecond);
567 uch_ButtonStateSecond = uchButtonSecond;
570 /* Macintosh 3-button mouse (handler 4). */
572 static unsigned char uch_ButtonStateThird = 0x80;
573 unsigned char uchButtonThird;
575 /* Store the button state for speed. */
576 uchButtonThird = (data[3] & 0x80);
578 /* Send third button. */
579 if (uchButtonThird != uch_ButtonStateThird) {
580 mac_put_queue(0x40 | uchButtonThird);
581 uch_ButtonStateThird = uchButtonThird;
586 #endif /* CONFIG_ADBMOUSE */
589 buttons_input(unsigned char *data, int nb, struct pt_regs *regs, int autopoll)
591 #ifdef CONFIG_PMAC_BACKLIGHT
592 int backlight = get_backlight_level();
595 * XXX: Where is the contrast control for the passive?
599 /* Ignore data from register other than 0 */
600 if ((data[0] & 0x3) || (nb < 2))
607 case 0x7: /* contrast decrease */
610 case 0x6: /* contrast increase */
613 case 0xa: /* brightness decrease */
616 if (backlight > BACKLIGHT_OFF)
617 set_backlight_level(backlight-1);
619 set_backlight_level(BACKLIGHT_OFF);
622 case 0x9: /* brightness increase */
625 if (backlight < BACKLIGHT_MAX)
626 set_backlight_level(backlight+1);
628 set_backlight_level(BACKLIGHT_MAX);
631 #endif /* CONFIG_PMAC_BACKLIGHT */
634 /* Map led flags as defined in kbd_kern.h to bits for Apple keyboard. */
635 static unsigned char mac_ledmap[8] = {
639 5, /* scroll + num lock */
641 6, /* caps + scroll lock */
642 3, /* caps + num lock */
643 7, /* caps + num + scroll lock */
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;
652 static void real_mackbd_leds(unsigned char leds, int device)
654 if (led_request.complete) {
655 adb_request(&led_request, leds_done, 0, 3,
656 ADB_WRITEREG(device, KEYB_LEDREG), 0xff,
659 if (!(leds_pending[device] & 0x100)) {
660 pending_devs[pending_led_end] = device;
662 pending_led_end = (pending_led_end < 16) ? pending_led_end : 0;
664 leds_pending[device] = leds | 0x100;
668 void mackbd_leds(unsigned char leds)
672 for(i = 0; i < keyboard_ids.nids; i++)
673 real_mackbd_leds(leds,keyboard_ids.id[i]);
676 static void leds_done(struct adb_request *req)
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;
685 pending_led_start = (pending_led_start < 16) ? pending_led_start : 0;
686 real_mackbd_leds(leds,device);
691 void __init mackbd_init_hw(void)
694 if ( (_machine != _MACH_chrp) && (_machine != _MACH_Pmac) )
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));
711 #ifdef CONFIG_ADBMOUSE
712 /* initialize mouse interrupt hook */
713 adb_mouse_interrupt_hook = NULL;
716 led_request.complete = 1;
720 notifier_chain_register(&adb_client_list, &mackeyb_adb_notifier);
724 adb_message_handler(struct notifier_block *this, unsigned long code, void *x)
729 case ADB_MSG_PRE_RESET:
730 case ADB_MSG_POWERDOWN:
731 /* Stop the repeat timer. Autopoll is already off at this point */
734 del_timer(&repeat_timer);
735 restore_flags(flags);
737 /* Stop pending led requests */
738 while(!led_request.complete)
742 case ADB_MSG_POST_RESET:
752 struct adb_request req;
755 #ifdef CONFIG_ADBMOUSE
756 adb_register(ADB_MOUSE, 0, &mouse_ids, mouse_input);
757 #endif /* CONFIG_ADBMOUSE */
759 adb_register(ADB_KEYBOARD, 0, &keyboard_ids, keyboard_input);
760 adb_register(0x07, 0x1F, &buttons_ids, buttons_input);
762 for (i = 0; i < keyboard_ids.nids; i++) {
763 int id = keyboard_ids.id[i];
765 /* turn off all leds */
766 adb_request(&req, NULL, ADBREQ_SYNC, 3,
767 ADB_WRITEREG(id, KEYB_LEDREG), 0xff, 0xff);
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);
777 if (adb_try_handler_change(id, 3))
778 printk("ADB keyboard at %d, handler set to 3\n", id);
780 printk("ADB keyboard at %d, handler 1\n", id);
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;
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;
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;
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;
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;
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;
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;
816 printk("ADB mouse at %d, handler 1", id);
817 adb_mouse_kinds[id] = ADBMOUSE_STANDARD_100;
820 if ((adb_mouse_kinds[id] == ADBMOUSE_TRACKBALLPRO)
821 || (adb_mouse_kinds[id] == ADBMOUSE_MICROSPEED)) {
823 } else if (adb_mouse_kinds[id] == ADBMOUSE_MS_A3) {
825 } else if (adb_mouse_kinds[id] == ADBMOUSE_EXTENDED) {
827 * Register 1 is usually used for device
828 * identification. Here, we try to identify
829 * a known device and call the appropriate
832 adb_request(&req, NULL, ADBREQ_SYNC | ADBREQ_REPLY, 1,
835 if ((req.reply_len) &&
836 (req.reply[1] == 0x9a) && ((req.reply[2] == 0x21)
837 || (req.reply[2] == 0x20)))
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))
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))
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;
861 init_trackpad(int id)
863 struct adb_request req;
864 unsigned char r1_buffer[8];
866 printk(" (trackpad)");
868 adb_mouse_kinds[id] = ADBMOUSE_TRACKPAD;
870 adb_request(&req, NULL, ADBREQ_SYNC | ADBREQ_REPLY, 1,
872 if (req.reply_len < 8)
873 printk("bad length for reg. 1\n");
876 memcpy(r1_buffer, &req.reply[1], 8);
877 adb_request(&req, NULL, ADBREQ_SYNC, 9,
885 0x0d, /*r1_buffer[6],*/
888 adb_request(&req, NULL, ADBREQ_SYNC, 9,
899 adb_request(&req, NULL, ADBREQ_SYNC, 9,
907 0x03, /*r1_buffer[6],*/
910 /* Without this flush, the trackpad may be locked up */
911 adb_request(&req, NULL, ADBREQ_SYNC, 1, ADB_FLUSH(id));
916 init_trackball(int id)
918 struct adb_request req;
920 printk(" (trackman/mouseman)");
922 adb_mouse_kinds[id] = ADBMOUSE_TRACKBALL;
924 adb_request(&req, NULL, ADBREQ_SYNC, 3,
925 ADB_WRITEREG(id,1), 00,0x81);
927 adb_request(&req, NULL, ADBREQ_SYNC, 3,
928 ADB_WRITEREG(id,1), 01,0x81);
930 adb_request(&req, NULL, ADBREQ_SYNC, 3,
931 ADB_WRITEREG(id,1), 02,0x81);
933 adb_request(&req, NULL, ADBREQ_SYNC, 3,
934 ADB_WRITEREG(id,1), 03,0x38);
936 adb_request(&req, NULL, ADBREQ_SYNC, 3,
937 ADB_WRITEREG(id,1), 00,0x81);
939 adb_request(&req, NULL, ADBREQ_SYNC, 3,
940 ADB_WRITEREG(id,1), 01,0x81);
942 adb_request(&req, NULL, ADBREQ_SYNC, 3,
943 ADB_WRITEREG(id,1), 02,0x81);
945 adb_request(&req, NULL, ADBREQ_SYNC, 3,
946 ADB_WRITEREG(id,1), 03,0x38);
950 init_turbomouse(int id)
952 struct adb_request req;
954 printk(" (TurboMouse 5)");
956 adb_mouse_kinds[id] = ADBMOUSE_TURBOMOUSE5;
958 adb_request(&req, NULL, ADBREQ_SYNC, 1, ADB_FLUSH(id));
960 adb_request(&req, NULL, ADBREQ_SYNC, 1, ADB_FLUSH(3));
962 adb_request(&req, NULL, ADBREQ_SYNC, 9,
973 adb_request(&req, NULL, ADBREQ_SYNC, 1, ADB_FLUSH(3));
975 adb_request(&req, NULL, ADBREQ_SYNC, 9,
988 init_microspeed(int id)
990 struct adb_request req;
992 printk(" (Microspeed/MacPoint or compatible)");
994 adb_request(&req, NULL, ADBREQ_SYNC, 1, ADB_FLUSH(id));
996 /* This will initialize mice using the Microspeed, MacPoint and
997 other compatible firmware. Bit 12 enables extended protocol.
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
1005 16 - 23 normal speed
1006 24 - 31 changed speed
1008 Register 1 talk holds version and product identification information.
1009 Register 1 Talk (4 Bytes):
1011 8 - 23 undefined, reserved
1012 24 - 31 Version number
1014 Speed 0 is max. 1 to 255 set speed in increments of 1/256 of max.
1016 adb_request(&req, NULL, ADBREQ_SYNC, 5,
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 */
1024 adb_request(&req, NULL, ADBREQ_SYNC, 1, ADB_FLUSH(id));
1030 struct adb_request req;
1032 printk(" (Mouse Systems A3 Mouse, or compatible)");
1033 adb_request(&req, NULL, ADBREQ_SYNC, 3,
1034 ADB_WRITEREG(id, 0x2),
1038 adb_request(&req, NULL, ADBREQ_SYNC, 1, ADB_FLUSH(id));