xref: /openbmc/linux/drivers/hid/hid-apple.c (revision 36db6e8484ed455bbb320d89a119378897ae991c)
12874c5fdSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
28c19a515SJiri Slaby /*
38c19a515SJiri Slaby  *  USB HID quirks support for Linux
48c19a515SJiri Slaby  *
58c19a515SJiri Slaby  *  Copyright (c) 1999 Andreas Gal
68c19a515SJiri Slaby  *  Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz>
78c19a515SJiri Slaby  *  Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc
88c19a515SJiri Slaby  *  Copyright (c) 2006-2007 Jiri Kosina
98c19a515SJiri Slaby  *  Copyright (c) 2008 Jiri Slaby <jirislaby@gmail.com>
109018eacbSPaul Pawlowski  *  Copyright (c) 2019 Paul Pawlowski <paul@mrarm.io>
118c19a515SJiri Slaby  */
128c19a515SJiri Slaby 
138c19a515SJiri Slaby /*
148c19a515SJiri Slaby  */
158c19a515SJiri Slaby 
164291ee30SJoe Perches #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
174291ee30SJoe Perches 
188c19a515SJiri Slaby #include <linux/device.h>
198c19a515SJiri Slaby #include <linux/hid.h>
206e143293SJosé Expósito #include <linux/jiffies.h>
218c19a515SJiri Slaby #include <linux/module.h>
225a0e3ad6STejun Heo #include <linux/slab.h>
236e143293SJosé Expósito #include <linux/timer.h>
24fa33382cSBryan Cain #include <linux/string.h>
256c89c116SThomas Weißschuh #include <linux/leds.h>
268c19a515SJiri Slaby 
278c19a515SJiri Slaby #include "hid-ids.h"
288c19a515SJiri Slaby 
297f52ece2SJosé Expósito #define APPLE_RDESC_JIS		BIT(0)
307f52ece2SJosé Expósito #define APPLE_IGNORE_MOUSE	BIT(1)
317f52ece2SJosé Expósito #define APPLE_HAS_FN		BIT(2)
327f52ece2SJosé Expósito /* BIT(3) reserved, was: APPLE_HIDDEV */
337f52ece2SJosé Expósito #define APPLE_ISO_TILDE_QUIRK	BIT(4)
347f52ece2SJosé Expósito #define APPLE_MIGHTYMOUSE	BIT(5)
357f52ece2SJosé Expósito #define APPLE_INVERT_HWHEEL	BIT(6)
367f52ece2SJosé Expósito /* BIT(7) reserved, was: APPLE_IGNORE_HIDINPUT */
377f52ece2SJosé Expósito #define APPLE_NUMLOCK_EMULATION	BIT(8)
386e143293SJosé Expósito #define APPLE_RDESC_BATTERY	BIT(9)
399018eacbSPaul Pawlowski #define APPLE_BACKLIGHT_CTL	BIT(10)
40a0a05054SHilton Chain #define APPLE_IS_NON_APPLE	BIT(11)
418c19a515SJiri Slaby 
428c19a515SJiri Slaby #define APPLE_FLAG_FKEY		0x01
438c19a515SJiri Slaby 
44bd77a0f0SAlex Henrie #define HID_COUNTRY_INTERNATIONAL_ISO	13
456e143293SJosé Expósito #define APPLE_BATTERY_TIMEOUT_MS	60000
46bd77a0f0SAlex Henrie 
47fa33382cSBryan Cain static unsigned int fnmode = 3;
488c19a515SJiri Slaby module_param(fnmode, uint, 0644);
498c19a515SJiri Slaby MODULE_PARM_DESC(fnmode, "Mode of fn key on Apple keyboards (0 = disabled, "
50fa33382cSBryan Cain 		"1 = fkeyslast, 2 = fkeysfirst, [3] = auto)");
518c19a515SJiri Slaby 
52d58cf34aSAlex Henrie static int iso_layout = -1;
53d58cf34aSAlex Henrie module_param(iso_layout, int, 0644);
54d58cf34aSAlex Henrie MODULE_PARM_DESC(iso_layout, "Swap the backtick/tilde and greater-than/less-than keys. "
55d58cf34aSAlex Henrie 		"([-1] = auto, 0 = disabled, 1 = enabled)");
5654a6593dSStefan Glasenhardt 
57a94c79bdSJiri Kosina static unsigned int swap_opt_cmd;
5843c83146SNanno Langstraat module_param(swap_opt_cmd, uint, 0644);
5943c83146SNanno Langstraat MODULE_PARM_DESC(swap_opt_cmd, "Swap the Option (\"Alt\") and Command (\"Flag\") keys. "
6043c83146SNanno Langstraat 		"(For people who want to keep Windows PC keyboard muscle memory. "
6172e49cadSLasse Brun 		"[0] = as-is, Mac layout. 1 = swapped, Windows layout., 2 = swapped, Swap only left side)");
6243c83146SNanno Langstraat 
63fd7b68b7SAditya Garg static unsigned int swap_ctrl_cmd;
64fd7b68b7SAditya Garg module_param(swap_ctrl_cmd, uint, 0644);
65fd7b68b7SAditya Garg MODULE_PARM_DESC(swap_ctrl_cmd, "Swap the Control (\"Ctrl\") and Command (\"Flag\") keys. "
66fd7b68b7SAditya Garg 		"(For people who are used to Mac shortcuts involving Command instead of Control. "
67fd7b68b7SAditya Garg 		"[0] = No change. 1 = Swapped.)");
68fd7b68b7SAditya Garg 
69346338efSfree5lot static unsigned int swap_fn_leftctrl;
70346338efSfree5lot module_param(swap_fn_leftctrl, uint, 0644);
71346338efSfree5lot MODULE_PARM_DESC(swap_fn_leftctrl, "Swap the Fn and left Control keys. "
72346338efSfree5lot 		"(For people who want to keep PC keyboard muscle memory. "
73346338efSfree5lot 		"[0] = as-is, Mac layout, 1 = swapped, PC layout)");
74346338efSfree5lot 
75a0a05054SHilton Chain struct apple_non_apple_keyboard {
76a0a05054SHilton Chain 	char *name;
77a0a05054SHilton Chain };
78a0a05054SHilton Chain 
799018eacbSPaul Pawlowski struct apple_sc_backlight {
809018eacbSPaul Pawlowski 	struct led_classdev cdev;
819018eacbSPaul Pawlowski 	struct hid_device *hdev;
829018eacbSPaul Pawlowski 	unsigned short backlight_off, backlight_on_min, backlight_on_max;
839018eacbSPaul Pawlowski };
849018eacbSPaul Pawlowski 
858c19a515SJiri Slaby struct apple_sc {
866e143293SJosé Expósito 	struct hid_device *hdev;
878c19a515SJiri Slaby 	unsigned long quirks;
888c19a515SJiri Slaby 	unsigned int fn_on;
89a5d81646SHans de Goede 	unsigned int fn_found;
908c19a515SJiri Slaby 	DECLARE_BITMAP(pressed_numlock, KEY_CNT);
916e143293SJosé Expósito 	struct timer_list battery_timer;
929018eacbSPaul Pawlowski 	struct apple_sc_backlight *backlight;
938c19a515SJiri Slaby };
948c19a515SJiri Slaby 
958c19a515SJiri Slaby struct apple_key_translation {
968c19a515SJiri Slaby 	u16 from;
978c19a515SJiri Slaby 	u16 to;
988c19a515SJiri Slaby 	u8 flags;
998c19a515SJiri Slaby };
1008c19a515SJiri Slaby 
1010fea6fe7SJosé Expósito static const struct apple_key_translation magic_keyboard_alu_fn_keys[] = {
1020fea6fe7SJosé Expósito 	{ KEY_BACKSPACE, KEY_DELETE },
1030fea6fe7SJosé Expósito 	{ KEY_ENTER,	KEY_INSERT },
1040fea6fe7SJosé Expósito 	{ KEY_F1,	KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY },
1050fea6fe7SJosé Expósito 	{ KEY_F2,	KEY_BRIGHTNESSUP,   APPLE_FLAG_FKEY },
1060fea6fe7SJosé Expósito 	{ KEY_F3,	KEY_SCALE,          APPLE_FLAG_FKEY },
1070fea6fe7SJosé Expósito 	{ KEY_F4,	KEY_DASHBOARD,      APPLE_FLAG_FKEY },
1080fea6fe7SJosé Expósito 	{ KEY_F6,	KEY_NUMLOCK,        APPLE_FLAG_FKEY },
1090fea6fe7SJosé Expósito 	{ KEY_F7,	KEY_PREVIOUSSONG,   APPLE_FLAG_FKEY },
1100fea6fe7SJosé Expósito 	{ KEY_F8,	KEY_PLAYPAUSE,      APPLE_FLAG_FKEY },
1110fea6fe7SJosé Expósito 	{ KEY_F9,	KEY_NEXTSONG,       APPLE_FLAG_FKEY },
1120fea6fe7SJosé Expósito 	{ KEY_F10,	KEY_MUTE,           APPLE_FLAG_FKEY },
1130fea6fe7SJosé Expósito 	{ KEY_F11,	KEY_VOLUMEDOWN,     APPLE_FLAG_FKEY },
1140fea6fe7SJosé Expósito 	{ KEY_F12,	KEY_VOLUMEUP,       APPLE_FLAG_FKEY },
1150fea6fe7SJosé Expósito 	{ KEY_UP,	KEY_PAGEUP },
1160fea6fe7SJosé Expósito 	{ KEY_DOWN,	KEY_PAGEDOWN },
1170fea6fe7SJosé Expósito 	{ KEY_LEFT,	KEY_HOME },
1180fea6fe7SJosé Expósito 	{ KEY_RIGHT,	KEY_END },
1190fea6fe7SJosé Expósito 	{ }
1200fea6fe7SJosé Expósito };
1210fea6fe7SJosé Expósito 
122250b369eSJosé Expósito static const struct apple_key_translation magic_keyboard_2015_fn_keys[] = {
123250b369eSJosé Expósito 	{ KEY_BACKSPACE, KEY_DELETE },
124250b369eSJosé Expósito 	{ KEY_ENTER,	KEY_INSERT },
125250b369eSJosé Expósito 	{ KEY_F1,	KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY },
126250b369eSJosé Expósito 	{ KEY_F2,	KEY_BRIGHTNESSUP,   APPLE_FLAG_FKEY },
127250b369eSJosé Expósito 	{ KEY_F3,	KEY_SCALE,          APPLE_FLAG_FKEY },
128250b369eSJosé Expósito 	{ KEY_F4,	KEY_DASHBOARD,      APPLE_FLAG_FKEY },
129250b369eSJosé Expósito 	{ KEY_F7,	KEY_PREVIOUSSONG,   APPLE_FLAG_FKEY },
130250b369eSJosé Expósito 	{ KEY_F8,	KEY_PLAYPAUSE,      APPLE_FLAG_FKEY },
131250b369eSJosé Expósito 	{ KEY_F9,	KEY_NEXTSONG,       APPLE_FLAG_FKEY },
132250b369eSJosé Expósito 	{ KEY_F10,	KEY_MUTE,           APPLE_FLAG_FKEY },
133250b369eSJosé Expósito 	{ KEY_F11,	KEY_VOLUMEDOWN,     APPLE_FLAG_FKEY },
134250b369eSJosé Expósito 	{ KEY_F12,	KEY_VOLUMEUP,       APPLE_FLAG_FKEY },
135250b369eSJosé Expósito 	{ KEY_UP,	KEY_PAGEUP },
136250b369eSJosé Expósito 	{ KEY_DOWN,	KEY_PAGEDOWN },
137250b369eSJosé Expósito 	{ KEY_LEFT,	KEY_HOME },
138250b369eSJosé Expósito 	{ KEY_RIGHT,	KEY_END },
139250b369eSJosé Expósito 	{ }
140250b369eSJosé Expósito };
141250b369eSJosé Expósito 
1429018eacbSPaul Pawlowski struct apple_backlight_config_report {
1439018eacbSPaul Pawlowski 	u8 report_id;
1449018eacbSPaul Pawlowski 	u8 version;
1459018eacbSPaul Pawlowski 	u16 backlight_off, backlight_on_min, backlight_on_max;
1469018eacbSPaul Pawlowski };
1479018eacbSPaul Pawlowski 
1489018eacbSPaul Pawlowski struct apple_backlight_set_report {
1499018eacbSPaul Pawlowski 	u8 report_id;
1509018eacbSPaul Pawlowski 	u8 version;
1519018eacbSPaul Pawlowski 	u16 backlight;
1529018eacbSPaul Pawlowski 	u16 rate;
1539018eacbSPaul Pawlowski };
1549018eacbSPaul Pawlowski 
1559018eacbSPaul Pawlowski 
156531cb569SBenjamin Berg static const struct apple_key_translation apple2021_fn_keys[] = {
157531cb569SBenjamin Berg 	{ KEY_BACKSPACE, KEY_DELETE },
158531cb569SBenjamin Berg 	{ KEY_ENTER,	KEY_INSERT },
159531cb569SBenjamin Berg 	{ KEY_F1,	KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY },
160531cb569SBenjamin Berg 	{ KEY_F2,	KEY_BRIGHTNESSUP,   APPLE_FLAG_FKEY },
161531cb569SBenjamin Berg 	{ KEY_F3,	KEY_SCALE,          APPLE_FLAG_FKEY },
162531cb569SBenjamin Berg 	{ KEY_F4,	KEY_SEARCH,         APPLE_FLAG_FKEY },
163531cb569SBenjamin Berg 	{ KEY_F5,	KEY_MICMUTE,        APPLE_FLAG_FKEY },
164531cb569SBenjamin Berg 	{ KEY_F6,	KEY_SLEEP,          APPLE_FLAG_FKEY },
165531cb569SBenjamin Berg 	{ KEY_F7,	KEY_PREVIOUSSONG,   APPLE_FLAG_FKEY },
166531cb569SBenjamin Berg 	{ KEY_F8,	KEY_PLAYPAUSE,      APPLE_FLAG_FKEY },
167531cb569SBenjamin Berg 	{ KEY_F9,	KEY_NEXTSONG,       APPLE_FLAG_FKEY },
168531cb569SBenjamin Berg 	{ KEY_F10,	KEY_MUTE,           APPLE_FLAG_FKEY },
169531cb569SBenjamin Berg 	{ KEY_F11,	KEY_VOLUMEDOWN,     APPLE_FLAG_FKEY },
170531cb569SBenjamin Berg 	{ KEY_F12,	KEY_VOLUMEUP,       APPLE_FLAG_FKEY },
171531cb569SBenjamin Berg 	{ KEY_UP,	KEY_PAGEUP },
172531cb569SBenjamin Berg 	{ KEY_DOWN,	KEY_PAGEDOWN },
173531cb569SBenjamin Berg 	{ KEY_LEFT,	KEY_HOME },
174531cb569SBenjamin Berg 	{ KEY_RIGHT,	KEY_END },
175531cb569SBenjamin Berg 	{ }
176531cb569SBenjamin Berg };
177531cb569SBenjamin Berg 
17899b9f758SEdgar (gimli) Hucek static const struct apple_key_translation macbookair_fn_keys[] = {
17999b9f758SEdgar (gimli) Hucek 	{ KEY_BACKSPACE, KEY_DELETE },
18099b9f758SEdgar (gimli) Hucek 	{ KEY_ENTER,	KEY_INSERT },
18199b9f758SEdgar (gimli) Hucek 	{ KEY_F1,	KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY },
18299b9f758SEdgar (gimli) Hucek 	{ KEY_F2,	KEY_BRIGHTNESSUP,   APPLE_FLAG_FKEY },
18399b9f758SEdgar (gimli) Hucek 	{ KEY_F3,	KEY_SCALE,          APPLE_FLAG_FKEY },
18499b9f758SEdgar (gimli) Hucek 	{ KEY_F4,	KEY_DASHBOARD,      APPLE_FLAG_FKEY },
18599b9f758SEdgar (gimli) Hucek 	{ KEY_F6,	KEY_PREVIOUSSONG,   APPLE_FLAG_FKEY },
18699b9f758SEdgar (gimli) Hucek 	{ KEY_F7,	KEY_PLAYPAUSE,      APPLE_FLAG_FKEY },
18799b9f758SEdgar (gimli) Hucek 	{ KEY_F8,	KEY_NEXTSONG,       APPLE_FLAG_FKEY },
18899b9f758SEdgar (gimli) Hucek 	{ KEY_F9,	KEY_MUTE,           APPLE_FLAG_FKEY },
18999b9f758SEdgar (gimli) Hucek 	{ KEY_F10,	KEY_VOLUMEDOWN,     APPLE_FLAG_FKEY },
19099b9f758SEdgar (gimli) Hucek 	{ KEY_F11,	KEY_VOLUMEUP,       APPLE_FLAG_FKEY },
19199b9f758SEdgar (gimli) Hucek 	{ KEY_F12,	KEY_EJECTCD,        APPLE_FLAG_FKEY },
19299b9f758SEdgar (gimli) Hucek 	{ KEY_UP,	KEY_PAGEUP },
19399b9f758SEdgar (gimli) Hucek 	{ KEY_DOWN,	KEY_PAGEDOWN },
19499b9f758SEdgar (gimli) Hucek 	{ KEY_LEFT,	KEY_HOME },
19599b9f758SEdgar (gimli) Hucek 	{ KEY_RIGHT,	KEY_END },
19699b9f758SEdgar (gimli) Hucek 	{ }
19799b9f758SEdgar (gimli) Hucek };
19899b9f758SEdgar (gimli) Hucek 
199c5f09b1bSAditya Garg static const struct apple_key_translation macbookpro_no_esc_fn_keys[] = {
200c5f09b1bSAditya Garg 	{ KEY_BACKSPACE, KEY_DELETE },
201c5f09b1bSAditya Garg 	{ KEY_ENTER,	KEY_INSERT },
202c5f09b1bSAditya Garg 	{ KEY_GRAVE,	KEY_ESC },
203c5f09b1bSAditya Garg 	{ KEY_1,	KEY_F1 },
204c5f09b1bSAditya Garg 	{ KEY_2,	KEY_F2 },
205c5f09b1bSAditya Garg 	{ KEY_3,	KEY_F3 },
206c5f09b1bSAditya Garg 	{ KEY_4,	KEY_F4 },
207c5f09b1bSAditya Garg 	{ KEY_5,	KEY_F5 },
208c5f09b1bSAditya Garg 	{ KEY_6,	KEY_F6 },
209c5f09b1bSAditya Garg 	{ KEY_7,	KEY_F7 },
210c5f09b1bSAditya Garg 	{ KEY_8,	KEY_F8 },
211c5f09b1bSAditya Garg 	{ KEY_9,	KEY_F9 },
212c5f09b1bSAditya Garg 	{ KEY_0,	KEY_F10 },
213c5f09b1bSAditya Garg 	{ KEY_MINUS,	KEY_F11 },
214c5f09b1bSAditya Garg 	{ KEY_EQUAL,	KEY_F12 },
215c5f09b1bSAditya Garg 	{ KEY_UP,	KEY_PAGEUP },
216c5f09b1bSAditya Garg 	{ KEY_DOWN,	KEY_PAGEDOWN },
217c5f09b1bSAditya Garg 	{ KEY_LEFT,	KEY_HOME },
218c5f09b1bSAditya Garg 	{ KEY_RIGHT,	KEY_END },
219c5f09b1bSAditya Garg 	{ }
220c5f09b1bSAditya Garg };
221c5f09b1bSAditya Garg 
222c5f09b1bSAditya Garg static const struct apple_key_translation macbookpro_dedicated_esc_fn_keys[] = {
223c5f09b1bSAditya Garg 	{ KEY_BACKSPACE, KEY_DELETE },
224c5f09b1bSAditya Garg 	{ KEY_ENTER,	KEY_INSERT },
225c5f09b1bSAditya Garg 	{ KEY_1,	KEY_F1 },
226c5f09b1bSAditya Garg 	{ KEY_2,	KEY_F2 },
227c5f09b1bSAditya Garg 	{ KEY_3,	KEY_F3 },
228c5f09b1bSAditya Garg 	{ KEY_4,	KEY_F4 },
229c5f09b1bSAditya Garg 	{ KEY_5,	KEY_F5 },
230c5f09b1bSAditya Garg 	{ KEY_6,	KEY_F6 },
231c5f09b1bSAditya Garg 	{ KEY_7,	KEY_F7 },
232c5f09b1bSAditya Garg 	{ KEY_8,	KEY_F8 },
233c5f09b1bSAditya Garg 	{ KEY_9,	KEY_F9 },
234c5f09b1bSAditya Garg 	{ KEY_0,	KEY_F10 },
235c5f09b1bSAditya Garg 	{ KEY_MINUS,	KEY_F11 },
236c5f09b1bSAditya Garg 	{ KEY_EQUAL,	KEY_F12 },
237c5f09b1bSAditya Garg 	{ KEY_UP,	KEY_PAGEUP },
238c5f09b1bSAditya Garg 	{ KEY_DOWN,	KEY_PAGEDOWN },
239c5f09b1bSAditya Garg 	{ KEY_LEFT,	KEY_HOME },
240c5f09b1bSAditya Garg 	{ KEY_RIGHT,	KEY_END },
241c5f09b1bSAditya Garg 	{ }
242c5f09b1bSAditya Garg };
243c5f09b1bSAditya Garg 
244b2ddd54eSPaul Collins static const struct apple_key_translation apple_fn_keys[] = {
2458c19a515SJiri Slaby 	{ KEY_BACKSPACE, KEY_DELETE },
246437184aeSHenrik Rydberg 	{ KEY_ENTER,	KEY_INSERT },
2478c19a515SJiri Slaby 	{ KEY_F1,	KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY },
2488c19a515SJiri Slaby 	{ KEY_F2,	KEY_BRIGHTNESSUP,   APPLE_FLAG_FKEY },
249437184aeSHenrik Rydberg 	{ KEY_F3,	KEY_SCALE,          APPLE_FLAG_FKEY },
250437184aeSHenrik Rydberg 	{ KEY_F4,	KEY_DASHBOARD,      APPLE_FLAG_FKEY },
2518c19a515SJiri Slaby 	{ KEY_F5,	KEY_KBDILLUMDOWN,   APPLE_FLAG_FKEY },
2528c19a515SJiri Slaby 	{ KEY_F6,	KEY_KBDILLUMUP,     APPLE_FLAG_FKEY },
2538c19a515SJiri Slaby 	{ KEY_F7,	KEY_PREVIOUSSONG,   APPLE_FLAG_FKEY },
2548c19a515SJiri Slaby 	{ KEY_F8,	KEY_PLAYPAUSE,      APPLE_FLAG_FKEY },
2558c19a515SJiri Slaby 	{ KEY_F9,	KEY_NEXTSONG,       APPLE_FLAG_FKEY },
2568c19a515SJiri Slaby 	{ KEY_F10,	KEY_MUTE,           APPLE_FLAG_FKEY },
2578c19a515SJiri Slaby 	{ KEY_F11,	KEY_VOLUMEDOWN,     APPLE_FLAG_FKEY },
2588c19a515SJiri Slaby 	{ KEY_F12,	KEY_VOLUMEUP,       APPLE_FLAG_FKEY },
2598c19a515SJiri Slaby 	{ KEY_UP,	KEY_PAGEUP },
2608c19a515SJiri Slaby 	{ KEY_DOWN,	KEY_PAGEDOWN },
2618c19a515SJiri Slaby 	{ KEY_LEFT,	KEY_HOME },
2628c19a515SJiri Slaby 	{ KEY_RIGHT,	KEY_END },
2638c19a515SJiri Slaby 	{ }
2648c19a515SJiri Slaby };
2658c19a515SJiri Slaby 
266b2ddd54eSPaul Collins static const struct apple_key_translation powerbook_fn_keys[] = {
2678c19a515SJiri Slaby 	{ KEY_BACKSPACE, KEY_DELETE },
2688c19a515SJiri Slaby 	{ KEY_F1,	KEY_BRIGHTNESSDOWN,     APPLE_FLAG_FKEY },
2698c19a515SJiri Slaby 	{ KEY_F2,	KEY_BRIGHTNESSUP,       APPLE_FLAG_FKEY },
2708c19a515SJiri Slaby 	{ KEY_F3,	KEY_MUTE,               APPLE_FLAG_FKEY },
2718c19a515SJiri Slaby 	{ KEY_F4,	KEY_VOLUMEDOWN,         APPLE_FLAG_FKEY },
2728c19a515SJiri Slaby 	{ KEY_F5,	KEY_VOLUMEUP,           APPLE_FLAG_FKEY },
2738c19a515SJiri Slaby 	{ KEY_F6,	KEY_NUMLOCK,            APPLE_FLAG_FKEY },
2748c19a515SJiri Slaby 	{ KEY_F7,	KEY_SWITCHVIDEOMODE,    APPLE_FLAG_FKEY },
2758c19a515SJiri Slaby 	{ KEY_F8,	KEY_KBDILLUMTOGGLE,     APPLE_FLAG_FKEY },
2768c19a515SJiri Slaby 	{ KEY_F9,	KEY_KBDILLUMDOWN,       APPLE_FLAG_FKEY },
2778c19a515SJiri Slaby 	{ KEY_F10,	KEY_KBDILLUMUP,         APPLE_FLAG_FKEY },
2788c19a515SJiri Slaby 	{ KEY_UP,	KEY_PAGEUP },
2798c19a515SJiri Slaby 	{ KEY_DOWN,	KEY_PAGEDOWN },
2808c19a515SJiri Slaby 	{ KEY_LEFT,	KEY_HOME },
2818c19a515SJiri Slaby 	{ KEY_RIGHT,	KEY_END },
2828c19a515SJiri Slaby 	{ }
2838c19a515SJiri Slaby };
2848c19a515SJiri Slaby 
285b2ddd54eSPaul Collins static const struct apple_key_translation powerbook_numlock_keys[] = {
2868c19a515SJiri Slaby 	{ KEY_J,	KEY_KP1 },
2878c19a515SJiri Slaby 	{ KEY_K,	KEY_KP2 },
2888c19a515SJiri Slaby 	{ KEY_L,	KEY_KP3 },
2898c19a515SJiri Slaby 	{ KEY_U,	KEY_KP4 },
2908c19a515SJiri Slaby 	{ KEY_I,	KEY_KP5 },
2918c19a515SJiri Slaby 	{ KEY_O,	KEY_KP6 },
2928c19a515SJiri Slaby 	{ KEY_7,	KEY_KP7 },
2938c19a515SJiri Slaby 	{ KEY_8,	KEY_KP8 },
2948c19a515SJiri Slaby 	{ KEY_9,	KEY_KP9 },
2958c19a515SJiri Slaby 	{ KEY_M,	KEY_KP0 },
2968c19a515SJiri Slaby 	{ KEY_DOT,	KEY_KPDOT },
2978c19a515SJiri Slaby 	{ KEY_SLASH,	KEY_KPPLUS },
2988c19a515SJiri Slaby 	{ KEY_SEMICOLON, KEY_KPMINUS },
2998c19a515SJiri Slaby 	{ KEY_P,	KEY_KPASTERISK },
3008c19a515SJiri Slaby 	{ KEY_MINUS,	KEY_KPEQUAL },
3018c19a515SJiri Slaby 	{ KEY_0,	KEY_KPSLASH },
3028c19a515SJiri Slaby 	{ KEY_F6,	KEY_NUMLOCK },
3038c19a515SJiri Slaby 	{ KEY_KPENTER,	KEY_KPENTER },
3048c19a515SJiri Slaby 	{ KEY_BACKSPACE, KEY_BACKSPACE },
3058c19a515SJiri Slaby 	{ }
3068c19a515SJiri Slaby };
3078c19a515SJiri Slaby 
308b2ddd54eSPaul Collins static const struct apple_key_translation apple_iso_keyboard[] = {
3098c19a515SJiri Slaby 	{ KEY_GRAVE,	KEY_102ND },
3108c19a515SJiri Slaby 	{ KEY_102ND,	KEY_GRAVE },
3118c19a515SJiri Slaby 	{ }
3128c19a515SJiri Slaby };
3138c19a515SJiri Slaby 
31443c83146SNanno Langstraat static const struct apple_key_translation swapped_option_cmd_keys[] = {
31543c83146SNanno Langstraat 	{ KEY_LEFTALT,	KEY_LEFTMETA },
31643c83146SNanno Langstraat 	{ KEY_LEFTMETA,	KEY_LEFTALT },
31743c83146SNanno Langstraat 	{ KEY_RIGHTALT,	KEY_RIGHTMETA },
31843c83146SNanno Langstraat 	{ KEY_RIGHTMETA, KEY_RIGHTALT },
31943c83146SNanno Langstraat 	{ }
32043c83146SNanno Langstraat };
32143c83146SNanno Langstraat 
32272e49cadSLasse Brun static const struct apple_key_translation swapped_option_cmd_left_keys[] = {
32372e49cadSLasse Brun 	{ KEY_LEFTALT,	KEY_LEFTMETA },
32472e49cadSLasse Brun 	{ KEY_LEFTMETA,	KEY_LEFTALT },
32572e49cadSLasse Brun 	{ }
32672e49cadSLasse Brun };
32772e49cadSLasse Brun 
328fd7b68b7SAditya Garg static const struct apple_key_translation swapped_ctrl_cmd_keys[] = {
329fd7b68b7SAditya Garg 	{ KEY_LEFTCTRL,	KEY_LEFTMETA },
330fd7b68b7SAditya Garg 	{ KEY_LEFTMETA,	KEY_LEFTCTRL },
331fd7b68b7SAditya Garg 	{ KEY_RIGHTCTRL, KEY_RIGHTMETA },
332fd7b68b7SAditya Garg 	{ KEY_RIGHTMETA, KEY_RIGHTCTRL },
333fd7b68b7SAditya Garg 	{ }
334fd7b68b7SAditya Garg };
335fd7b68b7SAditya Garg 
336346338efSfree5lot static const struct apple_key_translation swapped_fn_leftctrl_keys[] = {
337346338efSfree5lot 	{ KEY_FN, KEY_LEFTCTRL },
3385476fcf7SKerem Karabay 	{ KEY_LEFTCTRL, KEY_FN },
339346338efSfree5lot 	{ }
340346338efSfree5lot };
341346338efSfree5lot 
342a0a05054SHilton Chain static const struct apple_non_apple_keyboard non_apple_keyboards[] = {
343a0a05054SHilton Chain 	{ "SONiX USB DEVICE" },
344a0a05054SHilton Chain 	{ "Keychron" },
34520afcc46SHilton Chain 	{ "AONE" },
346c4444d87SNils Tonnaett 	{ "GANSS" },
347c4444d87SNils Tonnaett 	{ "Hailuck" },
3486b3507b8SYihong Cao 	{ "Jamesdonkey" },
3496b3507b8SYihong Cao 	{ "A3R" },
350a0a05054SHilton Chain };
351a0a05054SHilton Chain 
apple_is_non_apple_keyboard(struct hid_device * hdev)352a0a05054SHilton Chain static bool apple_is_non_apple_keyboard(struct hid_device *hdev)
353a0a05054SHilton Chain {
354a0a05054SHilton Chain 	int i;
355a0a05054SHilton Chain 
356a0a05054SHilton Chain 	for (i = 0; i < ARRAY_SIZE(non_apple_keyboards); i++) {
357a0a05054SHilton Chain 		char *non_apple = non_apple_keyboards[i].name;
358a0a05054SHilton Chain 
359a0a05054SHilton Chain 		if (strncmp(hdev->name, non_apple, strlen(non_apple)) == 0)
360a0a05054SHilton Chain 			return true;
361a0a05054SHilton Chain 	}
362a0a05054SHilton Chain 
363a0a05054SHilton Chain 	return false;
364a0a05054SHilton Chain }
365a0a05054SHilton Chain 
apple_setup_key_translation(struct input_dev * input,const struct apple_key_translation * table)366*62485737SAlex Henrie static bool apple_is_omoton_kb066(struct hid_device *hdev)
367*62485737SAlex Henrie {
368*62485737SAlex Henrie 	return hdev->product == USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI &&
369*62485737SAlex Henrie 		strcmp(hdev->name, "Bluetooth Keyboard") == 0;
370*62485737SAlex Henrie }
371*62485737SAlex Henrie 
372f1d1b3a9SJosé Expósito static inline void apple_setup_key_translation(struct input_dev *input,
373f1d1b3a9SJosé Expósito 		const struct apple_key_translation *table)
374f1d1b3a9SJosé Expósito {
apple_find_translation(const struct apple_key_translation * table,u16 from)375f1d1b3a9SJosé Expósito 	const struct apple_key_translation *trans;
376f1d1b3a9SJosé Expósito 
377f1d1b3a9SJosé Expósito 	for (trans = table; trans->from; trans++)
378f1d1b3a9SJosé Expósito 		set_bit(trans->to, input->keybit);
379f1d1b3a9SJosé Expósito }
380f1d1b3a9SJosé Expósito 
381b2ddd54eSPaul Collins static const struct apple_key_translation *apple_find_translation(
382b2ddd54eSPaul Collins 		const struct apple_key_translation *table, u16 from)
3838c19a515SJiri Slaby {
384b2ddd54eSPaul Collins 	const struct apple_key_translation *trans;
3858c19a515SJiri Slaby 
3868c19a515SJiri Slaby 	/* Look for the translation */
3878c19a515SJiri Slaby 	for (trans = table; trans->from; trans++)
input_event_with_scancode(struct input_dev * input,__u8 type,__u16 code,unsigned int hid,__s32 value)3888c19a515SJiri Slaby 		if (trans->from == from)
3898c19a515SJiri Slaby 			return trans;
3908c19a515SJiri Slaby 
3918c19a515SJiri Slaby 	return NULL;
3928c19a515SJiri Slaby }
3938c19a515SJiri Slaby 
3943b41fb40SVincent Lefevre static void input_event_with_scancode(struct input_dev *input,
3953b41fb40SVincent Lefevre 		__u8 type, __u16 code, unsigned int hid, __s32 value)
3963b41fb40SVincent Lefevre {
hidinput_apple_event(struct hid_device * hid,struct input_dev * input,struct hid_usage * usage,__s32 value)3973b41fb40SVincent Lefevre 	if (type == EV_KEY &&
3983b41fb40SVincent Lefevre 	    (!test_bit(code, input->key)) == value)
3993b41fb40SVincent Lefevre 		input_event(input, EV_MSC, MSC_SCAN, hid);
4003b41fb40SVincent Lefevre 	input_event(input, type, code, value);
4013b41fb40SVincent Lefevre }
4023b41fb40SVincent Lefevre 
4038c19a515SJiri Slaby static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input,
4048c19a515SJiri Slaby 		struct hid_usage *usage, __s32 value)
4058c19a515SJiri Slaby {
4068c19a515SJiri Slaby 	struct apple_sc *asc = hid_get_drvdata(hid);
407a4bc6926SJiri Kosina 	const struct apple_key_translation *trans, *table;
408aec256d0SJoao Moreno 	bool do_translate;
4095476fcf7SKerem Karabay 	u16 code = usage->code;
410fa33382cSBryan Cain 	unsigned int real_fnmode;
4118c19a515SJiri Slaby 
412fa33382cSBryan Cain 	if (fnmode == 3) {
413a0a05054SHilton Chain 		real_fnmode = (asc->quirks & APPLE_IS_NON_APPLE) ? 2 : 1;
414fa33382cSBryan Cain 	} else {
415fa33382cSBryan Cain 		real_fnmode = fnmode;
416fa33382cSBryan Cain 	}
417fa33382cSBryan Cain 
4185476fcf7SKerem Karabay 	if (swap_fn_leftctrl) {
4195476fcf7SKerem Karabay 		trans = apple_find_translation(swapped_fn_leftctrl_keys, code);
4205476fcf7SKerem Karabay 
4215476fcf7SKerem Karabay 		if (trans)
4225476fcf7SKerem Karabay 			code = trans->to;
4235476fcf7SKerem Karabay 	}
4245476fcf7SKerem Karabay 
4255476fcf7SKerem Karabay 	if (iso_layout > 0 || (iso_layout < 0 && (asc->quirks & APPLE_ISO_TILDE_QUIRK) &&
4265476fcf7SKerem Karabay 			hid->country == HID_COUNTRY_INTERNATIONAL_ISO)) {
4275476fcf7SKerem Karabay 		trans = apple_find_translation(apple_iso_keyboard, code);
4285476fcf7SKerem Karabay 
4295476fcf7SKerem Karabay 		if (trans)
4305476fcf7SKerem Karabay 			code = trans->to;
4315476fcf7SKerem Karabay 	}
4325476fcf7SKerem Karabay 
4335476fcf7SKerem Karabay 	if (swap_opt_cmd) {
43472e49cadSLasse Brun 		if (swap_opt_cmd == 2)
43572e49cadSLasse Brun 			trans = apple_find_translation(swapped_option_cmd_left_keys, code);
43672e49cadSLasse Brun 		else
4375476fcf7SKerem Karabay 			trans = apple_find_translation(swapped_option_cmd_keys, code);
4385476fcf7SKerem Karabay 
4395476fcf7SKerem Karabay 		if (trans)
4405476fcf7SKerem Karabay 			code = trans->to;
4415476fcf7SKerem Karabay 	}
4425476fcf7SKerem Karabay 
443fd7b68b7SAditya Garg 	if (swap_ctrl_cmd) {
444fd7b68b7SAditya Garg 		trans = apple_find_translation(swapped_ctrl_cmd_keys, code);
445fd7b68b7SAditya Garg 
446fd7b68b7SAditya Garg 		if (trans)
447fd7b68b7SAditya Garg 			code = trans->to;
448fd7b68b7SAditya Garg 	}
449fd7b68b7SAditya Garg 
4505476fcf7SKerem Karabay 	if (code == KEY_FN)
4515476fcf7SKerem Karabay 		asc->fn_on = !!value;
4525476fcf7SKerem Karabay 
453fa33382cSBryan Cain 	if (real_fnmode) {
4540fea6fe7SJosé Expósito 		if (hid->product == USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI ||
4550fea6fe7SJosé Expósito 		    hid->product == USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO ||
4560fea6fe7SJosé Expósito 		    hid->product == USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS ||
4570fea6fe7SJosé Expósito 		    hid->product == USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI ||
4580fea6fe7SJosé Expósito 		    hid->product == USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO ||
4590fea6fe7SJosé Expósito 		    hid->product == USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS ||
4600fea6fe7SJosé Expósito 		    hid->product == USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI ||
4610fea6fe7SJosé Expósito 		    hid->product == USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO ||
4620fea6fe7SJosé Expósito 		    hid->product == USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_JIS)
4630fea6fe7SJosé Expósito 			table = magic_keyboard_alu_fn_keys;
464250b369eSJosé Expósito 		else if (hid->product == USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2015 ||
465250b369eSJosé Expósito 			 hid->product == USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2015)
466250b369eSJosé Expósito 			table = magic_keyboard_2015_fn_keys;
4670fea6fe7SJosé Expósito 		else if (hid->product == USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2021 ||
46868eddb06SIevgen Vovk 			 hid->product == USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2024 ||
4697f84e243SJosé Expósito 			 hid->product == USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_FINGERPRINT_2021 ||
4707f84e243SJosé Expósito 			 hid->product == USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2021)
471531cb569SBenjamin Berg 			table = apple2021_fn_keys;
472c5f09b1bSAditya Garg 		else if (hid->product == USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132 ||
473c5f09b1bSAditya Garg 			 hid->product == USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680 ||
474c5f09b1bSAditya Garg 			 hid->product == USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213)
475c5f09b1bSAditya Garg 				table = macbookpro_no_esc_fn_keys;
476c5f09b1bSAditya Garg 		else if (hid->product == USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K ||
477c5f09b1bSAditya Garg 			 hid->product == USB_DEVICE_ID_APPLE_WELLSPRINGT2_J223 ||
478c5f09b1bSAditya Garg 			 hid->product == USB_DEVICE_ID_APPLE_WELLSPRINGT2_J152F)
479c5f09b1bSAditya Garg 				table = macbookpro_dedicated_esc_fn_keys;
480c5f09b1bSAditya Garg 		else if (hid->product == USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K ||
481c5f09b1bSAditya Garg 			 hid->product == USB_DEVICE_ID_APPLE_WELLSPRINGT2_J230K)
482c5f09b1bSAditya Garg 				table = apple_fn_keys;
483531cb569SBenjamin Berg 		else if (hid->product >= USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI &&
484a4bc6926SJiri Kosina 				hid->product <= USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS)
485a4bc6926SJiri Kosina 			table = macbookair_fn_keys;
486a4bc6926SJiri Kosina 		else if (hid->product < 0x21d || hid->product >= 0x300)
487a4bc6926SJiri Kosina 			table = powerbook_fn_keys;
488a4bc6926SJiri Kosina 		else
489a4bc6926SJiri Kosina 			table = apple_fn_keys;
490a4bc6926SJiri Kosina 
4915476fcf7SKerem Karabay 		trans = apple_find_translation(table, code);
49299b9f758SEdgar (gimli) Hucek 
4938c19a515SJiri Slaby 		if (trans) {
4945476fcf7SKerem Karabay 			bool from_is_set = test_bit(trans->from, input->key);
4955476fcf7SKerem Karabay 			bool to_is_set = test_bit(trans->to, input->key);
4965476fcf7SKerem Karabay 
4975476fcf7SKerem Karabay 			if (from_is_set)
498aec256d0SJoao Moreno 				code = trans->from;
4995476fcf7SKerem Karabay 			else if (to_is_set)
500aec256d0SJoao Moreno 				code = trans->to;
501aec256d0SJoao Moreno 
5025476fcf7SKerem Karabay 			if (!(from_is_set || to_is_set)) {
503aec256d0SJoao Moreno 				if (trans->flags & APPLE_FLAG_FKEY) {
504fa33382cSBryan Cain 					switch (real_fnmode) {
505aec256d0SJoao Moreno 					case 1:
506aec256d0SJoao Moreno 						do_translate = !asc->fn_on;
507aec256d0SJoao Moreno 						break;
508aec256d0SJoao Moreno 					case 2:
5098c19a515SJiri Slaby 						do_translate = asc->fn_on;
510aec256d0SJoao Moreno 						break;
511aec256d0SJoao Moreno 					default:
512aec256d0SJoao Moreno 						/* should never happen */
513aec256d0SJoao Moreno 						do_translate = false;
5148c19a515SJiri Slaby 					}
515aec256d0SJoao Moreno 				} else {
516aec256d0SJoao Moreno 					do_translate = asc->fn_on;
517aec256d0SJoao Moreno 				}
518aec256d0SJoao Moreno 
5195476fcf7SKerem Karabay 				if (do_translate)
5205476fcf7SKerem Karabay 					code = trans->to;
521aec256d0SJoao Moreno 			}
5228c19a515SJiri Slaby 		}
5238c19a515SJiri Slaby 
5248c19a515SJiri Slaby 		if (asc->quirks & APPLE_NUMLOCK_EMULATION &&
5255476fcf7SKerem Karabay 				(test_bit(code, asc->pressed_numlock) ||
5268c19a515SJiri Slaby 				test_bit(LED_NUML, input->led))) {
5275476fcf7SKerem Karabay 			trans = apple_find_translation(powerbook_numlock_keys, code);
5288c19a515SJiri Slaby 
5298c19a515SJiri Slaby 			if (trans) {
5308c19a515SJiri Slaby 				if (value)
5315476fcf7SKerem Karabay 					set_bit(code, asc->pressed_numlock);
5328c19a515SJiri Slaby 				else
5335476fcf7SKerem Karabay 					clear_bit(code, asc->pressed_numlock);
5348c19a515SJiri Slaby 
5355476fcf7SKerem Karabay 				code = trans->to;
5368c19a515SJiri Slaby 			}
5375476fcf7SKerem Karabay 		}
5385476fcf7SKerem Karabay 	}
5395476fcf7SKerem Karabay 
5405476fcf7SKerem Karabay 	if (usage->code != code) {
5415476fcf7SKerem Karabay 		input_event_with_scancode(input, usage->type, code, usage->hid, value);
apple_event(struct hid_device * hdev,struct hid_field * field,struct hid_usage * usage,__s32 value)5428c19a515SJiri Slaby 
5438c19a515SJiri Slaby 		return 1;
5448c19a515SJiri Slaby 	}
545346338efSfree5lot 
5468c19a515SJiri Slaby 	return 0;
5478c19a515SJiri Slaby }
5488c19a515SJiri Slaby 
5498c19a515SJiri Slaby static int apple_event(struct hid_device *hdev, struct hid_field *field,
5508c19a515SJiri Slaby 		struct hid_usage *usage, __s32 value)
5518c19a515SJiri Slaby {
5528c19a515SJiri Slaby 	struct apple_sc *asc = hid_get_drvdata(hdev);
5538c19a515SJiri Slaby 
5548c19a515SJiri Slaby 	if (!(hdev->claimed & HID_CLAIMED_INPUT) || !field->hidinput ||
5558c19a515SJiri Slaby 			!usage->type)
5568c19a515SJiri Slaby 		return 0;
5578c19a515SJiri Slaby 
5588c19a515SJiri Slaby 	if ((asc->quirks & APPLE_INVERT_HWHEEL) &&
5598c19a515SJiri Slaby 			usage->code == REL_HWHEEL) {
5603b41fb40SVincent Lefevre 		input_event_with_scancode(field->hidinput->input, usage->type,
5613b41fb40SVincent Lefevre 				usage->code, usage->hid, -value);
5628c19a515SJiri Slaby 		return 1;
5638c19a515SJiri Slaby 	}
5648c19a515SJiri Slaby 
5658c19a515SJiri Slaby 	if ((asc->quirks & APPLE_HAS_FN) &&
5668c19a515SJiri Slaby 			hidinput_apple_event(hdev, field->hidinput->input,
apple_fetch_battery(struct hid_device * hdev)5678c19a515SJiri Slaby 				usage, value))
5688c19a515SJiri Slaby 		return 1;
5698c19a515SJiri Slaby 
5708c19a515SJiri Slaby 
5718c19a515SJiri Slaby 	return 0;
5728c19a515SJiri Slaby }
5738c19a515SJiri Slaby 
5746e143293SJosé Expósito static int apple_fetch_battery(struct hid_device *hdev)
5756e143293SJosé Expósito {
5766e143293SJosé Expósito #ifdef CONFIG_HID_BATTERY_STRENGTH
5776e143293SJosé Expósito 	struct apple_sc *asc = hid_get_drvdata(hdev);
5786e143293SJosé Expósito 	struct hid_report_enum *report_enum;
5796e143293SJosé Expósito 	struct hid_report *report;
5806e143293SJosé Expósito 
5816e143293SJosé Expósito 	if (!(asc->quirks & APPLE_RDESC_BATTERY) || !hdev->battery)
5826e143293SJosé Expósito 		return -1;
5836e143293SJosé Expósito 
5846e143293SJosé Expósito 	report_enum = &hdev->report_enum[hdev->battery_report_type];
5856e143293SJosé Expósito 	report = report_enum->report_id_hash[hdev->battery_report_id];
5866e143293SJosé Expósito 
5876e143293SJosé Expósito 	if (!report || report->maxfield < 1)
5886e143293SJosé Expósito 		return -1;
5896e143293SJosé Expósito 
5906e143293SJosé Expósito 	if (hdev->battery_capacity == hdev->battery_max)
5916e143293SJosé Expósito 		return -1;
5926e143293SJosé Expósito 
apple_battery_timer_tick(struct timer_list * t)5936e143293SJosé Expósito 	hid_hw_request(hdev, report, HID_REQ_GET_REPORT);
5946e143293SJosé Expósito 	return 0;
5956e143293SJosé Expósito #else
5966e143293SJosé Expósito 	return -1;
5976e143293SJosé Expósito #endif
5986e143293SJosé Expósito }
5996e143293SJosé Expósito 
6006e143293SJosé Expósito static void apple_battery_timer_tick(struct timer_list *t)
6016e143293SJosé Expósito {
6026e143293SJosé Expósito 	struct apple_sc *asc = from_timer(asc, t, battery_timer);
6036e143293SJosé Expósito 	struct hid_device *hdev = asc->hdev;
6046e143293SJosé Expósito 
6056e143293SJosé Expósito 	if (apple_fetch_battery(hdev) == 0) {
6066e143293SJosé Expósito 		mod_timer(&asc->battery_timer,
6076e143293SJosé Expósito 			  jiffies + msecs_to_jiffies(APPLE_BATTERY_TIMEOUT_MS));
apple_report_fixup(struct hid_device * hdev,__u8 * rdesc,unsigned int * rsize)6086e143293SJosé Expósito 	}
6096e143293SJosé Expósito }
6106e143293SJosé Expósito 
6118c19a515SJiri Slaby /*
6128c19a515SJiri Slaby  * MacBook JIS keyboard has wrong logical maximum
61367fd71baSMizuho Mori  * Magic Keyboard JIS has wrong logical maximum
6148c19a515SJiri Slaby  */
61573e4008dSNikolai Kondrashov static __u8 *apple_report_fixup(struct hid_device *hdev, __u8 *rdesc,
61673e4008dSNikolai Kondrashov 		unsigned int *rsize)
6178c19a515SJiri Slaby {
6188c19a515SJiri Slaby 	struct apple_sc *asc = hid_get_drvdata(hdev);
6198c19a515SJiri Slaby 
62067fd71baSMizuho Mori 	if(*rsize >=71 && rdesc[70] == 0x65 && rdesc[64] == 0x65) {
62167fd71baSMizuho Mori 		hid_info(hdev,
62267fd71baSMizuho Mori 			 "fixing up Magic Keyboard JIS report descriptor\n");
62367fd71baSMizuho Mori 		rdesc[64] = rdesc[70] = 0xe7;
62467fd71baSMizuho Mori 	}
62567fd71baSMizuho Mori 
62673e4008dSNikolai Kondrashov 	if ((asc->quirks & APPLE_RDESC_JIS) && *rsize >= 60 &&
6278c19a515SJiri Slaby 			rdesc[53] == 0x65 && rdesc[59] == 0x65) {
6284291ee30SJoe Perches 		hid_info(hdev,
6294291ee30SJoe Perches 			 "fixing up MacBook JIS keyboard report descriptor\n");
6308c19a515SJiri Slaby 		rdesc[53] = rdesc[59] = 0xe7;
6318c19a515SJiri Slaby 	}
6326e143293SJosé Expósito 
6336e143293SJosé Expósito 	/*
6346e143293SJosé Expósito 	 * Change the usage from:
6356e143293SJosé Expósito 	 *   0x06, 0x00, 0xff, // Usage Page (Vendor Defined Page 1)  0
6366e143293SJosé Expósito 	 *   0x09, 0x0b,       // Usage (Vendor Usage 0x0b)           3
6376e143293SJosé Expósito 	 * To:
6386e143293SJosé Expósito 	 *   0x05, 0x01,       // Usage Page (Generic Desktop)        0
6396e143293SJosé Expósito 	 *   0x09, 0x06,       // Usage (Keyboard)                    2
6406e143293SJosé Expósito 	 */
6416e143293SJosé Expósito 	if ((asc->quirks & APPLE_RDESC_BATTERY) && *rsize == 83 &&
6426e143293SJosé Expósito 	    rdesc[46] == 0x84 && rdesc[58] == 0x85) {
6436e143293SJosé Expósito 		hid_info(hdev,
6446e143293SJosé Expósito 			 "fixing up Magic Keyboard battery report descriptor\n");
6456e143293SJosé Expósito 		*rsize = *rsize - 1;
6466e143293SJosé Expósito 		rdesc = kmemdup(rdesc + 1, *rsize, GFP_KERNEL);
6476e143293SJosé Expósito 		if (!rdesc)
6486e143293SJosé Expósito 			return NULL;
6496e143293SJosé Expósito 
6506e143293SJosé Expósito 		rdesc[0] = 0x05;
6516e143293SJosé Expósito 		rdesc[1] = 0x01;
6526e143293SJosé Expósito 		rdesc[2] = 0x09;
6536e143293SJosé Expósito 		rdesc[3] = 0x06;
6546e143293SJosé Expósito 	}
6556e143293SJosé Expósito 
65673e4008dSNikolai Kondrashov 	return rdesc;
6578c19a515SJiri Slaby }
6588c19a515SJiri Slaby 
6598c19a515SJiri Slaby static void apple_setup_input(struct input_dev *input)
6608c19a515SJiri Slaby {
6618c19a515SJiri Slaby 	set_bit(KEY_NUMLOCK, input->keybit);
6628c19a515SJiri Slaby 
6638c19a515SJiri Slaby 	/* Enable all needed keys */
664f1d1b3a9SJosé Expósito 	apple_setup_key_translation(input, apple_fn_keys);
665f1d1b3a9SJosé Expósito 	apple_setup_key_translation(input, powerbook_fn_keys);
666f1d1b3a9SJosé Expósito 	apple_setup_key_translation(input, powerbook_numlock_keys);
667f1d1b3a9SJosé Expósito 	apple_setup_key_translation(input, apple_iso_keyboard);
apple_input_mapping(struct hid_device * hdev,struct hid_input * hi,struct hid_field * field,struct hid_usage * usage,unsigned long ** bit,int * max)6680fea6fe7SJosé Expósito 	apple_setup_key_translation(input, magic_keyboard_alu_fn_keys);
669250b369eSJosé Expósito 	apple_setup_key_translation(input, magic_keyboard_2015_fn_keys);
670f1d1b3a9SJosé Expósito 	apple_setup_key_translation(input, apple2021_fn_keys);
671c5f09b1bSAditya Garg 	apple_setup_key_translation(input, macbookpro_no_esc_fn_keys);
672c5f09b1bSAditya Garg 	apple_setup_key_translation(input, macbookpro_dedicated_esc_fn_keys);
6738c19a515SJiri Slaby }
6748c19a515SJiri Slaby 
6758c19a515SJiri Slaby static int apple_input_mapping(struct hid_device *hdev, struct hid_input *hi,
6768c19a515SJiri Slaby 		struct hid_field *field, struct hid_usage *usage,
6778c19a515SJiri Slaby 		unsigned long **bit, int *max)
6788c19a515SJiri Slaby {
679a5d81646SHans de Goede 	struct apple_sc *asc = hid_get_drvdata(hdev);
680a5d81646SHans de Goede 
681ee345492SSean O'Brien 	if (usage->hid == (HID_UP_CUSTOM | 0x0003) ||
682e433be92SMansour Behabadi 			usage->hid == (HID_UP_MSVENDOR | 0x0003) ||
683e433be92SMansour Behabadi 			usage->hid == (HID_UP_HPVENDOR2 | 0x0003)) {
6848c19a515SJiri Slaby 		/* The fn key on Apple USB keyboards */
6858c19a515SJiri Slaby 		set_bit(EV_REP, hi->input->evbit);
6868c19a515SJiri Slaby 		hid_map_usage_clear(hi, usage, bit, max, EV_KEY, KEY_FN);
687a5d81646SHans de Goede 		asc->fn_found = true;
6888c19a515SJiri Slaby 		apple_setup_input(hi->input);
apple_input_mapped(struct hid_device * hdev,struct hid_input * hi,struct hid_field * field,struct hid_usage * usage,unsigned long ** bit,int * max)6898c19a515SJiri Slaby 		return 1;
6908c19a515SJiri Slaby 	}
6918c19a515SJiri Slaby 
6928c19a515SJiri Slaby 	/* we want the hid layer to go through standard path (set and ignore) */
6938c19a515SJiri Slaby 	return 0;
6948c19a515SJiri Slaby }
6958c19a515SJiri Slaby 
6968c19a515SJiri Slaby static int apple_input_mapped(struct hid_device *hdev, struct hid_input *hi,
6978c19a515SJiri Slaby 		struct hid_field *field, struct hid_usage *usage,
6988c19a515SJiri Slaby 		unsigned long **bit, int *max)
6998c19a515SJiri Slaby {
7008c19a515SJiri Slaby 	struct apple_sc *asc = hid_get_drvdata(hdev);
7018c19a515SJiri Slaby 
7028c19a515SJiri Slaby 	if (asc->quirks & APPLE_MIGHTYMOUSE) {
7038c19a515SJiri Slaby 		if (usage->hid == HID_GD_Z)
7048c19a515SJiri Slaby 			hid_map_usage(hi, usage, bit, max, EV_REL, REL_HWHEEL);
7058c19a515SJiri Slaby 		else if (usage->code == BTN_1)
7068c19a515SJiri Slaby 			hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_2);
apple_input_configured(struct hid_device * hdev,struct hid_input * hidinput)7078c19a515SJiri Slaby 		else if (usage->code == BTN_2)
7088c19a515SJiri Slaby 			hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_1);
7098c19a515SJiri Slaby 	}
7108c19a515SJiri Slaby 
7118c19a515SJiri Slaby 	return 0;
7128c19a515SJiri Slaby }
7138c19a515SJiri Slaby 
714a5d81646SHans de Goede static int apple_input_configured(struct hid_device *hdev,
715a5d81646SHans de Goede 		struct hid_input *hidinput)
716a5d81646SHans de Goede {
717a5d81646SHans de Goede 	struct apple_sc *asc = hid_get_drvdata(hdev);
718a5d81646SHans de Goede 
719*62485737SAlex Henrie 	if (((asc->quirks & APPLE_HAS_FN) && !asc->fn_found) || apple_is_omoton_kb066(hdev)) {
720a5d81646SHans de Goede 		hid_info(hdev, "Fn key not found (Apple Wireless Keyboard clone?), disabling Fn key handling\n");
721a5fe7864SJosé Expósito 		asc->quirks &= ~APPLE_HAS_FN;
722a5d81646SHans de Goede 	}
723a5d81646SHans de Goede 
724a0a05054SHilton Chain 	if (apple_is_non_apple_keyboard(hdev)) {
apple_backlight_check_support(struct hid_device * hdev)725a0a05054SHilton Chain 		hid_info(hdev, "Non-apple keyboard detected; function keys will default to fnmode=2 behavior\n");
726a0a05054SHilton Chain 		asc->quirks |= APPLE_IS_NON_APPLE;
727fa33382cSBryan Cain 	}
728fa33382cSBryan Cain 
729a5d81646SHans de Goede 	return 0;
730a5d81646SHans de Goede }
731a5d81646SHans de Goede 
7329018eacbSPaul Pawlowski static bool apple_backlight_check_support(struct hid_device *hdev)
7339018eacbSPaul Pawlowski {
7349018eacbSPaul Pawlowski 	int i;
7359018eacbSPaul Pawlowski 	unsigned int hid;
7369018eacbSPaul Pawlowski 	struct hid_report *report;
7379018eacbSPaul Pawlowski 
7389018eacbSPaul Pawlowski 	list_for_each_entry(report, &hdev->report_enum[HID_INPUT_REPORT].report_list, list) {
7399018eacbSPaul Pawlowski 		for (i = 0; i < report->maxfield; i++) {
7409018eacbSPaul Pawlowski 			hid = report->field[i]->usage->hid;
7419018eacbSPaul Pawlowski 			if ((hid & HID_USAGE_PAGE) == HID_UP_MSVENDOR && (hid & HID_USAGE) == 0xf)
apple_backlight_set(struct hid_device * hdev,u16 value,u16 rate)7429018eacbSPaul Pawlowski 				return true;
7439018eacbSPaul Pawlowski 		}
7449018eacbSPaul Pawlowski 	}
7459018eacbSPaul Pawlowski 
7469018eacbSPaul Pawlowski 	return false;
7479018eacbSPaul Pawlowski }
7489018eacbSPaul Pawlowski 
7499018eacbSPaul Pawlowski static int apple_backlight_set(struct hid_device *hdev, u16 value, u16 rate)
7509018eacbSPaul Pawlowski {
7519018eacbSPaul Pawlowski 	int ret = 0;
7529018eacbSPaul Pawlowski 	struct apple_backlight_set_report *rep;
7539018eacbSPaul Pawlowski 
7549018eacbSPaul Pawlowski 	rep = kmalloc(sizeof(*rep), GFP_KERNEL);
7559018eacbSPaul Pawlowski 	if (rep == NULL)
7569018eacbSPaul Pawlowski 		return -ENOMEM;
7579018eacbSPaul Pawlowski 
7589018eacbSPaul Pawlowski 	rep->report_id = 0xB0;
7599018eacbSPaul Pawlowski 	rep->version = 1;
7609018eacbSPaul Pawlowski 	rep->backlight = value;
7619018eacbSPaul Pawlowski 	rep->rate = rate;
7629018eacbSPaul Pawlowski 
apple_backlight_led_set(struct led_classdev * led_cdev,enum led_brightness brightness)7639018eacbSPaul Pawlowski 	ret = hid_hw_raw_request(hdev, 0xB0u, (u8 *) rep, sizeof(*rep),
7649018eacbSPaul Pawlowski 				 HID_OUTPUT_REPORT, HID_REQ_SET_REPORT);
7659018eacbSPaul Pawlowski 
7669018eacbSPaul Pawlowski 	kfree(rep);
7679018eacbSPaul Pawlowski 	return ret;
7689018eacbSPaul Pawlowski }
7699018eacbSPaul Pawlowski 
7709018eacbSPaul Pawlowski static int apple_backlight_led_set(struct led_classdev *led_cdev,
7719018eacbSPaul Pawlowski 	enum led_brightness brightness)
apple_backlight_init(struct hid_device * hdev)7729018eacbSPaul Pawlowski {
7739018eacbSPaul Pawlowski 	struct apple_sc_backlight *backlight = container_of(led_cdev,
7749018eacbSPaul Pawlowski 							    struct apple_sc_backlight, cdev);
7759018eacbSPaul Pawlowski 
7769018eacbSPaul Pawlowski 	return apple_backlight_set(backlight->hdev, brightness, 0);
7779018eacbSPaul Pawlowski }
7789018eacbSPaul Pawlowski 
7799018eacbSPaul Pawlowski static int apple_backlight_init(struct hid_device *hdev)
7809018eacbSPaul Pawlowski {
7819018eacbSPaul Pawlowski 	int ret;
7829018eacbSPaul Pawlowski 	struct apple_sc *asc = hid_get_drvdata(hdev);
7839018eacbSPaul Pawlowski 	struct apple_backlight_config_report *rep;
7849018eacbSPaul Pawlowski 
7859018eacbSPaul Pawlowski 	if (!apple_backlight_check_support(hdev))
7869018eacbSPaul Pawlowski 		return -EINVAL;
7879018eacbSPaul Pawlowski 
7889018eacbSPaul Pawlowski 	rep = kmalloc(0x200, GFP_KERNEL);
7899018eacbSPaul Pawlowski 	if (rep == NULL)
7909018eacbSPaul Pawlowski 		return -ENOMEM;
7919018eacbSPaul Pawlowski 
7929018eacbSPaul Pawlowski 	ret = hid_hw_raw_request(hdev, 0xBFu, (u8 *) rep, sizeof(*rep),
7939018eacbSPaul Pawlowski 				 HID_FEATURE_REPORT, HID_REQ_GET_REPORT);
7949018eacbSPaul Pawlowski 	if (ret < 0) {
7959018eacbSPaul Pawlowski 		hid_err(hdev, "backlight request failed: %d\n", ret);
7969018eacbSPaul Pawlowski 		goto cleanup_and_exit;
7979018eacbSPaul Pawlowski 	}
7989018eacbSPaul Pawlowski 	if (ret < 8 || rep->version != 1) {
7999018eacbSPaul Pawlowski 		hid_err(hdev, "backlight config struct: bad version %i\n", rep->version);
8009018eacbSPaul Pawlowski 		ret = -EINVAL;
8019018eacbSPaul Pawlowski 		goto cleanup_and_exit;
8029018eacbSPaul Pawlowski 	}
8039018eacbSPaul Pawlowski 
8049018eacbSPaul Pawlowski 	hid_dbg(hdev, "backlight config: off=%u, on_min=%u, on_max=%u\n",
8059018eacbSPaul Pawlowski 		rep->backlight_off, rep->backlight_on_min, rep->backlight_on_max);
8069018eacbSPaul Pawlowski 
8079018eacbSPaul Pawlowski 	asc->backlight = devm_kzalloc(&hdev->dev, sizeof(*asc->backlight), GFP_KERNEL);
8089018eacbSPaul Pawlowski 	if (!asc->backlight) {
8099018eacbSPaul Pawlowski 		ret = -ENOMEM;
8109018eacbSPaul Pawlowski 		goto cleanup_and_exit;
8119018eacbSPaul Pawlowski 	}
8129018eacbSPaul Pawlowski 
8139018eacbSPaul Pawlowski 	asc->backlight->hdev = hdev;
8149018eacbSPaul Pawlowski 	asc->backlight->cdev.name = "apple::kbd_backlight";
8159018eacbSPaul Pawlowski 	asc->backlight->cdev.max_brightness = rep->backlight_on_max;
8169018eacbSPaul Pawlowski 	asc->backlight->cdev.brightness_set_blocking = apple_backlight_led_set;
8179018eacbSPaul Pawlowski 
8189018eacbSPaul Pawlowski 	ret = apple_backlight_set(hdev, 0, 0);
8199018eacbSPaul Pawlowski 	if (ret < 0) {
8209018eacbSPaul Pawlowski 		hid_err(hdev, "backlight set request failed: %d\n", ret);
8219018eacbSPaul Pawlowski 		goto cleanup_and_exit;
8229018eacbSPaul Pawlowski 	}
8239018eacbSPaul Pawlowski 
apple_probe(struct hid_device * hdev,const struct hid_device_id * id)8249018eacbSPaul Pawlowski 	ret = devm_led_classdev_register(&hdev->dev, &asc->backlight->cdev);
8259018eacbSPaul Pawlowski 
8269018eacbSPaul Pawlowski cleanup_and_exit:
8279018eacbSPaul Pawlowski 	kfree(rep);
8289018eacbSPaul Pawlowski 	return ret;
8299018eacbSPaul Pawlowski }
8309018eacbSPaul Pawlowski 
8318c19a515SJiri Slaby static int apple_probe(struct hid_device *hdev,
8328c19a515SJiri Slaby 		const struct hid_device_id *id)
8338c19a515SJiri Slaby {
8348c19a515SJiri Slaby 	unsigned long quirks = id->driver_data;
8358c19a515SJiri Slaby 	struct apple_sc *asc;
8368c19a515SJiri Slaby 	int ret;
8378c19a515SJiri Slaby 
838abf832bfSBenjamin Tissoires 	asc = devm_kzalloc(&hdev->dev, sizeof(*asc), GFP_KERNEL);
8398c19a515SJiri Slaby 	if (asc == NULL) {
8404291ee30SJoe Perches 		hid_err(hdev, "can't alloc apple descriptor\n");
8418c19a515SJiri Slaby 		return -ENOMEM;
8428c19a515SJiri Slaby 	}
8438c19a515SJiri Slaby 
8446e143293SJosé Expósito 	asc->hdev = hdev;
8458c19a515SJiri Slaby 	asc->quirks = quirks;
8468c19a515SJiri Slaby 
8478c19a515SJiri Slaby 	hid_set_drvdata(hdev, asc);
8488c19a515SJiri Slaby 
8498c19a515SJiri Slaby 	ret = hid_parse(hdev);
8508c19a515SJiri Slaby 	if (ret) {
8514291ee30SJoe Perches 		hid_err(hdev, "parse failed\n");
852abf832bfSBenjamin Tissoires 		return ret;
8538c19a515SJiri Slaby 	}
8548c19a515SJiri Slaby 
855cc840942SAlexander F. Lent 	ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
8568c19a515SJiri Slaby 	if (ret) {
8574291ee30SJoe Perches 		hid_err(hdev, "hw start failed\n");
8588c19a515SJiri Slaby 		return ret;
8598c19a515SJiri Slaby 	}
8608c19a515SJiri Slaby 
8616e143293SJosé Expósito 	timer_setup(&asc->battery_timer, apple_battery_timer_tick, 0);
8626e143293SJosé Expósito 	mod_timer(&asc->battery_timer,
8636e143293SJosé Expósito 		  jiffies + msecs_to_jiffies(APPLE_BATTERY_TIMEOUT_MS));
8646e143293SJosé Expósito 	apple_fetch_battery(hdev);
apple_remove(struct hid_device * hdev)8656e143293SJosé Expósito 
8669018eacbSPaul Pawlowski 	if (quirks & APPLE_BACKLIGHT_CTL)
8679018eacbSPaul Pawlowski 		apple_backlight_init(hdev);
8689018eacbSPaul Pawlowski 
869abf832bfSBenjamin Tissoires 	return 0;
8708c19a515SJiri Slaby }
8718c19a515SJiri Slaby 
8726e143293SJosé Expósito static void apple_remove(struct hid_device *hdev)
8736e143293SJosé Expósito {
8746e143293SJosé Expósito 	struct apple_sc *asc = hid_get_drvdata(hdev);
8756e143293SJosé Expósito 
8766e143293SJosé Expósito 	del_timer_sync(&asc->battery_timer);
8776e143293SJosé Expósito 
8786e143293SJosé Expósito 	hid_hw_stop(hdev);
8796e143293SJosé Expósito }
8806e143293SJosé Expósito 
8818c19a515SJiri Slaby static const struct hid_device_id apple_devices[] = {
8828c19a515SJiri Slaby 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE),
8838c19a515SJiri Slaby 		.driver_data = APPLE_MIGHTYMOUSE | APPLE_INVERT_HWHEEL },
8848c19a515SJiri Slaby 
8858c19a515SJiri Slaby 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI),
886b4d8e473SJiri Slaby 		.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
8878c19a515SJiri Slaby 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ISO),
888b4d8e473SJiri Slaby 		.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
8898c19a515SJiri Slaby 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ANSI),
890b4d8e473SJiri Slaby 		.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
8918c19a515SJiri Slaby 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ISO),
892bd77a0f0SAlex Henrie 		.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
8938c19a515SJiri Slaby 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_JIS),
894b4d8e473SJiri Slaby 		.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
8958c19a515SJiri Slaby 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ANSI),
896b4d8e473SJiri Slaby 		.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
8978c19a515SJiri Slaby 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ISO),
89829e1ecc1SAlex Henrie 		.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
89929e1ecc1SAlex Henrie 			APPLE_ISO_TILDE_QUIRK },
9008c19a515SJiri Slaby 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_JIS),
9018c19a515SJiri Slaby 		.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
902b4d8e473SJiri Slaby 			APPLE_RDESC_JIS },
9038c19a515SJiri Slaby 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ANSI),
904b4d8e473SJiri Slaby 		.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
9058c19a515SJiri Slaby 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ISO),
906c3388ddcSAlex Henrie 		.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
907c3388ddcSAlex Henrie 			APPLE_ISO_TILDE_QUIRK },
9088c19a515SJiri Slaby 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_JIS),
9098c19a515SJiri Slaby 		.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
910b4d8e473SJiri Slaby 			APPLE_RDESC_JIS },
911fef3f571SRyan Finnie 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_MINI_ANSI),
912fef3f571SRyan Finnie 		.driver_data = APPLE_HAS_FN },
913fef3f571SRyan Finnie 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_MINI_ISO),
914bd77a0f0SAlex Henrie 		.driver_data = APPLE_HAS_FN },
915fef3f571SRyan Finnie 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_MINI_JIS),
916fef3f571SRyan Finnie 		.driver_data = APPLE_HAS_FN },
9178c19a515SJiri Slaby 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ANSI),
9188c19a515SJiri Slaby 		.driver_data = APPLE_HAS_FN },
9198c19a515SJiri Slaby 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ISO),
920bd77a0f0SAlex Henrie 		.driver_data = APPLE_HAS_FN },
9218c19a515SJiri Slaby 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_JIS),
9228c19a515SJiri Slaby 		.driver_data = APPLE_HAS_FN },
9238c19a515SJiri Slaby 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ANSI),
924b4d8e473SJiri Slaby 		.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
9258c19a515SJiri Slaby 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO),
926c3388ddcSAlex Henrie 		.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
927c3388ddcSAlex Henrie 			APPLE_ISO_TILDE_QUIRK },
9288c19a515SJiri Slaby 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS),
9298c19a515SJiri Slaby 		.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
930b4d8e473SJiri Slaby 			APPLE_RDESC_JIS },
9314a4c8799SDan Bastone 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_ANSI),
9324a4c8799SDan Bastone 		.driver_data = APPLE_HAS_FN },
933ebe0b42aSHaochen Tong 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_ANSI),
934ebe0b42aSHaochen Tong 		.driver_data = APPLE_HAS_FN },
9354a4c8799SDan Bastone 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_ISO),
936bd77a0f0SAlex Henrie 		.driver_data = APPLE_HAS_FN },
9374c945426SBALATON Zoltan 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_ISO),
9384c945426SBALATON Zoltan 		.driver_data = APPLE_HAS_FN },
9394a4c8799SDan Bastone 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_JIS),
9404a4c8799SDan Bastone 		.driver_data = APPLE_HAS_FN },
941ee8a1a0aSJan Scholz 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI),
9428c19a515SJiri Slaby 		.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
943ee8a1a0aSJan Scholz 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO),
944d58cf34aSAlex Henrie 		.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
945d58cf34aSAlex Henrie 			APPLE_ISO_TILDE_QUIRK },
946ad734bc1SAndreas Krist 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO),
947d58cf34aSAlex Henrie 		.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
948d58cf34aSAlex Henrie 			APPLE_ISO_TILDE_QUIRK },
9490a97e1e9SAlexey Kaminsky 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
9500a97e1e9SAlexey Kaminsky 				USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI),
9510a97e1e9SAlexey Kaminsky 		.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
952bd4a7ce1SHuei-Horng Yo 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
953bd4a7ce1SHuei-Horng Yo 				USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_JIS),
954bd4a7ce1SHuei-Horng Yo 		.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
955ee8a1a0aSJan Scholz 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS),
9568c19a515SJiri Slaby 		.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
957371a9dceSAlex Henrie 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2015),
9586e143293SJosé Expósito 		.driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_RDESC_BATTERY },
959371a9dceSAlex Henrie 	{ HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2015),
960d58cf34aSAlex Henrie 		.driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
961371a9dceSAlex Henrie 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2015),
9626e143293SJosé Expósito 		.driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_RDESC_BATTERY },
963371a9dceSAlex Henrie 	{ HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2015),
964d58cf34aSAlex Henrie 		.driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
9658c19a515SJiri Slaby 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ANSI),
966b4d8e473SJiri Slaby 		.driver_data = APPLE_HAS_FN },
9678c19a515SJiri Slaby 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ISO),
968c3388ddcSAlex Henrie 		.driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
9698c19a515SJiri Slaby 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_JIS),
970b4d8e473SJiri Slaby 		.driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
9718c19a515SJiri Slaby 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI),
972b4d8e473SJiri Slaby 		.driver_data = APPLE_HAS_FN },
9738c19a515SJiri Slaby 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ISO),
974c3388ddcSAlex Henrie 		.driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
9758c19a515SJiri Slaby 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_JIS),
976b4d8e473SJiri Slaby 		.driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
977a96d6ef3SHenrik Rydberg 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI),
978a96d6ef3SHenrik Rydberg 		.driver_data = APPLE_HAS_FN },
979a96d6ef3SHenrik Rydberg 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ISO),
980c3388ddcSAlex Henrie 		.driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
981a96d6ef3SHenrik Rydberg 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_JIS),
982a96d6ef3SHenrik Rydberg 		.driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
98399b9f758SEdgar (gimli) Hucek 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI),
98499b9f758SEdgar (gimli) Hucek 		.driver_data = APPLE_HAS_FN },
98599b9f758SEdgar (gimli) Hucek 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4_ISO),
986c3388ddcSAlex Henrie 		.driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
98799b9f758SEdgar (gimli) Hucek 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4_JIS),
98899b9f758SEdgar (gimli) Hucek 		.driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
98999b9f758SEdgar (gimli) Hucek 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_ANSI),
99099b9f758SEdgar (gimli) Hucek 		.driver_data = APPLE_HAS_FN },
99199b9f758SEdgar (gimli) Hucek 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_ISO),
992c3388ddcSAlex Henrie 		.driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
99399b9f758SEdgar (gimli) Hucek 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS),
99499b9f758SEdgar (gimli) Hucek 		.driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
99547340bd9SAndy Botting 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI),
99647340bd9SAndy Botting 		.driver_data = APPLE_HAS_FN },
99747340bd9SAndy Botting 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_ISO),
998e26a7805SAlex Henrie 		.driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
99947340bd9SAndy Botting 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_JIS),
100047340bd9SAndy Botting 		.driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
10015d922baaSJoshua V. Dillon 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_ANSI),
10025d922baaSJoshua V. Dillon 		.driver_data = APPLE_HAS_FN },
10035d922baaSJoshua V. Dillon 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_ISO),
1004e26a7805SAlex Henrie 		.driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
10055d922baaSJoshua V. Dillon 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_JIS),
10065d922baaSJoshua V. Dillon 		.driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
1007d762cc29SNobuhiro Iwamatsu 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_ANSI),
1008d762cc29SNobuhiro Iwamatsu 		.driver_data = APPLE_HAS_FN },
1009d762cc29SNobuhiro Iwamatsu 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_ISO),
1010e26a7805SAlex Henrie 		.driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
1011d762cc29SNobuhiro Iwamatsu 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_JIS),
1012d762cc29SNobuhiro Iwamatsu 		.driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
1013213f9da8SGökçen Eraslan 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5A_ANSI),
1014213f9da8SGökçen Eraslan 		.driver_data = APPLE_HAS_FN },
1015213f9da8SGökçen Eraslan 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5A_ISO),
1016e26a7805SAlex Henrie 		.driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
1017213f9da8SGökçen Eraslan 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5A_JIS),
1018213f9da8SGökçen Eraslan 		.driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
1019b2e6ad7dSRyan Bourgeois 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI),
1020b2e6ad7dSRyan Bourgeois 		.driver_data = APPLE_HAS_FN },
1021b2e6ad7dSRyan Bourgeois 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_ISO),
1022e26a7805SAlex Henrie 		.driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
1023b2e6ad7dSRyan Bourgeois 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_JIS),
1024b2e6ad7dSRyan Bourgeois 		.driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
10258d80da90SDirk Hohndel 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_ANSI),
10268d80da90SDirk Hohndel 		.driver_data = APPLE_HAS_FN },
10278d80da90SDirk Hohndel 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO),
1028e26a7805SAlex Henrie 		.driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
10298d80da90SDirk Hohndel 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS),
10308d80da90SDirk Hohndel 		.driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
10319d9a04eeSDmitry Torokhov 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING8_ANSI),
10329d9a04eeSDmitry Torokhov 		.driver_data = APPLE_HAS_FN },
10339d9a04eeSDmitry Torokhov 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING8_ISO),
1034e26a7805SAlex Henrie 		.driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
10359d9a04eeSDmitry Torokhov 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING8_JIS),
10369d9a04eeSDmitry Torokhov 		.driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
1037a4a2c545SHenrik Rydberg 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_ANSI),
1038a4a2c545SHenrik Rydberg 		.driver_data = APPLE_HAS_FN },
1039a4a2c545SHenrik Rydberg 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_ISO),
1040e26a7805SAlex Henrie 		.driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
1041a4a2c545SHenrik Rydberg 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_JIS),
1042a4a2c545SHenrik Rydberg 		.driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
104342f6a2d3SAun-Ali Zaidi 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K),
1044084bc074SKerem Karabay 		.driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL | APPLE_ISO_TILDE_QUIRK },
104542f6a2d3SAun-Ali Zaidi 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132),
1046084bc074SKerem Karabay 		.driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL | APPLE_ISO_TILDE_QUIRK },
104742f6a2d3SAun-Ali Zaidi 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680),
1048084bc074SKerem Karabay 		.driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL | APPLE_ISO_TILDE_QUIRK },
104942f6a2d3SAun-Ali Zaidi 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213),
1050084bc074SKerem Karabay 		.driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL | APPLE_ISO_TILDE_QUIRK },
105142f6a2d3SAun-Ali Zaidi 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K),
1052084bc074SKerem Karabay 		.driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
105342f6a2d3SAun-Ali Zaidi 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J223),
1054084bc074SKerem Karabay 		.driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
105542f6a2d3SAun-Ali Zaidi 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J230K),
1056084bc074SKerem Karabay 		.driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
105742f6a2d3SAun-Ali Zaidi 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J152F),
1058084bc074SKerem Karabay 		.driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
105923aeb61eSChristian Schuerer-Waldheim 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI),
106023aeb61eSChristian Schuerer-Waldheim 		.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
106123aeb61eSChristian Schuerer-Waldheim 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO),
1062d58cf34aSAlex Henrie 		.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
1063d58cf34aSAlex Henrie 			APPLE_ISO_TILDE_QUIRK },
106423aeb61eSChristian Schuerer-Waldheim 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS),
106523aeb61eSChristian Schuerer-Waldheim 		.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
10668c19a515SJiri Slaby 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY),
1067b4d8e473SJiri Slaby 		.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
10688c19a515SJiri Slaby 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY),
1069b4d8e473SJiri Slaby 		.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
10700cd3be51SAlex Henrie 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2021),
10718ae5c16cSJosé Expósito 		.driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_RDESC_BATTERY },
10720cd3be51SAlex Henrie 	{ HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2021),
1073d58cf34aSAlex Henrie 		.driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
107468eddb06SIevgen Vovk 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2024),
107568eddb06SIevgen Vovk 		.driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_RDESC_BATTERY },
107668eddb06SIevgen Vovk 	{ HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2024),
107768eddb06SIevgen Vovk 		.driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
10789f92d61fSAlex Henrie 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_FINGERPRINT_2021),
1079cbfcfbfcSJosé Expósito 		.driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_RDESC_BATTERY },
10809f92d61fSAlex Henrie 	{ HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_FINGERPRINT_2021),
10819f92d61fSAlex Henrie 		.driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
1082b2dcadefSAlex Henrie 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2021),
1083cbfcfbfcSJosé Expósito 		.driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_RDESC_BATTERY },
1084b2dcadefSAlex Henrie 	{ HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2021),
1085b2dcadefSAlex Henrie 		.driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
10868c19a515SJiri Slaby 
10878c19a515SJiri Slaby 	{ }
10888c19a515SJiri Slaby };
10898c19a515SJiri Slaby MODULE_DEVICE_TABLE(hid, apple_devices);
10908c19a515SJiri Slaby 
10918c19a515SJiri Slaby static struct hid_driver apple_driver = {
10928c19a515SJiri Slaby 	.name = "apple",
10938c19a515SJiri Slaby 	.id_table = apple_devices,
10948c19a515SJiri Slaby 	.report_fixup = apple_report_fixup,
10958c19a515SJiri Slaby 	.probe = apple_probe,
10966e143293SJosé Expósito 	.remove = apple_remove,
10978c19a515SJiri Slaby 	.event = apple_event,
10988c19a515SJiri Slaby 	.input_mapping = apple_input_mapping,
10998c19a515SJiri Slaby 	.input_mapped = apple_input_mapped,
1100a5d81646SHans de Goede 	.input_configured = apple_input_configured,
11018c19a515SJiri Slaby };
1102f425458eSH Hartley Sweeten module_hid_driver(apple_driver);
11038c19a515SJiri Slaby 
11048c19a515SJiri Slaby MODULE_LICENSE("GPL");
1105