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