63
63
}
64
64
65
65
/* table of devices that work with this driver */
66
- static const struct usb_device_id bcm5974_table [] = {
66
+ static const struct usb_device_id bcm5974_table [] = {
67
67
/* MacbookAir1.1 */
68
68
BCM5974_DEVICE (USB_DEVICE_ID_APPLE_WELLSPRING_ANSI ),
69
69
BCM5974_DEVICE (USB_DEVICE_ID_APPLE_WELLSPRING_ISO ),
@@ -105,7 +105,7 @@ struct tp_header {
105
105
106
106
/* trackpad finger structure */
107
107
struct tp_finger {
108
- __le16 origin ; /* left/right origin? */
108
+ __le16 origin ; /* zero when switching track finger */
109
109
__le16 abs_x ; /* absolute x coodinate */
110
110
__le16 abs_y ; /* absolute y coodinate */
111
111
__le16 rel_x ; /* relative x coodinate */
@@ -159,6 +159,7 @@ struct bcm5974 {
159
159
struct bt_data * bt_data ; /* button transferred data */
160
160
struct urb * tp_urb ; /* trackpad usb request block */
161
161
struct tp_data * tp_data ; /* trackpad transferred data */
162
+ int fingers ; /* number of fingers on trackpad */
162
163
};
163
164
164
165
/* logical dimensions */
@@ -172,6 +173,10 @@ struct bcm5974 {
172
173
#define SN_WIDTH 100 /* width signal-to-noise ratio */
173
174
#define SN_COORD 250 /* coordinate signal-to-noise ratio */
174
175
176
+ /* pressure thresholds */
177
+ #define PRESSURE_LOW (2 * DIM_PRESSURE / SN_PRESSURE)
178
+ #define PRESSURE_HIGH (3 * PRESSURE_LOW)
179
+
175
180
/* device constants */
176
181
static const struct bcm5974_config bcm5974_config_table [] = {
177
182
{
@@ -248,6 +253,7 @@ static void setup_events_to_report(struct input_dev *input_dev,
248
253
0 , cfg -> y .dim , cfg -> y .fuzz , 0 );
249
254
250
255
__set_bit (EV_KEY , input_dev -> evbit );
256
+ __set_bit (BTN_TOUCH , input_dev -> keybit );
251
257
__set_bit (BTN_TOOL_FINGER , input_dev -> keybit );
252
258
__set_bit (BTN_TOOL_DOUBLETAP , input_dev -> keybit );
253
259
__set_bit (BTN_TOOL_TRIPLETAP , input_dev -> keybit );
@@ -273,32 +279,66 @@ static int report_tp_state(struct bcm5974 *dev, int size)
273
279
const struct tp_finger * f = dev -> tp_data -> finger ;
274
280
struct input_dev * input = dev -> input ;
275
281
const int fingers = (size - 26 ) / 28 ;
276
- int p = 0 , w , x , y , n = 0 ;
282
+ int raw_p , raw_w , raw_x , raw_y ;
283
+ int ptest = 0 , origin = 0 , nmin = 0 , nmax = 0 ;
284
+ int abs_p = 0 , abs_w = 0 , abs_x = 0 , abs_y = 0 ;
277
285
278
286
if (size < 26 || (size - 26 ) % 28 != 0 )
279
287
return - EIO ;
280
288
289
+ /* always track the first finger; when detached, start over */
281
290
if (fingers ) {
282
- p = raw2int (f -> force_major );
283
- w = raw2int (f -> size_major );
284
- x = raw2int (f -> abs_x );
285
- y = raw2int (f -> abs_y );
286
- n = p > 0 ? fingers : 0 ;
291
+ raw_p = raw2int (f -> force_major );
292
+ raw_w = raw2int (f -> size_major );
293
+ raw_x = raw2int (f -> abs_x );
294
+ raw_y = raw2int (f -> abs_y );
287
295
288
296
dprintk (9 ,
289
- "bcm5974: p: %+05d w: %+05d x: %+05d y: %+05d n: %d\n" ,
290
- p , w , x , y , n );
297
+ "bcm5974: raw: p: %+05d w: %+05d x: %+05d y: %+05d\n" ,
298
+ raw_p , raw_w , raw_x , raw_y );
299
+
300
+ ptest = int2bound (& c -> p , raw_p );
301
+ origin = raw2int (f -> origin );
302
+ }
291
303
292
- input_report_abs (input , ABS_TOOL_WIDTH , int2bound (& c -> w , w ));
293
- input_report_abs (input , ABS_X , int2bound (& c -> x , x - c -> x .devmin ));
294
- input_report_abs (input , ABS_Y , int2bound (& c -> y , c -> y .devmax - y ));
304
+ /* while tracking finger still valid, count all fingers */
305
+ if (ptest > PRESSURE_LOW && origin ) {
306
+ abs_p = ptest ;
307
+ abs_w = int2bound (& c -> w , raw_w );
308
+ abs_x = int2bound (& c -> x , raw_x - c -> x .devmin );
309
+ abs_y = int2bound (& c -> y , c -> y .devmax - raw_y );
310
+ for (; f != dev -> tp_data -> finger + fingers ; f ++ ) {
311
+ ptest = int2bound (& c -> p , raw2int (f -> force_major ));
312
+ if (ptest > PRESSURE_LOW )
313
+ nmax ++ ;
314
+ if (ptest > PRESSURE_HIGH )
315
+ nmin ++ ;
316
+ }
295
317
}
296
318
297
- input_report_abs (input , ABS_PRESSURE , int2bound (& c -> p , p ));
319
+ if (dev -> fingers < nmin )
320
+ dev -> fingers = nmin ;
321
+ if (dev -> fingers > nmax )
322
+ dev -> fingers = nmax ;
323
+
324
+ input_report_key (input , BTN_TOUCH , dev -> fingers > 0 );
325
+ input_report_key (input , BTN_TOOL_FINGER , dev -> fingers == 1 );
326
+ input_report_key (input , BTN_TOOL_DOUBLETAP , dev -> fingers == 2 );
327
+ input_report_key (input , BTN_TOOL_TRIPLETAP , dev -> fingers > 2 );
298
328
299
- input_report_key (input , BTN_TOOL_FINGER , n == 1 );
300
- input_report_key (input , BTN_TOOL_DOUBLETAP , n == 2 );
301
- input_report_key (input , BTN_TOOL_TRIPLETAP , n > 2 );
329
+ input_report_abs (input , ABS_PRESSURE , abs_p );
330
+ input_report_abs (input , ABS_TOOL_WIDTH , abs_w );
331
+
332
+ if (abs_p ) {
333
+ input_report_abs (input , ABS_X , abs_x );
334
+ input_report_abs (input , ABS_Y , abs_y );
335
+
336
+ dprintk (8 ,
337
+ "bcm5974: abs: p: %+05d w: %+05d x: %+05d y: %+05d "
338
+ "nmin: %d nmax: %d n: %d\n" ,
339
+ abs_p , abs_w , abs_x , abs_y , nmin , nmax , dev -> fingers );
340
+
341
+ }
302
342
303
343
input_sync (input );
304
344
0 commit comments