18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci *  USB HID quirks support for Linux
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci *  Copyright (c) 1999 Andreas Gal
68c2ecf20Sopenharmony_ci *  Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz>
78c2ecf20Sopenharmony_ci *  Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc
88c2ecf20Sopenharmony_ci *  Copyright (c) 2006-2007 Jiri Kosina
98c2ecf20Sopenharmony_ci *  Copyright (c) 2008 Jiri Slaby <jirislaby@gmail.com>
108c2ecf20Sopenharmony_ci */
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_ci/*
138c2ecf20Sopenharmony_ci */
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_ci#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
168c2ecf20Sopenharmony_ci
178c2ecf20Sopenharmony_ci#include <linux/device.h>
188c2ecf20Sopenharmony_ci#include <linux/hid.h>
198c2ecf20Sopenharmony_ci#include <linux/module.h>
208c2ecf20Sopenharmony_ci#include <linux/slab.h>
218c2ecf20Sopenharmony_ci
228c2ecf20Sopenharmony_ci#include "hid-ids.h"
238c2ecf20Sopenharmony_ci
248c2ecf20Sopenharmony_ci#define APPLE_RDESC_JIS		0x0001
258c2ecf20Sopenharmony_ci#define APPLE_IGNORE_MOUSE	0x0002
268c2ecf20Sopenharmony_ci#define APPLE_HAS_FN		0x0004
278c2ecf20Sopenharmony_ci#define APPLE_HIDDEV		0x0008
288c2ecf20Sopenharmony_ci/* 0x0010 reserved, was: APPLE_ISO_KEYBOARD */
298c2ecf20Sopenharmony_ci#define APPLE_MIGHTYMOUSE	0x0020
308c2ecf20Sopenharmony_ci#define APPLE_INVERT_HWHEEL	0x0040
318c2ecf20Sopenharmony_ci#define APPLE_IGNORE_HIDINPUT	0x0080
328c2ecf20Sopenharmony_ci#define APPLE_NUMLOCK_EMULATION	0x0100
338c2ecf20Sopenharmony_ci
348c2ecf20Sopenharmony_ci#define APPLE_FLAG_FKEY		0x01
358c2ecf20Sopenharmony_ci
368c2ecf20Sopenharmony_ci#define HID_COUNTRY_INTERNATIONAL_ISO	13
378c2ecf20Sopenharmony_ci
388c2ecf20Sopenharmony_cistatic unsigned int fnmode = 1;
398c2ecf20Sopenharmony_cimodule_param(fnmode, uint, 0644);
408c2ecf20Sopenharmony_ciMODULE_PARM_DESC(fnmode, "Mode of fn key on Apple keyboards (0 = disabled, "
418c2ecf20Sopenharmony_ci		"[1] = fkeyslast, 2 = fkeysfirst)");
428c2ecf20Sopenharmony_ci
438c2ecf20Sopenharmony_cistatic unsigned int iso_layout = 1;
448c2ecf20Sopenharmony_cimodule_param(iso_layout, uint, 0644);
458c2ecf20Sopenharmony_ciMODULE_PARM_DESC(iso_layout, "Enable/Disable hardcoded ISO-layout of the keyboard. "
468c2ecf20Sopenharmony_ci		"(0 = disabled, [1] = enabled)");
478c2ecf20Sopenharmony_ci
488c2ecf20Sopenharmony_cistatic unsigned int swap_opt_cmd;
498c2ecf20Sopenharmony_cimodule_param(swap_opt_cmd, uint, 0644);
508c2ecf20Sopenharmony_ciMODULE_PARM_DESC(swap_opt_cmd, "Swap the Option (\"Alt\") and Command (\"Flag\") keys. "
518c2ecf20Sopenharmony_ci		"(For people who want to keep Windows PC keyboard muscle memory. "
528c2ecf20Sopenharmony_ci		"[0] = as-is, Mac layout. 1 = swapped, Windows layout.)");
538c2ecf20Sopenharmony_ci
548c2ecf20Sopenharmony_cistatic unsigned int swap_fn_leftctrl;
558c2ecf20Sopenharmony_cimodule_param(swap_fn_leftctrl, uint, 0644);
568c2ecf20Sopenharmony_ciMODULE_PARM_DESC(swap_fn_leftctrl, "Swap the Fn and left Control keys. "
578c2ecf20Sopenharmony_ci		"(For people who want to keep PC keyboard muscle memory. "
588c2ecf20Sopenharmony_ci		"[0] = as-is, Mac layout, 1 = swapped, PC layout)");
598c2ecf20Sopenharmony_ci
608c2ecf20Sopenharmony_cistruct apple_sc {
618c2ecf20Sopenharmony_ci	unsigned long quirks;
628c2ecf20Sopenharmony_ci	unsigned int fn_on;
638c2ecf20Sopenharmony_ci	unsigned int fn_found;
648c2ecf20Sopenharmony_ci	DECLARE_BITMAP(pressed_numlock, KEY_CNT);
658c2ecf20Sopenharmony_ci};
668c2ecf20Sopenharmony_ci
678c2ecf20Sopenharmony_cistruct apple_key_translation {
688c2ecf20Sopenharmony_ci	u16 from;
698c2ecf20Sopenharmony_ci	u16 to;
708c2ecf20Sopenharmony_ci	u8 flags;
718c2ecf20Sopenharmony_ci};
728c2ecf20Sopenharmony_ci
738c2ecf20Sopenharmony_cistatic const struct apple_key_translation apple2021_fn_keys[] = {
748c2ecf20Sopenharmony_ci	{ KEY_BACKSPACE, KEY_DELETE },
758c2ecf20Sopenharmony_ci	{ KEY_ENTER,	KEY_INSERT },
768c2ecf20Sopenharmony_ci	{ KEY_F1,	KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY },
778c2ecf20Sopenharmony_ci	{ KEY_F2,	KEY_BRIGHTNESSUP,   APPLE_FLAG_FKEY },
788c2ecf20Sopenharmony_ci	{ KEY_F3,	KEY_SCALE,          APPLE_FLAG_FKEY },
798c2ecf20Sopenharmony_ci	{ KEY_F4,	KEY_SEARCH,         APPLE_FLAG_FKEY },
808c2ecf20Sopenharmony_ci	{ KEY_F5,	KEY_MICMUTE,        APPLE_FLAG_FKEY },
818c2ecf20Sopenharmony_ci	{ KEY_F6,	KEY_SLEEP,          APPLE_FLAG_FKEY },
828c2ecf20Sopenharmony_ci	{ KEY_F7,	KEY_PREVIOUSSONG,   APPLE_FLAG_FKEY },
838c2ecf20Sopenharmony_ci	{ KEY_F8,	KEY_PLAYPAUSE,      APPLE_FLAG_FKEY },
848c2ecf20Sopenharmony_ci	{ KEY_F9,	KEY_NEXTSONG,       APPLE_FLAG_FKEY },
858c2ecf20Sopenharmony_ci	{ KEY_F10,	KEY_MUTE,           APPLE_FLAG_FKEY },
868c2ecf20Sopenharmony_ci	{ KEY_F11,	KEY_VOLUMEDOWN,     APPLE_FLAG_FKEY },
878c2ecf20Sopenharmony_ci	{ KEY_F12,	KEY_VOLUMEUP,       APPLE_FLAG_FKEY },
888c2ecf20Sopenharmony_ci	{ KEY_UP,	KEY_PAGEUP },
898c2ecf20Sopenharmony_ci	{ KEY_DOWN,	KEY_PAGEDOWN },
908c2ecf20Sopenharmony_ci	{ KEY_LEFT,	KEY_HOME },
918c2ecf20Sopenharmony_ci	{ KEY_RIGHT,	KEY_END },
928c2ecf20Sopenharmony_ci	{ }
938c2ecf20Sopenharmony_ci};
948c2ecf20Sopenharmony_ci
958c2ecf20Sopenharmony_cistatic const struct apple_key_translation macbookair_fn_keys[] = {
968c2ecf20Sopenharmony_ci	{ KEY_BACKSPACE, KEY_DELETE },
978c2ecf20Sopenharmony_ci	{ KEY_ENTER,	KEY_INSERT },
988c2ecf20Sopenharmony_ci	{ KEY_F1,	KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY },
998c2ecf20Sopenharmony_ci	{ KEY_F2,	KEY_BRIGHTNESSUP,   APPLE_FLAG_FKEY },
1008c2ecf20Sopenharmony_ci	{ KEY_F3,	KEY_SCALE,          APPLE_FLAG_FKEY },
1018c2ecf20Sopenharmony_ci	{ KEY_F4,	KEY_DASHBOARD,      APPLE_FLAG_FKEY },
1028c2ecf20Sopenharmony_ci	{ KEY_F6,	KEY_PREVIOUSSONG,   APPLE_FLAG_FKEY },
1038c2ecf20Sopenharmony_ci	{ KEY_F7,	KEY_PLAYPAUSE,      APPLE_FLAG_FKEY },
1048c2ecf20Sopenharmony_ci	{ KEY_F8,	KEY_NEXTSONG,       APPLE_FLAG_FKEY },
1058c2ecf20Sopenharmony_ci	{ KEY_F9,	KEY_MUTE,           APPLE_FLAG_FKEY },
1068c2ecf20Sopenharmony_ci	{ KEY_F10,	KEY_VOLUMEDOWN,     APPLE_FLAG_FKEY },
1078c2ecf20Sopenharmony_ci	{ KEY_F11,	KEY_VOLUMEUP,       APPLE_FLAG_FKEY },
1088c2ecf20Sopenharmony_ci	{ KEY_F12,	KEY_EJECTCD,        APPLE_FLAG_FKEY },
1098c2ecf20Sopenharmony_ci	{ KEY_UP,	KEY_PAGEUP },
1108c2ecf20Sopenharmony_ci	{ KEY_DOWN,	KEY_PAGEDOWN },
1118c2ecf20Sopenharmony_ci	{ KEY_LEFT,	KEY_HOME },
1128c2ecf20Sopenharmony_ci	{ KEY_RIGHT,	KEY_END },
1138c2ecf20Sopenharmony_ci	{ }
1148c2ecf20Sopenharmony_ci};
1158c2ecf20Sopenharmony_ci
1168c2ecf20Sopenharmony_cistatic const struct apple_key_translation apple_fn_keys[] = {
1178c2ecf20Sopenharmony_ci	{ KEY_BACKSPACE, KEY_DELETE },
1188c2ecf20Sopenharmony_ci	{ KEY_ENTER,	KEY_INSERT },
1198c2ecf20Sopenharmony_ci	{ KEY_F1,	KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY },
1208c2ecf20Sopenharmony_ci	{ KEY_F2,	KEY_BRIGHTNESSUP,   APPLE_FLAG_FKEY },
1218c2ecf20Sopenharmony_ci	{ KEY_F3,	KEY_SCALE,          APPLE_FLAG_FKEY },
1228c2ecf20Sopenharmony_ci	{ KEY_F4,	KEY_DASHBOARD,      APPLE_FLAG_FKEY },
1238c2ecf20Sopenharmony_ci	{ KEY_F5,	KEY_KBDILLUMDOWN,   APPLE_FLAG_FKEY },
1248c2ecf20Sopenharmony_ci	{ KEY_F6,	KEY_KBDILLUMUP,     APPLE_FLAG_FKEY },
1258c2ecf20Sopenharmony_ci	{ KEY_F7,	KEY_PREVIOUSSONG,   APPLE_FLAG_FKEY },
1268c2ecf20Sopenharmony_ci	{ KEY_F8,	KEY_PLAYPAUSE,      APPLE_FLAG_FKEY },
1278c2ecf20Sopenharmony_ci	{ KEY_F9,	KEY_NEXTSONG,       APPLE_FLAG_FKEY },
1288c2ecf20Sopenharmony_ci	{ KEY_F10,	KEY_MUTE,           APPLE_FLAG_FKEY },
1298c2ecf20Sopenharmony_ci	{ KEY_F11,	KEY_VOLUMEDOWN,     APPLE_FLAG_FKEY },
1308c2ecf20Sopenharmony_ci	{ KEY_F12,	KEY_VOLUMEUP,       APPLE_FLAG_FKEY },
1318c2ecf20Sopenharmony_ci	{ KEY_UP,	KEY_PAGEUP },
1328c2ecf20Sopenharmony_ci	{ KEY_DOWN,	KEY_PAGEDOWN },
1338c2ecf20Sopenharmony_ci	{ KEY_LEFT,	KEY_HOME },
1348c2ecf20Sopenharmony_ci	{ KEY_RIGHT,	KEY_END },
1358c2ecf20Sopenharmony_ci	{ }
1368c2ecf20Sopenharmony_ci};
1378c2ecf20Sopenharmony_ci
1388c2ecf20Sopenharmony_cistatic const struct apple_key_translation powerbook_fn_keys[] = {
1398c2ecf20Sopenharmony_ci	{ KEY_BACKSPACE, KEY_DELETE },
1408c2ecf20Sopenharmony_ci	{ KEY_F1,	KEY_BRIGHTNESSDOWN,     APPLE_FLAG_FKEY },
1418c2ecf20Sopenharmony_ci	{ KEY_F2,	KEY_BRIGHTNESSUP,       APPLE_FLAG_FKEY },
1428c2ecf20Sopenharmony_ci	{ KEY_F3,	KEY_MUTE,               APPLE_FLAG_FKEY },
1438c2ecf20Sopenharmony_ci	{ KEY_F4,	KEY_VOLUMEDOWN,         APPLE_FLAG_FKEY },
1448c2ecf20Sopenharmony_ci	{ KEY_F5,	KEY_VOLUMEUP,           APPLE_FLAG_FKEY },
1458c2ecf20Sopenharmony_ci	{ KEY_F6,	KEY_NUMLOCK,            APPLE_FLAG_FKEY },
1468c2ecf20Sopenharmony_ci	{ KEY_F7,	KEY_SWITCHVIDEOMODE,    APPLE_FLAG_FKEY },
1478c2ecf20Sopenharmony_ci	{ KEY_F8,	KEY_KBDILLUMTOGGLE,     APPLE_FLAG_FKEY },
1488c2ecf20Sopenharmony_ci	{ KEY_F9,	KEY_KBDILLUMDOWN,       APPLE_FLAG_FKEY },
1498c2ecf20Sopenharmony_ci	{ KEY_F10,	KEY_KBDILLUMUP,         APPLE_FLAG_FKEY },
1508c2ecf20Sopenharmony_ci	{ KEY_UP,	KEY_PAGEUP },
1518c2ecf20Sopenharmony_ci	{ KEY_DOWN,	KEY_PAGEDOWN },
1528c2ecf20Sopenharmony_ci	{ KEY_LEFT,	KEY_HOME },
1538c2ecf20Sopenharmony_ci	{ KEY_RIGHT,	KEY_END },
1548c2ecf20Sopenharmony_ci	{ }
1558c2ecf20Sopenharmony_ci};
1568c2ecf20Sopenharmony_ci
1578c2ecf20Sopenharmony_cistatic const struct apple_key_translation powerbook_numlock_keys[] = {
1588c2ecf20Sopenharmony_ci	{ KEY_J,	KEY_KP1 },
1598c2ecf20Sopenharmony_ci	{ KEY_K,	KEY_KP2 },
1608c2ecf20Sopenharmony_ci	{ KEY_L,	KEY_KP3 },
1618c2ecf20Sopenharmony_ci	{ KEY_U,	KEY_KP4 },
1628c2ecf20Sopenharmony_ci	{ KEY_I,	KEY_KP5 },
1638c2ecf20Sopenharmony_ci	{ KEY_O,	KEY_KP6 },
1648c2ecf20Sopenharmony_ci	{ KEY_7,	KEY_KP7 },
1658c2ecf20Sopenharmony_ci	{ KEY_8,	KEY_KP8 },
1668c2ecf20Sopenharmony_ci	{ KEY_9,	KEY_KP9 },
1678c2ecf20Sopenharmony_ci	{ KEY_M,	KEY_KP0 },
1688c2ecf20Sopenharmony_ci	{ KEY_DOT,	KEY_KPDOT },
1698c2ecf20Sopenharmony_ci	{ KEY_SLASH,	KEY_KPPLUS },
1708c2ecf20Sopenharmony_ci	{ KEY_SEMICOLON, KEY_KPMINUS },
1718c2ecf20Sopenharmony_ci	{ KEY_P,	KEY_KPASTERISK },
1728c2ecf20Sopenharmony_ci	{ KEY_MINUS,	KEY_KPEQUAL },
1738c2ecf20Sopenharmony_ci	{ KEY_0,	KEY_KPSLASH },
1748c2ecf20Sopenharmony_ci	{ KEY_F6,	KEY_NUMLOCK },
1758c2ecf20Sopenharmony_ci	{ KEY_KPENTER,	KEY_KPENTER },
1768c2ecf20Sopenharmony_ci	{ KEY_BACKSPACE, KEY_BACKSPACE },
1778c2ecf20Sopenharmony_ci	{ }
1788c2ecf20Sopenharmony_ci};
1798c2ecf20Sopenharmony_ci
1808c2ecf20Sopenharmony_cistatic const struct apple_key_translation apple_iso_keyboard[] = {
1818c2ecf20Sopenharmony_ci	{ KEY_GRAVE,	KEY_102ND },
1828c2ecf20Sopenharmony_ci	{ KEY_102ND,	KEY_GRAVE },
1838c2ecf20Sopenharmony_ci	{ }
1848c2ecf20Sopenharmony_ci};
1858c2ecf20Sopenharmony_ci
1868c2ecf20Sopenharmony_cistatic const struct apple_key_translation swapped_option_cmd_keys[] = {
1878c2ecf20Sopenharmony_ci	{ KEY_LEFTALT,	KEY_LEFTMETA },
1888c2ecf20Sopenharmony_ci	{ KEY_LEFTMETA,	KEY_LEFTALT },
1898c2ecf20Sopenharmony_ci	{ KEY_RIGHTALT,	KEY_RIGHTMETA },
1908c2ecf20Sopenharmony_ci	{ KEY_RIGHTMETA,KEY_RIGHTALT },
1918c2ecf20Sopenharmony_ci	{ }
1928c2ecf20Sopenharmony_ci};
1938c2ecf20Sopenharmony_ci
1948c2ecf20Sopenharmony_cistatic const struct apple_key_translation swapped_fn_leftctrl_keys[] = {
1958c2ecf20Sopenharmony_ci	{ KEY_FN, KEY_LEFTCTRL },
1968c2ecf20Sopenharmony_ci	{ }
1978c2ecf20Sopenharmony_ci};
1988c2ecf20Sopenharmony_ci
1998c2ecf20Sopenharmony_cistatic const struct apple_key_translation *apple_find_translation(
2008c2ecf20Sopenharmony_ci		const struct apple_key_translation *table, u16 from)
2018c2ecf20Sopenharmony_ci{
2028c2ecf20Sopenharmony_ci	const struct apple_key_translation *trans;
2038c2ecf20Sopenharmony_ci
2048c2ecf20Sopenharmony_ci	/* Look for the translation */
2058c2ecf20Sopenharmony_ci	for (trans = table; trans->from; trans++)
2068c2ecf20Sopenharmony_ci		if (trans->from == from)
2078c2ecf20Sopenharmony_ci			return trans;
2088c2ecf20Sopenharmony_ci
2098c2ecf20Sopenharmony_ci	return NULL;
2108c2ecf20Sopenharmony_ci}
2118c2ecf20Sopenharmony_ci
2128c2ecf20Sopenharmony_cistatic int hidinput_apple_event(struct hid_device *hid, struct input_dev *input,
2138c2ecf20Sopenharmony_ci		struct hid_usage *usage, __s32 value)
2148c2ecf20Sopenharmony_ci{
2158c2ecf20Sopenharmony_ci	struct apple_sc *asc = hid_get_drvdata(hid);
2168c2ecf20Sopenharmony_ci	const struct apple_key_translation *trans, *table;
2178c2ecf20Sopenharmony_ci	bool do_translate;
2188c2ecf20Sopenharmony_ci	u16 code = 0;
2198c2ecf20Sopenharmony_ci
2208c2ecf20Sopenharmony_ci	u16 fn_keycode = (swap_fn_leftctrl) ? (KEY_LEFTCTRL) : (KEY_FN);
2218c2ecf20Sopenharmony_ci
2228c2ecf20Sopenharmony_ci	if (usage->code == fn_keycode) {
2238c2ecf20Sopenharmony_ci		asc->fn_on = !!value;
2248c2ecf20Sopenharmony_ci		input_event(input, usage->type, KEY_FN, value);
2258c2ecf20Sopenharmony_ci		return 1;
2268c2ecf20Sopenharmony_ci	}
2278c2ecf20Sopenharmony_ci
2288c2ecf20Sopenharmony_ci	if (fnmode) {
2298c2ecf20Sopenharmony_ci		if (hid->product == USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2021)
2308c2ecf20Sopenharmony_ci			table = apple2021_fn_keys;
2318c2ecf20Sopenharmony_ci		else if (hid->product >= USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI &&
2328c2ecf20Sopenharmony_ci				hid->product <= USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS)
2338c2ecf20Sopenharmony_ci			table = macbookair_fn_keys;
2348c2ecf20Sopenharmony_ci		else if (hid->product < 0x21d || hid->product >= 0x300)
2358c2ecf20Sopenharmony_ci			table = powerbook_fn_keys;
2368c2ecf20Sopenharmony_ci		else
2378c2ecf20Sopenharmony_ci			table = apple_fn_keys;
2388c2ecf20Sopenharmony_ci
2398c2ecf20Sopenharmony_ci		trans = apple_find_translation (table, usage->code);
2408c2ecf20Sopenharmony_ci
2418c2ecf20Sopenharmony_ci		if (trans) {
2428c2ecf20Sopenharmony_ci			if (test_bit(trans->from, input->key))
2438c2ecf20Sopenharmony_ci				code = trans->from;
2448c2ecf20Sopenharmony_ci			else if (test_bit(trans->to, input->key))
2458c2ecf20Sopenharmony_ci				code = trans->to;
2468c2ecf20Sopenharmony_ci
2478c2ecf20Sopenharmony_ci			if (!code) {
2488c2ecf20Sopenharmony_ci				if (trans->flags & APPLE_FLAG_FKEY) {
2498c2ecf20Sopenharmony_ci					switch (fnmode) {
2508c2ecf20Sopenharmony_ci					case 1:
2518c2ecf20Sopenharmony_ci						do_translate = !asc->fn_on;
2528c2ecf20Sopenharmony_ci						break;
2538c2ecf20Sopenharmony_ci					case 2:
2548c2ecf20Sopenharmony_ci						do_translate = asc->fn_on;
2558c2ecf20Sopenharmony_ci						break;
2568c2ecf20Sopenharmony_ci					default:
2578c2ecf20Sopenharmony_ci						/* should never happen */
2588c2ecf20Sopenharmony_ci						do_translate = false;
2598c2ecf20Sopenharmony_ci					}
2608c2ecf20Sopenharmony_ci				} else {
2618c2ecf20Sopenharmony_ci					do_translate = asc->fn_on;
2628c2ecf20Sopenharmony_ci				}
2638c2ecf20Sopenharmony_ci
2648c2ecf20Sopenharmony_ci				code = do_translate ? trans->to : trans->from;
2658c2ecf20Sopenharmony_ci			}
2668c2ecf20Sopenharmony_ci
2678c2ecf20Sopenharmony_ci			input_event(input, usage->type, code, value);
2688c2ecf20Sopenharmony_ci			return 1;
2698c2ecf20Sopenharmony_ci		}
2708c2ecf20Sopenharmony_ci
2718c2ecf20Sopenharmony_ci		if (asc->quirks & APPLE_NUMLOCK_EMULATION &&
2728c2ecf20Sopenharmony_ci				(test_bit(usage->code, asc->pressed_numlock) ||
2738c2ecf20Sopenharmony_ci				test_bit(LED_NUML, input->led))) {
2748c2ecf20Sopenharmony_ci			trans = apple_find_translation(powerbook_numlock_keys,
2758c2ecf20Sopenharmony_ci					usage->code);
2768c2ecf20Sopenharmony_ci
2778c2ecf20Sopenharmony_ci			if (trans) {
2788c2ecf20Sopenharmony_ci				if (value)
2798c2ecf20Sopenharmony_ci					set_bit(usage->code,
2808c2ecf20Sopenharmony_ci							asc->pressed_numlock);
2818c2ecf20Sopenharmony_ci				else
2828c2ecf20Sopenharmony_ci					clear_bit(usage->code,
2838c2ecf20Sopenharmony_ci							asc->pressed_numlock);
2848c2ecf20Sopenharmony_ci
2858c2ecf20Sopenharmony_ci				input_event(input, usage->type, trans->to,
2868c2ecf20Sopenharmony_ci						value);
2878c2ecf20Sopenharmony_ci			}
2888c2ecf20Sopenharmony_ci
2898c2ecf20Sopenharmony_ci			return 1;
2908c2ecf20Sopenharmony_ci		}
2918c2ecf20Sopenharmony_ci	}
2928c2ecf20Sopenharmony_ci
2938c2ecf20Sopenharmony_ci	if (iso_layout) {
2948c2ecf20Sopenharmony_ci		if (hid->country == HID_COUNTRY_INTERNATIONAL_ISO) {
2958c2ecf20Sopenharmony_ci			trans = apple_find_translation(apple_iso_keyboard, usage->code);
2968c2ecf20Sopenharmony_ci			if (trans) {
2978c2ecf20Sopenharmony_ci				input_event(input, usage->type, trans->to, value);
2988c2ecf20Sopenharmony_ci				return 1;
2998c2ecf20Sopenharmony_ci			}
3008c2ecf20Sopenharmony_ci		}
3018c2ecf20Sopenharmony_ci	}
3028c2ecf20Sopenharmony_ci
3038c2ecf20Sopenharmony_ci	if (swap_opt_cmd) {
3048c2ecf20Sopenharmony_ci		trans = apple_find_translation(swapped_option_cmd_keys, usage->code);
3058c2ecf20Sopenharmony_ci		if (trans) {
3068c2ecf20Sopenharmony_ci			input_event(input, usage->type, trans->to, value);
3078c2ecf20Sopenharmony_ci			return 1;
3088c2ecf20Sopenharmony_ci		}
3098c2ecf20Sopenharmony_ci	}
3108c2ecf20Sopenharmony_ci
3118c2ecf20Sopenharmony_ci	if (swap_fn_leftctrl) {
3128c2ecf20Sopenharmony_ci		trans = apple_find_translation(swapped_fn_leftctrl_keys, usage->code);
3138c2ecf20Sopenharmony_ci		if (trans) {
3148c2ecf20Sopenharmony_ci			input_event(input, usage->type, trans->to, value);
3158c2ecf20Sopenharmony_ci			return 1;
3168c2ecf20Sopenharmony_ci		}
3178c2ecf20Sopenharmony_ci	}
3188c2ecf20Sopenharmony_ci
3198c2ecf20Sopenharmony_ci	return 0;
3208c2ecf20Sopenharmony_ci}
3218c2ecf20Sopenharmony_ci
3228c2ecf20Sopenharmony_cistatic int apple_event(struct hid_device *hdev, struct hid_field *field,
3238c2ecf20Sopenharmony_ci		struct hid_usage *usage, __s32 value)
3248c2ecf20Sopenharmony_ci{
3258c2ecf20Sopenharmony_ci	struct apple_sc *asc = hid_get_drvdata(hdev);
3268c2ecf20Sopenharmony_ci
3278c2ecf20Sopenharmony_ci	if (!(hdev->claimed & HID_CLAIMED_INPUT) || !field->hidinput ||
3288c2ecf20Sopenharmony_ci			!usage->type)
3298c2ecf20Sopenharmony_ci		return 0;
3308c2ecf20Sopenharmony_ci
3318c2ecf20Sopenharmony_ci	if ((asc->quirks & APPLE_INVERT_HWHEEL) &&
3328c2ecf20Sopenharmony_ci			usage->code == REL_HWHEEL) {
3338c2ecf20Sopenharmony_ci		input_event(field->hidinput->input, usage->type, usage->code,
3348c2ecf20Sopenharmony_ci				-value);
3358c2ecf20Sopenharmony_ci		return 1;
3368c2ecf20Sopenharmony_ci	}
3378c2ecf20Sopenharmony_ci
3388c2ecf20Sopenharmony_ci	if ((asc->quirks & APPLE_HAS_FN) &&
3398c2ecf20Sopenharmony_ci			hidinput_apple_event(hdev, field->hidinput->input,
3408c2ecf20Sopenharmony_ci				usage, value))
3418c2ecf20Sopenharmony_ci		return 1;
3428c2ecf20Sopenharmony_ci
3438c2ecf20Sopenharmony_ci
3448c2ecf20Sopenharmony_ci	return 0;
3458c2ecf20Sopenharmony_ci}
3468c2ecf20Sopenharmony_ci
3478c2ecf20Sopenharmony_ci/*
3488c2ecf20Sopenharmony_ci * MacBook JIS keyboard has wrong logical maximum
3498c2ecf20Sopenharmony_ci * Magic Keyboard JIS has wrong logical maximum
3508c2ecf20Sopenharmony_ci */
3518c2ecf20Sopenharmony_cistatic __u8 *apple_report_fixup(struct hid_device *hdev, __u8 *rdesc,
3528c2ecf20Sopenharmony_ci		unsigned int *rsize)
3538c2ecf20Sopenharmony_ci{
3548c2ecf20Sopenharmony_ci	struct apple_sc *asc = hid_get_drvdata(hdev);
3558c2ecf20Sopenharmony_ci
3568c2ecf20Sopenharmony_ci	if(*rsize >=71 && rdesc[70] == 0x65 && rdesc[64] == 0x65) {
3578c2ecf20Sopenharmony_ci		hid_info(hdev,
3588c2ecf20Sopenharmony_ci			 "fixing up Magic Keyboard JIS report descriptor\n");
3598c2ecf20Sopenharmony_ci		rdesc[64] = rdesc[70] = 0xe7;
3608c2ecf20Sopenharmony_ci	}
3618c2ecf20Sopenharmony_ci
3628c2ecf20Sopenharmony_ci	if ((asc->quirks & APPLE_RDESC_JIS) && *rsize >= 60 &&
3638c2ecf20Sopenharmony_ci			rdesc[53] == 0x65 && rdesc[59] == 0x65) {
3648c2ecf20Sopenharmony_ci		hid_info(hdev,
3658c2ecf20Sopenharmony_ci			 "fixing up MacBook JIS keyboard report descriptor\n");
3668c2ecf20Sopenharmony_ci		rdesc[53] = rdesc[59] = 0xe7;
3678c2ecf20Sopenharmony_ci	}
3688c2ecf20Sopenharmony_ci	return rdesc;
3698c2ecf20Sopenharmony_ci}
3708c2ecf20Sopenharmony_ci
3718c2ecf20Sopenharmony_cistatic void apple_setup_input(struct input_dev *input)
3728c2ecf20Sopenharmony_ci{
3738c2ecf20Sopenharmony_ci	const struct apple_key_translation *trans;
3748c2ecf20Sopenharmony_ci
3758c2ecf20Sopenharmony_ci	set_bit(KEY_NUMLOCK, input->keybit);
3768c2ecf20Sopenharmony_ci
3778c2ecf20Sopenharmony_ci	/* Enable all needed keys */
3788c2ecf20Sopenharmony_ci	for (trans = apple_fn_keys; trans->from; trans++)
3798c2ecf20Sopenharmony_ci		set_bit(trans->to, input->keybit);
3808c2ecf20Sopenharmony_ci
3818c2ecf20Sopenharmony_ci	for (trans = powerbook_fn_keys; trans->from; trans++)
3828c2ecf20Sopenharmony_ci		set_bit(trans->to, input->keybit);
3838c2ecf20Sopenharmony_ci
3848c2ecf20Sopenharmony_ci	for (trans = powerbook_numlock_keys; trans->from; trans++)
3858c2ecf20Sopenharmony_ci		set_bit(trans->to, input->keybit);
3868c2ecf20Sopenharmony_ci
3878c2ecf20Sopenharmony_ci	for (trans = apple_iso_keyboard; trans->from; trans++)
3888c2ecf20Sopenharmony_ci		set_bit(trans->to, input->keybit);
3898c2ecf20Sopenharmony_ci
3908c2ecf20Sopenharmony_ci	for (trans = apple2021_fn_keys; trans->from; trans++)
3918c2ecf20Sopenharmony_ci		set_bit(trans->to, input->keybit);
3928c2ecf20Sopenharmony_ci
3938c2ecf20Sopenharmony_ci	if (swap_fn_leftctrl) {
3948c2ecf20Sopenharmony_ci		for (trans = swapped_fn_leftctrl_keys; trans->from; trans++)
3958c2ecf20Sopenharmony_ci			set_bit(trans->to, input->keybit);
3968c2ecf20Sopenharmony_ci	}
3978c2ecf20Sopenharmony_ci}
3988c2ecf20Sopenharmony_ci
3998c2ecf20Sopenharmony_cistatic int apple_input_mapping(struct hid_device *hdev, struct hid_input *hi,
4008c2ecf20Sopenharmony_ci		struct hid_field *field, struct hid_usage *usage,
4018c2ecf20Sopenharmony_ci		unsigned long **bit, int *max)
4028c2ecf20Sopenharmony_ci{
4038c2ecf20Sopenharmony_ci	struct apple_sc *asc = hid_get_drvdata(hdev);
4048c2ecf20Sopenharmony_ci
4058c2ecf20Sopenharmony_ci	if (usage->hid == (HID_UP_CUSTOM | 0x0003) ||
4068c2ecf20Sopenharmony_ci			usage->hid == (HID_UP_MSVENDOR | 0x0003) ||
4078c2ecf20Sopenharmony_ci			usage->hid == (HID_UP_HPVENDOR2 | 0x0003)) {
4088c2ecf20Sopenharmony_ci		/* The fn key on Apple USB keyboards */
4098c2ecf20Sopenharmony_ci		set_bit(EV_REP, hi->input->evbit);
4108c2ecf20Sopenharmony_ci		hid_map_usage_clear(hi, usage, bit, max, EV_KEY, KEY_FN);
4118c2ecf20Sopenharmony_ci		asc->fn_found = true;
4128c2ecf20Sopenharmony_ci		apple_setup_input(hi->input);
4138c2ecf20Sopenharmony_ci		return 1;
4148c2ecf20Sopenharmony_ci	}
4158c2ecf20Sopenharmony_ci
4168c2ecf20Sopenharmony_ci	/* we want the hid layer to go through standard path (set and ignore) */
4178c2ecf20Sopenharmony_ci	return 0;
4188c2ecf20Sopenharmony_ci}
4198c2ecf20Sopenharmony_ci
4208c2ecf20Sopenharmony_cistatic int apple_input_mapped(struct hid_device *hdev, struct hid_input *hi,
4218c2ecf20Sopenharmony_ci		struct hid_field *field, struct hid_usage *usage,
4228c2ecf20Sopenharmony_ci		unsigned long **bit, int *max)
4238c2ecf20Sopenharmony_ci{
4248c2ecf20Sopenharmony_ci	struct apple_sc *asc = hid_get_drvdata(hdev);
4258c2ecf20Sopenharmony_ci
4268c2ecf20Sopenharmony_ci	if (asc->quirks & APPLE_MIGHTYMOUSE) {
4278c2ecf20Sopenharmony_ci		if (usage->hid == HID_GD_Z)
4288c2ecf20Sopenharmony_ci			hid_map_usage(hi, usage, bit, max, EV_REL, REL_HWHEEL);
4298c2ecf20Sopenharmony_ci		else if (usage->code == BTN_1)
4308c2ecf20Sopenharmony_ci			hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_2);
4318c2ecf20Sopenharmony_ci		else if (usage->code == BTN_2)
4328c2ecf20Sopenharmony_ci			hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_1);
4338c2ecf20Sopenharmony_ci	}
4348c2ecf20Sopenharmony_ci
4358c2ecf20Sopenharmony_ci	return 0;
4368c2ecf20Sopenharmony_ci}
4378c2ecf20Sopenharmony_ci
4388c2ecf20Sopenharmony_cistatic int apple_input_configured(struct hid_device *hdev,
4398c2ecf20Sopenharmony_ci		struct hid_input *hidinput)
4408c2ecf20Sopenharmony_ci{
4418c2ecf20Sopenharmony_ci	struct apple_sc *asc = hid_get_drvdata(hdev);
4428c2ecf20Sopenharmony_ci
4438c2ecf20Sopenharmony_ci	if ((asc->quirks & APPLE_HAS_FN) && !asc->fn_found) {
4448c2ecf20Sopenharmony_ci		hid_info(hdev, "Fn key not found (Apple Wireless Keyboard clone?), disabling Fn key handling\n");
4458c2ecf20Sopenharmony_ci		asc->quirks &= ~APPLE_HAS_FN;
4468c2ecf20Sopenharmony_ci	}
4478c2ecf20Sopenharmony_ci
4488c2ecf20Sopenharmony_ci	return 0;
4498c2ecf20Sopenharmony_ci}
4508c2ecf20Sopenharmony_ci
4518c2ecf20Sopenharmony_cistatic int apple_probe(struct hid_device *hdev,
4528c2ecf20Sopenharmony_ci		const struct hid_device_id *id)
4538c2ecf20Sopenharmony_ci{
4548c2ecf20Sopenharmony_ci	unsigned long quirks = id->driver_data;
4558c2ecf20Sopenharmony_ci	struct apple_sc *asc;
4568c2ecf20Sopenharmony_ci	unsigned int connect_mask = HID_CONNECT_DEFAULT;
4578c2ecf20Sopenharmony_ci	int ret;
4588c2ecf20Sopenharmony_ci
4598c2ecf20Sopenharmony_ci	asc = devm_kzalloc(&hdev->dev, sizeof(*asc), GFP_KERNEL);
4608c2ecf20Sopenharmony_ci	if (asc == NULL) {
4618c2ecf20Sopenharmony_ci		hid_err(hdev, "can't alloc apple descriptor\n");
4628c2ecf20Sopenharmony_ci		return -ENOMEM;
4638c2ecf20Sopenharmony_ci	}
4648c2ecf20Sopenharmony_ci
4658c2ecf20Sopenharmony_ci	asc->quirks = quirks;
4668c2ecf20Sopenharmony_ci
4678c2ecf20Sopenharmony_ci	hid_set_drvdata(hdev, asc);
4688c2ecf20Sopenharmony_ci
4698c2ecf20Sopenharmony_ci	ret = hid_parse(hdev);
4708c2ecf20Sopenharmony_ci	if (ret) {
4718c2ecf20Sopenharmony_ci		hid_err(hdev, "parse failed\n");
4728c2ecf20Sopenharmony_ci		return ret;
4738c2ecf20Sopenharmony_ci	}
4748c2ecf20Sopenharmony_ci
4758c2ecf20Sopenharmony_ci	if (quirks & APPLE_HIDDEV)
4768c2ecf20Sopenharmony_ci		connect_mask |= HID_CONNECT_HIDDEV_FORCE;
4778c2ecf20Sopenharmony_ci	if (quirks & APPLE_IGNORE_HIDINPUT)
4788c2ecf20Sopenharmony_ci		connect_mask &= ~HID_CONNECT_HIDINPUT;
4798c2ecf20Sopenharmony_ci
4808c2ecf20Sopenharmony_ci	ret = hid_hw_start(hdev, connect_mask);
4818c2ecf20Sopenharmony_ci	if (ret) {
4828c2ecf20Sopenharmony_ci		hid_err(hdev, "hw start failed\n");
4838c2ecf20Sopenharmony_ci		return ret;
4848c2ecf20Sopenharmony_ci	}
4858c2ecf20Sopenharmony_ci
4868c2ecf20Sopenharmony_ci	return 0;
4878c2ecf20Sopenharmony_ci}
4888c2ecf20Sopenharmony_ci
4898c2ecf20Sopenharmony_cistatic const struct hid_device_id apple_devices[] = {
4908c2ecf20Sopenharmony_ci	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE),
4918c2ecf20Sopenharmony_ci		.driver_data = APPLE_MIGHTYMOUSE | APPLE_INVERT_HWHEEL },
4928c2ecf20Sopenharmony_ci
4938c2ecf20Sopenharmony_ci	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI),
4948c2ecf20Sopenharmony_ci		.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
4958c2ecf20Sopenharmony_ci	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ISO),
4968c2ecf20Sopenharmony_ci		.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
4978c2ecf20Sopenharmony_ci	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ANSI),
4988c2ecf20Sopenharmony_ci		.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
4998c2ecf20Sopenharmony_ci	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ISO),
5008c2ecf20Sopenharmony_ci		.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
5018c2ecf20Sopenharmony_ci	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_JIS),
5028c2ecf20Sopenharmony_ci		.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
5038c2ecf20Sopenharmony_ci	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ANSI),
5048c2ecf20Sopenharmony_ci		.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
5058c2ecf20Sopenharmony_ci	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ISO),
5068c2ecf20Sopenharmony_ci		.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
5078c2ecf20Sopenharmony_ci	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_JIS),
5088c2ecf20Sopenharmony_ci		.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
5098c2ecf20Sopenharmony_ci			APPLE_RDESC_JIS },
5108c2ecf20Sopenharmony_ci	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ANSI),
5118c2ecf20Sopenharmony_ci		.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
5128c2ecf20Sopenharmony_ci	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ISO),
5138c2ecf20Sopenharmony_ci		.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
5148c2ecf20Sopenharmony_ci	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_JIS),
5158c2ecf20Sopenharmony_ci		.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
5168c2ecf20Sopenharmony_ci			APPLE_RDESC_JIS },
5178c2ecf20Sopenharmony_ci	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_MINI_ANSI),
5188c2ecf20Sopenharmony_ci		.driver_data = APPLE_HAS_FN },
5198c2ecf20Sopenharmony_ci	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_MINI_ISO),
5208c2ecf20Sopenharmony_ci		.driver_data = APPLE_HAS_FN },
5218c2ecf20Sopenharmony_ci	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_MINI_JIS),
5228c2ecf20Sopenharmony_ci		.driver_data = APPLE_HAS_FN },
5238c2ecf20Sopenharmony_ci	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ANSI),
5248c2ecf20Sopenharmony_ci		.driver_data = APPLE_HAS_FN },
5258c2ecf20Sopenharmony_ci	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ISO),
5268c2ecf20Sopenharmony_ci		.driver_data = APPLE_HAS_FN },
5278c2ecf20Sopenharmony_ci	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_JIS),
5288c2ecf20Sopenharmony_ci		.driver_data = APPLE_HAS_FN },
5298c2ecf20Sopenharmony_ci	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ANSI),
5308c2ecf20Sopenharmony_ci		.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
5318c2ecf20Sopenharmony_ci	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO),
5328c2ecf20Sopenharmony_ci		.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
5338c2ecf20Sopenharmony_ci	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS),
5348c2ecf20Sopenharmony_ci		.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
5358c2ecf20Sopenharmony_ci			APPLE_RDESC_JIS },
5368c2ecf20Sopenharmony_ci	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_ANSI),
5378c2ecf20Sopenharmony_ci		.driver_data = APPLE_HAS_FN },
5388c2ecf20Sopenharmony_ci	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_ISO),
5398c2ecf20Sopenharmony_ci		.driver_data = APPLE_HAS_FN },
5408c2ecf20Sopenharmony_ci	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_ISO),
5418c2ecf20Sopenharmony_ci		.driver_data = APPLE_HAS_FN },
5428c2ecf20Sopenharmony_ci	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_JIS),
5438c2ecf20Sopenharmony_ci		.driver_data = APPLE_HAS_FN },
5448c2ecf20Sopenharmony_ci	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI),
5458c2ecf20Sopenharmony_ci		.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
5468c2ecf20Sopenharmony_ci	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO),
5478c2ecf20Sopenharmony_ci		.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
5488c2ecf20Sopenharmony_ci	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO),
5498c2ecf20Sopenharmony_ci		.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
5508c2ecf20Sopenharmony_ci	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
5518c2ecf20Sopenharmony_ci				USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI),
5528c2ecf20Sopenharmony_ci		.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
5538c2ecf20Sopenharmony_ci	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
5548c2ecf20Sopenharmony_ci				USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_JIS),
5558c2ecf20Sopenharmony_ci		.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
5568c2ecf20Sopenharmony_ci	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS),
5578c2ecf20Sopenharmony_ci		.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
5588c2ecf20Sopenharmony_ci	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_ANSI),
5598c2ecf20Sopenharmony_ci		.driver_data = APPLE_HAS_FN },
5608c2ecf20Sopenharmony_ci	{ HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_ANSI),
5618c2ecf20Sopenharmony_ci		.driver_data = APPLE_HAS_FN },
5628c2ecf20Sopenharmony_ci	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_ANSI),
5638c2ecf20Sopenharmony_ci		.driver_data = APPLE_HAS_FN },
5648c2ecf20Sopenharmony_ci	{ HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_ANSI),
5658c2ecf20Sopenharmony_ci		.driver_data = APPLE_HAS_FN },
5668c2ecf20Sopenharmony_ci	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ANSI),
5678c2ecf20Sopenharmony_ci		.driver_data = APPLE_HAS_FN },
5688c2ecf20Sopenharmony_ci	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ISO),
5698c2ecf20Sopenharmony_ci		.driver_data = APPLE_HAS_FN },
5708c2ecf20Sopenharmony_ci	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_JIS),
5718c2ecf20Sopenharmony_ci		.driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
5728c2ecf20Sopenharmony_ci	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI),
5738c2ecf20Sopenharmony_ci		.driver_data = APPLE_HAS_FN },
5748c2ecf20Sopenharmony_ci	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ISO),
5758c2ecf20Sopenharmony_ci		.driver_data = APPLE_HAS_FN },
5768c2ecf20Sopenharmony_ci	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_JIS),
5778c2ecf20Sopenharmony_ci		.driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
5788c2ecf20Sopenharmony_ci	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI),
5798c2ecf20Sopenharmony_ci		.driver_data = APPLE_HAS_FN },
5808c2ecf20Sopenharmony_ci	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ISO),
5818c2ecf20Sopenharmony_ci		.driver_data = APPLE_HAS_FN },
5828c2ecf20Sopenharmony_ci	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_JIS),
5838c2ecf20Sopenharmony_ci		.driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
5848c2ecf20Sopenharmony_ci	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI),
5858c2ecf20Sopenharmony_ci		.driver_data = APPLE_HAS_FN },
5868c2ecf20Sopenharmony_ci	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4_ISO),
5878c2ecf20Sopenharmony_ci		.driver_data = APPLE_HAS_FN },
5888c2ecf20Sopenharmony_ci	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4_JIS),
5898c2ecf20Sopenharmony_ci		.driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
5908c2ecf20Sopenharmony_ci	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_ANSI),
5918c2ecf20Sopenharmony_ci		.driver_data = APPLE_HAS_FN },
5928c2ecf20Sopenharmony_ci	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_ISO),
5938c2ecf20Sopenharmony_ci		.driver_data = APPLE_HAS_FN },
5948c2ecf20Sopenharmony_ci	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS),
5958c2ecf20Sopenharmony_ci		.driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
5968c2ecf20Sopenharmony_ci	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI),
5978c2ecf20Sopenharmony_ci		.driver_data = APPLE_HAS_FN },
5988c2ecf20Sopenharmony_ci	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_ISO),
5998c2ecf20Sopenharmony_ci		.driver_data = APPLE_HAS_FN },
6008c2ecf20Sopenharmony_ci	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_JIS),
6018c2ecf20Sopenharmony_ci		.driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
6028c2ecf20Sopenharmony_ci	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_ANSI),
6038c2ecf20Sopenharmony_ci		.driver_data = APPLE_HAS_FN },
6048c2ecf20Sopenharmony_ci	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_ISO),
6058c2ecf20Sopenharmony_ci		.driver_data = APPLE_HAS_FN },
6068c2ecf20Sopenharmony_ci	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_JIS),
6078c2ecf20Sopenharmony_ci		.driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
6088c2ecf20Sopenharmony_ci	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_ANSI),
6098c2ecf20Sopenharmony_ci		.driver_data = APPLE_HAS_FN },
6108c2ecf20Sopenharmony_ci	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_ISO),
6118c2ecf20Sopenharmony_ci		.driver_data = APPLE_HAS_FN },
6128c2ecf20Sopenharmony_ci	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_JIS),
6138c2ecf20Sopenharmony_ci		.driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
6148c2ecf20Sopenharmony_ci	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5A_ANSI),
6158c2ecf20Sopenharmony_ci		.driver_data = APPLE_HAS_FN },
6168c2ecf20Sopenharmony_ci	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5A_ISO),
6178c2ecf20Sopenharmony_ci		.driver_data = APPLE_HAS_FN },
6188c2ecf20Sopenharmony_ci	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5A_JIS),
6198c2ecf20Sopenharmony_ci		.driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
6208c2ecf20Sopenharmony_ci	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI),
6218c2ecf20Sopenharmony_ci		.driver_data = APPLE_HAS_FN },
6228c2ecf20Sopenharmony_ci	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_ISO),
6238c2ecf20Sopenharmony_ci		.driver_data = APPLE_HAS_FN },
6248c2ecf20Sopenharmony_ci	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_JIS),
6258c2ecf20Sopenharmony_ci		.driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
6268c2ecf20Sopenharmony_ci	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_ANSI),
6278c2ecf20Sopenharmony_ci		.driver_data = APPLE_HAS_FN },
6288c2ecf20Sopenharmony_ci	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO),
6298c2ecf20Sopenharmony_ci		.driver_data = APPLE_HAS_FN },
6308c2ecf20Sopenharmony_ci	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS),
6318c2ecf20Sopenharmony_ci		.driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
6328c2ecf20Sopenharmony_ci	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING8_ANSI),
6338c2ecf20Sopenharmony_ci		.driver_data = APPLE_HAS_FN },
6348c2ecf20Sopenharmony_ci	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING8_ISO),
6358c2ecf20Sopenharmony_ci		.driver_data = APPLE_HAS_FN },
6368c2ecf20Sopenharmony_ci	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING8_JIS),
6378c2ecf20Sopenharmony_ci		.driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
6388c2ecf20Sopenharmony_ci	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_ANSI),
6398c2ecf20Sopenharmony_ci		.driver_data = APPLE_HAS_FN },
6408c2ecf20Sopenharmony_ci	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_ISO),
6418c2ecf20Sopenharmony_ci		.driver_data = APPLE_HAS_FN },
6428c2ecf20Sopenharmony_ci	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_JIS),
6438c2ecf20Sopenharmony_ci		.driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
6448c2ecf20Sopenharmony_ci	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI),
6458c2ecf20Sopenharmony_ci		.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
6468c2ecf20Sopenharmony_ci	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO),
6478c2ecf20Sopenharmony_ci		.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
6488c2ecf20Sopenharmony_ci	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS),
6498c2ecf20Sopenharmony_ci		.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
6508c2ecf20Sopenharmony_ci	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY),
6518c2ecf20Sopenharmony_ci		.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
6528c2ecf20Sopenharmony_ci	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY),
6538c2ecf20Sopenharmony_ci		.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
6548c2ecf20Sopenharmony_ci	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2021),
6558c2ecf20Sopenharmony_ci		.driver_data = APPLE_HAS_FN },
6568c2ecf20Sopenharmony_ci	{ HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2021),
6578c2ecf20Sopenharmony_ci		.driver_data = APPLE_HAS_FN },
6588c2ecf20Sopenharmony_ci
6598c2ecf20Sopenharmony_ci	{ }
6608c2ecf20Sopenharmony_ci};
6618c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(hid, apple_devices);
6628c2ecf20Sopenharmony_ci
6638c2ecf20Sopenharmony_cistatic struct hid_driver apple_driver = {
6648c2ecf20Sopenharmony_ci	.name = "apple",
6658c2ecf20Sopenharmony_ci	.id_table = apple_devices,
6668c2ecf20Sopenharmony_ci	.report_fixup = apple_report_fixup,
6678c2ecf20Sopenharmony_ci	.probe = apple_probe,
6688c2ecf20Sopenharmony_ci	.event = apple_event,
6698c2ecf20Sopenharmony_ci	.input_mapping = apple_input_mapping,
6708c2ecf20Sopenharmony_ci	.input_mapped = apple_input_mapped,
6718c2ecf20Sopenharmony_ci	.input_configured = apple_input_configured,
6728c2ecf20Sopenharmony_ci};
6738c2ecf20Sopenharmony_cimodule_hid_driver(apple_driver);
6748c2ecf20Sopenharmony_ci
6758c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL");
676