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
mac_hid_sysctl_keycodes(ctl_table * ctl,int write,struct file * filp,void * buffer,size_t * lenp)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
mac_hid_kbd_translate(unsigned char scancode,unsigned char * keycode,char raw_mode)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
mac_hid_kbd_unexpected_up(unsigned char keycode)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
mac_hid_keyboard_sends_linux_keycodes(void)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
mac_hid_setup(char * str)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
mac_hid_mouse_emulate_buttons(int caller,unsigned int keycode,int down)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
emumousebtn_input_register(void)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
mac_hid_init_hw(void)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 }
509