1616
1717#include <linux/device.h>
1818#include <linux/hid.h>
19+ #include <linux/jiffies.h>
1920#include <linux/module.h>
2021#include <linux/slab.h>
22+ #include <linux/timer.h>
2123
2224#include "hid-ids.h"
2325
24- #define APPLE_RDESC_JIS 0x0001
25- #define APPLE_IGNORE_MOUSE 0x0002
26- #define APPLE_HAS_FN 0x0004
27- /* 0x0008 reserved, was: APPLE_HIDDEV */
28- #define APPLE_ISO_TILDE_QUIRK 0x0010
29- #define APPLE_MIGHTYMOUSE 0x0020
30- #define APPLE_INVERT_HWHEEL 0x0040
31- /* 0x0080 reserved, was: APPLE_IGNORE_HIDINPUT */
32- #define APPLE_NUMLOCK_EMULATION 0x0100
26+ #define APPLE_RDESC_JIS BIT(0)
27+ #define APPLE_IGNORE_MOUSE BIT(1)
28+ #define APPLE_HAS_FN BIT(2)
29+ /* BIT(3) reserved, was: APPLE_HIDDEV */
30+ #define APPLE_ISO_TILDE_QUIRK BIT(4)
31+ #define APPLE_MIGHTYMOUSE BIT(5)
32+ #define APPLE_INVERT_HWHEEL BIT(6)
33+ /* BIT(7) reserved, was: APPLE_IGNORE_HIDINPUT */
34+ #define APPLE_NUMLOCK_EMULATION BIT(8)
35+ #define APPLE_RDESC_BATTERY BIT(9)
3336
3437#define APPLE_FLAG_FKEY 0x01
3538
3639#define HID_COUNTRY_INTERNATIONAL_ISO 13
40+ #define APPLE_BATTERY_TIMEOUT_MS 60000
3741
3842static unsigned int fnmode = 1 ;
3943module_param (fnmode , uint , 0644 );
@@ -58,10 +62,12 @@ MODULE_PARM_DESC(swap_fn_leftctrl, "Swap the Fn and left Control keys. "
5862 "[0] = as-is, Mac layout, 1 = swapped, PC layout)" );
5963
6064struct apple_sc {
65+ struct hid_device * hdev ;
6166 unsigned long quirks ;
6267 unsigned int fn_on ;
6368 unsigned int fn_found ;
6469 DECLARE_BITMAP (pressed_numlock , KEY_CNT );
70+ struct timer_list battery_timer ;
6571};
6672
6773struct apple_key_translation {
@@ -70,6 +76,28 @@ struct apple_key_translation {
7076 u8 flags ;
7177};
7278
79+ static const struct apple_key_translation apple2021_fn_keys [] = {
80+ { KEY_BACKSPACE , KEY_DELETE },
81+ { KEY_ENTER , KEY_INSERT },
82+ { KEY_F1 , KEY_BRIGHTNESSDOWN , APPLE_FLAG_FKEY },
83+ { KEY_F2 , KEY_BRIGHTNESSUP , APPLE_FLAG_FKEY },
84+ { KEY_F3 , KEY_SCALE , APPLE_FLAG_FKEY },
85+ { KEY_F4 , KEY_SEARCH , APPLE_FLAG_FKEY },
86+ { KEY_F5 , KEY_MICMUTE , APPLE_FLAG_FKEY },
87+ { KEY_F6 , KEY_SLEEP , APPLE_FLAG_FKEY },
88+ { KEY_F7 , KEY_PREVIOUSSONG , APPLE_FLAG_FKEY },
89+ { KEY_F8 , KEY_PLAYPAUSE , APPLE_FLAG_FKEY },
90+ { KEY_F9 , KEY_NEXTSONG , APPLE_FLAG_FKEY },
91+ { KEY_F10 , KEY_MUTE , APPLE_FLAG_FKEY },
92+ { KEY_F11 , KEY_VOLUMEDOWN , APPLE_FLAG_FKEY },
93+ { KEY_F12 , KEY_VOLUMEUP , APPLE_FLAG_FKEY },
94+ { KEY_UP , KEY_PAGEUP },
95+ { KEY_DOWN , KEY_PAGEDOWN },
96+ { KEY_LEFT , KEY_HOME },
97+ { KEY_RIGHT , KEY_END },
98+ { }
99+ };
100+
73101static const struct apple_key_translation macbookair_fn_keys [] = {
74102 { KEY_BACKSPACE , KEY_DELETE },
75103 { KEY_ENTER , KEY_INSERT },
@@ -214,7 +242,11 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input,
214242 }
215243
216244 if (fnmode ) {
217- if (hid -> product >= USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI &&
245+ if (hid -> product == USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2021 ||
246+ hid -> product == USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_FINGERPRINT_2021 ||
247+ hid -> product == USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2021 )
248+ table = apple2021_fn_keys ;
249+ else if (hid -> product >= USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI &&
218250 hid -> product <= USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS )
219251 table = macbookair_fn_keys ;
220252 else if (hid -> product < 0x21d || hid -> product >= 0x300 )
@@ -333,6 +365,43 @@ static int apple_event(struct hid_device *hdev, struct hid_field *field,
333365 return 0 ;
334366}
335367
368+ static int apple_fetch_battery (struct hid_device * hdev )
369+ {
370+ #ifdef CONFIG_HID_BATTERY_STRENGTH
371+ struct apple_sc * asc = hid_get_drvdata (hdev );
372+ struct hid_report_enum * report_enum ;
373+ struct hid_report * report ;
374+
375+ if (!(asc -> quirks & APPLE_RDESC_BATTERY ) || !hdev -> battery )
376+ return -1 ;
377+
378+ report_enum = & hdev -> report_enum [hdev -> battery_report_type ];
379+ report = report_enum -> report_id_hash [hdev -> battery_report_id ];
380+
381+ if (!report || report -> maxfield < 1 )
382+ return -1 ;
383+
384+ if (hdev -> battery_capacity == hdev -> battery_max )
385+ return -1 ;
386+
387+ hid_hw_request (hdev , report , HID_REQ_GET_REPORT );
388+ return 0 ;
389+ #else
390+ return -1 ;
391+ #endif
392+ }
393+
394+ static void apple_battery_timer_tick (struct timer_list * t )
395+ {
396+ struct apple_sc * asc = from_timer (asc , t , battery_timer );
397+ struct hid_device * hdev = asc -> hdev ;
398+
399+ if (apple_fetch_battery (hdev ) == 0 ) {
400+ mod_timer (& asc -> battery_timer ,
401+ jiffies + msecs_to_jiffies (APPLE_BATTERY_TIMEOUT_MS ));
402+ }
403+ }
404+
336405/*
337406 * MacBook JIS keyboard has wrong logical maximum
338407 * Magic Keyboard JIS has wrong logical maximum
@@ -354,6 +423,30 @@ static __u8 *apple_report_fixup(struct hid_device *hdev, __u8 *rdesc,
354423 "fixing up MacBook JIS keyboard report descriptor\n" );
355424 rdesc [53 ] = rdesc [59 ] = 0xe7 ;
356425 }
426+
427+ /*
428+ * Change the usage from:
429+ * 0x06, 0x00, 0xff, // Usage Page (Vendor Defined Page 1) 0
430+ * 0x09, 0x0b, // Usage (Vendor Usage 0x0b) 3
431+ * To:
432+ * 0x05, 0x01, // Usage Page (Generic Desktop) 0
433+ * 0x09, 0x06, // Usage (Keyboard) 2
434+ */
435+ if ((asc -> quirks & APPLE_RDESC_BATTERY ) && * rsize == 83 &&
436+ rdesc [46 ] == 0x84 && rdesc [58 ] == 0x85 ) {
437+ hid_info (hdev ,
438+ "fixing up Magic Keyboard battery report descriptor\n" );
439+ * rsize = * rsize - 1 ;
440+ rdesc = kmemdup (rdesc + 1 , * rsize , GFP_KERNEL );
441+ if (!rdesc )
442+ return NULL ;
443+
444+ rdesc [0 ] = 0x05 ;
445+ rdesc [1 ] = 0x01 ;
446+ rdesc [2 ] = 0x09 ;
447+ rdesc [3 ] = 0x06 ;
448+ }
449+
357450 return rdesc ;
358451}
359452
@@ -376,6 +469,9 @@ static void apple_setup_input(struct input_dev *input)
376469 for (trans = apple_iso_keyboard ; trans -> from ; trans ++ )
377470 set_bit (trans -> to , input -> keybit );
378471
472+ for (trans = apple2021_fn_keys ; trans -> from ; trans ++ )
473+ set_bit (trans -> to , input -> keybit );
474+
379475 if (swap_fn_leftctrl ) {
380476 for (trans = swapped_fn_leftctrl_keys ; trans -> from ; trans ++ )
381477 set_bit (trans -> to , input -> keybit );
@@ -428,7 +524,7 @@ static int apple_input_configured(struct hid_device *hdev,
428524
429525 if ((asc -> quirks & APPLE_HAS_FN ) && !asc -> fn_found ) {
430526 hid_info (hdev , "Fn key not found (Apple Wireless Keyboard clone?), disabling Fn key handling\n" );
431- asc -> quirks = 0 ;
527+ asc -> quirks &= ~ APPLE_HAS_FN ;
432528 }
433529
434530 return 0 ;
@@ -447,6 +543,7 @@ static int apple_probe(struct hid_device *hdev,
447543 return - ENOMEM ;
448544 }
449545
546+ asc -> hdev = hdev ;
450547 asc -> quirks = quirks ;
451548
452549 hid_set_drvdata (hdev , asc );
@@ -463,9 +560,23 @@ static int apple_probe(struct hid_device *hdev,
463560 return ret ;
464561 }
465562
563+ timer_setup (& asc -> battery_timer , apple_battery_timer_tick , 0 );
564+ mod_timer (& asc -> battery_timer ,
565+ jiffies + msecs_to_jiffies (APPLE_BATTERY_TIMEOUT_MS ));
566+ apple_fetch_battery (hdev );
567+
466568 return 0 ;
467569}
468570
571+ static void apple_remove (struct hid_device * hdev )
572+ {
573+ struct apple_sc * asc = hid_get_drvdata (hdev );
574+
575+ del_timer_sync (& asc -> battery_timer );
576+
577+ hid_hw_stop (hdev );
578+ }
579+
469580static const struct hid_device_id apple_devices [] = {
470581 { HID_USB_DEVICE (USB_VENDOR_ID_APPLE , USB_DEVICE_ID_APPLE_MIGHTYMOUSE ),
471582 .driver_data = APPLE_MIGHTYMOUSE | APPLE_INVERT_HWHEEL },
@@ -540,11 +651,11 @@ static const struct hid_device_id apple_devices[] = {
540651 { HID_BLUETOOTH_DEVICE (USB_VENDOR_ID_APPLE , USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS ),
541652 .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
542653 { HID_USB_DEVICE (USB_VENDOR_ID_APPLE , USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2015 ),
543- .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
654+ .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_RDESC_BATTERY },
544655 { HID_BLUETOOTH_DEVICE (BT_VENDOR_ID_APPLE , USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2015 ),
545656 .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
546657 { HID_USB_DEVICE (USB_VENDOR_ID_APPLE , USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2015 ),
547- .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
658+ .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_RDESC_BATTERY },
548659 { HID_BLUETOOTH_DEVICE (BT_VENDOR_ID_APPLE , USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2015 ),
549660 .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
550661 { HID_USB_DEVICE (USB_VENDOR_ID_APPLE , USB_DEVICE_ID_APPLE_WELLSPRING_ANSI ),
@@ -640,6 +751,14 @@ static const struct hid_device_id apple_devices[] = {
640751 .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
641752 { HID_BLUETOOTH_DEVICE (BT_VENDOR_ID_APPLE , USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2021 ),
642753 .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
754+ { HID_USB_DEVICE (USB_VENDOR_ID_APPLE , USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_FINGERPRINT_2021 ),
755+ .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
756+ { HID_BLUETOOTH_DEVICE (BT_VENDOR_ID_APPLE , USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_FINGERPRINT_2021 ),
757+ .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
758+ { HID_USB_DEVICE (USB_VENDOR_ID_APPLE , USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2021 ),
759+ .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
760+ { HID_BLUETOOTH_DEVICE (BT_VENDOR_ID_APPLE , USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2021 ),
761+ .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
643762
644763 { }
645764};
@@ -650,6 +769,7 @@ static struct hid_driver apple_driver = {
650769 .id_table = apple_devices ,
651770 .report_fixup = apple_report_fixup ,
652771 .probe = apple_probe ,
772+ .remove = apple_remove ,
653773 .event = apple_event ,
654774 .input_mapping = apple_input_mapping ,
655775 .input_mapped = apple_input_mapped ,
0 commit comments