Skip to content

Commit 5b69f87

Browse files
marcanjannau
authored andcommitted
hid: magicmouse: Add MTP multi-touch device support
Apple M2 devices expose the multi-touch device over the HID over DockChannel transport, which we represent as the HOST bus type. The report format is the same, except the legacy mouse header is gone and there is no enable request needed. Signed-off-by: Hector Martin <[email protected]>
1 parent f644dd6 commit 5b69f87

1 file changed

Lines changed: 49 additions & 18 deletions

File tree

drivers/hid/hid-magicmouse.c

Lines changed: 49 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state fie
5959
#define MOUSE_REPORT_ID 0x29
6060
#define MOUSE2_REPORT_ID 0x12
6161
#define DOUBLE_REPORT_ID 0xf7
62+
#define SPI_REPORT_ID 0x02
63+
#define MTP_REPORT_ID 0x75
6264
#define USB_BATTERY_TIMEOUT_MS 60000
6365

6466
#define MAX_CONTACTS 16
@@ -575,25 +577,32 @@ struct tp_finger {
575577
} __attribute__((packed, aligned(2)));
576578

577579
/**
578-
* struct trackpad report
580+
* vendor trackpad report
579581
*
580-
* @report_id: reportid
581-
* @buttons: HID Usage Buttons 3 1-bit reports
582582
* @num_fingers: the number of fingers being reported in @fingers
583-
* @clicked: same as @buttons
583+
* @buttons: same as HID buttons
584584
*/
585585
struct tp_header {
586+
// HID vendor part, up to 1751 bytes
587+
u8 unknown[22];
588+
u8 num_fingers;
589+
u8 buttons;
590+
u8 unknown3[14];
591+
};
592+
593+
/**
594+
* standard HID mouse report
595+
*
596+
* @report_id: reportid
597+
* @buttons: HID Usage Buttons 3 1-bit reports
598+
*/
599+
struct tp_mouse_report {
586600
// HID mouse report
587601
u8 report_id;
588602
u8 buttons;
589603
u8 rel_x;
590604
u8 rel_y;
591605
u8 padding[4];
592-
// HID vendor part, up to 1751 bytes
593-
u8 unknown[22];
594-
u8 num_fingers;
595-
u8 clicked;
596-
u8 unknown3[14];
597606
};
598607

599608
static inline int le16_to_int(__le16 x)
@@ -623,7 +632,7 @@ static void report_finger_data(struct input_dev *input, int slot,
623632
input_report_abs(input, ABS_MT_POSITION_Y, pos->y);
624633
}
625634

626-
static int magicmouse_raw_event_spi(struct hid_device *hdev,
635+
static int magicmouse_raw_event_mtp(struct hid_device *hdev,
627636
struct hid_report *report, u8 *data, int size)
628637
{
629638
struct magicmouse_sc *msc = hid_get_drvdata(hdev);
@@ -640,9 +649,6 @@ static int magicmouse_raw_event_spi(struct hid_device *hdev,
640649
// print_hex_dump_debug("appleft ev: ", DUMP_PREFIX_OFFSET, 16, 1, data,
641650
// size, false);
642651

643-
if (data[0] != TRACKPAD2_USB_REPORT_ID)
644-
return 0;
645-
646652
/* Expect 46 bytes of prefix, and N * 30 bytes of touch data. */
647653
if (size < hdr_sz || ((size - hdr_sz) % touch_sz) != 0)
648654
return 0;
@@ -681,12 +687,26 @@ static int magicmouse_raw_event_spi(struct hid_device *hdev,
681687
}
682688

683689
input_mt_sync_frame(input);
684-
input_report_key(input, BTN_MOUSE, data[1] & 1);
690+
input_report_key(input, BTN_MOUSE, tp_hdr->buttons & 1);
685691

686692
input_sync(input);
687693
return 1;
688694
}
689695

696+
static int magicmouse_raw_event_spi(struct hid_device *hdev,
697+
struct hid_report *report, u8 *data, int size)
698+
{
699+
const size_t hdr_sz = sizeof(struct tp_mouse_report);
700+
701+
if (size < hdr_sz)
702+
return 0;
703+
704+
if (data[0] != TRACKPAD2_USB_REPORT_ID)
705+
return 0;
706+
707+
return magicmouse_raw_event_mtp(hdev, report, data + hdr_sz, size - hdr_sz);
708+
}
709+
690710
static int magicmouse_event(struct hid_device *hdev, struct hid_field *field,
691711
struct hid_usage *usage, __s32 value)
692712
{
@@ -1071,7 +1091,7 @@ static int magicmouse_probe(struct hid_device *hdev,
10711091
struct hid_report *report;
10721092
int ret;
10731093

1074-
if (id->bus == BUS_SPI && id->vendor == SPI_VENDOR_ID_APPLE &&
1094+
if ((id->bus == BUS_SPI || id->bus == BUS_HOST) && id->vendor == SPI_VENDOR_ID_APPLE &&
10751095
hdev->type != HID_TYPE_SPI_MOUSE)
10761096
return -ENODEV;
10771097

@@ -1083,7 +1103,10 @@ static int magicmouse_probe(struct hid_device *hdev,
10831103

10841104
// internal trackpad use a data format use input ops to avoid
10851105
// conflicts with the report ID.
1086-
if (id->vendor == SPI_VENDOR_ID_APPLE) {
1106+
if (id->bus == BUS_HOST) {
1107+
msc->input_ops.raw_event = magicmouse_raw_event_mtp;
1108+
msc->input_ops.setup_input = magicmouse_setup_input_spi;
1109+
} else if (id->bus == BUS_SPI) {
10871110
msc->input_ops.raw_event = magicmouse_raw_event_spi;
10881111
msc->input_ops.setup_input = magicmouse_setup_input_spi;
10891112

@@ -1140,8 +1163,10 @@ static int magicmouse_probe(struct hid_device *hdev,
11401163
else /* USB_VENDOR_ID_APPLE */
11411164
report = hid_register_report(hdev, HID_INPUT_REPORT,
11421165
TRACKPAD2_USB_REPORT_ID, 0);
1143-
} else if (id->vendor == SPI_VENDOR_ID_APPLE) {
1144-
report = hid_register_report(hdev, HID_INPUT_REPORT, 2, 0);
1166+
} else if (id->bus == BUS_SPI) {
1167+
report = hid_register_report(hdev, HID_INPUT_REPORT, SPI_REPORT_ID, 0);
1168+
} else if (id->bus == BUS_HOST) {
1169+
report = hid_register_report(hdev, HID_INPUT_REPORT, MTP_REPORT_ID, 0);
11451170
} else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
11461171
report = hid_register_report(hdev, HID_INPUT_REPORT,
11471172
TRACKPAD_REPORT_ID, 0);
@@ -1156,6 +1181,10 @@ static int magicmouse_probe(struct hid_device *hdev,
11561181
}
11571182
report->size = 6;
11581183

1184+
/* MTP devices do not need the MT enable, this is handled by the MTP driver */
1185+
if (id->bus == BUS_HOST)
1186+
return 0;
1187+
11591188
/*
11601189
* Some devices repond with 'invalid report id' when feature
11611190
* report switching it into multitouch mode is sent to it.
@@ -1238,6 +1267,8 @@ static const struct hid_device_id magic_mice[] = {
12381267
USB_DEVICE_ID_APPLE_MAGICTRACKPAD2), .driver_data = 0 },
12391268
{ HID_SPI_DEVICE(SPI_VENDOR_ID_APPLE, HID_ANY_ID),
12401269
.driver_data = 0 },
1270+
{ HID_DEVICE(BUS_HOST, HID_GROUP_ANY, HOST_VENDOR_ID_APPLE,
1271+
HID_ANY_ID), .driver_data = 0 },
12411272
{ }
12421273
};
12431274
MODULE_DEVICE_TABLE(hid, magic_mice);

0 commit comments

Comments
 (0)