@@ -62,6 +62,7 @@ MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state fie
6262#define SPI_REPORT_ID 0x02
6363#define SPI_RESET_REPORT_ID 0x60
6464#define MTP_REPORT_ID 0x75
65+ #define SENSOR_DIMENSIONS_REPORT_ID 0xd9
6566#define USB_BATTERY_TIMEOUT_MS 60000
6667
6768#define MAX_CONTACTS 16
@@ -116,6 +117,7 @@ MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state fie
116117#define TRACKPAD2_RES_Y \
117118 ((TRACKPAD2_MAX_Y - TRACKPAD2_MIN_Y) / (TRACKPAD2_DIMENSION_Y / 100))
118119
120+ /* These are fallback values, since the real values will be queried from the device. */
119121#define J314_TP_DIMENSION_X (float)13000
120122#define J314_TP_MIN_X -5900
121123#define J314_TP_MAX_X 6500
@@ -139,6 +141,7 @@ struct magicmouse_input_ops {
139141 * struct magicmouse_sc - Tracks Magic Mouse-specific data.
140142 * @input: Input device through which we report events.
141143 * @quirks: Currently unused.
144+ * @query_dimensions: Whether to query and update dimensions on first open
142145 * @ntouches: Number of touches in most recent touch report.
143146 * @scroll_accel: Number of consecutive scroll motions.
144147 * @scroll_jiffies: Time of last scroll motion.
@@ -153,6 +156,7 @@ struct magicmouse_input_ops {
153156struct magicmouse_sc {
154157 struct input_dev * input ;
155158 unsigned long quirks ;
159+ bool query_dimensions ;
156160
157161 int ntouches ;
158162 int scroll_accel ;
@@ -176,6 +180,11 @@ struct magicmouse_sc {
176180 struct magicmouse_input_ops input_ops ;
177181};
178182
183+ static inline int le16_to_int (__le16 x )
184+ {
185+ return (signed short )le16_to_cpu (x );
186+ }
187+
179188static int magicmouse_enable_multitouch (struct hid_device * hdev )
180189{
181190 const u8 * feature ;
@@ -245,19 +254,71 @@ static int magicmouse_open(struct input_dev *dev)
245254 * This results in -EIO from the _raw low-level transport callback,
246255 * but there seems to be no other way of switching the mode.
247256 * Thus the super-ugly hacky success check below.
257+ *
258+ * MTP devices do not need this.
248259 */
249- ret = magicmouse_enable_multitouch (hdev );
250- if (ret == - EIO && hdev -> product == USB_DEVICE_ID_APPLE_MAGICMOUSE2 ) {
251- schedule_delayed_work (& msc -> work , msecs_to_jiffies (500 ));
252- return 0 ;
260+ if (hdev -> bus != BUS_HOST ) {
261+ ret = magicmouse_enable_multitouch (hdev );
262+ if (ret == - EIO && hdev -> product == USB_DEVICE_ID_APPLE_MAGICMOUSE2 ) {
263+ schedule_delayed_work (& msc -> work , msecs_to_jiffies (500 ));
264+ return 0 ;
265+ }
266+ if (ret < 0 )
267+ hid_err (hdev , "unable to request touch data (%d)\n" , ret );
253268 }
254- if (ret < 0 )
255- hid_err (hdev , "unable to request touch data (%d)\n" , ret );
256-
257269 /*
258270 * MT enable is usually not required after the first time, so don't
259271 * consider it fatal.
260272 */
273+
274+ /*
275+ * For Apple Silicon trackpads, we want to query the dimensions on
276+ * device open. This is because doing so requires the firmware, but
277+ * we don't want to force a firmware load until the device is opened
278+ * for the first time. So do that here and update the input properties
279+ * just in time before userspace queries them.
280+ */
281+ if (msc -> query_dimensions ) {
282+ struct input_dev * input = msc -> input ;
283+ u8 buf [32 ];
284+ struct {
285+ __le32 width ;
286+ __le32 height ;
287+ __le16 min_x ;
288+ __le16 min_y ;
289+ __le16 max_x ;
290+ __le16 max_y ;
291+ } dim ;
292+ uint32_t x_span , y_span ;
293+
294+ ret = hid_hw_raw_request (hdev , SENSOR_DIMENSIONS_REPORT_ID , buf , sizeof (buf ), HID_FEATURE_REPORT , HID_REQ_GET_REPORT );
295+ if (ret < (int )(1 + sizeof (dim ))) {
296+ hid_err (hdev , "unable to request dimensions (%d)\n" , ret );
297+ return ret ;
298+ }
299+
300+ memcpy (& dim , buf + 1 , sizeof (dim ));
301+
302+ /* finger position */
303+ input_set_abs_params (input , ABS_MT_POSITION_X ,
304+ le16_to_int (dim .min_x ), le16_to_int (dim .max_x ), 0 , 0 );
305+ /* Y axis is inverted */
306+ input_set_abs_params (input , ABS_MT_POSITION_Y ,
307+ - le16_to_int (dim .max_y ), - le16_to_int (dim .min_y ), 0 , 0 );
308+ x_span = le16_to_int (dim .max_x ) - le16_to_int (dim .min_x );
309+ y_span = le16_to_int (dim .max_y ) - le16_to_int (dim .min_y );
310+
311+ /* X/Y resolution */
312+ input_abs_set_res (input , ABS_MT_POSITION_X , 100 * x_span / le32_to_cpu (dim .width ) );
313+ input_abs_set_res (input , ABS_MT_POSITION_Y , 100 * y_span / le32_to_cpu (dim .height ) );
314+
315+ /* copy info, as input_mt_init_slots() does */
316+ dev -> absinfo [ABS_X ] = dev -> absinfo [ABS_MT_POSITION_X ];
317+ dev -> absinfo [ABS_Y ] = dev -> absinfo [ABS_MT_POSITION_Y ];
318+
319+ msc -> query_dimensions = false;
320+ }
321+
261322 return 0 ;
262323}
263324
@@ -707,11 +768,6 @@ struct tp_mouse_report {
707768 u8 padding [4 ];
708769};
709770
710- static inline int le16_to_int (__le16 x )
711- {
712- return (signed short )le16_to_cpu (x );
713- }
714-
715771static void report_finger_data (struct input_dev * input , int slot ,
716772 const struct input_mt_pos * pos ,
717773 const struct tp_finger * f )
@@ -1012,6 +1068,7 @@ static int magicmouse_setup_input_mtp(struct input_dev *input,
10121068{
10131069 int error ;
10141070 int mt_flags = 0 ;
1071+ struct magicmouse_sc * msc = hid_get_drvdata (hdev );
10151072
10161073 __set_bit (INPUT_PROP_BUTTONPAD , input -> propbit );
10171074 __clear_bit (BTN_0 , input -> keybit );
@@ -1077,6 +1134,18 @@ static int magicmouse_setup_input_mtp(struct input_dev *input,
10771134 if (error )
10781135 return error ;
10791136
1137+ /*
1138+ * Override the default input->open function to send the MT
1139+ * enable every time the device is opened. This ensures it works
1140+ * even if we missed a reset event due to the device being closed.
1141+ * input->close is overridden for symmetry.
1142+ *
1143+ * This also takes care of the dimensions query.
1144+ */
1145+ input -> open = magicmouse_open ;
1146+ input -> close = magicmouse_close ;
1147+ msc -> query_dimensions = true;
1148+
10801149 return 0 ;
10811150}
10821151
@@ -1087,15 +1156,6 @@ static int magicmouse_setup_input_spi(struct input_dev *input,
10871156 if (ret )
10881157 return ret ;
10891158
1090- /*
1091- * Override the default input->open function to send the MT
1092- * enable every time the device is opened. This ensures it works
1093- * even if we missed a reset event due to the device being closed.
1094- * input->close is overridden for symmetry.
1095- */
1096- input -> open = magicmouse_open ;
1097- input -> close = magicmouse_close ;
1098-
10991159 return 0 ;
11001160}
11011161
0 commit comments