@@ -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
@@ -170,6 +171,97 @@ struct magicmouse_sc {
170171 struct magicmouse_input_ops input_ops ;
171172};
172173
174+ static int magicmouse_enable_multitouch (struct hid_device * hdev )
175+ {
176+ const u8 * feature ;
177+ const u8 feature_mt [] = { 0xD7 , 0x01 };
178+ const u8 feature_mt_mouse2 [] = { 0xF1 , 0x02 , 0x01 };
179+ const u8 feature_mt_trackpad2_usb [] = { 0x02 , 0x01 };
180+ const u8 feature_mt_trackpad2_bt [] = { 0xF1 , 0x02 , 0x01 };
181+ u8 * buf ;
182+ int ret ;
183+ int feature_size ;
184+
185+ if (hdev -> product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 ) {
186+ if (hdev -> vendor == BT_VENDOR_ID_APPLE ) {
187+ feature_size = sizeof (feature_mt_trackpad2_bt );
188+ feature = feature_mt_trackpad2_bt ;
189+ } else { /* USB_VENDOR_ID_APPLE */
190+ feature_size = sizeof (feature_mt_trackpad2_usb );
191+ feature = feature_mt_trackpad2_usb ;
192+ }
193+ } else if (hdev -> vendor == SPI_VENDOR_ID_APPLE ) {
194+ feature_size = sizeof (feature_mt_trackpad2_usb );
195+ feature = feature_mt_trackpad2_usb ;
196+ } else if (hdev -> product == USB_DEVICE_ID_APPLE_MAGICMOUSE2 ) {
197+ feature_size = sizeof (feature_mt_mouse2 );
198+ feature = feature_mt_mouse2 ;
199+ } else {
200+ feature_size = sizeof (feature_mt );
201+ feature = feature_mt ;
202+ }
203+
204+ buf = kmemdup (feature , feature_size , GFP_KERNEL );
205+ if (!buf )
206+ return - ENOMEM ;
207+
208+ ret = hid_hw_raw_request (hdev , buf [0 ], buf , feature_size ,
209+ HID_FEATURE_REPORT , HID_REQ_SET_REPORT );
210+ kfree (buf );
211+ return ret ;
212+ }
213+
214+ static void magicmouse_enable_mt_work (struct work_struct * work )
215+ {
216+ struct magicmouse_sc * msc =
217+ container_of (work , struct magicmouse_sc , work .work );
218+ int ret ;
219+
220+ ret = magicmouse_enable_multitouch (msc -> hdev );
221+ if (ret < 0 )
222+ hid_err (msc -> hdev , "unable to request touch data (%d)\n" , ret );
223+ }
224+
225+ static int magicmouse_open (struct input_dev * dev )
226+ {
227+ struct hid_device * hdev = input_get_drvdata (dev );
228+ struct magicmouse_sc * msc = hid_get_drvdata (hdev );
229+ int ret ;
230+
231+ ret = hid_hw_open (hdev );
232+ if (ret )
233+ return ret ;
234+
235+ /*
236+ * Some devices repond with 'invalid report id' when feature
237+ * report switching it into multitouch mode is sent to it.
238+ *
239+ * This results in -EIO from the _raw low-level transport callback,
240+ * but there seems to be no other way of switching the mode.
241+ * Thus the super-ugly hacky success check below.
242+ */
243+ ret = magicmouse_enable_multitouch (hdev );
244+ if (ret == - EIO && hdev -> product == USB_DEVICE_ID_APPLE_MAGICMOUSE2 ) {
245+ schedule_delayed_work (& msc -> work , msecs_to_jiffies (500 ));
246+ return 0 ;
247+ }
248+ if (ret < 0 )
249+ hid_err (hdev , "unable to request touch data (%d)\n" , ret );
250+
251+ /*
252+ * MT enable is usually not required after the first time, so don't
253+ * consider it fatal.
254+ */
255+ return 0 ;
256+ }
257+
258+ static void magicmouse_close (struct input_dev * dev )
259+ {
260+ struct hid_device * hdev = input_get_drvdata (dev );
261+
262+ hid_hw_close (hdev );
263+ }
264+
173265static int magicmouse_firm_touch (struct magicmouse_sc * msc )
174266{
175267 int touch = -1 ;
@@ -691,12 +783,19 @@ static int magicmouse_raw_event_mtp(struct hid_device *hdev,
691783static int magicmouse_raw_event_spi (struct hid_device * hdev ,
692784 struct hid_report * report , u8 * data , int size )
693785{
786+ struct magicmouse_sc * msc = hid_get_drvdata (hdev );
694787 const size_t hdr_sz = sizeof (struct tp_mouse_report );
695788
696- if (size < hdr_sz )
789+ if (! size )
697790 return 0 ;
698791
699- if (data [0 ] != TRACKPAD2_USB_REPORT_ID )
792+ if (data [0 ] == SPI_RESET_REPORT_ID ) {
793+ hid_info (hdev , "Touch controller was reset, re-enabling touch mode\n" );
794+ schedule_delayed_work (& msc -> work , msecs_to_jiffies (10 ));
795+ return 1 ;
796+ }
797+
798+ if (data [0 ] != TRACKPAD2_USB_REPORT_ID || size < hdr_sz )
700799 return 0 ;
701800
702801 return magicmouse_raw_event_mtp (hdev , report , data + hdr_sz , size - hdr_sz );
@@ -878,10 +977,17 @@ static int magicmouse_setup_input_usb(struct input_dev *input,
878977 */
879978 __clear_bit (EV_REP , input -> evbit );
880979
980+ /*
981+ * This isn't strictly speaking needed for USB, but enabling MT on
982+ * device open is probably more robust than only doing it once on probe
983+ * even if USB devices are not known to suffer from the SPI reset issue.
984+ */
985+ input -> open = magicmouse_open ;
986+ input -> close = magicmouse_close ;
881987 return 0 ;
882988}
883989
884- static int magicmouse_setup_input_spi (struct input_dev * input ,
990+ static int magicmouse_setup_input_mtp (struct input_dev * input ,
885991 struct hid_device * hdev )
886992{
887993 int error ;
@@ -954,6 +1060,25 @@ static int magicmouse_setup_input_spi(struct input_dev *input,
9541060 return 0 ;
9551061}
9561062
1063+ static int magicmouse_setup_input_spi (struct input_dev * input ,
1064+ struct hid_device * hdev )
1065+ {
1066+ int ret = magicmouse_setup_input_mtp (input , hdev );
1067+ if (ret )
1068+ return ret ;
1069+
1070+ /*
1071+ * Override the default input->open function to send the MT
1072+ * enable every time the device is opened. This ensures it works
1073+ * even if we missed a reset event due to the device being closed.
1074+ * input->close is overridden for symmetry.
1075+ */
1076+ input -> open = magicmouse_open ;
1077+ input -> close = magicmouse_close ;
1078+
1079+ return 0 ;
1080+ }
1081+
9571082static int magicmouse_input_mapping (struct hid_device * hdev ,
9581083 struct hid_input * hi , struct hid_field * field ,
9591084 struct hid_usage * usage , unsigned long * * bit , int * max )
@@ -990,57 +1115,6 @@ static int magicmouse_input_configured(struct hid_device *hdev,
9901115 return 0 ;
9911116}
9921117
993- static int magicmouse_enable_multitouch (struct hid_device * hdev )
994- {
995- const u8 * feature ;
996- const u8 feature_mt [] = { 0xD7 , 0x01 };
997- const u8 feature_mt_mouse2 [] = { 0xF1 , 0x02 , 0x01 };
998- const u8 feature_mt_trackpad2_usb [] = { 0x02 , 0x01 };
999- const u8 feature_mt_trackpad2_bt [] = { 0xF1 , 0x02 , 0x01 };
1000- u8 * buf ;
1001- int ret ;
1002- int feature_size ;
1003-
1004- if (hdev -> product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 ) {
1005- if (hdev -> vendor == BT_VENDOR_ID_APPLE ) {
1006- feature_size = sizeof (feature_mt_trackpad2_bt );
1007- feature = feature_mt_trackpad2_bt ;
1008- } else { /* USB_VENDOR_ID_APPLE */
1009- feature_size = sizeof (feature_mt_trackpad2_usb );
1010- feature = feature_mt_trackpad2_usb ;
1011- }
1012- } else if (hdev -> vendor == SPI_VENDOR_ID_APPLE ) {
1013- feature_size = sizeof (feature_mt_trackpad2_usb );
1014- feature = feature_mt_trackpad2_usb ;
1015- } else if (hdev -> product == USB_DEVICE_ID_APPLE_MAGICMOUSE2 ) {
1016- feature_size = sizeof (feature_mt_mouse2 );
1017- feature = feature_mt_mouse2 ;
1018- } else {
1019- feature_size = sizeof (feature_mt );
1020- feature = feature_mt ;
1021- }
1022-
1023- buf = kmemdup (feature , feature_size , GFP_KERNEL );
1024- if (!buf )
1025- return - ENOMEM ;
1026-
1027- ret = hid_hw_raw_request (hdev , buf [0 ], buf , feature_size ,
1028- HID_FEATURE_REPORT , HID_REQ_SET_REPORT );
1029- kfree (buf );
1030- return ret ;
1031- }
1032-
1033- static void magicmouse_enable_mt_work (struct work_struct * work )
1034- {
1035- struct magicmouse_sc * msc =
1036- container_of (work , struct magicmouse_sc , work .work );
1037- int ret ;
1038-
1039- ret = magicmouse_enable_multitouch (msc -> hdev );
1040- if (ret < 0 )
1041- hid_err (msc -> hdev , "unable to request touch data (%d)\n" , ret );
1042- }
1043-
10441118static int magicmouse_fetch_battery (struct hid_device * hdev )
10451119{
10461120#ifdef CONFIG_HID_BATTERY_STRENGTH
@@ -1100,7 +1174,7 @@ static int magicmouse_probe(struct hid_device *hdev,
11001174 // conflicts with the report ID.
11011175 if (id -> bus == BUS_HOST ) {
11021176 msc -> input_ops .raw_event = magicmouse_raw_event_mtp ;
1103- msc -> input_ops .setup_input = magicmouse_setup_input_spi ;
1177+ msc -> input_ops .setup_input = magicmouse_setup_input_mtp ;
11041178 } else if (id -> bus == BUS_SPI ) {
11051179 msc -> input_ops .raw_event = magicmouse_raw_event_spi ;
11061180 msc -> input_ops .setup_input = magicmouse_setup_input_spi ;
@@ -1180,21 +1254,10 @@ static int magicmouse_probe(struct hid_device *hdev,
11801254 if (id -> bus == BUS_HOST )
11811255 return 0 ;
11821256
1183- /*
1184- * Some devices repond with 'invalid report id' when feature
1185- * report switching it into multitouch mode is sent to it.
1186- *
1187- * This results in -EIO from the _raw low-level transport callback,
1188- * but there seems to be no other way of switching the mode.
1189- * Thus the super-ugly hacky success check below.
1190- */
1191- ret = magicmouse_enable_multitouch (hdev );
1192- if (ret != - EIO && ret < 0 ) {
1193- hid_err (hdev , "unable to request touch data (%d)\n" , ret );
1194- goto err_stop_hw ;
1195- }
1196- if (ret == - EIO && id -> product == USB_DEVICE_ID_APPLE_MAGICMOUSE2 ) {
1197- schedule_delayed_work (& msc -> work , msecs_to_jiffies (500 ));
1257+ /* SPI devices need to watch for reset events to re-send the MT enable */
1258+ if (id -> bus == BUS_SPI ) {
1259+ report = hid_register_report (hdev , HID_INPUT_REPORT , SPI_RESET_REPORT_ID , 0 );
1260+ report -> size = 2 ;
11981261 }
11991262
12001263 return 0 ;
0 commit comments