@@ -61,6 +61,7 @@ MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state fie
6161#define MOUSE2_REPORT_ID 0x12
6262#define DOUBLE_REPORT_ID 0xf7
6363#define SPI_REPORT_ID 0x02
64+ #define SPI_RESET_REPORT_ID 0x60
6465#define MTP_REPORT_ID 0x75
6566#define USB_BATTERY_TIMEOUT_SEC 60
6667
@@ -176,6 +177,50 @@ struct magicmouse_sc {
176177 struct magicmouse_input_ops input_ops ;
177178};
178179
180+ static int magicmouse_enable_multitouch (struct hid_device * hdev );
181+
182+ static int magicmouse_open (struct input_dev * dev )
183+ {
184+ struct hid_device * hdev = input_get_drvdata (dev );
185+ struct magicmouse_sc * msc = hid_get_drvdata (hdev );
186+ int ret ;
187+
188+ ret = hid_hw_open (hdev );
189+ if (ret )
190+ return ret ;
191+
192+ /*
193+ * Some devices repond with 'invalid report id' when feature
194+ * report switching it into multitouch mode is sent to it.
195+ *
196+ * This results in -EIO from the _raw low-level transport callback,
197+ * but there seems to be no other way of switching the mode.
198+ * Thus the super-ugly hacky success check below.
199+ */
200+ ret = magicmouse_enable_multitouch (hdev );
201+ if (ret != - EIO && ret < 0 ) {
202+ hid_err (hdev , "unable to request touch data (%d)\n" , ret );
203+ return ret ;
204+ }
205+ if (ret == - EIO && (hdev -> product == USB_DEVICE_ID_APPLE_MAGICMOUSE2 ||
206+ hdev -> product == USB_DEVICE_ID_APPLE_MAGICMOUSE2_USBC )) {
207+ schedule_delayed_work (& msc -> work , msecs_to_jiffies (500 ));
208+ }
209+
210+ /*
211+ * MT enable is usually not required after the first time, so don't
212+ * consider it fatal.
213+ */
214+ return 0 ;
215+ }
216+
217+ static void magicmouse_close (struct input_dev * dev )
218+ {
219+ struct hid_device * hdev = input_get_drvdata (dev );
220+
221+ hid_hw_close (hdev );
222+ }
223+
179224static int magicmouse_firm_touch (struct magicmouse_sc * msc )
180225{
181226 int touch = -1 ;
@@ -706,12 +751,19 @@ static int magicmouse_raw_event_mtp(struct hid_device *hdev,
706751static int magicmouse_raw_event_spi (struct hid_device * hdev ,
707752 struct hid_report * report , u8 * data , int size )
708753{
754+ struct magicmouse_sc * msc = hid_get_drvdata (hdev );
709755 const size_t hdr_sz = sizeof (struct tp_mouse_report );
710756
711- if (size < hdr_sz )
757+ if (! size )
712758 return 0 ;
713759
714- if (data [0 ] != SPI_REPORT_ID )
760+ if (data [0 ] == SPI_RESET_REPORT_ID ) {
761+ hid_info (hdev , "Touch controller was reset, re-enabling touch mode\n" );
762+ schedule_delayed_work (& msc -> work , msecs_to_jiffies (10 ));
763+ return 1 ;
764+ }
765+
766+ if (data [0 ] != SPI_REPORT_ID || size < hdr_sz )
715767 return 0 ;
716768
717769 return magicmouse_raw_event_mtp (hdev , report , data + hdr_sz , size - hdr_sz );
@@ -904,10 +956,17 @@ static int magicmouse_setup_input_usb(struct input_dev *input,
904956 */
905957 __clear_bit (EV_REP , input -> evbit );
906958
959+ /*
960+ * This isn't strictly speaking needed for USB, but enabling MT on
961+ * device open is probably more robust than only doing it once on probe
962+ * even if USB devices are not known to suffer from the SPI reset issue.
963+ */
964+ input -> open = magicmouse_open ;
965+ input -> close = magicmouse_close ;
907966 return 0 ;
908967}
909968
910- static int magicmouse_setup_input_spi (struct input_dev * input ,
969+ static int magicmouse_setup_input_mtp (struct input_dev * input ,
911970 struct hid_device * hdev )
912971{
913972 int error ;
@@ -980,6 +1039,25 @@ static int magicmouse_setup_input_spi(struct input_dev *input,
9801039 return 0 ;
9811040}
9821041
1042+ static int magicmouse_setup_input_spi (struct input_dev * input ,
1043+ struct hid_device * hdev )
1044+ {
1045+ int ret = magicmouse_setup_input_mtp (input , hdev );
1046+ if (ret )
1047+ return ret ;
1048+
1049+ /*
1050+ * Override the default input->open function to send the MT
1051+ * enable every time the device is opened. This ensures it works
1052+ * even if we missed a reset event due to the device being closed.
1053+ * input->close is overridden for symmetry.
1054+ */
1055+ input -> open = magicmouse_open ;
1056+ input -> close = magicmouse_close ;
1057+
1058+ return 0 ;
1059+ }
1060+
9831061static int magicmouse_input_mapping (struct hid_device * hdev ,
9841062 struct hid_input * hi , struct hid_field * field ,
9851063 struct hid_usage * usage , unsigned long * * bit , int * max )
@@ -1041,7 +1119,7 @@ static int magicmouse_enable_multitouch(struct hid_device *hdev)
10411119 feature_size = sizeof (feature_mt_trackpad2_bt );
10421120 feature = feature_mt_trackpad2_bt ;
10431121 break ;
1044- default : /* USB_VENDOR_ID_APPLE || SPI_VENDOR_ID_APPLE */
1122+ default : /* USB_VENDOR_ID_APPLE || SPI_VENDOR_ID_APPLE */
10451123 feature_size = sizeof (feature_mt_trackpad2_usb );
10461124 feature = feature_mt_trackpad2_usb ;
10471125 }
@@ -1152,7 +1230,7 @@ static int magicmouse_probe(struct hid_device *hdev,
11521230 // conflicts with the report ID.
11531231 if (id -> bus == BUS_HOST ) {
11541232 msc -> input_ops .raw_event = magicmouse_raw_event_mtp ;
1155- msc -> input_ops .setup_input = magicmouse_setup_input_spi ;
1233+ msc -> input_ops .setup_input = magicmouse_setup_input_mtp ;
11561234 } else if (id -> bus == BUS_SPI ) {
11571235 msc -> input_ops .raw_event = magicmouse_raw_event_spi ;
11581236 msc -> input_ops .setup_input = magicmouse_setup_input_spi ;
@@ -1246,22 +1324,10 @@ static int magicmouse_probe(struct hid_device *hdev,
12461324 if (id -> bus == BUS_HOST )
12471325 return 0 ;
12481326
1249- /*
1250- * Some devices repond with 'invalid report id' when feature
1251- * report switching it into multitouch mode is sent to it.
1252- *
1253- * This results in -EIO from the _raw low-level transport callback,
1254- * but there seems to be no other way of switching the mode.
1255- * Thus the super-ugly hacky success check below.
1256- */
1257- ret = magicmouse_enable_multitouch (hdev );
1258- if (ret != - EIO && ret < 0 ) {
1259- hid_err (hdev , "unable to request touch data (%d)\n" , ret );
1260- goto err_stop_hw ;
1261- }
1262- if (ret == - EIO && (id -> product == USB_DEVICE_ID_APPLE_MAGICMOUSE2 ||
1263- id -> product == USB_DEVICE_ID_APPLE_MAGICMOUSE2_USBC )) {
1264- schedule_delayed_work (& msc -> work , msecs_to_jiffies (500 ));
1327+ /* SPI devices need to watch for reset events to re-send the MT enable */
1328+ if (id -> bus == BUS_SPI ) {
1329+ report = hid_register_report (hdev , HID_INPUT_REPORT , SPI_RESET_REPORT_ID , 0 );
1330+ report -> size = 2 ;
12651331 }
12661332
12671333 return 0 ;
0 commit comments