The hid-magicmouse driver is not handling the Apple Magic Trackpad 2 device properly after a sleep/wake session, where single clicks were recognized, but mouse movement and other clicks were not. The remedy has been to remove and re-connect the device, allowing it to work once again. More background on the issue is available here: https://github.com/robotrovsky/Linux-Magic-Trackpad-2-Driver/issues/37 This patch allows the device to operate properly after a sleep/wake session, but it returns a -32 (broken pipe) error code with the call to hid_hw_raw_request within the magicmouse_hdev_resume function below. In the original code, the prior developer(s) commented that some trackpads will send back an I/O error, and account for that in the if test below the hid_hw_raw_request call. At this time, I'm not sure why the -32 error is being returned. I'm continuing the search on my end, but any assistance or pointers would be appreciated. --- /home/dturton/kernel_hacking/linux/drivers/hid/hid-magicmouse.c 2019-11-24 16:28:11.150005796 -0600 +++ /home/dturton/kernel_hacking/magic_trackpad2_fix/linux/drivers/hid/hid-magicmouse.c 2019-11-26 10:37:14.450633946 -0600 @@ -700,6 +700,54 @@ }; MODULE_DEVICE_TABLE(hid, magic_mice); +static int magicmouse_hdev_resume(struct hid_device *hdev) +{ + int ret; + int feature_size; + u8 *buf; + const u8 *feature; + const u8 feature_mt[] = { 0xD7, 0x01 }; + const u8 feature_mt_trackpad2_usb[] = { 0x02, 0x01 }; + const u8 feature_mt_trackpad2_bt[] = { 0xF1, 0x02, 0x01 }; + + if (hdev->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2) { + if (hdev->vendor == BT_VENDOR_ID_APPLE) { + feature_size = sizeof(feature_mt_trackpad2_bt); + feature = feature_mt_trackpad2_bt; + } else { /* USB_VENDOR_ID_APPLE */ + feature_size = sizeof(feature_mt_trackpad2_usb); + feature = feature_mt_trackpad2_usb; + } + } else { + feature_size = sizeof(feature_mt); + feature = feature_mt; + } + + buf = kmemdup(feature, feature_size, GFP_KERNEL); + if (!buf) { + ret = -ENOMEM; + goto err_stop_hw; + } + + ret = hid_hw_raw_request(hdev, buf[0], buf, feature_size, + HID_FEATURE_REPORT, HID_REQ_SET_REPORT); + kfree(buf); + if (ret != -EIO && ret != feature_size) { + hid_err(hdev, "unable to request touch data (%d)\n", ret); + goto err_stop_hw; + } + return 0; + err_stop_hw: + hid_hw_stop(hdev); + return ret; + } + +static int magicmouse_hdev_suspend( + struct hid_device *hdev, + struct pm_message ignored +){ + return 0; +} static struct hid_driver magicmouse_driver = { .name = "magicmouse", .id_table = magic_mice, @@ -707,6 +755,8 @@ .raw_event = magicmouse_raw_event, .input_mapping = magicmouse_input_mapping, .input_configured = magicmouse_input_configured, + .reset_resume = magicmouse_hdev_resume, + .suspend = magicmouse_hdev_suspend, }; module_hid_driver(magicmouse_driver);