@@ -60,6 +60,7 @@ MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state fie
6060#define MOUSE2_REPORT_ID 0x12
6161#define DOUBLE_REPORT_ID 0xf7
6262#define SPI_REPORT_ID 0x02
63+ #define SPI_RESET_REPORT_ID 0x60
6364#define MTP_REPORT_ID 0x75
6465#define USB_BATTERY_TIMEOUT_MS 60000
6566
@@ -173,6 +174,97 @@ struct magicmouse_sc {
173174 struct magicmouse_input_ops input_ops ;
174175};
175176
177+ static int magicmouse_enable_multitouch (struct hid_device * hdev )
178+ {
179+ const u8 * feature ;
180+ const u8 feature_mt [] = { 0xD7 , 0x01 };
181+ const u8 feature_mt_mouse2 [] = { 0xF1 , 0x02 , 0x01 };
182+ const u8 feature_mt_trackpad2_usb [] = { 0x02 , 0x01 };
183+ const u8 feature_mt_trackpad2_bt [] = { 0xF1 , 0x02 , 0x01 };
184+ u8 * buf ;
185+ int ret ;
186+ int feature_size ;
187+
188+ if (hdev -> product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 ) {
189+ if (hdev -> vendor == BT_VENDOR_ID_APPLE ) {
190+ feature_size = sizeof (feature_mt_trackpad2_bt );
191+ feature = feature_mt_trackpad2_bt ;
192+ } else { /* USB_VENDOR_ID_APPLE */
193+ feature_size = sizeof (feature_mt_trackpad2_usb );
194+ feature = feature_mt_trackpad2_usb ;
195+ }
196+ } else if (hdev -> vendor == SPI_VENDOR_ID_APPLE ) {
197+ feature_size = sizeof (feature_mt_trackpad2_usb );
198+ feature = feature_mt_trackpad2_usb ;
199+ } else if (hdev -> product == USB_DEVICE_ID_APPLE_MAGICMOUSE2 ) {
200+ feature_size = sizeof (feature_mt_mouse2 );
201+ feature = feature_mt_mouse2 ;
202+ } else {
203+ feature_size = sizeof (feature_mt );
204+ feature = feature_mt ;
205+ }
206+
207+ buf = kmemdup (feature , feature_size , GFP_KERNEL );
208+ if (!buf )
209+ return - ENOMEM ;
210+
211+ ret = hid_hw_raw_request (hdev , buf [0 ], buf , feature_size ,
212+ HID_FEATURE_REPORT , HID_REQ_SET_REPORT );
213+ kfree (buf );
214+ return ret ;
215+ }
216+
217+ static void magicmouse_enable_mt_work (struct work_struct * work )
218+ {
219+ struct magicmouse_sc * msc =
220+ container_of (work , struct magicmouse_sc , work .work );
221+ int ret ;
222+
223+ ret = magicmouse_enable_multitouch (msc -> hdev );
224+ if (ret < 0 )
225+ hid_err (msc -> hdev , "unable to request touch data (%d)\n" , ret );
226+ }
227+
228+ static int magicmouse_open (struct input_dev * dev )
229+ {
230+ struct hid_device * hdev = input_get_drvdata (dev );
231+ struct magicmouse_sc * msc = hid_get_drvdata (hdev );
232+ int ret ;
233+
234+ ret = hid_hw_open (hdev );
235+ if (ret )
236+ return ret ;
237+
238+ /*
239+ * Some devices repond with 'invalid report id' when feature
240+ * report switching it into multitouch mode is sent to it.
241+ *
242+ * This results in -EIO from the _raw low-level transport callback,
243+ * but there seems to be no other way of switching the mode.
244+ * Thus the super-ugly hacky success check below.
245+ */
246+ ret = magicmouse_enable_multitouch (hdev );
247+ if (ret == - EIO && hdev -> product == USB_DEVICE_ID_APPLE_MAGICMOUSE2 ) {
248+ schedule_delayed_work (& msc -> work , msecs_to_jiffies (500 ));
249+ return 0 ;
250+ }
251+ if (ret < 0 )
252+ hid_err (hdev , "unable to request touch data (%d)\n" , ret );
253+
254+ /*
255+ * MT enable is usually not required after the first time, so don't
256+ * consider it fatal.
257+ */
258+ return 0 ;
259+ }
260+
261+ static void magicmouse_close (struct input_dev * dev )
262+ {
263+ struct hid_device * hdev = input_get_drvdata (dev );
264+
265+ hid_hw_close (hdev );
266+ }
267+
176268static int magicmouse_firm_touch (struct magicmouse_sc * msc )
177269{
178270 int touch = -1 ;
@@ -694,12 +786,19 @@ static int magicmouse_raw_event_mtp(struct hid_device *hdev,
694786static int magicmouse_raw_event_spi (struct hid_device * hdev ,
695787 struct hid_report * report , u8 * data , int size )
696788{
789+ struct magicmouse_sc * msc = hid_get_drvdata (hdev );
697790 const size_t hdr_sz = sizeof (struct tp_mouse_report );
698791
699- if (size < hdr_sz )
792+ if (! size )
700793 return 0 ;
701794
702- if (data [0 ] != TRACKPAD2_USB_REPORT_ID )
795+ if (data [0 ] == SPI_RESET_REPORT_ID ) {
796+ hid_info (hdev , "Touch controller was reset, re-enabling touch mode\n" );
797+ schedule_delayed_work (& msc -> work , msecs_to_jiffies (10 ));
798+ return 1 ;
799+ }
800+
801+ if (data [0 ] != TRACKPAD2_USB_REPORT_ID || size < hdr_sz )
703802 return 0 ;
704803
705804 return magicmouse_raw_event_mtp (hdev , report , data + hdr_sz , size - hdr_sz );
@@ -881,10 +980,17 @@ static int magicmouse_setup_input_usb(struct input_dev *input,
881980 */
882981 __clear_bit (EV_REP , input -> evbit );
883982
983+ /*
984+ * This isn't strictly speaking needed for USB, but enabling MT on
985+ * device open is probably more robust than only doing it once on probe
986+ * even if USB devices are not known to suffer from the SPI reset issue.
987+ */
988+ input -> open = magicmouse_open ;
989+ input -> close = magicmouse_close ;
884990 return 0 ;
885991}
886992
887- static int magicmouse_setup_input_spi (struct input_dev * input ,
993+ static int magicmouse_setup_input_mtp (struct input_dev * input ,
888994 struct hid_device * hdev )
889995{
890996 int error ;
@@ -957,6 +1063,25 @@ static int magicmouse_setup_input_spi(struct input_dev *input,
9571063 return 0 ;
9581064}
9591065
1066+ static int magicmouse_setup_input_spi (struct input_dev * input ,
1067+ struct hid_device * hdev )
1068+ {
1069+ int ret = magicmouse_setup_input_mtp (input , hdev );
1070+ if (ret )
1071+ return ret ;
1072+
1073+ /*
1074+ * Override the default input->open function to send the MT
1075+ * enable every time the device is opened. This ensures it works
1076+ * even if we missed a reset event due to the device being closed.
1077+ * input->close is overridden for symmetry.
1078+ */
1079+ input -> open = magicmouse_open ;
1080+ input -> close = magicmouse_close ;
1081+
1082+ return 0 ;
1083+ }
1084+
9601085static int magicmouse_input_mapping (struct hid_device * hdev ,
9611086 struct hid_input * hi , struct hid_field * field ,
9621087 struct hid_usage * usage , unsigned long * * bit , int * max )
@@ -993,57 +1118,6 @@ static int magicmouse_input_configured(struct hid_device *hdev,
9931118 return 0 ;
9941119}
9951120
996- static int magicmouse_enable_multitouch (struct hid_device * hdev )
997- {
998- const u8 * feature ;
999- const u8 feature_mt [] = { 0xD7 , 0x01 };
1000- const u8 feature_mt_mouse2 [] = { 0xF1 , 0x02 , 0x01 };
1001- const u8 feature_mt_trackpad2_usb [] = { 0x02 , 0x01 };
1002- const u8 feature_mt_trackpad2_bt [] = { 0xF1 , 0x02 , 0x01 };
1003- u8 * buf ;
1004- int ret ;
1005- int feature_size ;
1006-
1007- if (hdev -> product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 ) {
1008- if (hdev -> vendor == BT_VENDOR_ID_APPLE ) {
1009- feature_size = sizeof (feature_mt_trackpad2_bt );
1010- feature = feature_mt_trackpad2_bt ;
1011- } else { /* USB_VENDOR_ID_APPLE */
1012- feature_size = sizeof (feature_mt_trackpad2_usb );
1013- feature = feature_mt_trackpad2_usb ;
1014- }
1015- } else if (hdev -> vendor == SPI_VENDOR_ID_APPLE ) {
1016- feature_size = sizeof (feature_mt_trackpad2_usb );
1017- feature = feature_mt_trackpad2_usb ;
1018- } else if (hdev -> product == USB_DEVICE_ID_APPLE_MAGICMOUSE2 ) {
1019- feature_size = sizeof (feature_mt_mouse2 );
1020- feature = feature_mt_mouse2 ;
1021- } else {
1022- feature_size = sizeof (feature_mt );
1023- feature = feature_mt ;
1024- }
1025-
1026- buf = kmemdup (feature , feature_size , GFP_KERNEL );
1027- if (!buf )
1028- return - ENOMEM ;
1029-
1030- ret = hid_hw_raw_request (hdev , buf [0 ], buf , feature_size ,
1031- HID_FEATURE_REPORT , HID_REQ_SET_REPORT );
1032- kfree (buf );
1033- return ret ;
1034- }
1035-
1036- static void magicmouse_enable_mt_work (struct work_struct * work )
1037- {
1038- struct magicmouse_sc * msc =
1039- container_of (work , struct magicmouse_sc , work .work );
1040- int ret ;
1041-
1042- ret = magicmouse_enable_multitouch (msc -> hdev );
1043- if (ret < 0 )
1044- hid_err (msc -> hdev , "unable to request touch data (%d)\n" , ret );
1045- }
1046-
10471121static int magicmouse_fetch_battery (struct hid_device * hdev )
10481122{
10491123#ifdef CONFIG_HID_BATTERY_STRENGTH
@@ -1103,7 +1177,7 @@ static int magicmouse_probe(struct hid_device *hdev,
11031177 // conflicts with the report ID.
11041178 if (id -> bus == BUS_HOST ) {
11051179 msc -> input_ops .raw_event = magicmouse_raw_event_mtp ;
1106- msc -> input_ops .setup_input = magicmouse_setup_input_spi ;
1180+ msc -> input_ops .setup_input = magicmouse_setup_input_mtp ;
11071181 } else if (id -> bus == BUS_SPI ) {
11081182 msc -> input_ops .raw_event = magicmouse_raw_event_spi ;
11091183 msc -> input_ops .setup_input = magicmouse_setup_input_spi ;
@@ -1183,21 +1257,10 @@ static int magicmouse_probe(struct hid_device *hdev,
11831257 if (id -> bus == BUS_HOST )
11841258 return 0 ;
11851259
1186- /*
1187- * Some devices repond with 'invalid report id' when feature
1188- * report switching it into multitouch mode is sent to it.
1189- *
1190- * This results in -EIO from the _raw low-level transport callback,
1191- * but there seems to be no other way of switching the mode.
1192- * Thus the super-ugly hacky success check below.
1193- */
1194- ret = magicmouse_enable_multitouch (hdev );
1195- if (ret != - EIO && ret < 0 ) {
1196- hid_err (hdev , "unable to request touch data (%d)\n" , ret );
1197- goto err_stop_hw ;
1198- }
1199- if (ret == - EIO && id -> product == USB_DEVICE_ID_APPLE_MAGICMOUSE2 ) {
1200- schedule_delayed_work (& msc -> work , msecs_to_jiffies (500 ));
1260+ /* SPI devices need to watch for reset events to re-send the MT enable */
1261+ if (id -> bus == BUS_SPI ) {
1262+ report = hid_register_report (hdev , HID_INPUT_REPORT , SPI_RESET_REPORT_ID , 0 );
1263+ report -> size = 2 ;
12011264 }
12021265
12031266 return 0 ;
0 commit comments