mirror of
https://github.com/coolsnowwolf/lede.git
synced 2025-07-19 01:56:59 +08:00
175 lines
5.7 KiB
Diff
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
|
|
|