import of upstream 2.4.34.4 from kernel.org
[linux-2.4.git] / drivers / macintosh / mac_hid.c
1 /*
2  * drivers/macintosh/mac_hid.c
3  *
4  * HID support stuff for Macintosh computers.
5  *
6  * Copyright (C) 2000 Franz Sirl.
7  *
8  * Stuff inside CONFIG_MAC_ADBKEYCODES should go away during 2.5 when all
9  * major distributions are using the Linux keycodes.
10  * Stuff inside CONFIG_MAC_EMUMOUSEBTN should really be moved to userspace.
11  */
12
13 #include <linux/config.h>
14 #include <linux/init.h>
15 #include <linux/proc_fs.h>
16 #include <linux/sysctl.h>
17 #include <linux/input.h>
18 #include <linux/module.h>
19
20 #ifdef CONFIG_MAC_ADBKEYCODES
21 #include <linux/keyboard.h>
22 #include <asm/keyboard.h>
23 #include <asm/machdep.h>
24 #endif
25
26 #ifdef CONFIG_MAC_ADBKEYCODES
27 /* Simple translation table for the SysRq keys */
28
29 #ifdef CONFIG_MAGIC_SYSRQ
30 unsigned char mac_hid_kbd_sysrq_xlate[128] =
31         "asdfhgzxcv\000bqwer"                           /* 0x00 - 0x0f */
32         "yt123465=97-80o]"                              /* 0x10 - 0x1f */
33         "u[ip\rlj'k;\\,/nm."                            /* 0x20 - 0x2f */
34         "\t `\177\000\033\000\000\000\000\000\000\000\000\000\000"
35                                                         /* 0x30 - 0x3f */
36         "\000\000\000*\000+\000\000\000\000\000/\r\000-\000"
37                                                         /* 0x40 - 0x4f */
38         "\000\0000123456789\000\000\000"                /* 0x50 - 0x5f */
39         "\205\206\207\203\210\211\000\213\000\215\000\000\000\000\000\212\000\214";
40                                                         /* 0x60 - 0x6f */
41 extern unsigned char pckbd_sysrq_xlate[128];
42 #endif
43
44 static u_short macplain_map[NR_KEYS] = {
45         0xfb61, 0xfb73, 0xfb64, 0xfb66, 0xfb68, 0xfb67, 0xfb7a, 0xfb78,
46         0xfb63, 0xfb76, 0xf200, 0xfb62, 0xfb71, 0xfb77, 0xfb65, 0xfb72,
47         0xfb79, 0xfb74, 0xf031, 0xf032, 0xf033, 0xf034, 0xf036, 0xf035,
48         0xf03d, 0xf039, 0xf037, 0xf02d, 0xf038, 0xf030, 0xf05d, 0xfb6f,
49         0xfb75, 0xf05b, 0xfb69, 0xfb70, 0xf201, 0xfb6c, 0xfb6a, 0xf027,
50         0xfb6b, 0xf03b, 0xf05c, 0xf02c, 0xf02f, 0xfb6e, 0xfb6d, 0xf02e,
51         0xf009, 0xf020, 0xf060, 0xf07f, 0xf200, 0xf01b, 0xf702, 0xf703,
52         0xf700, 0xf207, 0xf701, 0xf601, 0xf602, 0xf600, 0xf603, 0xf200,
53         0xf200, 0xf310, 0xf200, 0xf30c, 0xf200, 0xf30a, 0xf200, 0xf208,
54         0xf200, 0xf200, 0xf200, 0xf30d, 0xf30e, 0xf200, 0xf30b, 0xf200,
55         0xf200, 0xf200, 0xf300, 0xf301, 0xf302, 0xf303, 0xf304, 0xf305,
56         0xf306, 0xf307, 0xf200, 0xf308, 0xf309, 0xf200, 0xf200, 0xf200,
57         0xf104, 0xf105, 0xf106, 0xf102, 0xf107, 0xf108, 0xf200, 0xf10a,
58         0xf200, 0xf10c, 0xf200, 0xf209, 0xf200, 0xf109, 0xf200, 0xf10b,
59         0xf200, 0xf11d, 0xf115, 0xf114, 0xf118, 0xf116, 0xf103, 0xf117,
60         0xf101, 0xf119, 0xf100, 0xf700, 0xf701, 0xf702, 0xf200, 0xf200,
61 };
62
63 static u_short macshift_map[NR_KEYS] = {
64         0xfb41, 0xfb53, 0xfb44, 0xfb46, 0xfb48, 0xfb47, 0xfb5a, 0xfb58,
65         0xfb43, 0xfb56, 0xf200, 0xfb42, 0xfb51, 0xfb57, 0xfb45, 0xfb52,
66         0xfb59, 0xfb54, 0xf021, 0xf040, 0xf023, 0xf024, 0xf05e, 0xf025,
67         0xf02b, 0xf028, 0xf026, 0xf05f, 0xf02a, 0xf029, 0xf07d, 0xfb4f,
68         0xfb55, 0xf07b, 0xfb49, 0xfb50, 0xf201, 0xfb4c, 0xfb4a, 0xf022,
69         0xfb4b, 0xf03a, 0xf07c, 0xf03c, 0xf03f, 0xfb4e, 0xfb4d, 0xf03e,
70         0xf009, 0xf020, 0xf07e, 0xf07f, 0xf200, 0xf01b, 0xf702, 0xf703,
71         0xf700, 0xf207, 0xf701, 0xf601, 0xf602, 0xf600, 0xf603, 0xf200,
72         0xf200, 0xf310, 0xf200, 0xf30c, 0xf200, 0xf30a, 0xf200, 0xf208,
73         0xf200, 0xf200, 0xf200, 0xf30d, 0xf30e, 0xf200, 0xf30b, 0xf200,
74         0xf200, 0xf200, 0xf300, 0xf301, 0xf302, 0xf303, 0xf304, 0xf305,
75         0xf306, 0xf307, 0xf200, 0xf308, 0xf309, 0xf200, 0xf200, 0xf200,
76         0xf10e, 0xf10f, 0xf110, 0xf10c, 0xf111, 0xf112, 0xf200, 0xf10a,
77         0xf200, 0xf10c, 0xf200, 0xf203, 0xf200, 0xf113, 0xf200, 0xf10b,
78         0xf200, 0xf11d, 0xf115, 0xf114, 0xf20b, 0xf116, 0xf10d, 0xf117,
79         0xf10b, 0xf20a, 0xf10a, 0xf700, 0xf701, 0xf702, 0xf200, 0xf200,
80 };
81
82 static u_short macaltgr_map[NR_KEYS] = {
83         0xf914, 0xfb73, 0xf917, 0xf919, 0xfb68, 0xfb67, 0xfb7a, 0xfb78,
84         0xf916, 0xfb76, 0xf200, 0xf915, 0xfb71, 0xfb77, 0xf918, 0xfb72,
85         0xfb79, 0xfb74, 0xf200, 0xf040, 0xf200, 0xf024, 0xf200, 0xf200,
86         0xf200, 0xf05d, 0xf07b, 0xf05c, 0xf05b, 0xf07d, 0xf07e, 0xfb6f,
87         0xfb75, 0xf200, 0xfb69, 0xfb70, 0xf201, 0xfb6c, 0xfb6a, 0xf200,
88         0xfb6b, 0xf200, 0xf200, 0xf200, 0xf200, 0xfb6e, 0xfb6d, 0xf200,
89         0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf702, 0xf703,
90         0xf700, 0xf207, 0xf701, 0xf601, 0xf602, 0xf600, 0xf603, 0xf200,
91         0xf200, 0xf310, 0xf200, 0xf30c, 0xf200, 0xf30a, 0xf200, 0xf208,
92         0xf200, 0xf200, 0xf200, 0xf30d, 0xf30e, 0xf200, 0xf30b, 0xf200,
93         0xf200, 0xf200, 0xf90a, 0xf90b, 0xf90c, 0xf90d, 0xf90e, 0xf90f,
94         0xf910, 0xf911, 0xf200, 0xf912, 0xf913, 0xf200, 0xf200, 0xf200,
95         0xf510, 0xf511, 0xf512, 0xf50e, 0xf513, 0xf514, 0xf200, 0xf516,
96         0xf200, 0xf10c, 0xf200, 0xf202, 0xf200, 0xf515, 0xf200, 0xf517,
97         0xf200, 0xf11d, 0xf115, 0xf114, 0xf118, 0xf116, 0xf50f, 0xf117,
98         0xf50d, 0xf119, 0xf50c, 0xf700, 0xf701, 0xf702, 0xf200, 0xf200,
99 };
100
101 static u_short macctrl_map[NR_KEYS] = {
102         0xf001, 0xf013, 0xf004, 0xf006, 0xf008, 0xf007, 0xf01a, 0xf018,
103         0xf003, 0xf016, 0xf200, 0xf002, 0xf011, 0xf017, 0xf005, 0xf012,
104         0xf019, 0xf014, 0xf200, 0xf000, 0xf01b, 0xf01c, 0xf01e, 0xf01d,
105         0xf200, 0xf200, 0xf01f, 0xf01f, 0xf07f, 0xf200, 0xf01d, 0xf00f,
106         0xf015, 0xf01b, 0xf009, 0xf010, 0xf201, 0xf00c, 0xf00a, 0xf007,
107         0xf00b, 0xf200, 0xf01c, 0xf200, 0xf07f, 0xf00e, 0xf00d, 0xf20e,
108         0xf200, 0xf000, 0xf000, 0xf008, 0xf200, 0xf200, 0xf702, 0xf703,
109         0xf700, 0xf207, 0xf701, 0xf601, 0xf602, 0xf600, 0xf603, 0xf200,
110         0xf200, 0xf310, 0xf200, 0xf30c, 0xf200, 0xf30a, 0xf200, 0xf208,
111         0xf200, 0xf200, 0xf200, 0xf30d, 0xf30e, 0xf200, 0xf30b, 0xf200,
112         0xf200, 0xf200, 0xf300, 0xf301, 0xf302, 0xf303, 0xf304, 0xf305,
113         0xf306, 0xf307, 0xf200, 0xf308, 0xf309, 0xf200, 0xf200, 0xf200,
114         0xf104, 0xf105, 0xf106, 0xf102, 0xf107, 0xf108, 0xf200, 0xf10a,
115         0xf200, 0xf10c, 0xf200, 0xf204, 0xf200, 0xf109, 0xf200, 0xf10b,
116         0xf200, 0xf11d, 0xf115, 0xf114, 0xf118, 0xf116, 0xf103, 0xf117,
117         0xf101, 0xf119, 0xf100, 0xf700, 0xf701, 0xf702, 0xf200, 0xf200,
118 };
119
120 static u_short macshift_ctrl_map[NR_KEYS] = {
121         0xf001, 0xf013, 0xf004, 0xf006, 0xf008, 0xf007, 0xf01a, 0xf018,
122         0xf003, 0xf016, 0xf200, 0xf002, 0xf011, 0xf017, 0xf005, 0xf012,
123         0xf019, 0xf014, 0xf200, 0xf000, 0xf200, 0xf200, 0xf200, 0xf200,
124         0xf200, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf200, 0xf200, 0xf00f,
125         0xf015, 0xf200, 0xf009, 0xf010, 0xf201, 0xf00c, 0xf00a, 0xf200,
126         0xf00b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf00e, 0xf00d, 0xf200,
127         0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf702, 0xf703,
128         0xf700, 0xf207, 0xf701, 0xf601, 0xf602, 0xf600, 0xf603, 0xf200,
129         0xf200, 0xf310, 0xf200, 0xf30c, 0xf200, 0xf30a, 0xf200, 0xf208,
130         0xf200, 0xf200, 0xf200, 0xf30d, 0xf30e, 0xf200, 0xf30b, 0xf200,
131         0xf200, 0xf200, 0xf300, 0xf301, 0xf302, 0xf303, 0xf304, 0xf305,
132         0xf306, 0xf307, 0xf200, 0xf308, 0xf309, 0xf200, 0xf200, 0xf200,
133         0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
134         0xf200, 0xf10c, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
135         0xf200, 0xf11d, 0xf115, 0xf114, 0xf118, 0xf116, 0xf200, 0xf117,
136         0xf200, 0xf119, 0xf200, 0xf700, 0xf701, 0xf702, 0xf200, 0xf20c,
137 };
138
139 static u_short macalt_map[NR_KEYS] = {
140         0xf861, 0xf873, 0xf864, 0xf866, 0xf868, 0xf867, 0xf87a, 0xf878,
141         0xf863, 0xf876, 0xf200, 0xf862, 0xf871, 0xf877, 0xf865, 0xf872,
142         0xf879, 0xf874, 0xf831, 0xf832, 0xf833, 0xf834, 0xf836, 0xf835,
143         0xf83d, 0xf839, 0xf837, 0xf82d, 0xf838, 0xf830, 0xf85d, 0xf86f,
144         0xf875, 0xf85b, 0xf869, 0xf870, 0xf80d, 0xf86c, 0xf86a, 0xf827,
145         0xf86b, 0xf83b, 0xf85c, 0xf82c, 0xf82f, 0xf86e, 0xf86d, 0xf82e,
146         0xf809, 0xf820, 0xf860, 0xf87f, 0xf200, 0xf81b, 0xf702, 0xf703,
147         0xf700, 0xf207, 0xf701, 0xf210, 0xf211, 0xf600, 0xf603, 0xf200,
148         0xf200, 0xf310, 0xf200, 0xf30c, 0xf200, 0xf30a, 0xf200, 0xf208,
149         0xf200, 0xf200, 0xf200, 0xf30d, 0xf30e, 0xf200, 0xf30b, 0xf200,
150         0xf200, 0xf200, 0xf900, 0xf901, 0xf902, 0xf903, 0xf904, 0xf905,
151         0xf906, 0xf907, 0xf200, 0xf908, 0xf909, 0xf200, 0xf200, 0xf200,
152         0xf504, 0xf505, 0xf506, 0xf502, 0xf507, 0xf508, 0xf200, 0xf50a,
153         0xf200, 0xf10c, 0xf200, 0xf209, 0xf200, 0xf509, 0xf200, 0xf50b,
154         0xf200, 0xf11d, 0xf115, 0xf114, 0xf118, 0xf116, 0xf503, 0xf117,
155         0xf501, 0xf119, 0xf500, 0xf700, 0xf701, 0xf702, 0xf200, 0xf200,
156 };
157
158 static u_short macctrl_alt_map[NR_KEYS] = {
159         0xf801, 0xf813, 0xf804, 0xf806, 0xf808, 0xf807, 0xf81a, 0xf818,
160         0xf803, 0xf816, 0xf200, 0xf802, 0xf811, 0xf817, 0xf805, 0xf812,
161         0xf819, 0xf814, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
162         0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf80f,
163         0xf815, 0xf200, 0xf809, 0xf810, 0xf201, 0xf80c, 0xf80a, 0xf200,
164         0xf80b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf80e, 0xf80d, 0xf200,
165         0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf702, 0xf703,
166         0xf700, 0xf207, 0xf701, 0xf601, 0xf602, 0xf600, 0xf603, 0xf200,
167         0xf200, 0xf310, 0xf200, 0xf30c, 0xf200, 0xf30a, 0xf200, 0xf208,
168         0xf200, 0xf200, 0xf200, 0xf30d, 0xf30e, 0xf200, 0xf30b, 0xf200,
169         0xf200, 0xf200, 0xf300, 0xf301, 0xf302, 0xf303, 0xf304, 0xf305,
170         0xf306, 0xf307, 0xf200, 0xf308, 0xf309, 0xf200, 0xf200, 0xf200,
171         0xf504, 0xf505, 0xf506, 0xf502, 0xf507, 0xf508, 0xf200, 0xf50a,
172         0xf200, 0xf10c, 0xf200, 0xf200, 0xf200, 0xf509, 0xf200, 0xf50b,
173         0xf200, 0xf11d, 0xf115, 0xf114, 0xf118, 0xf116, 0xf503, 0xf117,
174         0xf501, 0xf119, 0xf500, 0xf700, 0xf701, 0xf702, 0xf200, 0xf200,
175 };
176
177 static unsigned short *mac_key_maps_save[MAX_NR_KEYMAPS] = {
178         macplain_map, macshift_map, macaltgr_map, 0,
179         macctrl_map, macshift_ctrl_map, 0, 0,
180         macalt_map, 0, 0, 0,
181         macctrl_alt_map,   0
182 };
183
184 static unsigned short *pc_key_maps_save[MAX_NR_KEYMAPS];
185
186 int mac_hid_kbd_translate(unsigned char keycode, unsigned char *keycodep,
187                           char raw_mode);
188 static int mac_hid_sysctl_keycodes(ctl_table *ctl, int write, struct file * filp,
189                                    void *buffer, size_t *lenp);
190 char mac_hid_kbd_unexpected_up(unsigned char keycode);
191
192 static int keyboard_lock_keycodes = 0;
193 int keyboard_sends_linux_keycodes = 0;
194 #else
195 int keyboard_sends_linux_keycodes = 1;
196 #endif
197
198
199 static unsigned char e0_keys[128] = {
200         0, 0, 0, KEY_KPCOMMA, 0, KEY_INTL3, 0, 0,               /* 0x00-0x07 */
201         0, 0, 0, 0, KEY_LANG1, KEY_LANG2, 0, 0,                 /* 0x08-0x0f */
202         0, 0, 0, 0, 0, 0, 0, 0,                                 /* 0x10-0x17 */
203         0, 0, 0, 0, KEY_KPENTER, KEY_RIGHTCTRL, KEY_VOLUMEUP, 0,/* 0x18-0x1f */
204         0, 0, 0, 0, 0, KEY_VOLUMEDOWN, KEY_MUTE, 0,             /* 0x20-0x27 */
205         0, 0, 0, 0, 0, 0, 0, 0,                                 /* 0x28-0x2f */
206         0, 0, 0, 0, 0, KEY_KPSLASH, 0, KEY_SYSRQ,               /* 0x30-0x37 */
207         KEY_RIGHTALT, KEY_BRIGHTNESSUP, KEY_BRIGHTNESSDOWN, 
208                 KEY_EJECTCD, 0, 0, 0, 0,                        /* 0x38-0x3f */
209         0, 0, 0, 0, 0, 0, 0, KEY_HOME,                          /* 0x40-0x47 */
210         KEY_UP, KEY_PAGEUP, 0, KEY_LEFT, 0, KEY_RIGHT, 0, KEY_END, /* 0x48-0x4f */
211         KEY_DOWN, KEY_PAGEDOWN, KEY_INSERT, KEY_DELETE, 0, 0, 0, 0, /* 0x50-0x57 */
212         0, 0, 0, KEY_LEFTMETA, KEY_RIGHTMETA, KEY_COMPOSE, KEY_POWER, 0, /* 0x58-0x5f */
213         0, 0, 0, 0, 0, 0, 0, 0,                                 /* 0x60-0x67 */
214         0, 0, 0, 0, 0, 0, 0, KEY_MACRO,                         /* 0x68-0x6f */
215         0, 0, 0, 0, 0, 0, 0, 0,                                 /* 0x70-0x77 */
216         0, 0, 0, 0, 0, 0, 0, 0                                  /* 0x78-0x7f */
217 };
218
219 #ifdef CONFIG_MAC_EMUMOUSEBTN
220 static struct input_dev emumousebtn;
221 static void emumousebtn_input_register(void);
222 static int mouse_emulate_buttons = 0;
223 static int mouse_button2_keycode = KEY_RIGHTCTRL;       /* right control key */
224 static int mouse_button3_keycode = KEY_RIGHTALT;        /* right option key */
225 static int mouse_last_keycode = 0;
226 #endif
227
228 extern void pckbd_init_hw(void);
229
230 #if defined CONFIG_SYSCTL && (defined(CONFIG_MAC_ADBKEYCODES) || defined(CONFIG_MAC_EMUMOUSEBTN))
231 /* file(s) in /proc/sys/dev/mac_hid */
232 ctl_table mac_hid_files[] =
233 {
234 #ifdef CONFIG_MAC_ADBKEYCODES
235   {
236     DEV_MAC_HID_KEYBOARD_SENDS_LINUX_KEYCODES,
237     "keyboard_sends_linux_keycodes", &keyboard_sends_linux_keycodes, sizeof(int),
238     0644, NULL, &mac_hid_sysctl_keycodes
239   },
240   {
241     DEV_MAC_HID_KEYBOARD_LOCK_KEYCODES,
242     "keyboard_lock_keycodes", &keyboard_lock_keycodes, sizeof(int),
243     0644, NULL, &proc_dointvec
244   },
245 #endif
246 #ifdef CONFIG_MAC_EMUMOUSEBTN
247   {
248     DEV_MAC_HID_MOUSE_BUTTON_EMULATION,
249     "mouse_button_emulation", &mouse_emulate_buttons, sizeof(int),
250     0644, NULL, &proc_dointvec
251   },
252   {
253     DEV_MAC_HID_MOUSE_BUTTON2_KEYCODE,
254     "mouse_button2_keycode", &mouse_button2_keycode, sizeof(int),
255     0644, NULL, &proc_dointvec
256   },
257   {
258     DEV_MAC_HID_MOUSE_BUTTON3_KEYCODE,
259     "mouse_button3_keycode", &mouse_button3_keycode, sizeof(int),
260     0644, NULL, &proc_dointvec
261   },
262 #endif
263   { 0 }
264 };
265
266 /* dir in /proc/sys/dev */
267 ctl_table mac_hid_dir[] =
268 {
269   { DEV_MAC_HID, "mac_hid", NULL, 0, 0555, mac_hid_files },
270   { 0 }
271 };
272
273 /* /proc/sys/dev itself, in case that is not there yet */
274 ctl_table mac_hid_root_dir[] =
275 {
276   { CTL_DEV, "dev", NULL, 0, 0555, mac_hid_dir },
277   { 0 }
278 };
279
280 static struct ctl_table_header *mac_hid_sysctl_header;
281
282 #ifdef CONFIG_MAC_ADBKEYCODES
283 static
284 int mac_hid_sysctl_keycodes(ctl_table *ctl, int write, struct file * filp,
285                             void *buffer, size_t *lenp)
286 {
287         int val = keyboard_sends_linux_keycodes;
288         int ret = 0;
289
290         if (!write
291             || (write && !keyboard_lock_keycodes))
292                 ret = proc_dointvec(ctl, write, filp, buffer, lenp);
293
294         if (write
295             && keyboard_sends_linux_keycodes != val) {
296                 if (!keyboard_sends_linux_keycodes) {
297 #ifdef CONFIG_MAGIC_SYSRQ
298                         ppc_md.ppc_kbd_sysrq_xlate   = mac_hid_kbd_sysrq_xlate;
299                         SYSRQ_KEY                = 0x69;
300 #endif
301                         memcpy(pc_key_maps_save, key_maps, sizeof(key_maps));
302                         memcpy(key_maps, mac_key_maps_save, sizeof(key_maps));
303                 } else {
304 #ifdef CONFIG_MAGIC_SYSRQ
305                         ppc_md.ppc_kbd_sysrq_xlate   = pckbd_sysrq_xlate;
306                         SYSRQ_KEY                = 0x54;
307 #endif
308                         memcpy(mac_key_maps_save, key_maps, sizeof(key_maps));
309                         memcpy(key_maps, pc_key_maps_save, sizeof(key_maps));
310                 }
311         }
312
313         return ret;
314 }
315 #endif
316 #endif /* endif CONFIG_SYSCTL */
317
318 int mac_hid_kbd_translate(unsigned char scancode, unsigned char *keycode,
319                           char raw_mode)
320 {
321 #ifdef CONFIG_MAC_ADBKEYCODES
322         if (!keyboard_sends_linux_keycodes) {
323                 if (!raw_mode) {
324                 /*
325                  * Convert R-shift/control/option to L version.
326                  */
327                         switch (scancode) {
328                         case 0x7b: scancode = 0x38; break; /* R-shift */
329                         case 0x7c: scancode = 0x3a; break; /* R-option */
330                         case 0x7d: scancode = 0x36; break; /* R-control */
331                         }
332                 }
333                 *keycode = scancode;
334                 return 1;
335         } else
336 #endif
337         {
338                 /* This code was copied from char/pc_keyb.c and will be
339                  * superflous when the input layer is fully integrated.
340                  * We don't need the high_keys handling, so this part
341                  * has been removed.
342                  */
343                 static int prev_scancode = 0;
344
345                 /* special prefix scancodes.. */
346                 if (scancode == 0xe0 || scancode == 0xe1) {
347                         prev_scancode = scancode;
348                         return 0;
349                 }
350
351                 scancode &= 0x7f;
352
353                 if (prev_scancode) {
354                         if (prev_scancode != 0xe0) {
355                                 if (prev_scancode == 0xe1 && scancode == 0x1d) {
356                                         prev_scancode = 0x100;
357                                         return 0;
358                                 } else if (prev_scancode == 0x100 && scancode == 0x45) {
359                                         *keycode = KEY_PAUSE;
360                                         prev_scancode = 0;
361                                 } else {
362                                         if (!raw_mode)
363                                                 printk(KERN_INFO "keyboard: unknown e1 escape sequence\n");
364                                         prev_scancode = 0;
365                                         return 0;
366                                 }
367                         } else {
368                                 prev_scancode = 0;
369                                 if (scancode == 0x2a || scancode == 0x36)
370                                         return 0;
371                         }
372                         if (e0_keys[scancode])
373                                 *keycode = e0_keys[scancode];
374                         else {
375                                 if (!raw_mode)
376                                         printk(KERN_INFO "keyboard: unknown scancode e0 %02x\n",
377                                                scancode);
378                                 return 0;
379                         }
380                 } else {
381                         switch (scancode) {
382                         case  91: scancode = KEY_LINEFEED; break;
383                         case  92: scancode = KEY_KPEQUAL; break;
384                         case 125: scancode = KEY_INTL1; break;
385                         }
386                         *keycode = scancode;
387                 }
388                 return 1;
389         }
390 }
391
392 char mac_hid_kbd_unexpected_up(unsigned char keycode)
393 {
394         if (keyboard_sends_linux_keycodes && keycode == KEY_F13)
395                 return 0;
396         else
397                 return 0x80;
398 }
399
400 #ifdef CONFIG_MAC_ADBKEYCODES
401 int mac_hid_keyboard_sends_linux_keycodes(void)
402 {
403         return keyboard_sends_linux_keycodes;
404 }
405
406 EXPORT_SYMBOL(mac_hid_keyboard_sends_linux_keycodes);
407
408 static int __init mac_hid_setup(char *str)
409 {
410         int ints[2];
411
412         str = get_options(str, ARRAY_SIZE(ints), ints);
413         if (ints[0] == 1) {
414                 keyboard_sends_linux_keycodes = ints[1] != 0;
415                 keyboard_lock_keycodes = 1;
416         }
417         return 1;
418 }
419
420 __setup("keyboard_sends_linux_keycodes=", mac_hid_setup);
421
422 #endif
423
424 #ifdef CONFIG_MAC_EMUMOUSEBTN
425 int mac_hid_mouse_emulate_buttons(int caller, unsigned int keycode, int down)
426 {
427         switch (caller) {
428         case 1:
429                 /* Called from keybdev.c */
430                 if (mouse_emulate_buttons
431                     && (keycode == mouse_button2_keycode
432                         || keycode == mouse_button3_keycode)) {
433                         if (mouse_emulate_buttons == 1) {
434                                 input_report_key(&emumousebtn,
435                                                  keycode == mouse_button2_keycode ? BTN_MIDDLE : BTN_RIGHT,
436                                                  down);
437                                 return 1;
438                         }
439                         mouse_last_keycode = down ? keycode : 0;
440                 }
441                 break;
442         case 2:
443                 /* Called from mousedev.c */
444                 if (mouse_emulate_buttons == 2 && keycode == 0) {
445                         if (mouse_last_keycode == mouse_button2_keycode)
446                                 return 1; /* map to middle button */
447                         if (mouse_last_keycode == mouse_button3_keycode)
448                                 return 2; /* map to right button */
449                 }
450                 return keycode; /* keep button */
451         }
452         return 0;
453 }
454
455 EXPORT_SYMBOL(mac_hid_mouse_emulate_buttons);
456
457 static void emumousebtn_input_register(void)
458 {
459         emumousebtn.name = "Macintosh mouse button emulation";
460
461         emumousebtn.evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
462         emumousebtn.keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
463         emumousebtn.relbit[0] = BIT(REL_X) | BIT(REL_Y);
464
465         emumousebtn.idbus = BUS_ADB;
466         emumousebtn.idvendor = 0x0001;
467         emumousebtn.idproduct = 0x0001;
468         emumousebtn.idversion = 0x0100;
469
470         input_register_device(&emumousebtn);
471
472         printk(KERN_INFO "input%d: Macintosh mouse button emulation\n", emumousebtn.number);
473 }
474 #endif
475
476 void __init mac_hid_init_hw(void)
477 {
478
479 #ifdef CONFIG_MAC_ADBKEYCODES
480         memcpy(pc_key_maps_save, key_maps, sizeof(key_maps));
481
482         if (!keyboard_sends_linux_keycodes) {
483 #ifdef CONFIG_MAGIC_SYSRQ
484                 ppc_md.ppc_kbd_sysrq_xlate   = mac_hid_kbd_sysrq_xlate;
485                 SYSRQ_KEY                = 0x69;
486 #endif
487                 memcpy(key_maps, mac_key_maps_save, sizeof(key_maps));
488         } else {
489 #ifdef CONFIG_MAGIC_SYSRQ
490                 ppc_md.ppc_kbd_sysrq_xlate   = pckbd_sysrq_xlate;
491                 SYSRQ_KEY                = 0x54;
492 #endif
493         }
494 #endif /* CONFIG_MAC_ADBKEYCODES */
495
496 #ifdef CONFIG_MAC_EMUMOUSEBTN
497         emumousebtn_input_register();
498 #endif
499
500 #if CONFIG_PPC
501         if (_machine != _MACH_Pmac)
502                 pckbd_init_hw();
503 #endif
504
505 #if defined(CONFIG_SYSCTL) && (defined(CONFIG_MAC_ADBKEYCODES) || defined(CONFIG_MAC_EMUMOUSEBTN))
506         mac_hid_sysctl_header = register_sysctl_table(mac_hid_root_dir, 1);
507 #endif /* CONFIG_SYSCTL */
508 }