@@ -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
@@ -175,6 +176,97 @@ struct magicmouse_sc {
175176 struct magicmouse_input_ops input_ops ;
176177};
177178
179+ static int magicmouse_enable_multitouch (struct hid_device * hdev )
180+ {
181+ const u8 * feature ;
182+ const u8 feature_mt [] = { 0xD7 , 0x01 };
183+ const u8 feature_mt_mouse2 [] = { 0xF1 , 0x02 , 0x01 };
184+ const u8 feature_mt_trackpad2_usb [] = { 0x02 , 0x01 };
185+ const u8 feature_mt_trackpad2_bt [] = { 0xF1 , 0x02 , 0x01 };
186+ u8 * buf ;
187+ int ret ;
188+ int feature_size ;
189+
190+ if (hdev -> product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 ) {
191+ if (hdev -> vendor == BT_VENDOR_ID_APPLE ) {
192+ feature_size = sizeof (feature_mt_trackpad2_bt );
193+ feature = feature_mt_trackpad2_bt ;
194+ } else { /* USB_VENDOR_ID_APPLE */
195+ feature_size = sizeof (feature_mt_trackpad2_usb );
196+ feature = feature_mt_trackpad2_usb ;
197+ }
198+ } else if (hdev -> vendor == SPI_VENDOR_ID_APPLE ) {
199+ feature_size = sizeof (feature_mt_trackpad2_usb );
200+ feature = feature_mt_trackpad2_usb ;
201+ } else if (hdev -> product == USB_DEVICE_ID_APPLE_MAGICMOUSE2 ) {
202+ feature_size = sizeof (feature_mt_mouse2 );
203+ feature = feature_mt_mouse2 ;
204+ } else {
205+ feature_size = sizeof (feature_mt );
206+ feature = feature_mt ;
207+ }
208+
209+ buf = kmemdup (feature , feature_size , GFP_KERNEL );
210+ if (!buf )
211+ return - ENOMEM ;
212+
213+ ret = hid_hw_raw_request (hdev , buf [0 ], buf , feature_size ,
214+ HID_FEATURE_REPORT , HID_REQ_SET_REPORT );
215+ kfree (buf );
216+ return ret ;
217+ }
218+
219+ static void magicmouse_enable_mt_work (struct work_struct * work )
220+ {
221+ struct magicmouse_sc * msc =
222+ container_of (work , struct magicmouse_sc , work .work );
223+ int ret ;
224+
225+ ret = magicmouse_enable_multitouch (msc -> hdev );
226+ if (ret < 0 )
227+ hid_err (msc -> hdev , "unable to request touch data (%d)\n" , ret );
228+ }
229+
230+ static int magicmouse_open (struct input_dev * dev )
231+ {
232+ struct hid_device * hdev = input_get_drvdata (dev );
233+ struct magicmouse_sc * msc = hid_get_drvdata (hdev );
234+ int ret ;
235+
236+ ret = hid_hw_open (hdev );
237+ if (ret )
238+ return ret ;
239+
240+ /*
241+ * Some devices repond with 'invalid report id' when feature
242+ * report switching it into multitouch mode is sent to it.
243+ *
244+ * This results in -EIO from the _raw low-level transport callback,
245+ * but there seems to be no other way of switching the mode.
246+ * Thus the super-ugly hacky success check below.
247+ */
248+ ret = magicmouse_enable_multitouch (hdev );
249+ if (ret == - EIO && hdev -> product == USB_DEVICE_ID_APPLE_MAGICMOUSE2 ) {
250+ schedule_delayed_work (& msc -> work , msecs_to_jiffies (500 ));
251+ return 0 ;
252+ }
253+ if (ret < 0 )
254+ hid_err (hdev , "unable to request touch data (%d)\n" , ret );
255+
256+ /*
257+ * MT enable is usually not required after the first time, so don't
258+ * consider it fatal.
259+ */
260+ return 0 ;
261+ }
262+
263+ static void magicmouse_close (struct input_dev * dev )
264+ {
265+ struct hid_device * hdev = input_get_drvdata (dev );
266+
267+ hid_hw_close (hdev );
268+ }
269+
178270static int magicmouse_firm_touch (struct magicmouse_sc * msc )
179271{
180272 int touch = -1 ;
@@ -696,12 +788,19 @@ static int magicmouse_raw_event_mtp(struct hid_device *hdev,
696788static int magicmouse_raw_event_spi (struct hid_device * hdev ,
697789 struct hid_report * report , u8 * data , int size )
698790{
791+ struct magicmouse_sc * msc = hid_get_drvdata (hdev );
699792 const size_t hdr_sz = sizeof (struct tp_mouse_report );
700793
701- if (size < hdr_sz )
794+ if (! size )
702795 return 0 ;
703796
704- if (data [0 ] != TRACKPAD2_USB_REPORT_ID )
797+ if (data [0 ] == SPI_RESET_REPORT_ID ) {
798+ hid_info (hdev , "Touch controller was reset, re-enabling touch mode\n" );
799+ schedule_delayed_work (& msc -> work , msecs_to_jiffies (10 ));
800+ return 1 ;
801+ }
802+
803+ if (data [0 ] != TRACKPAD2_USB_REPORT_ID || size < hdr_sz )
705804 return 0 ;
706805
707806 return magicmouse_raw_event_mtp (hdev , report , data + hdr_sz , size - hdr_sz );
@@ -883,10 +982,17 @@ static int magicmouse_setup_input_usb(struct input_dev *input,
883982 */
884983 __clear_bit (EV_REP , input -> evbit );
885984
985+ /*
986+ * This isn't strictly speaking needed for USB, but enabling MT on
987+ * device open is probably more robust than only doing it once on probe
988+ * even if USB devices are not known to suffer from the SPI reset issue.
989+ */
990+ input -> open = magicmouse_open ;
991+ input -> close = magicmouse_close ;
886992 return 0 ;
887993}
888994
889- static int magicmouse_setup_input_spi (struct input_dev * input ,
995+ static int magicmouse_setup_input_mtp (struct input_dev * input ,
890996 struct hid_device * hdev )
891997{
892998 int error ;
@@ -959,6 +1065,25 @@ static int magicmouse_setup_input_spi(struct input_dev *input,
9591065 return 0 ;
9601066}
9611067
1068+ static int magicmouse_setup_input_spi (struct input_dev * input ,
1069+ struct hid_device * hdev )
1070+ {
1071+ int ret = magicmouse_setup_input_mtp (input , hdev );
1072+ if (ret )
1073+ return ret ;
1074+
1075+ /*
1076+ * Override the default input->open function to send the MT
1077+ * enable every time the device is opened. This ensures it works
1078+ * even if we missed a reset event due to the device being closed.
1079+ * input->close is overridden for symmetry.
1080+ */
1081+ input -> open = magicmouse_open ;
1082+ input -> close = magicmouse_close ;
1083+
1084+ return 0 ;
1085+ }
1086+
9621087static int magicmouse_input_mapping (struct hid_device * hdev ,
9631088 struct hid_input * hi , struct hid_field * field ,
9641089 struct hid_usage * usage , unsigned long * * bit , int * max )
@@ -995,57 +1120,6 @@ static int magicmouse_input_configured(struct hid_device *hdev,
9951120 return 0 ;
9961121}
9971122
998- static int magicmouse_enable_multitouch (struct hid_device * hdev )
999- {
1000- const u8 * feature ;
1001- const u8 feature_mt [] = { 0xD7 , 0x01 };
1002- const u8 feature_mt_mouse2 [] = { 0xF1 , 0x02 , 0x01 };
1003- const u8 feature_mt_trackpad2_usb [] = { 0x02 , 0x01 };
1004- const u8 feature_mt_trackpad2_bt [] = { 0xF1 , 0x02 , 0x01 };
1005- u8 * buf ;
1006- int ret ;
1007- int feature_size ;
1008-
1009- if (hdev -> product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 ) {
1010- if (hdev -> vendor == BT_VENDOR_ID_APPLE ) {
1011- feature_size = sizeof (feature_mt_trackpad2_bt );
1012- feature = feature_mt_trackpad2_bt ;
1013- } else { /* USB_VENDOR_ID_APPLE */
1014- feature_size = sizeof (feature_mt_trackpad2_usb );
1015- feature = feature_mt_trackpad2_usb ;
1016- }
1017- } else if (hdev -> vendor == SPI_VENDOR_ID_APPLE ) {
1018- feature_size = sizeof (feature_mt_trackpad2_usb );
1019- feature = feature_mt_trackpad2_usb ;
1020- } else if (hdev -> product == USB_DEVICE_ID_APPLE_MAGICMOUSE2 ) {
1021- feature_size = sizeof (feature_mt_mouse2 );
1022- feature = feature_mt_mouse2 ;
1023- } else {
1024- feature_size = sizeof (feature_mt );
1025- feature = feature_mt ;
1026- }
1027-
1028- buf = kmemdup (feature , feature_size , GFP_KERNEL );
1029- if (!buf )
1030- return - ENOMEM ;
1031-
1032- ret = hid_hw_raw_request (hdev , buf [0 ], buf , feature_size ,
1033- HID_FEATURE_REPORT , HID_REQ_SET_REPORT );
1034- kfree (buf );
1035- return ret ;
1036- }
1037-
1038- static void magicmouse_enable_mt_work (struct work_struct * work )
1039- {
1040- struct magicmouse_sc * msc =
1041- container_of (work , struct magicmouse_sc , work .work );
1042- int ret ;
1043-
1044- ret = magicmouse_enable_multitouch (msc -> hdev );
1045- if (ret < 0 )
1046- hid_err (msc -> hdev , "unable to request touch data (%d)\n" , ret );
1047- }
1048-
10491123static int magicmouse_fetch_battery (struct hid_device * hdev )
10501124{
10511125#ifdef CONFIG_HID_BATTERY_STRENGTH
@@ -1105,7 +1179,7 @@ static int magicmouse_probe(struct hid_device *hdev,
11051179 // conflicts with the report ID.
11061180 if (id -> bus == BUS_HOST ) {
11071181 msc -> input_ops .raw_event = magicmouse_raw_event_mtp ;
1108- msc -> input_ops .setup_input = magicmouse_setup_input_spi ;
1182+ msc -> input_ops .setup_input = magicmouse_setup_input_mtp ;
11091183 } else if (id -> bus == BUS_SPI ) {
11101184 msc -> input_ops .raw_event = magicmouse_raw_event_spi ;
11111185 msc -> input_ops .setup_input = magicmouse_setup_input_spi ;
@@ -1185,21 +1259,10 @@ static int magicmouse_probe(struct hid_device *hdev,
11851259 if (id -> bus == BUS_HOST )
11861260 return 0 ;
11871261
1188- /*
1189- * Some devices repond with 'invalid report id' when feature
1190- * report switching it into multitouch mode is sent to it.
1191- *
1192- * This results in -EIO from the _raw low-level transport callback,
1193- * but there seems to be no other way of switching the mode.
1194- * Thus the super-ugly hacky success check below.
1195- */
1196- ret = magicmouse_enable_multitouch (hdev );
1197- if (ret != - EIO && ret < 0 ) {
1198- hid_err (hdev , "unable to request touch data (%d)\n" , ret );
1199- goto err_stop_hw ;
1200- }
1201- if (ret == - EIO && id -> product == USB_DEVICE_ID_APPLE_MAGICMOUSE2 ) {
1202- schedule_delayed_work (& msc -> work , msecs_to_jiffies (500 ));
1262+ /* SPI devices need to watch for reset events to re-send the MT enable */
1263+ if (id -> bus == BUS_SPI ) {
1264+ report = hid_register_report (hdev , HID_INPUT_REPORT , SPI_RESET_REPORT_ID , 0 );
1265+ report -> size = 2 ;
12031266 }
12041267
12051268 return 0 ;
0 commit comments