Skip to content

Commit 394ba61

Browse files
RedecoratingBenjamin Tissoires
authored andcommitted
HID: apple: Add support for magic keyboard backlight on T2 Macs
Unlike T2 Macs with Butterfly keyboard, who have their keyboard backlight on the USB device the T2 Macs with Magic keyboard have their backlight on the Touchbar backlight device (05ac:8102). Support for Butterfly keyboards has already been added in commit 9018eac ("HID: apple: Add support for keyboard backlight on certain T2 Macs.") This patch adds support for the Magic keyboards. Signed-off-by: Orlando Chamberlain <[email protected]> Co-developed-by: Aditya Garg <[email protected]> Signed-off-by: Aditya Garg <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Benjamin Tissoires <[email protected]>
1 parent 061d1af commit 394ba61

File tree

1 file changed

+87
-0
lines changed

1 file changed

+87
-0
lines changed

drivers/hid/hid-apple.c

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
* Copyright (c) 2006-2007 Jiri Kosina
99
* Copyright (c) 2008 Jiri Slaby <[email protected]>
1010
* Copyright (c) 2019 Paul Pawlowski <[email protected]>
11+
* Copyright (c) 2023 Orlando Chamberlain <[email protected]>
12+
* Copyright (c) 2024 Aditya Garg <[email protected]>
1113
*/
1214

1315
/*
@@ -23,6 +25,7 @@
2325
#include <linux/timer.h>
2426
#include <linux/string.h>
2527
#include <linux/leds.h>
28+
#include <dt-bindings/leds/common.h>
2629

2730
#include "hid-ids.h"
2831

@@ -38,12 +41,17 @@
3841
#define APPLE_RDESC_BATTERY BIT(9)
3942
#define APPLE_BACKLIGHT_CTL BIT(10)
4043
#define APPLE_IS_NON_APPLE BIT(11)
44+
#define APPLE_MAGIC_BACKLIGHT BIT(12)
4145

4246
#define APPLE_FLAG_FKEY 0x01
4347

4448
#define HID_COUNTRY_INTERNATIONAL_ISO 13
4549
#define APPLE_BATTERY_TIMEOUT_MS 60000
4650

51+
#define HID_USAGE_MAGIC_BL 0xff00000f
52+
#define APPLE_MAGIC_REPORT_ID_POWER 3
53+
#define APPLE_MAGIC_REPORT_ID_BRIGHTNESS 1
54+
4755
static unsigned int fnmode = 3;
4856
module_param(fnmode, uint, 0644);
4957
MODULE_PARM_DESC(fnmode, "Mode of fn key on Apple keyboards (0 = disabled, "
@@ -81,6 +89,12 @@ struct apple_sc_backlight {
8189
struct hid_device *hdev;
8290
};
8391

92+
struct apple_magic_backlight {
93+
struct led_classdev cdev;
94+
struct hid_report *brightness;
95+
struct hid_report *power;
96+
};
97+
8498
struct apple_sc {
8599
struct hid_device *hdev;
86100
unsigned long quirks;
@@ -822,6 +836,66 @@ static int apple_backlight_init(struct hid_device *hdev)
822836
return ret;
823837
}
824838

839+
static void apple_magic_backlight_report_set(struct hid_report *rep, s32 value, u8 rate)
840+
{
841+
rep->field[0]->value[0] = value;
842+
rep->field[1]->value[0] = 0x5e; /* Mimic Windows */
843+
rep->field[1]->value[0] |= rate << 8;
844+
845+
hid_hw_request(rep->device, rep, HID_REQ_SET_REPORT);
846+
}
847+
848+
static void apple_magic_backlight_set(struct apple_magic_backlight *backlight,
849+
int brightness, char rate)
850+
{
851+
apple_magic_backlight_report_set(backlight->power, brightness ? 1 : 0, rate);
852+
if (brightness)
853+
apple_magic_backlight_report_set(backlight->brightness, brightness, rate);
854+
}
855+
856+
static int apple_magic_backlight_led_set(struct led_classdev *led_cdev,
857+
enum led_brightness brightness)
858+
{
859+
struct apple_magic_backlight *backlight = container_of(led_cdev,
860+
struct apple_magic_backlight, cdev);
861+
862+
apple_magic_backlight_set(backlight, brightness, 1);
863+
return 0;
864+
}
865+
866+
static int apple_magic_backlight_init(struct hid_device *hdev)
867+
{
868+
struct apple_magic_backlight *backlight;
869+
struct hid_report_enum *report_enum;
870+
871+
/*
872+
* Ensure this usb endpoint is for the keyboard backlight, not touchbar
873+
* backlight.
874+
*/
875+
if (hdev->collection[0].usage != HID_USAGE_MAGIC_BL)
876+
return -ENODEV;
877+
878+
backlight = devm_kzalloc(&hdev->dev, sizeof(*backlight), GFP_KERNEL);
879+
if (!backlight)
880+
return -ENOMEM;
881+
882+
report_enum = &hdev->report_enum[HID_FEATURE_REPORT];
883+
backlight->brightness = report_enum->report_id_hash[APPLE_MAGIC_REPORT_ID_BRIGHTNESS];
884+
backlight->power = report_enum->report_id_hash[APPLE_MAGIC_REPORT_ID_POWER];
885+
886+
if (!backlight->brightness || !backlight->power)
887+
return -ENODEV;
888+
889+
backlight->cdev.name = ":white:" LED_FUNCTION_KBD_BACKLIGHT;
890+
backlight->cdev.max_brightness = backlight->brightness->field[0]->logical_maximum;
891+
backlight->cdev.brightness_set_blocking = apple_magic_backlight_led_set;
892+
893+
apple_magic_backlight_set(backlight, 0, 0);
894+
895+
return devm_led_classdev_register(&hdev->dev, &backlight->cdev);
896+
897+
}
898+
825899
static int apple_probe(struct hid_device *hdev,
826900
const struct hid_device_id *id)
827901
{
@@ -860,7 +934,18 @@ static int apple_probe(struct hid_device *hdev,
860934
if (quirks & APPLE_BACKLIGHT_CTL)
861935
apple_backlight_init(hdev);
862936

937+
if (quirks & APPLE_MAGIC_BACKLIGHT) {
938+
ret = apple_magic_backlight_init(hdev);
939+
if (ret)
940+
goto out_err;
941+
}
942+
863943
return 0;
944+
945+
out_err:
946+
del_timer_sync(&asc->battery_timer);
947+
hid_hw_stop(hdev);
948+
return ret;
864949
}
865950

866951
static void apple_remove(struct hid_device *hdev)
@@ -1073,6 +1158,8 @@ static const struct hid_device_id apple_devices[] = {
10731158
.driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_RDESC_BATTERY },
10741159
{ HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2021),
10751160
.driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
1161+
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_TOUCHBAR_BACKLIGHT),
1162+
.driver_data = APPLE_MAGIC_BACKLIGHT },
10761163

10771164
{ }
10781165
};

0 commit comments

Comments
 (0)