From f41d736acc039d86512951f4e874b0f5e666babf Mon Sep 17 00:00:00 2001 From: Kerem Karabay Date: Tue, 27 May 2025 22:13:13 +0530 Subject: [PATCH 1/5] HID: multitouch: Get the contact ID from HID_DG_TRANSDUCER_INDEX fields in case of Apple Touch Bar In Apple Touch Bar, the contact ID is contained in fields with the HID_DG_TRANSDUCER_INDEX usage rather than HID_DG_CONTACTID, thus differing from the HID spec. Add a quirk for the same. Acked-by: Benjamin Tissoires Signed-off-by: Kerem Karabay Co-developed-by: Aditya Garg Signed-off-by: Aditya Garg Signed-off-by: Jiri Kosina --- drivers/hid/hid-multitouch.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index ded0fef7d8c7..849344b0ee57 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -73,6 +73,7 @@ MODULE_LICENSE("GPL"); #define MT_QUIRK_FORCE_MULTI_INPUT BIT(20) #define MT_QUIRK_DISABLE_WAKEUP BIT(21) #define MT_QUIRK_ORIENTATION_INVERT BIT(22) +#define MT_QUIRK_APPLE_TOUCHBAR BIT(23) #define MT_INPUTMODE_TOUCHSCREEN 0x02 #define MT_INPUTMODE_TOUCHPAD 0x03 @@ -625,6 +626,7 @@ static struct mt_application *mt_find_application(struct mt_device *td, static struct mt_report_data *mt_allocate_report_data(struct mt_device *td, struct hid_report *report) { + struct mt_class *cls = &td->mtclass; struct mt_report_data *rdata; struct hid_field *field; int r, n; @@ -649,7 +651,11 @@ static struct mt_report_data *mt_allocate_report_data(struct mt_device *td, if (field->logical == HID_DG_FINGER || td->hdev->group != HID_GROUP_MULTITOUCH_WIN_8) { for (n = 0; n < field->report_count; n++) { - if (field->usage[n].hid == HID_DG_CONTACTID) { + unsigned int hid = field->usage[n].hid; + + if (hid == HID_DG_CONTACTID || + (cls->quirks & MT_QUIRK_APPLE_TOUCHBAR && + hid == HID_DG_TRANSDUCER_INDEX)) { rdata->is_mt_collection = true; break; } @@ -827,6 +833,14 @@ static int mt_touch_input_mapping(struct hid_device *hdev, struct hid_input *hi, EV_KEY, BTN_TOUCH); MT_STORE_FIELD(tip_state); return 1; + case HID_DG_TRANSDUCER_INDEX: + /* + * Contact ID in case of Apple Touch Bars is contained + * in fields with HID_DG_TRANSDUCER_INDEX usage. + */ + if (!(cls->quirks & MT_QUIRK_APPLE_TOUCHBAR)) + return 0; + fallthrough; case HID_DG_CONTACTID: MT_STORE_FIELD(contactid); app->touches_by_report++; From e0976a61a543b5e03bc0d08030a0ea036ee3751d Mon Sep 17 00:00:00 2001 From: Kerem Karabay Date: Tue, 27 May 2025 22:13:14 +0530 Subject: [PATCH 2/5] HID: multitouch: support getting the tip state from HID_DG_TOUCH fields in Apple Touch Bar In Apple Touch Bar, the tip state is contained in fields with the HID_DG_TOUCH usage. This feature is gated by a quirk in order to prevent breaking other devices, see commit c2ef8f21ea8f ("HID: multitouch: add support for trackpads"). Acked-by: Benjamin Tissoires Signed-off-by: Kerem Karabay Co-developed-by: Aditya Garg Signed-off-by: Aditya Garg Signed-off-by: Jiri Kosina --- drivers/hid/hid-multitouch.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 849344b0ee57..e3382afc74c9 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -827,6 +827,17 @@ static int mt_touch_input_mapping(struct hid_device *hdev, struct hid_input *hi, MT_STORE_FIELD(confidence_state); return 1; + case HID_DG_TOUCH: + /* + * Legacy devices use TIPSWITCH and not TOUCH. + * One special case here is of the Apple Touch Bars. + * In these devices, the tip state is contained in + * fields with the HID_DG_TOUCH usage. + * Let's just ignore this field for other devices. + */ + if (!(cls->quirks & MT_QUIRK_APPLE_TOUCHBAR)) + return -1; + fallthrough; case HID_DG_TIPSWITCH: if (field->application != HID_GD_SYSTEM_MULTIAXIS) input_set_capability(hi->input, @@ -897,10 +908,6 @@ static int mt_touch_input_mapping(struct hid_device *hdev, struct hid_input *hi, case HID_DG_CONTACTMAX: /* contact max are global to the report */ return -1; - case HID_DG_TOUCH: - /* Legacy devices use TIPSWITCH and not TOUCH. - * Let's just ignore this field. */ - return -1; } /* let hid-input decide for the others */ return 0; From 7dfe48bdc9d38db46283f2e0281bc1626277b8bf Mon Sep 17 00:00:00 2001 From: Kerem Karabay Date: Tue, 27 May 2025 22:13:15 +0530 Subject: [PATCH 3/5] HID: multitouch: take cls->maxcontacts into account for Apple Touch Bar even without a HID_DG_CONTACTMAX field In Apple Touch Bar, the HID_DG_CONTACTMAX is not present, but the maximum contact count is still greater than the default. Add quirks for the same. Acked-by: Benjamin Tissoires Signed-off-by: Kerem Karabay Co-developed-by: Aditya Garg Signed-off-by: Aditya Garg Signed-off-by: Jiri Kosina --- drivers/hid/hid-multitouch.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index e3382afc74c9..756136f84168 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -1335,6 +1335,13 @@ static int mt_touch_input_configured(struct hid_device *hdev, struct input_dev *input = hi->input; int ret; + /* + * HID_DG_CONTACTMAX field is not present on Apple Touch Bars, + * but the maximum contact count is greater than the default. + */ + if (cls->quirks & MT_QUIRK_APPLE_TOUCHBAR && cls->maxcontacts) + td->maxcontacts = cls->maxcontacts; + if (!td->maxcontacts) td->maxcontacts = MT_DEFAULT_MAXCONTACT; From 45ca23c5ee8b2b3074377fecc92fa72aa595f7c9 Mon Sep 17 00:00:00 2001 From: Kerem Karabay Date: Tue, 27 May 2025 22:13:16 +0530 Subject: [PATCH 4/5] HID: multitouch: specify that Apple Touch Bar is direct Currently the driver determines the device type based on the application, but this value is not reliable on Apple Touch Bar, where the application is HID_DG_TOUCHPAD even though this device is direct, so add a quirk for the same. Acked-by: Benjamin Tissoires Signed-off-by: Kerem Karabay Co-developed-by: Aditya Garg Signed-off-by: Aditya Garg Signed-off-by: Jiri Kosina --- drivers/hid/hid-multitouch.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 756136f84168..31b88eb43527 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -1349,6 +1349,13 @@ static int mt_touch_input_configured(struct hid_device *hdev, if (td->serial_maybe) mt_post_parse_default_settings(td, app); + /* + * The application for Apple Touch Bars is HID_DG_TOUCHPAD, + * but these devices are direct. + */ + if (cls->quirks & MT_QUIRK_APPLE_TOUCHBAR) + app->mt_flags |= INPUT_MT_DIRECT; + if (cls->is_indirect) app->mt_flags |= INPUT_MT_POINTER; From 2c31ec923c323229566d799267000f8123af4449 Mon Sep 17 00:00:00 2001 From: Kerem Karabay Date: Tue, 27 May 2025 22:13:17 +0530 Subject: [PATCH 5/5] HID: multitouch: add device ID for Apple Touch Bar This patch adds the device ID of Apple Touch Bar found on x86 MacBook Pros to the hid-multitouch driver. Note that this is device ID is for T2 Macs. Testing on T1 Macs would be appreciated. Signed-off-by: Kerem Karabay Co-developed-by: Aditya Garg Signed-off-by: Aditya Garg Signed-off-by: Jiri Kosina --- drivers/hid/Kconfig | 1 + drivers/hid/hid-multitouch.c | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 43859fc75747..a57901203aeb 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -771,6 +771,7 @@ config HID_MULTITOUCH Say Y here if you have one of the following devices: - 3M PCT touch screens - ActionStar dual touch panels + - Apple Touch Bar on x86 MacBook Pros - Atmel panels - Cando dual touch panels - Chunghwa panels diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 31b88eb43527..6ab838c36cad 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -221,6 +221,7 @@ static void mt_post_parse(struct mt_device *td, struct mt_application *app); #define MT_CLS_GOOGLE 0x0111 #define MT_CLS_RAZER_BLADE_STEALTH 0x0112 #define MT_CLS_SMART_TECH 0x0113 +#define MT_CLS_APPLE_TOUCHBAR 0x0114 #define MT_CLS_SIS 0x0457 #define MT_DEFAULT_MAXCONTACT 10 @@ -406,6 +407,12 @@ static const struct mt_class mt_classes[] = { MT_QUIRK_CONTACT_CNT_ACCURATE | MT_QUIRK_SEPARATE_APP_REPORT, }, + { .name = MT_CLS_APPLE_TOUCHBAR, + .quirks = MT_QUIRK_HOVERING | + MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE | + MT_QUIRK_APPLE_TOUCHBAR, + .maxcontacts = 11, + }, { .name = MT_CLS_SIS, .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP | MT_QUIRK_ALWAYS_VALID | @@ -1858,6 +1865,11 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) if (ret != 0) return ret; + if (mtclass->name == MT_CLS_APPLE_TOUCHBAR && + !hid_find_field(hdev, HID_INPUT_REPORT, + HID_DG_TOUCHPAD, HID_DG_TRANSDUCER_INDEX)) + return -ENODEV; + if (mtclass->quirks & MT_QUIRK_FIX_CONST_CONTACT_ID) mt_fix_const_fields(hdev, HID_DG_CONTACTID); @@ -2349,6 +2361,11 @@ static const struct hid_device_id mt_devices[] = { MT_USB_DEVICE(USB_VENDOR_ID_XIROKU, USB_DEVICE_ID_XIROKU_CSR2) }, + /* Apple Touch Bar */ + { .driver_data = MT_CLS_APPLE_TOUCHBAR, + HID_USB_DEVICE(USB_VENDOR_ID_APPLE, + USB_DEVICE_ID_APPLE_TOUCHBAR_DISPLAY) }, + /* Google MT devices */ { .driver_data = MT_CLS_GOOGLE, HID_DEVICE(HID_BUS_ANY, HID_GROUP_ANY, USB_VENDOR_ID_GOOGLE,