1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* |
3 | * USB HID quirks support for Linux |
4 | * |
5 | * Copyright (c) 1999 Andreas Gal |
6 | * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz> |
7 | * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc |
8 | * Copyright (c) 2006-2007 Jiri Kosina |
9 | * Copyright (c) 2008 Jiri Slaby <jirislaby@gmail.com> |
10 | * Copyright (c) 2019 Paul Pawlowski <paul@mrarm.io> |
11 | */ |
12 | |
13 | /* |
14 | */ |
15 | |
16 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
17 | |
18 | #include <linux/device.h> |
19 | #include <linux/hid.h> |
20 | #include <linux/jiffies.h> |
21 | #include <linux/module.h> |
22 | #include <linux/slab.h> |
23 | #include <linux/timer.h> |
24 | #include <linux/string.h> |
25 | #include <linux/leds.h> |
26 | |
27 | #include "hid-ids.h" |
28 | |
29 | #define APPLE_RDESC_JIS BIT(0) |
30 | #define APPLE_IGNORE_MOUSE BIT(1) |
31 | #define APPLE_HAS_FN BIT(2) |
32 | /* BIT(3) reserved, was: APPLE_HIDDEV */ |
33 | #define APPLE_ISO_TILDE_QUIRK BIT(4) |
34 | #define APPLE_MIGHTYMOUSE BIT(5) |
35 | #define APPLE_INVERT_HWHEEL BIT(6) |
36 | /* BIT(7) reserved, was: APPLE_IGNORE_HIDINPUT */ |
37 | #define APPLE_NUMLOCK_EMULATION BIT(8) |
38 | #define APPLE_RDESC_BATTERY BIT(9) |
39 | #define APPLE_BACKLIGHT_CTL BIT(10) |
40 | #define APPLE_IS_NON_APPLE BIT(11) |
41 | |
42 | #define APPLE_FLAG_FKEY 0x01 |
43 | |
44 | #define HID_COUNTRY_INTERNATIONAL_ISO 13 |
45 | #define APPLE_BATTERY_TIMEOUT_MS 60000 |
46 | |
47 | static unsigned int fnmode = 3; |
48 | module_param(fnmode, uint, 0644); |
49 | MODULE_PARM_DESC(fnmode, "Mode of fn key on Apple keyboards (0 = disabled, " |
50 | "1 = fkeyslast, 2 = fkeysfirst, [3] = auto)" ); |
51 | |
52 | static int iso_layout = -1; |
53 | module_param(iso_layout, int, 0644); |
54 | MODULE_PARM_DESC(iso_layout, "Swap the backtick/tilde and greater-than/less-than keys. " |
55 | "([-1] = auto, 0 = disabled, 1 = enabled)" ); |
56 | |
57 | static unsigned int swap_opt_cmd; |
58 | module_param(swap_opt_cmd, uint, 0644); |
59 | MODULE_PARM_DESC(swap_opt_cmd, "Swap the Option (\"Alt\") and Command (\"Flag\") keys. " |
60 | "(For people who want to keep Windows PC keyboard muscle memory. " |
61 | "[0] = as-is, Mac layout. 1 = swapped, Windows layout., 2 = swapped, Swap only left side)" ); |
62 | |
63 | static unsigned int swap_ctrl_cmd; |
64 | module_param(swap_ctrl_cmd, uint, 0644); |
65 | MODULE_PARM_DESC(swap_ctrl_cmd, "Swap the Control (\"Ctrl\") and Command (\"Flag\") keys. " |
66 | "(For people who are used to Mac shortcuts involving Command instead of Control. " |
67 | "[0] = No change. 1 = Swapped.)" ); |
68 | |
69 | static unsigned int swap_fn_leftctrl; |
70 | module_param(swap_fn_leftctrl, uint, 0644); |
71 | MODULE_PARM_DESC(swap_fn_leftctrl, "Swap the Fn and left Control keys. " |
72 | "(For people who want to keep PC keyboard muscle memory. " |
73 | "[0] = as-is, Mac layout, 1 = swapped, PC layout)" ); |
74 | |
75 | struct apple_non_apple_keyboard { |
76 | char *name; |
77 | }; |
78 | |
79 | struct apple_sc_backlight { |
80 | struct led_classdev cdev; |
81 | struct hid_device *hdev; |
82 | unsigned short backlight_off, backlight_on_min, backlight_on_max; |
83 | }; |
84 | |
85 | struct apple_sc { |
86 | struct hid_device *hdev; |
87 | unsigned long quirks; |
88 | unsigned int fn_on; |
89 | unsigned int fn_found; |
90 | DECLARE_BITMAP(pressed_numlock, KEY_CNT); |
91 | struct timer_list battery_timer; |
92 | struct apple_sc_backlight *backlight; |
93 | }; |
94 | |
95 | struct apple_key_translation { |
96 | u16 from; |
97 | u16 to; |
98 | u8 flags; |
99 | }; |
100 | |
101 | static const struct apple_key_translation magic_keyboard_alu_fn_keys[] = { |
102 | { KEY_BACKSPACE, KEY_DELETE }, |
103 | { KEY_ENTER, KEY_INSERT }, |
104 | { KEY_F1, KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY }, |
105 | { KEY_F2, KEY_BRIGHTNESSUP, APPLE_FLAG_FKEY }, |
106 | { KEY_F3, KEY_SCALE, APPLE_FLAG_FKEY }, |
107 | { KEY_F4, KEY_DASHBOARD, APPLE_FLAG_FKEY }, |
108 | { KEY_F6, KEY_NUMLOCK, APPLE_FLAG_FKEY }, |
109 | { KEY_F7, KEY_PREVIOUSSONG, APPLE_FLAG_FKEY }, |
110 | { KEY_F8, KEY_PLAYPAUSE, APPLE_FLAG_FKEY }, |
111 | { KEY_F9, KEY_NEXTSONG, APPLE_FLAG_FKEY }, |
112 | { KEY_F10, KEY_MUTE, APPLE_FLAG_FKEY }, |
113 | { KEY_F11, KEY_VOLUMEDOWN, APPLE_FLAG_FKEY }, |
114 | { KEY_F12, KEY_VOLUMEUP, APPLE_FLAG_FKEY }, |
115 | { KEY_UP, KEY_PAGEUP }, |
116 | { KEY_DOWN, KEY_PAGEDOWN }, |
117 | { KEY_LEFT, KEY_HOME }, |
118 | { KEY_RIGHT, KEY_END }, |
119 | { } |
120 | }; |
121 | |
122 | static const struct apple_key_translation magic_keyboard_2015_fn_keys[] = { |
123 | { KEY_BACKSPACE, KEY_DELETE }, |
124 | { KEY_ENTER, KEY_INSERT }, |
125 | { KEY_F1, KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY }, |
126 | { KEY_F2, KEY_BRIGHTNESSUP, APPLE_FLAG_FKEY }, |
127 | { KEY_F3, KEY_SCALE, APPLE_FLAG_FKEY }, |
128 | { KEY_F4, KEY_DASHBOARD, APPLE_FLAG_FKEY }, |
129 | { KEY_F7, KEY_PREVIOUSSONG, APPLE_FLAG_FKEY }, |
130 | { KEY_F8, KEY_PLAYPAUSE, APPLE_FLAG_FKEY }, |
131 | { KEY_F9, KEY_NEXTSONG, APPLE_FLAG_FKEY }, |
132 | { KEY_F10, KEY_MUTE, APPLE_FLAG_FKEY }, |
133 | { KEY_F11, KEY_VOLUMEDOWN, APPLE_FLAG_FKEY }, |
134 | { KEY_F12, KEY_VOLUMEUP, APPLE_FLAG_FKEY }, |
135 | { KEY_UP, KEY_PAGEUP }, |
136 | { KEY_DOWN, KEY_PAGEDOWN }, |
137 | { KEY_LEFT, KEY_HOME }, |
138 | { KEY_RIGHT, KEY_END }, |
139 | { } |
140 | }; |
141 | |
142 | struct apple_backlight_config_report { |
143 | u8 report_id; |
144 | u8 version; |
145 | u16 backlight_off, backlight_on_min, backlight_on_max; |
146 | }; |
147 | |
148 | struct apple_backlight_set_report { |
149 | u8 report_id; |
150 | u8 version; |
151 | u16 backlight; |
152 | u16 rate; |
153 | }; |
154 | |
155 | |
156 | static const struct apple_key_translation apple2021_fn_keys[] = { |
157 | { KEY_BACKSPACE, KEY_DELETE }, |
158 | { KEY_ENTER, KEY_INSERT }, |
159 | { KEY_F1, KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY }, |
160 | { KEY_F2, KEY_BRIGHTNESSUP, APPLE_FLAG_FKEY }, |
161 | { KEY_F3, KEY_SCALE, APPLE_FLAG_FKEY }, |
162 | { KEY_F4, KEY_SEARCH, APPLE_FLAG_FKEY }, |
163 | { KEY_F5, KEY_MICMUTE, APPLE_FLAG_FKEY }, |
164 | { KEY_F6, KEY_SLEEP, APPLE_FLAG_FKEY }, |
165 | { KEY_F7, KEY_PREVIOUSSONG, APPLE_FLAG_FKEY }, |
166 | { KEY_F8, KEY_PLAYPAUSE, APPLE_FLAG_FKEY }, |
167 | { KEY_F9, KEY_NEXTSONG, APPLE_FLAG_FKEY }, |
168 | { KEY_F10, KEY_MUTE, APPLE_FLAG_FKEY }, |
169 | { KEY_F11, KEY_VOLUMEDOWN, APPLE_FLAG_FKEY }, |
170 | { KEY_F12, KEY_VOLUMEUP, APPLE_FLAG_FKEY }, |
171 | { KEY_UP, KEY_PAGEUP }, |
172 | { KEY_DOWN, KEY_PAGEDOWN }, |
173 | { KEY_LEFT, KEY_HOME }, |
174 | { KEY_RIGHT, KEY_END }, |
175 | { } |
176 | }; |
177 | |
178 | static const struct apple_key_translation macbookair_fn_keys[] = { |
179 | { KEY_BACKSPACE, KEY_DELETE }, |
180 | { KEY_ENTER, KEY_INSERT }, |
181 | { KEY_F1, KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY }, |
182 | { KEY_F2, KEY_BRIGHTNESSUP, APPLE_FLAG_FKEY }, |
183 | { KEY_F3, KEY_SCALE, APPLE_FLAG_FKEY }, |
184 | { KEY_F4, KEY_DASHBOARD, APPLE_FLAG_FKEY }, |
185 | { KEY_F6, KEY_PREVIOUSSONG, APPLE_FLAG_FKEY }, |
186 | { KEY_F7, KEY_PLAYPAUSE, APPLE_FLAG_FKEY }, |
187 | { KEY_F8, KEY_NEXTSONG, APPLE_FLAG_FKEY }, |
188 | { KEY_F9, KEY_MUTE, APPLE_FLAG_FKEY }, |
189 | { KEY_F10, KEY_VOLUMEDOWN, APPLE_FLAG_FKEY }, |
190 | { KEY_F11, KEY_VOLUMEUP, APPLE_FLAG_FKEY }, |
191 | { KEY_F12, KEY_EJECTCD, APPLE_FLAG_FKEY }, |
192 | { KEY_UP, KEY_PAGEUP }, |
193 | { KEY_DOWN, KEY_PAGEDOWN }, |
194 | { KEY_LEFT, KEY_HOME }, |
195 | { KEY_RIGHT, KEY_END }, |
196 | { } |
197 | }; |
198 | |
199 | static const struct apple_key_translation macbookpro_no_esc_fn_keys[] = { |
200 | { KEY_BACKSPACE, KEY_DELETE }, |
201 | { KEY_ENTER, KEY_INSERT }, |
202 | { KEY_GRAVE, KEY_ESC }, |
203 | { KEY_1, KEY_F1 }, |
204 | { KEY_2, KEY_F2 }, |
205 | { KEY_3, KEY_F3 }, |
206 | { KEY_4, KEY_F4 }, |
207 | { KEY_5, KEY_F5 }, |
208 | { KEY_6, KEY_F6 }, |
209 | { KEY_7, KEY_F7 }, |
210 | { KEY_8, KEY_F8 }, |
211 | { KEY_9, KEY_F9 }, |
212 | { KEY_0, KEY_F10 }, |
213 | { KEY_MINUS, KEY_F11 }, |
214 | { KEY_EQUAL, KEY_F12 }, |
215 | { KEY_UP, KEY_PAGEUP }, |
216 | { KEY_DOWN, KEY_PAGEDOWN }, |
217 | { KEY_LEFT, KEY_HOME }, |
218 | { KEY_RIGHT, KEY_END }, |
219 | { } |
220 | }; |
221 | |
222 | static const struct apple_key_translation macbookpro_dedicated_esc_fn_keys[] = { |
223 | { KEY_BACKSPACE, KEY_DELETE }, |
224 | { KEY_ENTER, KEY_INSERT }, |
225 | { KEY_1, KEY_F1 }, |
226 | { KEY_2, KEY_F2 }, |
227 | { KEY_3, KEY_F3 }, |
228 | { KEY_4, KEY_F4 }, |
229 | { KEY_5, KEY_F5 }, |
230 | { KEY_6, KEY_F6 }, |
231 | { KEY_7, KEY_F7 }, |
232 | { KEY_8, KEY_F8 }, |
233 | { KEY_9, KEY_F9 }, |
234 | { KEY_0, KEY_F10 }, |
235 | { KEY_MINUS, KEY_F11 }, |
236 | { KEY_EQUAL, KEY_F12 }, |
237 | { KEY_UP, KEY_PAGEUP }, |
238 | { KEY_DOWN, KEY_PAGEDOWN }, |
239 | { KEY_LEFT, KEY_HOME }, |
240 | { KEY_RIGHT, KEY_END }, |
241 | { } |
242 | }; |
243 | |
244 | static const struct apple_key_translation apple_fn_keys[] = { |
245 | { KEY_BACKSPACE, KEY_DELETE }, |
246 | { KEY_ENTER, KEY_INSERT }, |
247 | { KEY_F1, KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY }, |
248 | { KEY_F2, KEY_BRIGHTNESSUP, APPLE_FLAG_FKEY }, |
249 | { KEY_F3, KEY_SCALE, APPLE_FLAG_FKEY }, |
250 | { KEY_F4, KEY_DASHBOARD, APPLE_FLAG_FKEY }, |
251 | { KEY_F5, KEY_KBDILLUMDOWN, APPLE_FLAG_FKEY }, |
252 | { KEY_F6, KEY_KBDILLUMUP, APPLE_FLAG_FKEY }, |
253 | { KEY_F7, KEY_PREVIOUSSONG, APPLE_FLAG_FKEY }, |
254 | { KEY_F8, KEY_PLAYPAUSE, APPLE_FLAG_FKEY }, |
255 | { KEY_F9, KEY_NEXTSONG, APPLE_FLAG_FKEY }, |
256 | { KEY_F10, KEY_MUTE, APPLE_FLAG_FKEY }, |
257 | { KEY_F11, KEY_VOLUMEDOWN, APPLE_FLAG_FKEY }, |
258 | { KEY_F12, KEY_VOLUMEUP, APPLE_FLAG_FKEY }, |
259 | { KEY_UP, KEY_PAGEUP }, |
260 | { KEY_DOWN, KEY_PAGEDOWN }, |
261 | { KEY_LEFT, KEY_HOME }, |
262 | { KEY_RIGHT, KEY_END }, |
263 | { } |
264 | }; |
265 | |
266 | static const struct apple_key_translation powerbook_fn_keys[] = { |
267 | { KEY_BACKSPACE, KEY_DELETE }, |
268 | { KEY_F1, KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY }, |
269 | { KEY_F2, KEY_BRIGHTNESSUP, APPLE_FLAG_FKEY }, |
270 | { KEY_F3, KEY_MUTE, APPLE_FLAG_FKEY }, |
271 | { KEY_F4, KEY_VOLUMEDOWN, APPLE_FLAG_FKEY }, |
272 | { KEY_F5, KEY_VOLUMEUP, APPLE_FLAG_FKEY }, |
273 | { KEY_F6, KEY_NUMLOCK, APPLE_FLAG_FKEY }, |
274 | { KEY_F7, KEY_SWITCHVIDEOMODE, APPLE_FLAG_FKEY }, |
275 | { KEY_F8, KEY_KBDILLUMTOGGLE, APPLE_FLAG_FKEY }, |
276 | { KEY_F9, KEY_KBDILLUMDOWN, APPLE_FLAG_FKEY }, |
277 | { KEY_F10, KEY_KBDILLUMUP, APPLE_FLAG_FKEY }, |
278 | { KEY_UP, KEY_PAGEUP }, |
279 | { KEY_DOWN, KEY_PAGEDOWN }, |
280 | { KEY_LEFT, KEY_HOME }, |
281 | { KEY_RIGHT, KEY_END }, |
282 | { } |
283 | }; |
284 | |
285 | static const struct apple_key_translation powerbook_numlock_keys[] = { |
286 | { KEY_J, KEY_KP1 }, |
287 | { KEY_K, KEY_KP2 }, |
288 | { KEY_L, KEY_KP3 }, |
289 | { KEY_U, KEY_KP4 }, |
290 | { KEY_I, KEY_KP5 }, |
291 | { KEY_O, KEY_KP6 }, |
292 | { KEY_7, KEY_KP7 }, |
293 | { KEY_8, KEY_KP8 }, |
294 | { KEY_9, KEY_KP9 }, |
295 | { KEY_M, KEY_KP0 }, |
296 | { KEY_DOT, KEY_KPDOT }, |
297 | { KEY_SLASH, KEY_KPPLUS }, |
298 | { KEY_SEMICOLON, KEY_KPMINUS }, |
299 | { KEY_P, KEY_KPASTERISK }, |
300 | { KEY_MINUS, KEY_KPEQUAL }, |
301 | { KEY_0, KEY_KPSLASH }, |
302 | { KEY_F6, KEY_NUMLOCK }, |
303 | { KEY_KPENTER, KEY_KPENTER }, |
304 | { KEY_BACKSPACE, KEY_BACKSPACE }, |
305 | { } |
306 | }; |
307 | |
308 | static const struct apple_key_translation apple_iso_keyboard[] = { |
309 | { KEY_GRAVE, KEY_102ND }, |
310 | { KEY_102ND, KEY_GRAVE }, |
311 | { } |
312 | }; |
313 | |
314 | static const struct apple_key_translation swapped_option_cmd_keys[] = { |
315 | { KEY_LEFTALT, KEY_LEFTMETA }, |
316 | { KEY_LEFTMETA, KEY_LEFTALT }, |
317 | { KEY_RIGHTALT, KEY_RIGHTMETA }, |
318 | { KEY_RIGHTMETA, KEY_RIGHTALT }, |
319 | { } |
320 | }; |
321 | |
322 | static const struct apple_key_translation swapped_option_cmd_left_keys[] = { |
323 | { KEY_LEFTALT, KEY_LEFTMETA }, |
324 | { KEY_LEFTMETA, KEY_LEFTALT }, |
325 | { } |
326 | }; |
327 | |
328 | static const struct apple_key_translation swapped_ctrl_cmd_keys[] = { |
329 | { KEY_LEFTCTRL, KEY_LEFTMETA }, |
330 | { KEY_LEFTMETA, KEY_LEFTCTRL }, |
331 | { KEY_RIGHTCTRL, KEY_RIGHTMETA }, |
332 | { KEY_RIGHTMETA, KEY_RIGHTCTRL }, |
333 | { } |
334 | }; |
335 | |
336 | static const struct apple_key_translation swapped_fn_leftctrl_keys[] = { |
337 | { KEY_FN, KEY_LEFTCTRL }, |
338 | { KEY_LEFTCTRL, KEY_FN }, |
339 | { } |
340 | }; |
341 | |
342 | static const struct apple_non_apple_keyboard non_apple_keyboards[] = { |
343 | { "SONiX USB DEVICE" }, |
344 | { "Keychron" }, |
345 | { "AONE" }, |
346 | { "GANSS" }, |
347 | { "Hailuck" }, |
348 | }; |
349 | |
350 | static bool apple_is_non_apple_keyboard(struct hid_device *hdev) |
351 | { |
352 | int i; |
353 | |
354 | for (i = 0; i < ARRAY_SIZE(non_apple_keyboards); i++) { |
355 | char *non_apple = non_apple_keyboards[i].name; |
356 | |
357 | if (strncmp(hdev->name, non_apple, strlen(non_apple)) == 0) |
358 | return true; |
359 | } |
360 | |
361 | return false; |
362 | } |
363 | |
364 | static inline void apple_setup_key_translation(struct input_dev *input, |
365 | const struct apple_key_translation *table) |
366 | { |
367 | const struct apple_key_translation *trans; |
368 | |
369 | for (trans = table; trans->from; trans++) |
370 | set_bit(nr: trans->to, addr: input->keybit); |
371 | } |
372 | |
373 | static const struct apple_key_translation *apple_find_translation( |
374 | const struct apple_key_translation *table, u16 from) |
375 | { |
376 | const struct apple_key_translation *trans; |
377 | |
378 | /* Look for the translation */ |
379 | for (trans = table; trans->from; trans++) |
380 | if (trans->from == from) |
381 | return trans; |
382 | |
383 | return NULL; |
384 | } |
385 | |
386 | static void input_event_with_scancode(struct input_dev *input, |
387 | __u8 type, __u16 code, unsigned int hid, __s32 value) |
388 | { |
389 | if (type == EV_KEY && |
390 | (!test_bit(code, input->key)) == value) |
391 | input_event(dev: input, EV_MSC, MSC_SCAN, value: hid); |
392 | input_event(dev: input, type, code, value); |
393 | } |
394 | |
395 | static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input, |
396 | struct hid_usage *usage, __s32 value) |
397 | { |
398 | struct apple_sc *asc = hid_get_drvdata(hdev: hid); |
399 | const struct apple_key_translation *trans, *table; |
400 | bool do_translate; |
401 | u16 code = usage->code; |
402 | unsigned int real_fnmode; |
403 | |
404 | if (fnmode == 3) { |
405 | real_fnmode = (asc->quirks & APPLE_IS_NON_APPLE) ? 2 : 1; |
406 | } else { |
407 | real_fnmode = fnmode; |
408 | } |
409 | |
410 | if (swap_fn_leftctrl) { |
411 | trans = apple_find_translation(table: swapped_fn_leftctrl_keys, from: code); |
412 | |
413 | if (trans) |
414 | code = trans->to; |
415 | } |
416 | |
417 | if (iso_layout > 0 || (iso_layout < 0 && (asc->quirks & APPLE_ISO_TILDE_QUIRK) && |
418 | hid->country == HID_COUNTRY_INTERNATIONAL_ISO)) { |
419 | trans = apple_find_translation(table: apple_iso_keyboard, from: code); |
420 | |
421 | if (trans) |
422 | code = trans->to; |
423 | } |
424 | |
425 | if (swap_opt_cmd) { |
426 | if (swap_opt_cmd == 2) |
427 | trans = apple_find_translation(table: swapped_option_cmd_left_keys, from: code); |
428 | else |
429 | trans = apple_find_translation(table: swapped_option_cmd_keys, from: code); |
430 | |
431 | if (trans) |
432 | code = trans->to; |
433 | } |
434 | |
435 | if (swap_ctrl_cmd) { |
436 | trans = apple_find_translation(table: swapped_ctrl_cmd_keys, from: code); |
437 | |
438 | if (trans) |
439 | code = trans->to; |
440 | } |
441 | |
442 | if (code == KEY_FN) |
443 | asc->fn_on = !!value; |
444 | |
445 | if (real_fnmode) { |
446 | if (hid->product == USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI || |
447 | hid->product == USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO || |
448 | hid->product == USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS || |
449 | hid->product == USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI || |
450 | hid->product == USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO || |
451 | hid->product == USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS || |
452 | hid->product == USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI || |
453 | hid->product == USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO || |
454 | hid->product == USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_JIS) |
455 | table = magic_keyboard_alu_fn_keys; |
456 | else if (hid->product == USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2015 || |
457 | hid->product == USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2015) |
458 | table = magic_keyboard_2015_fn_keys; |
459 | else if (hid->product == USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2021 || |
460 | hid->product == USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_FINGERPRINT_2021 || |
461 | hid->product == USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2021) |
462 | table = apple2021_fn_keys; |
463 | else if (hid->product == USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132 || |
464 | hid->product == USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680 || |
465 | hid->product == USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213) |
466 | table = macbookpro_no_esc_fn_keys; |
467 | else if (hid->product == USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K || |
468 | hid->product == USB_DEVICE_ID_APPLE_WELLSPRINGT2_J223 || |
469 | hid->product == USB_DEVICE_ID_APPLE_WELLSPRINGT2_J152F) |
470 | table = macbookpro_dedicated_esc_fn_keys; |
471 | else if (hid->product == USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K || |
472 | hid->product == USB_DEVICE_ID_APPLE_WELLSPRINGT2_J230K) |
473 | table = apple_fn_keys; |
474 | else if (hid->product >= USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI && |
475 | hid->product <= USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS) |
476 | table = macbookair_fn_keys; |
477 | else if (hid->product < 0x21d || hid->product >= 0x300) |
478 | table = powerbook_fn_keys; |
479 | else |
480 | table = apple_fn_keys; |
481 | |
482 | trans = apple_find_translation(table, from: code); |
483 | |
484 | if (trans) { |
485 | bool from_is_set = test_bit(trans->from, input->key); |
486 | bool to_is_set = test_bit(trans->to, input->key); |
487 | |
488 | if (from_is_set) |
489 | code = trans->from; |
490 | else if (to_is_set) |
491 | code = trans->to; |
492 | |
493 | if (!(from_is_set || to_is_set)) { |
494 | if (trans->flags & APPLE_FLAG_FKEY) { |
495 | switch (real_fnmode) { |
496 | case 1: |
497 | do_translate = !asc->fn_on; |
498 | break; |
499 | case 2: |
500 | do_translate = asc->fn_on; |
501 | break; |
502 | default: |
503 | /* should never happen */ |
504 | do_translate = false; |
505 | } |
506 | } else { |
507 | do_translate = asc->fn_on; |
508 | } |
509 | |
510 | if (do_translate) |
511 | code = trans->to; |
512 | } |
513 | } |
514 | |
515 | if (asc->quirks & APPLE_NUMLOCK_EMULATION && |
516 | (test_bit(code, asc->pressed_numlock) || |
517 | test_bit(LED_NUML, input->led))) { |
518 | trans = apple_find_translation(table: powerbook_numlock_keys, from: code); |
519 | |
520 | if (trans) { |
521 | if (value) |
522 | set_bit(nr: code, addr: asc->pressed_numlock); |
523 | else |
524 | clear_bit(nr: code, addr: asc->pressed_numlock); |
525 | |
526 | code = trans->to; |
527 | } |
528 | } |
529 | } |
530 | |
531 | if (usage->code != code) { |
532 | input_event_with_scancode(input, type: usage->type, code, hid: usage->hid, value); |
533 | |
534 | return 1; |
535 | } |
536 | |
537 | return 0; |
538 | } |
539 | |
540 | static int apple_event(struct hid_device *hdev, struct hid_field *field, |
541 | struct hid_usage *usage, __s32 value) |
542 | { |
543 | struct apple_sc *asc = hid_get_drvdata(hdev); |
544 | |
545 | if (!(hdev->claimed & HID_CLAIMED_INPUT) || !field->hidinput || |
546 | !usage->type) |
547 | return 0; |
548 | |
549 | if ((asc->quirks & APPLE_INVERT_HWHEEL) && |
550 | usage->code == REL_HWHEEL) { |
551 | input_event_with_scancode(input: field->hidinput->input, type: usage->type, |
552 | code: usage->code, hid: usage->hid, value: -value); |
553 | return 1; |
554 | } |
555 | |
556 | if ((asc->quirks & APPLE_HAS_FN) && |
557 | hidinput_apple_event(hid: hdev, input: field->hidinput->input, |
558 | usage, value)) |
559 | return 1; |
560 | |
561 | |
562 | return 0; |
563 | } |
564 | |
565 | static int apple_fetch_battery(struct hid_device *hdev) |
566 | { |
567 | #ifdef CONFIG_HID_BATTERY_STRENGTH |
568 | struct apple_sc *asc = hid_get_drvdata(hdev); |
569 | struct hid_report_enum *report_enum; |
570 | struct hid_report *report; |
571 | |
572 | if (!(asc->quirks & APPLE_RDESC_BATTERY) || !hdev->battery) |
573 | return -1; |
574 | |
575 | report_enum = &hdev->report_enum[hdev->battery_report_type]; |
576 | report = report_enum->report_id_hash[hdev->battery_report_id]; |
577 | |
578 | if (!report || report->maxfield < 1) |
579 | return -1; |
580 | |
581 | if (hdev->battery_capacity == hdev->battery_max) |
582 | return -1; |
583 | |
584 | hid_hw_request(hdev, report, reqtype: HID_REQ_GET_REPORT); |
585 | return 0; |
586 | #else |
587 | return -1; |
588 | #endif |
589 | } |
590 | |
591 | static void apple_battery_timer_tick(struct timer_list *t) |
592 | { |
593 | struct apple_sc *asc = from_timer(asc, t, battery_timer); |
594 | struct hid_device *hdev = asc->hdev; |
595 | |
596 | if (apple_fetch_battery(hdev) == 0) { |
597 | mod_timer(timer: &asc->battery_timer, |
598 | expires: jiffies + msecs_to_jiffies(APPLE_BATTERY_TIMEOUT_MS)); |
599 | } |
600 | } |
601 | |
602 | /* |
603 | * MacBook JIS keyboard has wrong logical maximum |
604 | * Magic Keyboard JIS has wrong logical maximum |
605 | */ |
606 | static __u8 *apple_report_fixup(struct hid_device *hdev, __u8 *rdesc, |
607 | unsigned int *rsize) |
608 | { |
609 | struct apple_sc *asc = hid_get_drvdata(hdev); |
610 | |
611 | if(*rsize >=71 && rdesc[70] == 0x65 && rdesc[64] == 0x65) { |
612 | hid_info(hdev, |
613 | "fixing up Magic Keyboard JIS report descriptor\n" ); |
614 | rdesc[64] = rdesc[70] = 0xe7; |
615 | } |
616 | |
617 | if ((asc->quirks & APPLE_RDESC_JIS) && *rsize >= 60 && |
618 | rdesc[53] == 0x65 && rdesc[59] == 0x65) { |
619 | hid_info(hdev, |
620 | "fixing up MacBook JIS keyboard report descriptor\n" ); |
621 | rdesc[53] = rdesc[59] = 0xe7; |
622 | } |
623 | |
624 | /* |
625 | * Change the usage from: |
626 | * 0x06, 0x00, 0xff, // Usage Page (Vendor Defined Page 1) 0 |
627 | * 0x09, 0x0b, // Usage (Vendor Usage 0x0b) 3 |
628 | * To: |
629 | * 0x05, 0x01, // Usage Page (Generic Desktop) 0 |
630 | * 0x09, 0x06, // Usage (Keyboard) 2 |
631 | */ |
632 | if ((asc->quirks & APPLE_RDESC_BATTERY) && *rsize == 83 && |
633 | rdesc[46] == 0x84 && rdesc[58] == 0x85) { |
634 | hid_info(hdev, |
635 | "fixing up Magic Keyboard battery report descriptor\n" ); |
636 | *rsize = *rsize - 1; |
637 | rdesc = kmemdup(p: rdesc + 1, size: *rsize, GFP_KERNEL); |
638 | if (!rdesc) |
639 | return NULL; |
640 | |
641 | rdesc[0] = 0x05; |
642 | rdesc[1] = 0x01; |
643 | rdesc[2] = 0x09; |
644 | rdesc[3] = 0x06; |
645 | } |
646 | |
647 | return rdesc; |
648 | } |
649 | |
650 | static void apple_setup_input(struct input_dev *input) |
651 | { |
652 | set_bit(KEY_NUMLOCK, addr: input->keybit); |
653 | |
654 | /* Enable all needed keys */ |
655 | apple_setup_key_translation(input, table: apple_fn_keys); |
656 | apple_setup_key_translation(input, table: powerbook_fn_keys); |
657 | apple_setup_key_translation(input, table: powerbook_numlock_keys); |
658 | apple_setup_key_translation(input, table: apple_iso_keyboard); |
659 | apple_setup_key_translation(input, table: magic_keyboard_alu_fn_keys); |
660 | apple_setup_key_translation(input, table: magic_keyboard_2015_fn_keys); |
661 | apple_setup_key_translation(input, table: apple2021_fn_keys); |
662 | apple_setup_key_translation(input, table: macbookpro_no_esc_fn_keys); |
663 | apple_setup_key_translation(input, table: macbookpro_dedicated_esc_fn_keys); |
664 | } |
665 | |
666 | static int apple_input_mapping(struct hid_device *hdev, struct hid_input *hi, |
667 | struct hid_field *field, struct hid_usage *usage, |
668 | unsigned long **bit, int *max) |
669 | { |
670 | struct apple_sc *asc = hid_get_drvdata(hdev); |
671 | |
672 | if (usage->hid == (HID_UP_CUSTOM | 0x0003) || |
673 | usage->hid == (HID_UP_MSVENDOR | 0x0003) || |
674 | usage->hid == (HID_UP_HPVENDOR2 | 0x0003)) { |
675 | /* The fn key on Apple USB keyboards */ |
676 | set_bit(EV_REP, addr: hi->input->evbit); |
677 | hid_map_usage_clear(hidinput: hi, usage, bit, max, EV_KEY, KEY_FN); |
678 | asc->fn_found = true; |
679 | apple_setup_input(input: hi->input); |
680 | return 1; |
681 | } |
682 | |
683 | /* we want the hid layer to go through standard path (set and ignore) */ |
684 | return 0; |
685 | } |
686 | |
687 | static int apple_input_mapped(struct hid_device *hdev, struct hid_input *hi, |
688 | struct hid_field *field, struct hid_usage *usage, |
689 | unsigned long **bit, int *max) |
690 | { |
691 | struct apple_sc *asc = hid_get_drvdata(hdev); |
692 | |
693 | if (asc->quirks & APPLE_MIGHTYMOUSE) { |
694 | if (usage->hid == HID_GD_Z) |
695 | hid_map_usage(hidinput: hi, usage, bit, max, EV_REL, REL_HWHEEL); |
696 | else if (usage->code == BTN_1) |
697 | hid_map_usage(hidinput: hi, usage, bit, max, EV_KEY, BTN_2); |
698 | else if (usage->code == BTN_2) |
699 | hid_map_usage(hidinput: hi, usage, bit, max, EV_KEY, BTN_1); |
700 | } |
701 | |
702 | return 0; |
703 | } |
704 | |
705 | static int apple_input_configured(struct hid_device *hdev, |
706 | struct hid_input *hidinput) |
707 | { |
708 | struct apple_sc *asc = hid_get_drvdata(hdev); |
709 | |
710 | if ((asc->quirks & APPLE_HAS_FN) && !asc->fn_found) { |
711 | hid_info(hdev, "Fn key not found (Apple Wireless Keyboard clone?), disabling Fn key handling\n" ); |
712 | asc->quirks &= ~APPLE_HAS_FN; |
713 | } |
714 | |
715 | if (apple_is_non_apple_keyboard(hdev)) { |
716 | hid_info(hdev, "Non-apple keyboard detected; function keys will default to fnmode=2 behavior\n" ); |
717 | asc->quirks |= APPLE_IS_NON_APPLE; |
718 | } |
719 | |
720 | return 0; |
721 | } |
722 | |
723 | static bool apple_backlight_check_support(struct hid_device *hdev) |
724 | { |
725 | int i; |
726 | unsigned int hid; |
727 | struct hid_report *report; |
728 | |
729 | list_for_each_entry(report, &hdev->report_enum[HID_INPUT_REPORT].report_list, list) { |
730 | for (i = 0; i < report->maxfield; i++) { |
731 | hid = report->field[i]->usage->hid; |
732 | if ((hid & HID_USAGE_PAGE) == HID_UP_MSVENDOR && (hid & HID_USAGE) == 0xf) |
733 | return true; |
734 | } |
735 | } |
736 | |
737 | return false; |
738 | } |
739 | |
740 | static int apple_backlight_set(struct hid_device *hdev, u16 value, u16 rate) |
741 | { |
742 | int ret = 0; |
743 | struct apple_backlight_set_report *rep; |
744 | |
745 | rep = kmalloc(size: sizeof(*rep), GFP_KERNEL); |
746 | if (rep == NULL) |
747 | return -ENOMEM; |
748 | |
749 | rep->report_id = 0xB0; |
750 | rep->version = 1; |
751 | rep->backlight = value; |
752 | rep->rate = rate; |
753 | |
754 | ret = hid_hw_raw_request(hdev, reportnum: 0xB0u, buf: (u8 *) rep, len: sizeof(*rep), |
755 | rtype: HID_OUTPUT_REPORT, reqtype: HID_REQ_SET_REPORT); |
756 | |
757 | kfree(objp: rep); |
758 | return ret; |
759 | } |
760 | |
761 | static int apple_backlight_led_set(struct led_classdev *led_cdev, |
762 | enum led_brightness brightness) |
763 | { |
764 | struct apple_sc_backlight *backlight = container_of(led_cdev, |
765 | struct apple_sc_backlight, cdev); |
766 | |
767 | return apple_backlight_set(hdev: backlight->hdev, value: brightness, rate: 0); |
768 | } |
769 | |
770 | static int apple_backlight_init(struct hid_device *hdev) |
771 | { |
772 | int ret; |
773 | struct apple_sc *asc = hid_get_drvdata(hdev); |
774 | struct apple_backlight_config_report *rep; |
775 | |
776 | if (!apple_backlight_check_support(hdev)) |
777 | return -EINVAL; |
778 | |
779 | rep = kmalloc(size: 0x200, GFP_KERNEL); |
780 | if (rep == NULL) |
781 | return -ENOMEM; |
782 | |
783 | ret = hid_hw_raw_request(hdev, reportnum: 0xBFu, buf: (u8 *) rep, len: sizeof(*rep), |
784 | rtype: HID_FEATURE_REPORT, reqtype: HID_REQ_GET_REPORT); |
785 | if (ret < 0) { |
786 | hid_err(hdev, "backlight request failed: %d\n" , ret); |
787 | goto cleanup_and_exit; |
788 | } |
789 | if (ret < 8 || rep->version != 1) { |
790 | hid_err(hdev, "backlight config struct: bad version %i\n" , rep->version); |
791 | ret = -EINVAL; |
792 | goto cleanup_and_exit; |
793 | } |
794 | |
795 | hid_dbg(hdev, "backlight config: off=%u, on_min=%u, on_max=%u\n" , |
796 | rep->backlight_off, rep->backlight_on_min, rep->backlight_on_max); |
797 | |
798 | asc->backlight = devm_kzalloc(dev: &hdev->dev, size: sizeof(*asc->backlight), GFP_KERNEL); |
799 | if (!asc->backlight) { |
800 | ret = -ENOMEM; |
801 | goto cleanup_and_exit; |
802 | } |
803 | |
804 | asc->backlight->hdev = hdev; |
805 | asc->backlight->cdev.name = "apple::kbd_backlight" ; |
806 | asc->backlight->cdev.max_brightness = rep->backlight_on_max; |
807 | asc->backlight->cdev.brightness_set_blocking = apple_backlight_led_set; |
808 | |
809 | ret = apple_backlight_set(hdev, value: 0, rate: 0); |
810 | if (ret < 0) { |
811 | hid_err(hdev, "backlight set request failed: %d\n" , ret); |
812 | goto cleanup_and_exit; |
813 | } |
814 | |
815 | ret = devm_led_classdev_register(parent: &hdev->dev, led_cdev: &asc->backlight->cdev); |
816 | |
817 | cleanup_and_exit: |
818 | kfree(objp: rep); |
819 | return ret; |
820 | } |
821 | |
822 | static int apple_probe(struct hid_device *hdev, |
823 | const struct hid_device_id *id) |
824 | { |
825 | unsigned long quirks = id->driver_data; |
826 | struct apple_sc *asc; |
827 | int ret; |
828 | |
829 | asc = devm_kzalloc(dev: &hdev->dev, size: sizeof(*asc), GFP_KERNEL); |
830 | if (asc == NULL) { |
831 | hid_err(hdev, "can't alloc apple descriptor\n" ); |
832 | return -ENOMEM; |
833 | } |
834 | |
835 | asc->hdev = hdev; |
836 | asc->quirks = quirks; |
837 | |
838 | hid_set_drvdata(hdev, data: asc); |
839 | |
840 | ret = hid_parse(hdev); |
841 | if (ret) { |
842 | hid_err(hdev, "parse failed\n" ); |
843 | return ret; |
844 | } |
845 | |
846 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); |
847 | if (ret) { |
848 | hid_err(hdev, "hw start failed\n" ); |
849 | return ret; |
850 | } |
851 | |
852 | timer_setup(&asc->battery_timer, apple_battery_timer_tick, 0); |
853 | mod_timer(timer: &asc->battery_timer, |
854 | expires: jiffies + msecs_to_jiffies(APPLE_BATTERY_TIMEOUT_MS)); |
855 | apple_fetch_battery(hdev); |
856 | |
857 | if (quirks & APPLE_BACKLIGHT_CTL) |
858 | apple_backlight_init(hdev); |
859 | |
860 | return 0; |
861 | } |
862 | |
863 | static void apple_remove(struct hid_device *hdev) |
864 | { |
865 | struct apple_sc *asc = hid_get_drvdata(hdev); |
866 | |
867 | del_timer_sync(timer: &asc->battery_timer); |
868 | |
869 | hid_hw_stop(hdev); |
870 | } |
871 | |
872 | static const struct hid_device_id apple_devices[] = { |
873 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE), |
874 | .driver_data = APPLE_MIGHTYMOUSE | APPLE_INVERT_HWHEEL }, |
875 | |
876 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI), |
877 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, |
878 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ISO), |
879 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, |
880 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ANSI), |
881 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, |
882 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ISO), |
883 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, |
884 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_JIS), |
885 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, |
886 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ANSI), |
887 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, |
888 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ISO), |
889 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN | |
890 | APPLE_ISO_TILDE_QUIRK }, |
891 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_JIS), |
892 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN | |
893 | APPLE_RDESC_JIS }, |
894 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ANSI), |
895 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, |
896 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ISO), |
897 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN | |
898 | APPLE_ISO_TILDE_QUIRK }, |
899 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_JIS), |
900 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN | |
901 | APPLE_RDESC_JIS }, |
902 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_MINI_ANSI), |
903 | .driver_data = APPLE_HAS_FN }, |
904 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_MINI_ISO), |
905 | .driver_data = APPLE_HAS_FN }, |
906 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_MINI_JIS), |
907 | .driver_data = APPLE_HAS_FN }, |
908 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ANSI), |
909 | .driver_data = APPLE_HAS_FN }, |
910 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ISO), |
911 | .driver_data = APPLE_HAS_FN }, |
912 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_JIS), |
913 | .driver_data = APPLE_HAS_FN }, |
914 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ANSI), |
915 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, |
916 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO), |
917 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN | |
918 | APPLE_ISO_TILDE_QUIRK }, |
919 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS), |
920 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN | |
921 | APPLE_RDESC_JIS }, |
922 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_ANSI), |
923 | .driver_data = APPLE_HAS_FN }, |
924 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_ANSI), |
925 | .driver_data = APPLE_HAS_FN }, |
926 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_ISO), |
927 | .driver_data = APPLE_HAS_FN }, |
928 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_ISO), |
929 | .driver_data = APPLE_HAS_FN }, |
930 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_JIS), |
931 | .driver_data = APPLE_HAS_FN }, |
932 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI), |
933 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, |
934 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO), |
935 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN | |
936 | APPLE_ISO_TILDE_QUIRK }, |
937 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO), |
938 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN | |
939 | APPLE_ISO_TILDE_QUIRK }, |
940 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, |
941 | USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI), |
942 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, |
943 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, |
944 | USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_JIS), |
945 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, |
946 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS), |
947 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, |
948 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2015), |
949 | .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_RDESC_BATTERY }, |
950 | { HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2015), |
951 | .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK }, |
952 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2015), |
953 | .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_RDESC_BATTERY }, |
954 | { HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2015), |
955 | .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK }, |
956 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ANSI), |
957 | .driver_data = APPLE_HAS_FN }, |
958 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ISO), |
959 | .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK }, |
960 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_JIS), |
961 | .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS }, |
962 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI), |
963 | .driver_data = APPLE_HAS_FN }, |
964 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ISO), |
965 | .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK }, |
966 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_JIS), |
967 | .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS }, |
968 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI), |
969 | .driver_data = APPLE_HAS_FN }, |
970 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ISO), |
971 | .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK }, |
972 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_JIS), |
973 | .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS }, |
974 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI), |
975 | .driver_data = APPLE_HAS_FN }, |
976 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4_ISO), |
977 | .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK }, |
978 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4_JIS), |
979 | .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS }, |
980 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_ANSI), |
981 | .driver_data = APPLE_HAS_FN }, |
982 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_ISO), |
983 | .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK }, |
984 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS), |
985 | .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS }, |
986 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI), |
987 | .driver_data = APPLE_HAS_FN }, |
988 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_ISO), |
989 | .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK }, |
990 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_JIS), |
991 | .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS }, |
992 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_ANSI), |
993 | .driver_data = APPLE_HAS_FN }, |
994 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_ISO), |
995 | .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK }, |
996 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_JIS), |
997 | .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS }, |
998 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_ANSI), |
999 | .driver_data = APPLE_HAS_FN }, |
1000 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_ISO), |
1001 | .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK }, |
1002 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_JIS), |
1003 | .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS }, |
1004 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5A_ANSI), |
1005 | .driver_data = APPLE_HAS_FN }, |
1006 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5A_ISO), |
1007 | .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK }, |
1008 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5A_JIS), |
1009 | .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS }, |
1010 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI), |
1011 | .driver_data = APPLE_HAS_FN }, |
1012 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_ISO), |
1013 | .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK }, |
1014 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_JIS), |
1015 | .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS }, |
1016 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_ANSI), |
1017 | .driver_data = APPLE_HAS_FN }, |
1018 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO), |
1019 | .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK }, |
1020 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS), |
1021 | .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS }, |
1022 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING8_ANSI), |
1023 | .driver_data = APPLE_HAS_FN }, |
1024 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING8_ISO), |
1025 | .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK }, |
1026 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING8_JIS), |
1027 | .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS }, |
1028 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_ANSI), |
1029 | .driver_data = APPLE_HAS_FN }, |
1030 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_ISO), |
1031 | .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK }, |
1032 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_JIS), |
1033 | .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS }, |
1034 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K), |
1035 | .driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL | APPLE_ISO_TILDE_QUIRK }, |
1036 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132), |
1037 | .driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL | APPLE_ISO_TILDE_QUIRK }, |
1038 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680), |
1039 | .driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL | APPLE_ISO_TILDE_QUIRK }, |
1040 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213), |
1041 | .driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL | APPLE_ISO_TILDE_QUIRK }, |
1042 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K), |
1043 | .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK }, |
1044 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J223), |
1045 | .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK }, |
1046 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J230K), |
1047 | .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK }, |
1048 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J152F), |
1049 | .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK }, |
1050 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI), |
1051 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, |
1052 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO), |
1053 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN | |
1054 | APPLE_ISO_TILDE_QUIRK }, |
1055 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS), |
1056 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, |
1057 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY), |
1058 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, |
1059 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY), |
1060 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, |
1061 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2021), |
1062 | .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_RDESC_BATTERY }, |
1063 | { HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2021), |
1064 | .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK }, |
1065 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_FINGERPRINT_2021), |
1066 | .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_RDESC_BATTERY }, |
1067 | { HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_FINGERPRINT_2021), |
1068 | .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK }, |
1069 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2021), |
1070 | .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_RDESC_BATTERY }, |
1071 | { HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2021), |
1072 | .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK }, |
1073 | |
1074 | { } |
1075 | }; |
1076 | MODULE_DEVICE_TABLE(hid, apple_devices); |
1077 | |
1078 | static struct hid_driver apple_driver = { |
1079 | .name = "apple" , |
1080 | .id_table = apple_devices, |
1081 | .report_fixup = apple_report_fixup, |
1082 | .probe = apple_probe, |
1083 | .remove = apple_remove, |
1084 | .event = apple_event, |
1085 | .input_mapping = apple_input_mapping, |
1086 | .input_mapped = apple_input_mapped, |
1087 | .input_configured = apple_input_configured, |
1088 | }; |
1089 | module_hid_driver(apple_driver); |
1090 | |
1091 | MODULE_LICENSE("GPL" ); |
1092 | |