lede/target/linux/silicon/patches-5.19/0128-hid-magicmouse-Add-MTP-multi-touch-device-support.patch

175 lines
5.7 KiB
Diff

From 5624d8c356fe43797e45c28af6faddc425e307aa Mon Sep 17 00:00:00 2001
From: Hector Martin <marcan@marcan.st>
Date: Fri, 8 Jul 2022 02:12:57 +0900
Subject: [PATCH 128/171] 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 <marcan@marcan.st>
---
drivers/hid/hid-magicmouse.c | 67 ++++++++++++++++++++++++++----------
1 file changed, 49 insertions(+), 18 deletions(-)
diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c
index 65c4b6307ce9..a951e8a8f085 100644
--- a/drivers/hid/hid-magicmouse.c
+++ b/drivers/hid/hid-magicmouse.c
@@ -59,6 +59,8 @@ MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state fie
#define MOUSE_REPORT_ID 0x29
#define MOUSE2_REPORT_ID 0x12
#define DOUBLE_REPORT_ID 0xf7
+#define SPI_REPORT_ID 0x02
+#define MTP_REPORT_ID 0x75
#define USB_BATTERY_TIMEOUT_MS 60000
#define MAX_CONTACTS 16
@@ -570,25 +572,32 @@ struct tp_finger {
} __attribute__((packed, aligned(2)));
/**
- * struct trackpad report
+ * vendor trackpad report
*
- * @report_id: reportid
- * @buttons: HID Usage Buttons 3 1-bit reports
* @num_fingers: the number of fingers being reported in @fingers
- * @clicked: same as @buttons
+ * @buttons: same as HID buttons
*/
struct tp_header {
+ // HID vendor part, up to 1751 bytes
+ u8 unknown[22];
+ u8 num_fingers;
+ u8 buttons;
+ u8 unknown3[14];
+};
+
+/**
+ * standard HID mouse report
+ *
+ * @report_id: reportid
+ * @buttons: HID Usage Buttons 3 1-bit reports
+ */
+struct tp_mouse_report {
// HID mouse report
u8 report_id;
u8 buttons;
u8 rel_x;
u8 rel_y;
u8 padding[4];
- // HID vendor part, up to 1751 bytes
- u8 unknown[22];
- u8 num_fingers;
- u8 clicked;
- u8 unknown3[14];
};
static inline int le16_to_int(__le16 x)
@@ -618,7 +627,7 @@ static void report_finger_data(struct input_dev *input, int slot,
input_report_abs(input, ABS_MT_POSITION_Y, pos->y);
}
-static int magicmouse_raw_event_spi(struct hid_device *hdev,
+static int magicmouse_raw_event_mtp(struct hid_device *hdev,
struct hid_report *report, u8 *data, int size)
{
struct magicmouse_sc *msc = hid_get_drvdata(hdev);
@@ -635,9 +644,6 @@ static int magicmouse_raw_event_spi(struct hid_device *hdev,
// print_hex_dump_debug("appleft ev: ", DUMP_PREFIX_OFFSET, 16, 1, data,
// size, false);
- if (data[0] != TRACKPAD2_USB_REPORT_ID)
- return 0;
-
/* Expect 46 bytes of prefix, and N * 30 bytes of touch data. */
if (size < hdr_sz || ((size - hdr_sz) % touch_sz) != 0)
return 0;
@@ -676,12 +682,26 @@ static int magicmouse_raw_event_spi(struct hid_device *hdev,
}
input_mt_sync_frame(input);
- input_report_key(input, BTN_MOUSE, data[1] & 1);
+ input_report_key(input, BTN_MOUSE, tp_hdr->buttons & 1);
input_sync(input);
return 1;
}
+static int magicmouse_raw_event_spi(struct hid_device *hdev,
+ struct hid_report *report, u8 *data, int size)
+{
+ const size_t hdr_sz = sizeof(struct tp_mouse_report);
+
+ if (size < hdr_sz)
+ return 0;
+
+ if (data[0] != TRACKPAD2_USB_REPORT_ID)
+ return 0;
+
+ return magicmouse_raw_event_mtp(hdev, report, data + hdr_sz, size - hdr_sz);
+}
+
static int magicmouse_event(struct hid_device *hdev, struct hid_field *field,
struct hid_usage *usage, __s32 value)
{
@@ -1066,7 +1086,7 @@ static int magicmouse_probe(struct hid_device *hdev,
struct hid_report *report;
int ret;
- if (id->bus == BUS_SPI && id->vendor == SPI_VENDOR_ID_APPLE &&
+ if ((id->bus == BUS_SPI || id->bus == BUS_HOST) && id->vendor == SPI_VENDOR_ID_APPLE &&
hdev->type != HID_TYPE_SPI_MOUSE)
return -ENODEV;
@@ -1078,7 +1098,10 @@ static int magicmouse_probe(struct hid_device *hdev,
// internal trackpad use a data format use input ops to avoid
// conflicts with the report ID.
- if (id->vendor == SPI_VENDOR_ID_APPLE) {
+ if (id->bus == BUS_HOST) {
+ msc->input_ops.raw_event = magicmouse_raw_event_mtp;
+ msc->input_ops.setup_input = magicmouse_setup_input_spi;
+ } else if (id->bus == BUS_SPI) {
msc->input_ops.raw_event = magicmouse_raw_event_spi;
msc->input_ops.setup_input = magicmouse_setup_input_spi;
@@ -1135,8 +1158,10 @@ static int magicmouse_probe(struct hid_device *hdev,
else /* USB_VENDOR_ID_APPLE */
report = hid_register_report(hdev, HID_INPUT_REPORT,
TRACKPAD2_USB_REPORT_ID, 0);
- } else if (id->vendor == SPI_VENDOR_ID_APPLE) {
- report = hid_register_report(hdev, HID_INPUT_REPORT, 2, 0);
+ } else if (id->bus == BUS_SPI) {
+ report = hid_register_report(hdev, HID_INPUT_REPORT, SPI_REPORT_ID, 0);
+ } else if (id->bus == BUS_HOST) {
+ report = hid_register_report(hdev, HID_INPUT_REPORT, MTP_REPORT_ID, 0);
} else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
report = hid_register_report(hdev, HID_INPUT_REPORT,
TRACKPAD_REPORT_ID, 0);
@@ -1151,6 +1176,10 @@ static int magicmouse_probe(struct hid_device *hdev,
}
report->size = 6;
+ /* MTP devices do not need the MT enable, this is handled by the MTP driver */
+ if (id->bus == BUS_HOST)
+ return 0;
+
/*
* Some devices repond with 'invalid report id' when feature
* report switching it into multitouch mode is sent to it.
@@ -1233,6 +1262,8 @@ static const struct hid_device_id magic_mice[] = {
USB_DEVICE_ID_APPLE_MAGICTRACKPAD2), .driver_data = 0 },
{ HID_SPI_DEVICE(SPI_VENDOR_ID_APPLE, HID_ANY_ID),
.driver_data = 0 },
+ { HID_DEVICE(BUS_HOST, HID_GROUP_ANY, HOST_VENDOR_ID_APPLE,
+ HID_ANY_ID), .driver_data = 0 },
{ }
};
MODULE_DEVICE_TABLE(hid, magic_mice);
--
2.34.1