#include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/timer.h>
+#include <linux/string.h>
 
 #include "hid-ids.h"
 
 #define APPLE_NUMLOCK_EMULATION        BIT(8)
 #define APPLE_RDESC_BATTERY    BIT(9)
 #define APPLE_BACKLIGHT_CTL    BIT(10)
+#define APPLE_IS_KEYCHRON      BIT(11)
 
 #define APPLE_FLAG_FKEY                0x01
 
 #define HID_COUNTRY_INTERNATIONAL_ISO  13
 #define APPLE_BATTERY_TIMEOUT_MS       60000
 
-static unsigned int fnmode = 1;
+static unsigned int fnmode = 3;
 module_param(fnmode, uint, 0644);
 MODULE_PARM_DESC(fnmode, "Mode of fn key on Apple keyboards (0 = disabled, "
-               "[1] = fkeyslast, 2 = fkeysfirst)");
+               "1 = fkeyslast, 2 = fkeysfirst, [3] = auto)");
 
 static int iso_layout = -1;
 module_param(iso_layout, int, 0644);
        const struct apple_key_translation *trans, *table;
        bool do_translate;
        u16 code = 0;
+       unsigned int real_fnmode;
 
        u16 fn_keycode = (swap_fn_leftctrl) ? (KEY_LEFTCTRL) : (KEY_FN);
 
                return 1;
        }
 
-       if (fnmode) {
+       if (fnmode == 3) {
+               real_fnmode = (asc->quirks & APPLE_IS_KEYCHRON) ? 2 : 1;
+       } else {
+               real_fnmode = fnmode;
+       }
+
+       if (real_fnmode) {
                if (hid->product == USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI ||
                    hid->product == USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO ||
                    hid->product == USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS ||
 
                        if (!code) {
                                if (trans->flags & APPLE_FLAG_FKEY) {
-                                       switch (fnmode) {
+                                       switch (real_fnmode) {
                                        case 1:
                                                do_translate = !asc->fn_on;
                                                break;
                asc->quirks &= ~APPLE_HAS_FN;
        }
 
+       if (strncmp(hdev->name, "Keychron", 8) == 0) {
+               hid_info(hdev, "Keychron keyboard detected; function keys will default to fnmode=2 behavior\n");
+               asc->quirks |= APPLE_IS_KEYCHRON;
+       }
+
        return 0;
 }