From 4e960bb550962fe5bfbcbb34ed59c1af9daff9fa Mon Sep 17 00:00:00 2001 From: Aditya Garg Date: Mon, 19 May 2025 17:46:16 +0530 Subject: [PATCH 1/9] HID: apple: move backlight report structs to other backlight structs The apple_backlight_config_report and apple_backlight_set_report structs were incorrectly placed between the translation tables. Fix this. Signed-off-by: Aditya Garg Signed-off-by: Jiri Kosina --- drivers/hid/hid-apple.c | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c index ed34f5cd5a91..6c71baa38715 100644 --- a/drivers/hid/hid-apple.c +++ b/drivers/hid/hid-apple.c @@ -89,6 +89,19 @@ struct apple_sc_backlight { struct hid_device *hdev; }; +struct apple_backlight_config_report { + u8 report_id; + u8 version; + u16 backlight_off, backlight_on_min, backlight_on_max; +}; + +struct apple_backlight_set_report { + u8 report_id; + u8 version; + u16 backlight; + u16 rate; +}; + struct apple_magic_backlight { struct led_classdev cdev; struct hid_report *brightness; @@ -152,20 +165,6 @@ static const struct apple_key_translation magic_keyboard_2015_fn_keys[] = { { } }; -struct apple_backlight_config_report { - u8 report_id; - u8 version; - u16 backlight_off, backlight_on_min, backlight_on_max; -}; - -struct apple_backlight_set_report { - u8 report_id; - u8 version; - u16 backlight; - u16 rate; -}; - - static const struct apple_key_translation apple2021_fn_keys[] = { { KEY_BACKSPACE, KEY_DELETE }, { KEY_ENTER, KEY_INSERT }, From b45944946a19636f7bbded0763b536ce007c3c9b Mon Sep 17 00:00:00 2001 From: Aditya Garg Date: Mon, 19 May 2025 17:46:17 +0530 Subject: [PATCH 2/9] HID: apple: use switch case to set fn translation table There has been a continuous increase in the number of devices requiring hid-apple driver during the last few years. Moreover, unlike previous releases, the PIDs of the newer devices released cannot be combined in a specific range, thus filling up the if else if statements with individual device IDs. For such large table, its now more suitable to use switch case instead of if else if for improved readability. Signed-off-by: Aditya Garg Signed-off-by: Jiri Kosina --- drivers/hid/hid-apple.c | 73 +++++++++++++++++++++++------------------ 1 file changed, 41 insertions(+), 32 deletions(-) diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c index 6c71baa38715..1c8475598f51 100644 --- a/drivers/hid/hid-apple.c +++ b/drivers/hid/hid-apple.c @@ -465,42 +465,51 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input, asc->fn_on = !!value; 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 || - hid->product == USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI || - hid->product == USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO || - hid->product == USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS || - hid->product == USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI || - hid->product == USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO || - hid->product == USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_JIS) + switch (hid->product) { + case USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI: + case USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO: + case USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS: + case USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI: + case USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO: + case USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS: + case USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI: + case USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO: + case USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_JIS: table = magic_keyboard_alu_fn_keys; - else if (hid->product == USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2015 || - hid->product == USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2015) + break; + case USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2015: + case USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2015: table = magic_keyboard_2015_fn_keys; - else if (hid->product == USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2021 || - hid->product == USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2024 || - hid->product == USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_FINGERPRINT_2021 || - hid->product == USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2021) + break; + case USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2021: + case USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2024: + case USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_FINGERPRINT_2021: + case USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2021: table = apple2021_fn_keys; - else if (hid->product == USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132 || - hid->product == USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680 || - hid->product == USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213) - table = macbookpro_no_esc_fn_keys; - else if (hid->product == USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K || - hid->product == USB_DEVICE_ID_APPLE_WELLSPRINGT2_J223 || - hid->product == USB_DEVICE_ID_APPLE_WELLSPRINGT2_J152F) - table = macbookpro_dedicated_esc_fn_keys; - else if (hid->product == USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K || - hid->product == USB_DEVICE_ID_APPLE_WELLSPRINGT2_J230K) - table = apple_fn_keys; - else if (hid->product >= USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI && - hid->product <= USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS) - table = macbookair_fn_keys; - else if (hid->product < 0x21d || hid->product >= 0x300) - table = powerbook_fn_keys; - else + break; + case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132: + case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213: + case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680: + table = macbookpro_no_esc_fn_keys; + break; + case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J152F: + case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K: + case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J223: + table = macbookpro_dedicated_esc_fn_keys; + break; + case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K: + case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J230K: table = apple_fn_keys; + break; + default: + if (hid->product >= USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI && + hid->product <= USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS) + table = macbookair_fn_keys; + else if (hid->product < 0x21d || hid->product >= 0x300) + table = powerbook_fn_keys; + else + table = apple_fn_keys; + } trans = apple_find_translation(table, code); From 46d74dd9b45f84bf8e900447c5b4b69d58733f42 Mon Sep 17 00:00:00 2001 From: Aditya Garg Date: Mon, 19 May 2025 17:46:18 +0530 Subject: [PATCH 3/9] HID: apple: remove unused APPLE_IGNORE_MOUSE quirk The APPLE_IGNORE_MOUSE quirk was not used anywhere in this driver, so can be removed. Signed-off-by: Aditya Garg Signed-off-by: Jiri Kosina --- drivers/hid/hid-apple.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c index 1c8475598f51..7bbc811b06f8 100644 --- a/drivers/hid/hid-apple.c +++ b/drivers/hid/hid-apple.c @@ -30,7 +30,7 @@ #include "hid-ids.h" #define APPLE_RDESC_JIS BIT(0) -#define APPLE_IGNORE_MOUSE BIT(1) +/* BIT(1) reserved, was: APPLE_IGNORE_MOUSE */ #define APPLE_HAS_FN BIT(2) /* BIT(3) reserved, was: APPLE_HIDDEV */ #define APPLE_ISO_TILDE_QUIRK BIT(4) From e77bdf51de070610328255d011c439634a9ea932 Mon Sep 17 00:00:00 2001 From: Grigorii Sokolik Date: Mon, 19 May 2025 17:46:19 +0530 Subject: [PATCH 4/9] HID: apple: Add Apple Magic Keyboard A3118 USB-C support Add Apple Magic Keyboard 2024 with Touch ID device ID (05ac:0321) to those recognized by the hid-apple driver. Keyboard is otherwise compatible with the existing implementation for its earlier 2021 model. Signed-off-by: Grigorii Sokolik Co-developed-by: Aditya Garg Signed-off-by: Aditya Garg Signed-off-by: Jiri Kosina --- drivers/hid/hid-apple.c | 21 +++++++++++++-------- drivers/hid/hid-ids.h | 9 +++++---- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c index 7bbc811b06f8..5c040976638b 100644 --- a/drivers/hid/hid-apple.c +++ b/drivers/hid/hid-apple.c @@ -165,7 +165,7 @@ static const struct apple_key_translation magic_keyboard_2015_fn_keys[] = { { } }; -static const struct apple_key_translation apple2021_fn_keys[] = { +static const struct apple_key_translation magic_keyboard_2021_and_2024_fn_keys[] = { { KEY_BACKSPACE, KEY_DELETE }, { KEY_ENTER, KEY_INSERT }, { KEY_F1, KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY }, @@ -482,10 +482,11 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input, table = magic_keyboard_2015_fn_keys; break; case USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2021: - case USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2024: case USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_FINGERPRINT_2021: case USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2021: - table = apple2021_fn_keys; + case USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2024: + case USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_FINGERPRINT_2024: + table = magic_keyboard_2021_and_2024_fn_keys; break; case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132: case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213: @@ -690,7 +691,7 @@ static void apple_setup_input(struct input_dev *input) apple_setup_key_translation(input, apple_iso_keyboard); apple_setup_key_translation(input, magic_keyboard_alu_fn_keys); apple_setup_key_translation(input, magic_keyboard_2015_fn_keys); - apple_setup_key_translation(input, apple2021_fn_keys); + apple_setup_key_translation(input, magic_keyboard_2021_and_2024_fn_keys); apple_setup_key_translation(input, macbookpro_no_esc_fn_keys); apple_setup_key_translation(input, macbookpro_dedicated_esc_fn_keys); } @@ -1165,10 +1166,6 @@ static const struct hid_device_id apple_devices[] = { .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_RDESC_BATTERY }, { HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2021), .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2024), - .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_RDESC_BATTERY }, - { HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2024), - .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_FINGERPRINT_2021), .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_RDESC_BATTERY }, { HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_FINGERPRINT_2021), @@ -1177,6 +1174,14 @@ static const struct hid_device_id apple_devices[] = { .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_RDESC_BATTERY }, { HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2021), .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2024), + .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_RDESC_BATTERY }, + { HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2024), + .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_FINGERPRINT_2024), + .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_RDESC_BATTERY }, + { HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_FINGERPRINT_2024), + .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_TOUCHBAR_BACKLIGHT), .driver_data = APPLE_MAGIC_BACKLIGHT }, diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index e3fb4e2fe911..6e66067347f7 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -167,6 +167,11 @@ #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_JIS 0x0257 #define USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2015 0x0267 #define USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2015 0x026c +#define USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2021 0x029c +#define USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_FINGERPRINT_2021 0x029a +#define USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2021 0x029f +#define USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2024 0x0320 +#define USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_FINGERPRINT_2024 0x0321 #define USB_DEVICE_ID_APPLE_WELLSPRING8_ANSI 0x0290 #define USB_DEVICE_ID_APPLE_WELLSPRING8_ISO 0x0291 #define USB_DEVICE_ID_APPLE_WELLSPRING8_JIS 0x0292 @@ -188,10 +193,6 @@ #define USB_DEVICE_ID_APPLE_IRCONTROL3 0x8241 #define USB_DEVICE_ID_APPLE_IRCONTROL4 0x8242 #define USB_DEVICE_ID_APPLE_IRCONTROL5 0x8243 -#define USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2021 0x029c -#define USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2024 0x0320 -#define USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_FINGERPRINT_2021 0x029a -#define USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2021 0x029f #define USB_DEVICE_ID_APPLE_TOUCHBAR_BACKLIGHT 0x8102 #define USB_DEVICE_ID_APPLE_TOUCHBAR_DISPLAY 0x8302 From 4604baafaaeeb131dfb8d9325b1e8e90f364c468 Mon Sep 17 00:00:00 2001 From: Aditya Garg Date: Mon, 19 May 2025 17:46:20 +0530 Subject: [PATCH 5/9] HID: apple: Add Apple Magic Keyboard A3119 USB-C support Add Apple Magic Keyboard 2024 with Touch ID and Numeric Keypad device ID (05ac:0322) to those recognized by the hid-apple driver. Keyboard is otherwise compatible with the existing implementation for its earlier 2021 model. Signed-off-by: Aditya Garg Signed-off-by: Jiri Kosina --- drivers/hid/hid-apple.c | 5 +++++ drivers/hid/hid-ids.h | 1 + 2 files changed, 6 insertions(+) diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c index 5c040976638b..d9f13f610b28 100644 --- a/drivers/hid/hid-apple.c +++ b/drivers/hid/hid-apple.c @@ -486,6 +486,7 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input, case USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2021: case USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2024: case USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_FINGERPRINT_2024: + case USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2024: table = magic_keyboard_2021_and_2024_fn_keys; break; case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132: @@ -1182,6 +1183,10 @@ static const struct hid_device_id apple_devices[] = { .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_RDESC_BATTERY }, { HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_FINGERPRINT_2024), .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2024), + .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_RDESC_BATTERY }, + { HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2024), + .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_TOUCHBAR_BACKLIGHT), .driver_data = APPLE_MAGIC_BACKLIGHT }, diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 6e66067347f7..dd0a48595d57 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -172,6 +172,7 @@ #define USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2021 0x029f #define USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2024 0x0320 #define USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_FINGERPRINT_2024 0x0321 +#define USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2024 0x0322 #define USB_DEVICE_ID_APPLE_WELLSPRING8_ANSI 0x0290 #define USB_DEVICE_ID_APPLE_WELLSPRING8_ISO 0x0291 #define USB_DEVICE_ID_APPLE_WELLSPRING8_JIS 0x0292 From a23ff6080e7197922e3a9fd8856e142b612eb50a Mon Sep 17 00:00:00 2001 From: Aditya Garg Date: Mon, 19 May 2025 17:46:21 +0530 Subject: [PATCH 6/9] HID: apple: add fnmode=4 to disable translation of fkeys and make it default on Macs with Touch Bar The kernel now has a dedicated driver for Touch Bar on Macs. Since function keys can now be accessed via the Touch Bar, emulating them using non standard ways like Fn+1=F1 should be avoided. This patch adds an fnmode=4 which ignores only the Function key translation, and is enabled by default on MacBook Pros with a Touch Bar. Signed-off-by: Aditya Garg Signed-off-by: Jiri Kosina --- drivers/hid/hid-apple.c | 90 ++++++++++++++++++++++++----------------- 1 file changed, 54 insertions(+), 36 deletions(-) diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c index d9f13f610b28..155d514fb4c5 100644 --- a/drivers/hid/hid-apple.c +++ b/drivers/hid/hid-apple.c @@ -42,8 +42,10 @@ #define APPLE_BACKLIGHT_CTL BIT(10) #define APPLE_IS_NON_APPLE BIT(11) #define APPLE_MAGIC_BACKLIGHT BIT(12) +#define APPLE_DISABLE_FKEYS BIT(13) -#define APPLE_FLAG_FKEY 0x01 +#define APPLE_FLAG_FKEY BIT(0) +#define APPLE_FLAG_TB_FKEY BIT(1) #define HID_COUNTRY_INTERNATIONAL_ISO 13 #define APPLE_BATTERY_TIMEOUT_MS 60000 @@ -55,7 +57,7 @@ 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, [3] = auto)"); + "1 = fkeyslast, 2 = fkeysfirst, [3] = auto, 4 = fkeysdisabled)"); static int iso_layout = -1; module_param(iso_layout, int, 0644); @@ -121,7 +123,7 @@ struct apple_sc { struct apple_key_translation { u16 from; u16 to; - u8 flags; + unsigned long flags; }; static const struct apple_key_translation magic_keyboard_alu_fn_keys[] = { @@ -211,19 +213,19 @@ static const struct apple_key_translation macbookair_fn_keys[] = { static const struct apple_key_translation macbookpro_no_esc_fn_keys[] = { { KEY_BACKSPACE, KEY_DELETE }, { KEY_ENTER, KEY_INSERT }, - { KEY_GRAVE, KEY_ESC }, - { KEY_1, KEY_F1 }, - { KEY_2, KEY_F2 }, - { KEY_3, KEY_F3 }, - { KEY_4, KEY_F4 }, - { KEY_5, KEY_F5 }, - { KEY_6, KEY_F6 }, - { KEY_7, KEY_F7 }, - { KEY_8, KEY_F8 }, - { KEY_9, KEY_F9 }, - { KEY_0, KEY_F10 }, - { KEY_MINUS, KEY_F11 }, - { KEY_EQUAL, KEY_F12 }, + { KEY_GRAVE, KEY_ESC, APPLE_FLAG_TB_FKEY }, + { KEY_1, KEY_F1, APPLE_FLAG_TB_FKEY }, + { KEY_2, KEY_F2, APPLE_FLAG_TB_FKEY }, + { KEY_3, KEY_F3, APPLE_FLAG_TB_FKEY }, + { KEY_4, KEY_F4, APPLE_FLAG_TB_FKEY }, + { KEY_5, KEY_F5, APPLE_FLAG_TB_FKEY }, + { KEY_6, KEY_F6, APPLE_FLAG_TB_FKEY }, + { KEY_7, KEY_F7, APPLE_FLAG_TB_FKEY }, + { KEY_8, KEY_F8, APPLE_FLAG_TB_FKEY }, + { KEY_9, KEY_F9, APPLE_FLAG_TB_FKEY }, + { KEY_0, KEY_F10, APPLE_FLAG_TB_FKEY }, + { KEY_MINUS, KEY_F11, APPLE_FLAG_TB_FKEY }, + { KEY_EQUAL, KEY_F12, APPLE_FLAG_TB_FKEY }, { KEY_UP, KEY_PAGEUP }, { KEY_DOWN, KEY_PAGEDOWN }, { KEY_LEFT, KEY_HOME }, @@ -234,18 +236,18 @@ static const struct apple_key_translation macbookpro_no_esc_fn_keys[] = { static const struct apple_key_translation macbookpro_dedicated_esc_fn_keys[] = { { KEY_BACKSPACE, KEY_DELETE }, { KEY_ENTER, KEY_INSERT }, - { KEY_1, KEY_F1 }, - { KEY_2, KEY_F2 }, - { KEY_3, KEY_F3 }, - { KEY_4, KEY_F4 }, - { KEY_5, KEY_F5 }, - { KEY_6, KEY_F6 }, - { KEY_7, KEY_F7 }, - { KEY_8, KEY_F8 }, - { KEY_9, KEY_F9 }, - { KEY_0, KEY_F10 }, - { KEY_MINUS, KEY_F11 }, - { KEY_EQUAL, KEY_F12 }, + { KEY_1, KEY_F1, APPLE_FLAG_TB_FKEY }, + { KEY_2, KEY_F2, APPLE_FLAG_TB_FKEY }, + { KEY_3, KEY_F3, APPLE_FLAG_TB_FKEY }, + { KEY_4, KEY_F4, APPLE_FLAG_TB_FKEY }, + { KEY_5, KEY_F5, APPLE_FLAG_TB_FKEY }, + { KEY_6, KEY_F6, APPLE_FLAG_TB_FKEY }, + { KEY_7, KEY_F7, APPLE_FLAG_TB_FKEY }, + { KEY_8, KEY_F8, APPLE_FLAG_TB_FKEY }, + { KEY_9, KEY_F9, APPLE_FLAG_TB_FKEY }, + { KEY_0, KEY_F10, APPLE_FLAG_TB_FKEY }, + { KEY_MINUS, KEY_F11, APPLE_FLAG_TB_FKEY }, + { KEY_EQUAL, KEY_F12, APPLE_FLAG_TB_FKEY }, { KEY_UP, KEY_PAGEUP }, { KEY_DOWN, KEY_PAGEDOWN }, { KEY_LEFT, KEY_HOME }, @@ -424,7 +426,12 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input, unsigned int real_fnmode; if (fnmode == 3) { - real_fnmode = (asc->quirks & APPLE_IS_NON_APPLE) ? 2 : 1; + if (asc->quirks & APPLE_DISABLE_FKEYS) + real_fnmode = 4; + else if (asc->quirks & APPLE_IS_NON_APPLE) + real_fnmode = 2; + else + real_fnmode = 1; } else { real_fnmode = fnmode; } @@ -534,9 +541,17 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input, do_translate = asc->fn_on; break; default: - /* should never happen */ + /* case 4 */ do_translate = false; } + } else if (trans->flags & APPLE_FLAG_TB_FKEY) { + switch (real_fnmode) { + case 4: + do_translate = false; + break; + default: + do_translate = asc->fn_on; + } } else { do_translate = asc->fn_on; } @@ -1139,19 +1154,22 @@ static const struct hid_device_id apple_devices[] = { { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K), .driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL | APPLE_ISO_TILDE_QUIRK }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132), - .driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL | APPLE_ISO_TILDE_QUIRK }, + .driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL | APPLE_ISO_TILDE_QUIRK | + APPLE_DISABLE_FKEYS }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680), - .driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL | APPLE_ISO_TILDE_QUIRK }, + .driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL | APPLE_ISO_TILDE_QUIRK | + APPLE_DISABLE_FKEYS }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213), - .driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL | APPLE_ISO_TILDE_QUIRK }, + .driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL | APPLE_ISO_TILDE_QUIRK | + APPLE_DISABLE_FKEYS }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K), - .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK }, + .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_DISABLE_FKEYS }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J223), - .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK }, + .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_DISABLE_FKEYS }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J230K), .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J152F), - .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK }, + .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_DISABLE_FKEYS }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI), .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO), From c5f3a74310fa807d0383c109799100217f739563 Mon Sep 17 00:00:00 2001 From: Aditya Garg Date: Mon, 19 May 2025 17:46:22 +0530 Subject: [PATCH 7/9] HID: quirks: remove T2 devices from hid_mouse_ignore_list While the T2 devices have been added to hid_mouse_ignore_list, no driver exists outside the HID subsystem for their trackpads. So, remove them and let the trackpad be at least used without the gestures. This patch will also enable using hid-magicmouse for these trackpads later, which is currently wip downstream. Signed-off-by: Aditya Garg Signed-off-by: Jiri Kosina --- drivers/hid/hid-quirks.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c index 7fefeb413ec3..8a418f4878e2 100644 --- a/drivers/hid/hid-quirks.c +++ b/drivers/hid/hid-quirks.c @@ -969,14 +969,6 @@ static const struct hid_device_id hid_mouse_ignore_list[] = { { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_ANSI) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_ISO) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_JIS) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J223) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J230K) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J152F) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, { } From a71338bb8bb1bbaa43e682137d8dc484a1391ea6 Mon Sep 17 00:00:00 2001 From: Aditya Garg Date: Mon, 19 May 2025 17:46:23 +0530 Subject: [PATCH 8/9] HID: apple: Add necessary IDs and support for replacement trackpad on MacBookPro15,1 Some third party trackpad replacements like that of HAWSON may have a different PID than the stock trackpad. This commit adds one such trackpad to hid-apple, available for MacBookPro15,1 Signed-off-by: Aditya Garg Signed-off-by: Jiri Kosina --- drivers/hid/hid-apple.c | 4 ++++ drivers/hid/hid-ids.h | 17 +++++++++-------- drivers/hid/hid-quirks.c | 1 + 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c index 155d514fb4c5..b8b99eb01a35 100644 --- a/drivers/hid/hid-apple.c +++ b/drivers/hid/hid-apple.c @@ -499,6 +499,7 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input, case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132: case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213: case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680: + case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680_ALT: table = macbookpro_no_esc_fn_keys; break; case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J152F: @@ -1159,6 +1160,9 @@ static const struct hid_device_id apple_devices[] = { { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680), .driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL | APPLE_ISO_TILDE_QUIRK | APPLE_DISABLE_FKEYS }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680_ALT), + .driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL | APPLE_ISO_TILDE_QUIRK | + APPLE_DISABLE_FKEYS }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213), .driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL | APPLE_ISO_TILDE_QUIRK | APPLE_DISABLE_FKEYS }, diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index dd0a48595d57..041b80bf3c99 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -179,14 +179,15 @@ #define USB_DEVICE_ID_APPLE_WELLSPRING9_ANSI 0x0272 #define USB_DEVICE_ID_APPLE_WELLSPRING9_ISO 0x0273 #define USB_DEVICE_ID_APPLE_WELLSPRING9_JIS 0x0274 -#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K 0x027a -#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132 0x027b -#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680 0x027c -#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213 0x027d -#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K 0x027e -#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J223 0x027f -#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J230K 0x0280 -#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J152F 0x0340 +#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K 0x027a +#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132 0x027b +#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680 0x027c +#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680_ALT 0x0278 +#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213 0x027d +#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K 0x027e +#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J223 0x027f +#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J230K 0x0280 +#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J152F 0x0340 #define USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY 0x030a #define USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY 0x030b #define USB_DEVICE_ID_APPLE_IRCONTROL 0x8240 diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c index 8a418f4878e2..1fba3b7f6d41 100644 --- a/drivers/hid/hid-quirks.c +++ b/drivers/hid/hid-quirks.c @@ -314,6 +314,7 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680_ALT) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J223) }, From 1bb3363da862e0464ec050eea2fb5472a36ad86b Mon Sep 17 00:00:00 2001 From: Qasim Ijaz Date: Mon, 14 Jul 2025 00:30:08 +0100 Subject: [PATCH 9/9] HID: apple: validate feature-report field count to prevent NULL pointer dereference A malicious HID device with quirk APPLE_MAGIC_BACKLIGHT can trigger a NULL pointer dereference whilst the power feature-report is toggled and sent to the device in apple_magic_backlight_report_set(). The power feature-report is expected to have two data fields, but if the descriptor declares one field then accessing field[1] and dereferencing it in apple_magic_backlight_report_set() becomes invalid since field[1] will be NULL. An example of a minimal descriptor which can cause the crash is something like the following where the report with ID 3 (power report) only references a single 1-byte field. When hid core parses the descriptor it will encounter the final feature tag, allocate a hid_report (all members of field[] will be zeroed out), create field structure and populate it, increasing the maxfield to 1. The subsequent field[1] access and dereference causes the crash. Usage Page (Vendor Defined 0xFF00) Usage (0x0F) Collection (Application) Report ID (1) Usage (0x01) Logical Minimum (0) Logical Maximum (255) Report Size (8) Report Count (1) Feature (Data,Var,Abs) Usage (0x02) Logical Maximum (32767) Report Size (16) Report Count (1) Feature (Data,Var,Abs) Report ID (3) Usage (0x03) Logical Minimum (0) Logical Maximum (1) Report Size (8) Report Count (1) Feature (Data,Var,Abs) End Collection Here we see the KASAN splat when the kernel dereferences the NULL pointer and crashes: [ 15.164723] Oops: general protection fault, probably for non-canonical address 0xdffffc0000000006: 0000 [#1] SMP KASAN NOPTI [ 15.165691] KASAN: null-ptr-deref in range [0x0000000000000030-0x0000000000000037] [ 15.165691] CPU: 0 UID: 0 PID: 10 Comm: kworker/0:1 Not tainted 6.15.0 #31 PREEMPT(voluntary) [ 15.165691] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.2-debian-1.16.2-1 04/01/2014 [ 15.165691] RIP: 0010:apple_magic_backlight_report_set+0xbf/0x210 [ 15.165691] Call Trace: [ 15.165691] [ 15.165691] apple_probe+0x571/0xa20 [ 15.165691] hid_device_probe+0x2e2/0x6f0 [ 15.165691] really_probe+0x1ca/0x5c0 [ 15.165691] __driver_probe_device+0x24f/0x310 [ 15.165691] driver_probe_device+0x4a/0xd0 [ 15.165691] __device_attach_driver+0x169/0x220 [ 15.165691] bus_for_each_drv+0x118/0x1b0 [ 15.165691] __device_attach+0x1d5/0x380 [ 15.165691] device_initial_probe+0x12/0x20 [ 15.165691] bus_probe_device+0x13d/0x180 [ 15.165691] device_add+0xd87/0x1510 [...] To fix this issue we should validate the number of fields that the backlight and power reports have and if they do not have the required number of fields then bail. Fixes: 394ba612f941 ("HID: apple: Add support for magic keyboard backlight on T2 Macs") Cc: stable@vger.kernel.org Signed-off-by: Qasim Ijaz Reviewed-by: Orlando Chamberlain Tested-by: Aditya Garg Link: https://patch.msgid.link/20250713233008.15131-1-qasdev00@gmail.com Signed-off-by: Benjamin Tissoires --- drivers/hid/hid-apple.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c index b8b99eb01a35..78920a8afa85 100644 --- a/drivers/hid/hid-apple.c +++ b/drivers/hid/hid-apple.c @@ -916,7 +916,8 @@ static int apple_magic_backlight_init(struct hid_device *hdev) backlight->brightness = report_enum->report_id_hash[APPLE_MAGIC_REPORT_ID_BRIGHTNESS]; backlight->power = report_enum->report_id_hash[APPLE_MAGIC_REPORT_ID_POWER]; - if (!backlight->brightness || !backlight->power) + if (!backlight->brightness || backlight->brightness->maxfield < 2 || + !backlight->power || backlight->power->maxfield < 2) return -ENODEV; backlight->cdev.name = ":white:" LED_FUNCTION_KBD_BACKLIGHT;