2121#include <linux/module.h>
2222#include <linux/slab.h>
2323#include <linux/timer.h>
24+ #include <linux/string.h>
2425
2526#include "hid-ids.h"
2627
3536#define APPLE_NUMLOCK_EMULATION BIT(8)
3637#define APPLE_RDESC_BATTERY BIT(9)
3738#define APPLE_BACKLIGHT_CTL BIT(10)
39+ #define APPLE_IS_KEYCHRON BIT(11)
3840
3941#define APPLE_FLAG_FKEY 0x01
4042
4143#define HID_COUNTRY_INTERNATIONAL_ISO 13
4244#define APPLE_BATTERY_TIMEOUT_MS 60000
4345
44- static unsigned int fnmode = 1 ;
46+ static unsigned int fnmode = 3 ;
4547module_param (fnmode , uint , 0644 );
4648MODULE_PARM_DESC (fnmode , "Mode of fn key on Apple keyboards (0 = disabled, "
47- "[1] = fkeyslast, 2 = fkeysfirst)" );
49+ "1 = fkeyslast, 2 = fkeysfirst, [3] = auto )" );
4850
4951static int iso_layout = -1 ;
5052module_param (iso_layout , int , 0644 );
@@ -349,6 +351,7 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input,
349351 const struct apple_key_translation * trans , * table ;
350352 bool do_translate ;
351353 u16 code = 0 ;
354+ unsigned int real_fnmode ;
352355
353356 u16 fn_keycode = (swap_fn_leftctrl ) ? (KEY_LEFTCTRL ) : (KEY_FN );
354357
@@ -359,7 +362,13 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input,
359362 return 1 ;
360363 }
361364
362- if (fnmode ) {
365+ if (fnmode == 3 ) {
366+ real_fnmode = (asc -> quirks & APPLE_IS_KEYCHRON ) ? 2 : 1 ;
367+ } else {
368+ real_fnmode = fnmode ;
369+ }
370+
371+ if (real_fnmode ) {
363372 if (hid -> product == USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI ||
364373 hid -> product == USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO ||
365374 hid -> product == USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS ||
@@ -406,7 +415,7 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input,
406415
407416 if (!code ) {
408417 if (trans -> flags & APPLE_FLAG_FKEY ) {
409- switch (fnmode ) {
418+ switch (real_fnmode ) {
410419 case 1 :
411420 do_translate = !asc -> fn_on ;
412421 break ;
@@ -660,6 +669,11 @@ static int apple_input_configured(struct hid_device *hdev,
660669 asc -> quirks &= ~APPLE_HAS_FN ;
661670 }
662671
672+ if (strncmp (hdev -> name , "Keychron" , 8 ) == 0 ) {
673+ hid_info (hdev , "Keychron keyboard detected; function keys will default to fnmode=2 behavior\n" );
674+ asc -> quirks |= APPLE_IS_KEYCHRON ;
675+ }
676+
663677 return 0 ;
664678}
665679
0 commit comments