--- drivers/hid/hid-apple.c | 53 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 50 insertions(+), 3 deletions(-) diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c index 4e8b01793..eaafa285a 100644 --- a/drivers/hid/hid-apple.c +++ b/drivers/hid/hid-apple.c @@ -42,6 +42,7 @@ #define APPLE_BACKLIGHT_CTL BIT(10) #define APPLE_IS_NON_APPLE BIT(11) #define APPLE_MAGIC_BACKLIGHT BIT(12) +#define APPLE_IS_OMOTON BIT(13) #define APPLE_FLAG_FKEY 0x01 #define APPLE_FLAG_DONT_TRANSLATE 0x02 @@ -53,6 +54,8 @@ #define APPLE_MAGIC_REPORT_ID_POWER 3 #define APPLE_MAGIC_REPORT_ID_BRIGHTNESS 1 +#define KEY_F6_OMOTON 0xc0301 + static unsigned int fnmode = 3; module_param(fnmode, uint, 0644); MODULE_PARM_DESC(fnmode, "Mode of fn key on Apple keyboards (0 = disabled, " @@ -81,6 +84,8 @@ MODULE_PARM_DESC(swap_fn_leftctrl, "Swap the Fn and left Control keys. " "(For people who want to keep PC keyboard muscle memory. " "[0] = as-is, Mac layout, 1 = swapped, PC layout)"); +bool omoton_media_key; + struct apple_non_apple_keyboard { char *name; }; @@ -276,6 +281,25 @@ static const struct apple_key_translation powerbook_numlock_keys[] = { { } }; +static const struct apple_key_translation omoton_media_keys[] = { + { KEY_F1, KEY_BRIGHTNESSDOWN }, + { KEY_F2, KEY_BRIGHTNESSUP }, + { } +}; + +static const struct apple_key_translation omoton_function_keys[] = { + { KEY_SEARCH, KEY_F3 }, + { KEY_EJECTCD, KEY_F4 }, + { KEY_NUMLOCK, KEY_F5 }, + { KEY_PREVIOUSSONG, KEY_F7 }, + { KEY_PLAYPAUSE, KEY_F8 }, + { KEY_NEXTSONG, KEY_F9 }, + { KEY_MUTE, KEY_F10 }, + { KEY_VOLUMEDOWN, KEY_F11 }, + { KEY_VOLUMEUP, KEY_F12 }, + { } +}; + static const struct apple_key_translation apple_iso_keyboard[] = { { KEY_GRAVE, KEY_102ND }, { KEY_102ND, KEY_GRAVE }, @@ -377,6 +401,25 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input, real_fnmode = fnmode; } + /* Omoton KB066 quirk */ + if (asc->quirks & APPLE_IS_OMOTON) { + real_fnmode = 0; + if (usage->hid == KEY_F6_OMOTON) + code = KEY_F6; + + if (usage->code == KEY_F6) { + if (value == 1) + omoton_media_key = !omoton_media_key; + code = KEY_UNKNOWN; + } + + table = omoton_media_key ? omoton_media_keys : omoton_function_keys; + trans = apple_find_translation(table, code); + + if (trans) + code = trans->to; + } + if (swap_fn_leftctrl) { trans = apple_find_translation(swapped_fn_leftctrl_keys, code); @@ -511,9 +554,6 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input, } } - if (usage->hid == 0xc0301) /* Omoton KB066 quirk */ - code = KEY_F6; - if (usage->code != code) { input_event_with_scancode(input, usage->type, code, usage->hid, value); @@ -701,6 +741,12 @@ static int apple_input_configured(struct hid_device *hdev, asc->quirks |= APPLE_IS_NON_APPLE; } + if (strncmp(hdev->name, "Bluetooth Keyboard", 18) == 0 && + hdev->product == USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI) { + hid_info(hdev, "Omoton keyboard detected; use Fn+F6 to toggle between media and function keys\n"); + asc->quirks |= APPLE_IS_OMOTON; + } + return 0; } @@ -897,6 +943,7 @@ static int apple_probe(struct hid_device *hdev, mod_timer(&asc->battery_timer, jiffies + msecs_to_jiffies(APPLE_BATTERY_TIMEOUT_MS)); apple_fetch_battery(hdev); + omoton_media_key = true; if (quirks & APPLE_BACKLIGHT_CTL) apple_backlight_init(hdev); -- 2.43.0