Hi Benjamin > On 3 Jul 2024, at 7:38 PM, Benjamin Tissoires <bentiss@xxxxxxxxxx> wrote: > > On Jul 03 2024, Aditya Garg wrote: >> From: Orlando Chamberlain <orlandoch.dev@xxxxxxxxx> >> >> 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 9018eacbe623 >> ("HID: apple: Add support for keyboard backlight on certain T2 Macs."). >> This patch adds support for the Magic keyboards. >> >> Co-developed-by: Aditya Garg <gargaditya08@xxxxxxxx> >> Signed-off-by: Aditya Garg <gargaditya08@xxxxxxxx> >> Signed-off-by: Orlando Chamberlain <orlandoch.dev@xxxxxxxxx> > > Nitpick: the ordering of the signed-off is weird. It should be in order > of persons who touched this driver. > > Given that the From is Orlando and Aditya is submitting, I would have > expected Orlando, then Aditya… > Will fix this. >> --- >> drivers/hid/hid-apple.c | 87 ++++++++++++++++++++++++++++++++++++++++- >> 1 file changed, 86 insertions(+), 1 deletion(-) >> >> diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c >> index bd022e004356..2d1cd4456303 100644 >> --- a/drivers/hid/hid-apple.c >> +++ b/drivers/hid/hid-apple.c >> @@ -8,6 +8,8 @@ >> * Copyright (c) 2006-2007 Jiri Kosina >> * Copyright (c) 2008 Jiri Slaby <jirislaby@xxxxxxxxx> >> * Copyright (c) 2019 Paul Pawlowski <paul@xxxxxxxx> >> + * Copyright (c) 2023 Orlando Chamberlain <orlandoch.dev@xxxxxxxxx> >> + * Copyright (c) 2024 Aditya Garg <gargaditya08@xxxxxxxx> >> */ >> >> /* >> @@ -23,6 +25,7 @@ >> #include <linux/timer.h> >> #include <linux/string.h> >> #include <linux/leds.h> >> +#include <dt-bindings/leds/common.h> >> >> #include "hid-ids.h" >> >> @@ -37,13 +40,18 @@ >> #define APPLE_NUMLOCK_EMULATION BIT(8) >> #define APPLE_RDESC_BATTERY BIT(9) >> #define APPLE_BACKLIGHT_CTL BIT(10) >> -#define APPLE_IS_NON_APPLE BIT(11) >> +#define APPLE_MAGIC_BACKLIGHT BIT(11) >> +#define APPLE_IS_NON_APPLE BIT(12) > > Please keep existing quirks definition in place, it adds noise for > nothing in the patch. Also, technically, these quirks are used in > .driver_data so they are uapi. > Sure >> >> #define APPLE_FLAG_FKEY 0x01 >> >> #define HID_COUNTRY_INTERNATIONAL_ISO 13 >> #define APPLE_BATTERY_TIMEOUT_MS 60000 >> >> +#define HID_USAGE_MAGIC_BL 0xff00000f >> +#define APPLE_MAGIC_REPORT_ID_POWER 3 >> +#define APPLE_MAGIC_REPORT_ID_BRIGHTNESS 1 >> + >> static unsigned int fnmode = 3; >> module_param(fnmode, uint, 0644); >> MODULE_PARM_DESC(fnmode, "Mode of fn key on Apple keyboards (0 = disabled, " >> @@ -81,6 +89,12 @@ struct apple_sc_backlight { >> struct hid_device *hdev; >> }; >> >> +struct apple_magic_backlight { >> + struct led_classdev cdev; >> + struct hid_report *brightness; >> + struct hid_report *power; >> +}; >> + >> struct apple_sc { >> struct hid_device *hdev; >> unsigned long quirks; >> @@ -822,6 +836,66 @@ static int apple_backlight_init(struct hid_device *hdev) >> return ret; >> } >> >> +static void apple_magic_backlight_report_set(struct hid_report *rep, s32 value, u8 rate) >> +{ >> + rep->field[0]->value[0] = value; >> + rep->field[1]->value[0] = 0x5e; /* Mimic Windows */ >> + rep->field[1]->value[0] |= rate << 8; >> + >> + hid_hw_request(rep->device, rep, HID_REQ_SET_REPORT); >> +} >> + >> +static void apple_magic_backlight_set(struct apple_magic_backlight *backlight, >> + int brightness, char rate) >> +{ >> + apple_magic_backlight_report_set(backlight->power, brightness ? 1 : 0, rate); >> + if (brightness) >> + apple_magic_backlight_report_set(backlight->brightness, brightness, rate); >> +} >> + >> +static int apple_magic_backlight_led_set(struct led_classdev *led_cdev, >> + enum led_brightness brightness) >> +{ >> + struct apple_magic_backlight *backlight = container_of(led_cdev, >> + struct apple_magic_backlight, cdev); >> + >> + apple_magic_backlight_set(backlight, brightness, 1); >> + return 0; >> +} >> + >> +static int apple_magic_backlight_init(struct hid_device *hdev) >> +{ >> + struct apple_magic_backlight *backlight; >> + >> + /* >> + * Ensure this usb endpoint is for the keyboard backlight, not touchbar >> + * backlight. >> + */ >> + if (hdev->collection[0].usage != HID_USAGE_MAGIC_BL) >> + return -ENODEV; >> + >> + backlight = devm_kzalloc(&hdev->dev, sizeof(*backlight), GFP_KERNEL); >> + if (!backlight) >> + return -ENOMEM; >> + >> + backlight->brightness = hid_register_report(hdev, HID_FEATURE_REPORT, >> + APPLE_MAGIC_REPORT_ID_BRIGHTNESS, 0); >> + backlight->power = hid_register_report(hdev, HID_FEATURE_REPORT, >> + APPLE_MAGIC_REPORT_ID_POWER, 0); >> + >> + if (!backlight->brightness || !backlight->power) >> + return -ENODEV; >> + >> + backlight->cdev.name = ":white:" LED_FUNCTION_KBD_BACKLIGHT; >> + backlight->cdev.max_brightness = backlight->brightness->field[0]->logical_maximum; > > This is weird: a few lines above, you register a new report with > hid_register_report() and now you are directly accessing > field[0]->logical_maximum in that new report, which should be set to 0. > > Unless you are using hid_register_report() to retrieve an existing > report, which is bending the API a bit but is OK, but you should at > least check that report->size is > 0 (and put a comment that the reports > exist already). > > (or do what is done in apple_fetch_battery() to retrieve the current > report) > Instead of if (!backlight->brightness || !backlight->power) return -ENODEV; Should I do (will all proper whitespace and line formatting): if (!backlight->brightness || backlight->brightness->size == 0 || !backlight->power || backlight->power->size == 0) return -ENODEV; > >> + backlight->cdev.brightness_set_blocking = apple_magic_backlight_led_set; >> + >> + apple_magic_backlight_set(backlight, 0, 0); >> + >> + return devm_led_classdev_register(&hdev->dev, &backlight->cdev); >> + >> +} >> + >> static int apple_probe(struct hid_device *hdev, >> const struct hid_device_id *id) >> { >> @@ -860,6 +934,15 @@ static int apple_probe(struct hid_device *hdev, >> if (quirks & APPLE_BACKLIGHT_CTL) >> apple_backlight_init(hdev); >> >> + if (quirks & APPLE_MAGIC_BACKLIGHT) { >> + ret = apple_magic_backlight_init(hdev); >> + if (ret) { >> + del_timer_sync(&asc->battery_timer); >> + hid_hw_stop(hdev); >> + return ret; > > Instead of manually unwind the probe in each sub-quirk, please add a new > goto label and do goto out_err; You mean this?: if (quirks & APPLE_MAGIC_BACKLIGHT) { ret = apple_magic_backlight_init(hdev); if (ret) goto out_err; } return 0; out_err: del_timer_sync(&asc->battery_timer); hid_hw_stop(hdev); return ret; } > >> + } >> + } >> + >> return 0; >> } >> >> @@ -1073,6 +1156,8 @@ 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_TOUCHBAR_BACKLIGHT), >> + .driver_data = APPLE_MAGIC_BACKLIGHT }, >> >> { } >> }; >> -- >> 2.45.2 >> > > Other than those few nitpicks, patch looks good. Please roll a v3 and > I'll apply it. > > Cheers, > Benjamin