]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/usb/input/atp.c
dma: import snapshot 2021-07-10
[FreeBSD/FreeBSD.git] / sys / dev / usb / input / atp.c
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (c) 2014 Rohit Grover
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28
29 /*
30  * Some tables, structures, definitions and constant values for the
31  * touchpad protocol has been copied from Linux's
32  * "drivers/input/mouse/bcm5974.c" which has the following copyright
33  * holders under GPLv2. All device specific code in this driver has
34  * been written from scratch. The decoding algorithm is based on
35  * output from FreeBSD's usbdump.
36  *
37  * Copyright (C) 2008      Henrik Rydberg (rydberg@euromail.se)
38  * Copyright (C) 2008      Scott Shawcroft (scott.shawcroft@gmail.com)
39  * Copyright (C) 2001-2004 Greg Kroah-Hartman (greg@kroah.com)
40  * Copyright (C) 2005      Johannes Berg (johannes@sipsolutions.net)
41  * Copyright (C) 2005      Stelian Pop (stelian@popies.net)
42  * Copyright (C) 2005      Frank Arnold (frank@scirocco-5v-turbo.de)
43  * Copyright (C) 2005      Peter Osterlund (petero2@telia.com)
44  * Copyright (C) 2005      Michael Hanselmann (linux-kernel@hansmi.ch)
45  * Copyright (C) 2006      Nicolas Boichat (nicolas@boichat.ch)
46  */
47
48 /*
49  * Author's note: 'atp' supports two distinct families of Apple trackpad
50  * products: the older Fountain/Geyser and the latest Wellspring trackpads.
51  * The first version made its appearance with FreeBSD 8 and worked only with
52  * the Fountain/Geyser hardware. A fork of this driver for Wellspring was
53  * contributed by Huang Wen Hui. This driver unifies the Wellspring effort
54  * and also improves upon the original work.
55  *
56  * I'm grateful to Stephan Scheunig, Angela Naegele, and Nokia IT-support
57  * for helping me with access to hardware. Thanks also go to Nokia for
58  * giving me an opportunity to do this work.
59  */
60
61 #include <sys/cdefs.h>
62 __FBSDID("$FreeBSD$");
63
64 #include <sys/stdint.h>
65 #include <sys/stddef.h>
66 #include <sys/param.h>
67 #include <sys/types.h>
68 #include <sys/systm.h>
69 #include <sys/kernel.h>
70 #include <sys/bus.h>
71 #include <sys/module.h>
72 #include <sys/lock.h>
73 #include <sys/mutex.h>
74 #include <sys/sysctl.h>
75 #include <sys/malloc.h>
76 #include <sys/conf.h>
77 #include <sys/fcntl.h>
78 #include <sys/file.h>
79 #include <sys/selinfo.h>
80 #include <sys/poll.h>
81
82 #include <dev/hid/hid.h>
83
84 #include <dev/usb/usb.h>
85 #include <dev/usb/usbdi.h>
86 #include <dev/usb/usbdi_util.h>
87 #include <dev/usb/usbhid.h>
88
89 #include "usbdevs.h"
90
91 #define USB_DEBUG_VAR atp_debug
92 #include <dev/usb/usb_debug.h>
93
94 #include <sys/mouse.h>
95
96 #define ATP_DRIVER_NAME "atp"
97
98 /*
99  * Driver specific options: the following options may be set by
100  * `options' statements in the kernel configuration file.
101  */
102
103 /* The divisor used to translate sensor reported positions to mickeys. */
104 #ifndef ATP_SCALE_FACTOR
105 #define ATP_SCALE_FACTOR                  16
106 #endif
107
108 /* Threshold for small movement noise (in mickeys) */
109 #ifndef ATP_SMALL_MOVEMENT_THRESHOLD
110 #define ATP_SMALL_MOVEMENT_THRESHOLD      30
111 #endif
112
113 /* Threshold of instantaneous deltas beyond which movement is considered fast.*/
114 #ifndef ATP_FAST_MOVEMENT_TRESHOLD
115 #define ATP_FAST_MOVEMENT_TRESHOLD        150
116 #endif
117
118 /*
119  * This is the age in microseconds beyond which a touch is considered
120  * to be a slide; and therefore a tap event isn't registered.
121  */
122 #ifndef ATP_TOUCH_TIMEOUT
123 #define ATP_TOUCH_TIMEOUT                 125000
124 #endif
125
126 #ifndef ATP_IDLENESS_THRESHOLD
127 #define ATP_IDLENESS_THRESHOLD 10
128 #endif
129
130 #ifndef FG_SENSOR_NOISE_THRESHOLD
131 #define FG_SENSOR_NOISE_THRESHOLD 2
132 #endif
133
134 /*
135  * A double-tap followed by a single-finger slide is treated as a
136  * special gesture. The driver responds to this gesture by assuming a
137  * virtual button-press for the lifetime of the slide. The following
138  * threshold is the maximum time gap (in microseconds) between the two
139  * tap events preceding the slide for such a gesture.
140  */
141 #ifndef ATP_DOUBLE_TAP_N_DRAG_THRESHOLD
142 #define ATP_DOUBLE_TAP_N_DRAG_THRESHOLD   200000
143 #endif
144
145 /*
146  * The wait duration in ticks after losing a touch contact before
147  * zombied strokes are reaped and turned into button events.
148  */
149 #define ATP_ZOMBIE_STROKE_REAP_INTERVAL   (hz / 20)     /* 50 ms */
150
151 /* The multiplier used to translate sensor reported positions to mickeys. */
152 #define FG_SCALE_FACTOR                   380
153
154 /*
155  * The movement threshold for a stroke; this is the maximum difference
156  * in position which will be resolved as a continuation of a stroke
157  * component.
158  */
159 #define FG_MAX_DELTA_MICKEYS             ((3 * (FG_SCALE_FACTOR)) >> 1)
160
161 /* Distance-squared threshold for matching a finger with a known stroke */
162 #ifndef WSP_MAX_ALLOWED_MATCH_DISTANCE_SQ
163 #define WSP_MAX_ALLOWED_MATCH_DISTANCE_SQ 1000000
164 #endif
165
166 /* Ignore pressure spans with cumulative press. below this value. */
167 #define FG_PSPAN_MIN_CUM_PRESSURE         10
168
169 /* Maximum allowed width for pressure-spans.*/
170 #define FG_PSPAN_MAX_WIDTH                4
171
172 /* end of driver specific options */
173
174 /* Tunables */
175 static SYSCTL_NODE(_hw_usb, OID_AUTO, atp, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
176     "USB ATP");
177
178 #ifdef USB_DEBUG
179 enum atp_log_level {
180         ATP_LLEVEL_DISABLED = 0,
181         ATP_LLEVEL_ERROR,
182         ATP_LLEVEL_DEBUG,       /* for troubleshooting */
183         ATP_LLEVEL_INFO,        /* for diagnostics */
184 };
185 static int atp_debug = ATP_LLEVEL_ERROR; /* the default is to only log errors */
186 SYSCTL_INT(_hw_usb_atp, OID_AUTO, debug, CTLFLAG_RWTUN,
187     &atp_debug, ATP_LLEVEL_ERROR, "ATP debug level");
188 #endif /* USB_DEBUG */
189
190 static u_int atp_touch_timeout = ATP_TOUCH_TIMEOUT;
191 SYSCTL_UINT(_hw_usb_atp, OID_AUTO, touch_timeout, CTLFLAG_RWTUN,
192     &atp_touch_timeout, 125000, "age threshold in microseconds for a touch");
193
194 static u_int atp_double_tap_threshold = ATP_DOUBLE_TAP_N_DRAG_THRESHOLD;
195 SYSCTL_UINT(_hw_usb_atp, OID_AUTO, double_tap_threshold, CTLFLAG_RWTUN,
196     &atp_double_tap_threshold, ATP_DOUBLE_TAP_N_DRAG_THRESHOLD,
197     "maximum time in microseconds to allow association between a double-tap and "
198     "drag gesture");
199
200 static u_int atp_mickeys_scale_factor = ATP_SCALE_FACTOR;
201 static int atp_sysctl_scale_factor_handler(SYSCTL_HANDLER_ARGS);
202 SYSCTL_PROC(_hw_usb_atp, OID_AUTO, scale_factor,
203     CTLTYPE_UINT | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
204     &atp_mickeys_scale_factor, sizeof(atp_mickeys_scale_factor),
205     atp_sysctl_scale_factor_handler, "IU",
206     "movement scale factor");
207
208 static u_int atp_small_movement_threshold = ATP_SMALL_MOVEMENT_THRESHOLD;
209 SYSCTL_UINT(_hw_usb_atp, OID_AUTO, small_movement, CTLFLAG_RWTUN,
210     &atp_small_movement_threshold, ATP_SMALL_MOVEMENT_THRESHOLD,
211     "the small movement black-hole for filtering noise");
212
213 static u_int atp_tap_minimum = 1;
214 SYSCTL_UINT(_hw_usb_atp, OID_AUTO, tap_minimum, CTLFLAG_RWTUN,
215     &atp_tap_minimum, 1, "Minimum number of taps before detection");
216
217 /*
218  * Strokes which accumulate at least this amount of absolute movement
219  * from the aggregate of their components are considered as
220  * slides. Unit: mickeys.
221  */
222 static u_int atp_slide_min_movement = 2 * ATP_SMALL_MOVEMENT_THRESHOLD;
223 SYSCTL_UINT(_hw_usb_atp, OID_AUTO, slide_min_movement, CTLFLAG_RWTUN,
224     &atp_slide_min_movement, 2 * ATP_SMALL_MOVEMENT_THRESHOLD,
225     "strokes with at least this amt. of movement are considered slides");
226
227 /*
228  * The minimum age of a stroke for it to be considered mature; this
229  * helps filter movements (noise) from immature strokes. Units: interrupts.
230  */
231 static u_int atp_stroke_maturity_threshold = 4;
232 SYSCTL_UINT(_hw_usb_atp, OID_AUTO, stroke_maturity_threshold, CTLFLAG_RWTUN,
233     &atp_stroke_maturity_threshold, 4,
234     "the minimum age of a stroke for it to be considered mature");
235
236 typedef enum atp_trackpad_family {
237         TRACKPAD_FAMILY_FOUNTAIN_GEYSER,
238         TRACKPAD_FAMILY_WELLSPRING,
239         TRACKPAD_FAMILY_MAX /* keep this at the tail end of the enumeration */
240 } trackpad_family_t;
241
242 enum fountain_geyser_product {
243         FOUNTAIN,
244         GEYSER1,
245         GEYSER1_17inch,
246         GEYSER2,
247         GEYSER3,
248         GEYSER4,
249         FOUNTAIN_GEYSER_PRODUCT_MAX /* keep this at the end */
250 };
251
252 enum wellspring_product {
253         WELLSPRING1,
254         WELLSPRING2,
255         WELLSPRING3,
256         WELLSPRING4,
257         WELLSPRING4A,
258         WELLSPRING5,
259         WELLSPRING6A,
260         WELLSPRING6,
261         WELLSPRING5A,
262         WELLSPRING7,
263         WELLSPRING7A,
264         WELLSPRING8,
265         WELLSPRING_PRODUCT_MAX /* keep this at the end of the enumeration */
266 };
267
268 /* trackpad header types */
269 enum fountain_geyser_trackpad_type {
270         FG_TRACKPAD_TYPE_GEYSER1,
271         FG_TRACKPAD_TYPE_GEYSER2,
272         FG_TRACKPAD_TYPE_GEYSER3,
273         FG_TRACKPAD_TYPE_GEYSER4,
274 };
275 enum wellspring_trackpad_type {
276         WSP_TRACKPAD_TYPE1,      /* plain trackpad */
277         WSP_TRACKPAD_TYPE2,      /* button integrated in trackpad */
278         WSP_TRACKPAD_TYPE3       /* additional header fields since June 2013 */
279 };
280
281 /*
282  * Trackpad family and product and family are encoded together in the
283  * driver_info value associated with a trackpad product.
284  */
285 #define N_PROD_BITS 8  /* Number of bits used to encode product */
286 #define ENCODE_DRIVER_INFO(FAMILY, PROD)      \
287     (((FAMILY) << N_PROD_BITS) | (PROD))
288 #define DECODE_FAMILY_FROM_DRIVER_INFO(INFO)  ((INFO) >> N_PROD_BITS)
289 #define DECODE_PRODUCT_FROM_DRIVER_INFO(INFO) \
290     ((INFO) & ((1 << N_PROD_BITS) - 1))
291
292 #define FG_DRIVER_INFO(PRODUCT)               \
293     ENCODE_DRIVER_INFO(TRACKPAD_FAMILY_FOUNTAIN_GEYSER, PRODUCT)
294 #define WELLSPRING_DRIVER_INFO(PRODUCT)       \
295     ENCODE_DRIVER_INFO(TRACKPAD_FAMILY_WELLSPRING, PRODUCT)
296
297 /*
298  * The following structure captures the state of a pressure span along
299  * an axis. Each contact with the touchpad results in separate
300  * pressure spans along the two axes.
301  */
302 typedef struct fg_pspan {
303         u_int width;       /* in units of sensors */
304         u_int cum;         /* cumulative compression (from all sensors) */
305         u_int cog;         /* center of gravity */
306         u_int loc;         /* location (scaled using the mickeys factor) */
307         boolean_t matched; /* to track pspans as they match against strokes. */
308 } fg_pspan;
309
310 #define FG_MAX_PSPANS_PER_AXIS 3
311 #define FG_MAX_STROKES         (2 * FG_MAX_PSPANS_PER_AXIS)
312
313 #define WELLSPRING_INTERFACE_INDEX 1
314
315 /* trackpad finger data offsets, le16-aligned */
316 #define WSP_TYPE1_FINGER_DATA_OFFSET  (13 * 2)
317 #define WSP_TYPE2_FINGER_DATA_OFFSET  (15 * 2)
318 #define WSP_TYPE3_FINGER_DATA_OFFSET  (19 * 2)
319
320 /* trackpad button data offsets */
321 #define WSP_TYPE2_BUTTON_DATA_OFFSET   15
322 #define WSP_TYPE3_BUTTON_DATA_OFFSET   23
323
324 /* list of device capability bits */
325 #define HAS_INTEGRATED_BUTTON   1
326
327 /* trackpad finger structure - little endian */
328 struct wsp_finger_sensor_data {
329         int16_t origin;       /* zero when switching track finger */
330         int16_t abs_x;        /* absolute x coordinate */
331         int16_t abs_y;        /* absolute y coordinate */
332         int16_t rel_x;        /* relative x coordinate */
333         int16_t rel_y;        /* relative y coordinate */
334         int16_t tool_major;   /* tool area, major axis */
335         int16_t tool_minor;   /* tool area, minor axis */
336         int16_t orientation;  /* 16384 when point, else 15 bit angle */
337         int16_t touch_major;  /* touch area, major axis */
338         int16_t touch_minor;  /* touch area, minor axis */
339         int16_t unused[3];    /* zeros */
340         int16_t multi;        /* one finger: varies, more fingers: constant */
341 } __packed;
342
343 typedef struct wsp_finger {
344         /* to track fingers as they match against strokes. */
345         boolean_t matched;
346
347         /* location (scaled using the mickeys factor) */
348         int x;
349         int y;
350 } wsp_finger_t;
351
352 #define WSP_MAX_FINGERS               16
353 #define WSP_SIZEOF_FINGER_SENSOR_DATA sizeof(struct wsp_finger_sensor_data)
354 #define WSP_SIZEOF_ALL_FINGER_DATA    (WSP_MAX_FINGERS * \
355                                        WSP_SIZEOF_FINGER_SENSOR_DATA)
356 #define WSP_MAX_FINGER_ORIENTATION    16384
357
358 #define ATP_SENSOR_DATA_BUF_MAX       1024
359 #if (ATP_SENSOR_DATA_BUF_MAX < ((WSP_MAX_FINGERS * 14 * 2) + \
360                                 WSP_TYPE3_FINGER_DATA_OFFSET))
361 /* note: 14 * 2 in the above is based on sizeof(struct wsp_finger_sensor_data)*/
362 #error "ATP_SENSOR_DATA_BUF_MAX is too small"
363 #endif
364
365 #define ATP_MAX_STROKES               MAX(WSP_MAX_FINGERS, FG_MAX_STROKES)
366
367 #define FG_MAX_XSENSORS 26
368 #define FG_MAX_YSENSORS 16
369
370 /* device-specific configuration */
371 struct fg_dev_params {
372         u_int                              data_len;   /* for sensor data */
373         u_int                              n_xsensors;
374         u_int                              n_ysensors;
375         enum fountain_geyser_trackpad_type prot;
376 };
377 struct wsp_dev_params {
378         uint8_t  caps;               /* device capability bitmask */
379         uint8_t  tp_type;            /* type of trackpad interface */
380         uint8_t  finger_data_offset; /* offset to trackpad finger data */
381 };
382
383 static const struct fg_dev_params fg_dev_params[FOUNTAIN_GEYSER_PRODUCT_MAX] = {
384         [FOUNTAIN] = {
385                 .data_len   = 81,
386                 .n_xsensors = 16,
387                 .n_ysensors = 16,
388                 .prot       = FG_TRACKPAD_TYPE_GEYSER1
389         },
390         [GEYSER1] = {
391                 .data_len   = 81,
392                 .n_xsensors = 16,
393                 .n_ysensors = 16,
394                 .prot       = FG_TRACKPAD_TYPE_GEYSER1
395         },
396         [GEYSER1_17inch] = {
397                 .data_len   = 81,
398                 .n_xsensors = 26,
399                 .n_ysensors = 16,
400                 .prot       = FG_TRACKPAD_TYPE_GEYSER1
401         },
402         [GEYSER2] = {
403                 .data_len   = 64,
404                 .n_xsensors = 15,
405                 .n_ysensors = 9,
406                 .prot       = FG_TRACKPAD_TYPE_GEYSER2
407         },
408         [GEYSER3] = {
409                 .data_len   = 64,
410                 .n_xsensors = 20,
411                 .n_ysensors = 10,
412                 .prot       = FG_TRACKPAD_TYPE_GEYSER3
413         },
414         [GEYSER4] = {
415                 .data_len   = 64,
416                 .n_xsensors = 20,
417                 .n_ysensors = 10,
418                 .prot       = FG_TRACKPAD_TYPE_GEYSER4
419         }
420 };
421
422 static const STRUCT_USB_HOST_ID fg_devs[] = {
423         /* PowerBooks Feb 2005, iBooks G4 */
424         { USB_VPI(USB_VENDOR_APPLE, 0x020e, FG_DRIVER_INFO(FOUNTAIN)) },
425         { USB_VPI(USB_VENDOR_APPLE, 0x020f, FG_DRIVER_INFO(FOUNTAIN)) },
426         { USB_VPI(USB_VENDOR_APPLE, 0x0210, FG_DRIVER_INFO(FOUNTAIN)) },
427         { USB_VPI(USB_VENDOR_APPLE, 0x030a, FG_DRIVER_INFO(FOUNTAIN)) },
428         { USB_VPI(USB_VENDOR_APPLE, 0x030b, FG_DRIVER_INFO(GEYSER1)) },
429
430         /* PowerBooks Oct 2005 */
431         { USB_VPI(USB_VENDOR_APPLE, 0x0214, FG_DRIVER_INFO(GEYSER2)) },
432         { USB_VPI(USB_VENDOR_APPLE, 0x0215, FG_DRIVER_INFO(GEYSER2)) },
433         { USB_VPI(USB_VENDOR_APPLE, 0x0216, FG_DRIVER_INFO(GEYSER2)) },
434
435         /* Core Duo MacBook & MacBook Pro */
436         { USB_VPI(USB_VENDOR_APPLE, 0x0217, FG_DRIVER_INFO(GEYSER3)) },
437         { USB_VPI(USB_VENDOR_APPLE, 0x0218, FG_DRIVER_INFO(GEYSER3)) },
438         { USB_VPI(USB_VENDOR_APPLE, 0x0219, FG_DRIVER_INFO(GEYSER3)) },
439
440         /* Core2 Duo MacBook & MacBook Pro */
441         { USB_VPI(USB_VENDOR_APPLE, 0x021a, FG_DRIVER_INFO(GEYSER4)) },
442         { USB_VPI(USB_VENDOR_APPLE, 0x021b, FG_DRIVER_INFO(GEYSER4)) },
443         { USB_VPI(USB_VENDOR_APPLE, 0x021c, FG_DRIVER_INFO(GEYSER4)) },
444
445         /* Core2 Duo MacBook3,1 */
446         { USB_VPI(USB_VENDOR_APPLE, 0x0229, FG_DRIVER_INFO(GEYSER4)) },
447         { USB_VPI(USB_VENDOR_APPLE, 0x022a, FG_DRIVER_INFO(GEYSER4)) },
448         { USB_VPI(USB_VENDOR_APPLE, 0x022b, FG_DRIVER_INFO(GEYSER4)) },
449
450         /* 17 inch PowerBook */
451         { USB_VPI(USB_VENDOR_APPLE, 0x020d, FG_DRIVER_INFO(GEYSER1_17inch)) },
452 };
453
454 static const struct wsp_dev_params wsp_dev_params[WELLSPRING_PRODUCT_MAX] = {
455         [WELLSPRING1] = {
456                 .caps       = 0,
457                 .tp_type    = WSP_TRACKPAD_TYPE1,
458                 .finger_data_offset  = WSP_TYPE1_FINGER_DATA_OFFSET,
459         },
460         [WELLSPRING2] = {
461                 .caps       = 0,
462                 .tp_type    = WSP_TRACKPAD_TYPE1,
463                 .finger_data_offset  = WSP_TYPE1_FINGER_DATA_OFFSET,
464         },
465         [WELLSPRING3] = {
466                 .caps       = HAS_INTEGRATED_BUTTON,
467                 .tp_type    = WSP_TRACKPAD_TYPE2,
468                 .finger_data_offset  = WSP_TYPE2_FINGER_DATA_OFFSET,
469         },
470         [WELLSPRING4] = {
471                 .caps       = HAS_INTEGRATED_BUTTON,
472                 .tp_type    = WSP_TRACKPAD_TYPE2,
473                 .finger_data_offset  = WSP_TYPE2_FINGER_DATA_OFFSET,
474         },
475         [WELLSPRING4A] = {
476                 .caps       = HAS_INTEGRATED_BUTTON,
477                 .tp_type    = WSP_TRACKPAD_TYPE2,
478                 .finger_data_offset  = WSP_TYPE2_FINGER_DATA_OFFSET,
479         },
480         [WELLSPRING5] = {
481                 .caps       = HAS_INTEGRATED_BUTTON,
482                 .tp_type    = WSP_TRACKPAD_TYPE2,
483                 .finger_data_offset  = WSP_TYPE2_FINGER_DATA_OFFSET,
484         },
485         [WELLSPRING6] = {
486                 .caps       = HAS_INTEGRATED_BUTTON,
487                 .tp_type    = WSP_TRACKPAD_TYPE2,
488                 .finger_data_offset  = WSP_TYPE2_FINGER_DATA_OFFSET,
489         },
490         [WELLSPRING5A] = {
491                 .caps       = HAS_INTEGRATED_BUTTON,
492                 .tp_type    = WSP_TRACKPAD_TYPE2,
493                 .finger_data_offset  = WSP_TYPE2_FINGER_DATA_OFFSET,
494         },
495         [WELLSPRING6A] = {
496                 .caps       = HAS_INTEGRATED_BUTTON,
497                 .tp_type    = WSP_TRACKPAD_TYPE2,
498                 .finger_data_offset  = WSP_TYPE2_FINGER_DATA_OFFSET,
499         },
500         [WELLSPRING7] = {
501                 .caps       = HAS_INTEGRATED_BUTTON,
502                 .tp_type    = WSP_TRACKPAD_TYPE2,
503                 .finger_data_offset  = WSP_TYPE2_FINGER_DATA_OFFSET,
504         },
505         [WELLSPRING7A] = {
506                 .caps       = HAS_INTEGRATED_BUTTON,
507                 .tp_type    = WSP_TRACKPAD_TYPE2,
508                 .finger_data_offset  = WSP_TYPE2_FINGER_DATA_OFFSET,
509         },
510         [WELLSPRING8] = {
511                 .caps       = HAS_INTEGRATED_BUTTON,
512                 .tp_type    = WSP_TRACKPAD_TYPE3,
513                 .finger_data_offset  = WSP_TYPE3_FINGER_DATA_OFFSET,
514         },
515 };
516 #define ATP_DEV(v,p,i) { USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, i) }
517
518 /* TODO: STRUCT_USB_HOST_ID */
519 static const struct usb_device_id wsp_devs[] = {
520         /* MacbookAir1.1 */
521         ATP_DEV(APPLE, WELLSPRING_ANSI, WELLSPRING_DRIVER_INFO(WELLSPRING1)),
522         ATP_DEV(APPLE, WELLSPRING_ISO,  WELLSPRING_DRIVER_INFO(WELLSPRING1)),
523         ATP_DEV(APPLE, WELLSPRING_JIS,  WELLSPRING_DRIVER_INFO(WELLSPRING1)),
524
525         /* MacbookProPenryn, aka wellspring2 */
526         ATP_DEV(APPLE, WELLSPRING2_ANSI, WELLSPRING_DRIVER_INFO(WELLSPRING2)),
527         ATP_DEV(APPLE, WELLSPRING2_ISO,  WELLSPRING_DRIVER_INFO(WELLSPRING2)),
528         ATP_DEV(APPLE, WELLSPRING2_JIS,  WELLSPRING_DRIVER_INFO(WELLSPRING2)),
529
530         /* Macbook5,1 (unibody), aka wellspring3 */
531         ATP_DEV(APPLE, WELLSPRING3_ANSI, WELLSPRING_DRIVER_INFO(WELLSPRING3)),
532         ATP_DEV(APPLE, WELLSPRING3_ISO,  WELLSPRING_DRIVER_INFO(WELLSPRING3)),
533         ATP_DEV(APPLE, WELLSPRING3_JIS,  WELLSPRING_DRIVER_INFO(WELLSPRING3)),
534
535         /* MacbookAir3,2 (unibody), aka wellspring4 */
536         ATP_DEV(APPLE, WELLSPRING4_ANSI, WELLSPRING_DRIVER_INFO(WELLSPRING4)),
537         ATP_DEV(APPLE, WELLSPRING4_ISO,  WELLSPRING_DRIVER_INFO(WELLSPRING4)),
538         ATP_DEV(APPLE, WELLSPRING4_JIS,  WELLSPRING_DRIVER_INFO(WELLSPRING4)),
539
540         /* MacbookAir3,1 (unibody), aka wellspring4 */
541         ATP_DEV(APPLE, WELLSPRING4A_ANSI, WELLSPRING_DRIVER_INFO(WELLSPRING4A)),
542         ATP_DEV(APPLE, WELLSPRING4A_ISO,  WELLSPRING_DRIVER_INFO(WELLSPRING4A)),
543         ATP_DEV(APPLE, WELLSPRING4A_JIS,  WELLSPRING_DRIVER_INFO(WELLSPRING4A)),
544
545         /* Macbook8 (unibody, March 2011) */
546         ATP_DEV(APPLE, WELLSPRING5_ANSI, WELLSPRING_DRIVER_INFO(WELLSPRING5)),
547         ATP_DEV(APPLE, WELLSPRING5_ISO,  WELLSPRING_DRIVER_INFO(WELLSPRING5)),
548         ATP_DEV(APPLE, WELLSPRING5_JIS,  WELLSPRING_DRIVER_INFO(WELLSPRING5)),
549
550         /* MacbookAir4,1 (unibody, July 2011) */
551         ATP_DEV(APPLE, WELLSPRING6A_ANSI, WELLSPRING_DRIVER_INFO(WELLSPRING6A)),
552         ATP_DEV(APPLE, WELLSPRING6A_ISO,  WELLSPRING_DRIVER_INFO(WELLSPRING6A)),
553         ATP_DEV(APPLE, WELLSPRING6A_JIS,  WELLSPRING_DRIVER_INFO(WELLSPRING6A)),
554
555         /* MacbookAir4,2 (unibody, July 2011) */
556         ATP_DEV(APPLE, WELLSPRING6_ANSI, WELLSPRING_DRIVER_INFO(WELLSPRING6)),
557         ATP_DEV(APPLE, WELLSPRING6_ISO,  WELLSPRING_DRIVER_INFO(WELLSPRING6)),
558         ATP_DEV(APPLE, WELLSPRING6_JIS,  WELLSPRING_DRIVER_INFO(WELLSPRING6)),
559
560         /* Macbook8,2 (unibody) */
561         ATP_DEV(APPLE, WELLSPRING5A_ANSI, WELLSPRING_DRIVER_INFO(WELLSPRING5A)),
562         ATP_DEV(APPLE, WELLSPRING5A_ISO,  WELLSPRING_DRIVER_INFO(WELLSPRING5A)),
563         ATP_DEV(APPLE, WELLSPRING5A_JIS,  WELLSPRING_DRIVER_INFO(WELLSPRING5A)),
564
565         /* MacbookPro10,1 (unibody, June 2012) */
566         /* MacbookPro11,? (unibody, June 2013) */
567         ATP_DEV(APPLE, WELLSPRING7_ANSI, WELLSPRING_DRIVER_INFO(WELLSPRING7)),
568         ATP_DEV(APPLE, WELLSPRING7_ISO,  WELLSPRING_DRIVER_INFO(WELLSPRING7)),
569         ATP_DEV(APPLE, WELLSPRING7_JIS,  WELLSPRING_DRIVER_INFO(WELLSPRING7)),
570
571         /* MacbookPro10,2 (unibody, October 2012) */
572         ATP_DEV(APPLE, WELLSPRING7A_ANSI, WELLSPRING_DRIVER_INFO(WELLSPRING7A)),
573         ATP_DEV(APPLE, WELLSPRING7A_ISO,  WELLSPRING_DRIVER_INFO(WELLSPRING7A)),
574         ATP_DEV(APPLE, WELLSPRING7A_JIS,  WELLSPRING_DRIVER_INFO(WELLSPRING7A)),
575
576         /* MacbookAir6,2 (unibody, June 2013) */
577         ATP_DEV(APPLE, WELLSPRING8_ANSI, WELLSPRING_DRIVER_INFO(WELLSPRING8)),
578         ATP_DEV(APPLE, WELLSPRING8_ISO,  WELLSPRING_DRIVER_INFO(WELLSPRING8)),
579         ATP_DEV(APPLE, WELLSPRING8_JIS,  WELLSPRING_DRIVER_INFO(WELLSPRING8)),
580 };
581
582 typedef enum atp_stroke_type {
583         ATP_STROKE_TOUCH,
584         ATP_STROKE_SLIDE,
585 } atp_stroke_type;
586
587 typedef enum atp_axis {
588         X = 0,
589         Y = 1,
590         NUM_AXES
591 } atp_axis;
592
593 #define ATP_FIFO_BUF_SIZE        8 /* bytes */
594 #define ATP_FIFO_QUEUE_MAXLEN   50 /* units */
595
596 enum {
597         ATP_INTR_DT,
598         ATP_RESET,
599         ATP_N_TRANSFER,
600 };
601
602 typedef struct fg_stroke_component {
603         /* Fields encapsulating the pressure-span. */
604         u_int loc;              /* location (scaled) */
605         u_int cum_pressure;     /* cumulative compression */
606         u_int max_cum_pressure; /* max cumulative compression */
607         boolean_t matched; /*to track components as they match against pspans.*/
608
609         int   delta_mickeys;    /* change in location (un-smoothened movement)*/
610 } fg_stroke_component_t;
611
612 /*
613  * The following structure captures a finger contact with the
614  * touchpad. A stroke comprises two p-span components and some state.
615  */
616 typedef struct atp_stroke {
617         TAILQ_ENTRY(atp_stroke) entry;
618
619         atp_stroke_type type;
620         uint32_t        flags; /* the state of this stroke */
621 #define ATSF_ZOMBIE 0x1
622         boolean_t       matched;          /* to track match against fingers.*/
623
624         struct timeval  ctime; /* create time; for coincident siblings. */
625
626         /*
627          * Unit: interrupts; we maintain this value in
628          * addition to 'ctime' in order to avoid the
629          * expensive call to microtime() at every
630          * interrupt.
631          */
632         uint32_t age;
633
634         /* Location */
635         int x;
636         int y;
637
638         /* Fields containing information about movement. */
639         int   instantaneous_dx; /* curr. change in X location (un-smoothened) */
640         int   instantaneous_dy; /* curr. change in Y location (un-smoothened) */
641         int   pending_dx;       /* cum. of pending short movements */
642         int   pending_dy;       /* cum. of pending short movements */
643         int   movement_dx;      /* interpreted smoothened movement */
644         int   movement_dy;      /* interpreted smoothened movement */
645         int   cum_movement_x;   /* cum. horizontal movement */
646         int   cum_movement_y;   /* cum. vertical movement */
647
648         /*
649          * The following member is relevant only for fountain-geyser trackpads.
650          * For these, there is the need to track pressure-spans and cumulative
651          * pressures for stroke components.
652          */
653         fg_stroke_component_t components[NUM_AXES];
654 } atp_stroke_t;
655
656 struct atp_softc; /* forward declaration */
657 typedef void (*sensor_data_interpreter_t)(struct atp_softc *sc, u_int len);
658
659 struct atp_softc {
660         device_t            sc_dev;
661         struct usb_device  *sc_usb_device;
662         struct mtx          sc_mutex; /* for synchronization */
663         struct usb_fifo_sc  sc_fifo;
664
665 #define MODE_LENGTH 8
666         char                sc_mode_bytes[MODE_LENGTH]; /* device mode */
667
668         trackpad_family_t   sc_family;
669         const void         *sc_params; /* device configuration */
670         sensor_data_interpreter_t sensor_data_interpreter;
671
672         mousehw_t           sc_hw;
673         mousemode_t         sc_mode;
674         mousestatus_t       sc_status;
675
676         u_int               sc_state;
677 #define ATP_ENABLED          0x01
678 #define ATP_ZOMBIES_EXIST    0x02
679 #define ATP_DOUBLE_TAP_DRAG  0x04
680 #define ATP_VALID            0x08
681
682         struct usb_xfer    *sc_xfer[ATP_N_TRANSFER];
683
684         u_int               sc_pollrate;
685         int                 sc_fflags;
686
687         atp_stroke_t        sc_strokes_data[ATP_MAX_STROKES];
688         TAILQ_HEAD(,atp_stroke) sc_stroke_free;
689         TAILQ_HEAD(,atp_stroke) sc_stroke_used;
690         u_int               sc_n_strokes;
691
692         struct callout      sc_callout;
693
694         /*
695          * button status. Set to non-zero if the mouse-button is physically
696          * pressed. This state variable is exposed through softc to allow
697          * reap_sibling_zombies to avoid registering taps while the trackpad
698          * button is pressed.
699          */
700         uint8_t             sc_ibtn;
701
702         /*
703          * Time when touch zombies were last reaped; useful for detecting
704          * double-touch-n-drag.
705          */
706         struct timeval      sc_touch_reap_time;
707
708         u_int               sc_idlecount;
709
710         /* Regarding the data transferred from t-pad in USB INTR packets. */
711         u_int   sc_expected_sensor_data_len;
712         uint8_t sc_sensor_data[ATP_SENSOR_DATA_BUF_MAX] __aligned(4);
713
714         int      sc_cur_x[FG_MAX_XSENSORS];      /* current sensor readings */
715         int      sc_cur_y[FG_MAX_YSENSORS];
716         int      sc_base_x[FG_MAX_XSENSORS];     /* base sensor readings */
717         int      sc_base_y[FG_MAX_YSENSORS];
718         int      sc_pressure_x[FG_MAX_XSENSORS]; /* computed pressures */
719         int      sc_pressure_y[FG_MAX_YSENSORS];
720         fg_pspan sc_pspans_x[FG_MAX_PSPANS_PER_AXIS];
721         fg_pspan sc_pspans_y[FG_MAX_PSPANS_PER_AXIS];
722 };
723
724 /*
725  * The last byte of the fountain-geyser sensor data contains status bits; the
726  * following values define the meanings of these bits.
727  * (only Geyser 3/4)
728  */
729 enum geyser34_status_bits {
730         FG_STATUS_BUTTON      = (uint8_t)0x01, /* The button was pressed */
731         FG_STATUS_BASE_UPDATE = (uint8_t)0x04, /* Data from an untouched pad.*/
732 };
733
734 typedef enum interface_mode {
735         RAW_SENSOR_MODE = (uint8_t)0x01,
736         HID_MODE        = (uint8_t)0x08
737 } interface_mode;
738
739 /*
740  * function prototypes
741  */
742 static usb_fifo_cmd_t   atp_start_read;
743 static usb_fifo_cmd_t   atp_stop_read;
744 static usb_fifo_open_t  atp_open;
745 static usb_fifo_close_t atp_close;
746 static usb_fifo_ioctl_t atp_ioctl;
747
748 static struct usb_fifo_methods atp_fifo_methods = {
749         .f_open       = &atp_open,
750         .f_close      = &atp_close,
751         .f_ioctl      = &atp_ioctl,
752         .f_start_read = &atp_start_read,
753         .f_stop_read  = &atp_stop_read,
754         .basename[0]  = ATP_DRIVER_NAME,
755 };
756
757 /* device initialization and shutdown */
758 static usb_error_t   atp_set_device_mode(struct atp_softc *, interface_mode);
759 static void          atp_reset_callback(struct usb_xfer *, usb_error_t);
760 static int           atp_enable(struct atp_softc *);
761 static void          atp_disable(struct atp_softc *);
762
763 /* sensor interpretation */
764 static void          fg_interpret_sensor_data(struct atp_softc *, u_int);
765 static void          fg_extract_sensor_data(const int8_t *, u_int, atp_axis,
766     int *, enum fountain_geyser_trackpad_type);
767 static void          fg_get_pressures(int *, const int *, const int *, int);
768 static void          fg_detect_pspans(int *, u_int, u_int, fg_pspan *, u_int *);
769 static void          wsp_interpret_sensor_data(struct atp_softc *, u_int);
770
771 /* movement detection */
772 static boolean_t     fg_match_stroke_component(fg_stroke_component_t *,
773     const fg_pspan *, atp_stroke_type);
774 static void          fg_match_strokes_against_pspans(struct atp_softc *,
775     atp_axis, fg_pspan *, u_int, u_int);
776 static boolean_t     wsp_match_strokes_against_fingers(struct atp_softc *,
777     wsp_finger_t *, u_int);
778 static boolean_t     fg_update_strokes(struct atp_softc *, fg_pspan *, u_int,
779     fg_pspan *, u_int);
780 static boolean_t     wsp_update_strokes(struct atp_softc *,
781     wsp_finger_t [WSP_MAX_FINGERS], u_int);
782 static void fg_add_stroke(struct atp_softc *, const fg_pspan *, const fg_pspan *);
783 static void          fg_add_new_strokes(struct atp_softc *, fg_pspan *,
784     u_int, fg_pspan *, u_int);
785 static void wsp_add_stroke(struct atp_softc *, const wsp_finger_t *);
786 static void          atp_advance_stroke_state(struct atp_softc *,
787     atp_stroke_t *, boolean_t *);
788 static boolean_t atp_stroke_has_small_movement(const atp_stroke_t *);
789 static void          atp_update_pending_mickeys(atp_stroke_t *);
790 static boolean_t     atp_compute_stroke_movement(atp_stroke_t *);
791 static void          atp_terminate_stroke(struct atp_softc *, atp_stroke_t *);
792
793 /* tap detection */
794 static boolean_t atp_is_horizontal_scroll(const atp_stroke_t *);
795 static boolean_t atp_is_vertical_scroll(const atp_stroke_t *);
796 static void          atp_reap_sibling_zombies(void *);
797 static void          atp_convert_to_slide(struct atp_softc *, atp_stroke_t *);
798
799 /* updating fifo */
800 static void          atp_reset_buf(struct atp_softc *);
801 static void          atp_add_to_queue(struct atp_softc *, int, int, int, uint32_t);
802
803 /* Device methods. */
804 static device_probe_t  atp_probe;
805 static device_attach_t atp_attach;
806 static device_detach_t atp_detach;
807 static usb_callback_t  atp_intr;
808
809 static const struct usb_config atp_xfer_config[ATP_N_TRANSFER] = {
810         [ATP_INTR_DT] = {
811                 .type      = UE_INTERRUPT,
812                 .endpoint  = UE_ADDR_ANY,
813                 .direction = UE_DIR_IN,
814                 .flags = {
815                         .pipe_bof = 1, /* block pipe on failure */
816                         .short_xfer_ok = 1,
817                 },
818                 .bufsize   = ATP_SENSOR_DATA_BUF_MAX,
819                 .callback  = &atp_intr,
820         },
821         [ATP_RESET] = {
822                 .type      = UE_CONTROL,
823                 .endpoint  = 0, /* Control pipe */
824                 .direction = UE_DIR_ANY,
825                 .bufsize   = sizeof(struct usb_device_request) + MODE_LENGTH,
826                 .callback  = &atp_reset_callback,
827                 .interval  = 0,  /* no pre-delay */
828         },
829 };
830
831 static atp_stroke_t *
832 atp_alloc_stroke(struct atp_softc *sc)
833 {
834         atp_stroke_t *pstroke;
835
836         pstroke = TAILQ_FIRST(&sc->sc_stroke_free);
837         if (pstroke == NULL)
838                 goto done;
839
840         TAILQ_REMOVE(&sc->sc_stroke_free, pstroke, entry);
841         memset(pstroke, 0, sizeof(*pstroke));
842         TAILQ_INSERT_TAIL(&sc->sc_stroke_used, pstroke, entry);
843
844         sc->sc_n_strokes++;
845 done:
846         return (pstroke);
847 }
848
849 static void
850 atp_free_stroke(struct atp_softc *sc, atp_stroke_t *pstroke)
851 {
852         if (pstroke == NULL)
853                 return;
854
855         sc->sc_n_strokes--;
856
857         TAILQ_REMOVE(&sc->sc_stroke_used, pstroke, entry);
858         TAILQ_INSERT_TAIL(&sc->sc_stroke_free, pstroke, entry);
859 }
860
861 static void
862 atp_init_stroke_pool(struct atp_softc *sc)
863 {
864         u_int x;
865
866         TAILQ_INIT(&sc->sc_stroke_free);
867         TAILQ_INIT(&sc->sc_stroke_used);
868
869         sc->sc_n_strokes = 0;
870
871         memset(&sc->sc_strokes_data, 0, sizeof(sc->sc_strokes_data));
872
873         for (x = 0; x != ATP_MAX_STROKES; x++) {
874                 TAILQ_INSERT_TAIL(&sc->sc_stroke_free, &sc->sc_strokes_data[x],
875                     entry);
876         }
877 }
878
879 static usb_error_t
880 atp_set_device_mode(struct atp_softc *sc, interface_mode newMode)
881 {
882         uint8_t mode_value;
883         usb_error_t err;
884
885         if ((newMode != RAW_SENSOR_MODE) && (newMode != HID_MODE))
886                 return (USB_ERR_INVAL);
887
888         if ((newMode == RAW_SENSOR_MODE) &&
889             (sc->sc_family == TRACKPAD_FAMILY_FOUNTAIN_GEYSER))
890                 mode_value = (uint8_t)0x04;
891         else
892                 mode_value = newMode;
893
894         err = usbd_req_get_report(sc->sc_usb_device, NULL /* mutex */,
895             sc->sc_mode_bytes, sizeof(sc->sc_mode_bytes), 0 /* interface idx */,
896             0x03 /* type */, 0x00 /* id */);
897         if (err != USB_ERR_NORMAL_COMPLETION) {
898                 DPRINTF("Failed to read device mode (%d)\n", err);
899                 return (err);
900         }
901
902         if (sc->sc_mode_bytes[0] == mode_value)
903                 return (err);
904
905         /*
906          * XXX Need to wait at least 250ms for hardware to get
907          * ready. The device mode handling appears to be handled
908          * asynchronously and we should not issue these commands too
909          * quickly.
910          */
911         pause("WHW", hz / 4);
912
913         sc->sc_mode_bytes[0] = mode_value;
914         return (usbd_req_set_report(sc->sc_usb_device, NULL /* mutex */,
915             sc->sc_mode_bytes, sizeof(sc->sc_mode_bytes), 0 /* interface idx */,
916             0x03 /* type */, 0x00 /* id */));
917 }
918
919 static void
920 atp_reset_callback(struct usb_xfer *xfer, usb_error_t error)
921 {
922         usb_device_request_t   req;
923         struct usb_page_cache *pc;
924         struct atp_softc      *sc = usbd_xfer_softc(xfer);
925
926         uint8_t mode_value;
927         if (sc->sc_family == TRACKPAD_FAMILY_FOUNTAIN_GEYSER)
928                 mode_value = 0x04;
929         else
930                 mode_value = RAW_SENSOR_MODE;
931
932         switch (USB_GET_STATE(xfer)) {
933         case USB_ST_SETUP:
934                 sc->sc_mode_bytes[0] = mode_value;
935                 req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
936                 req.bRequest = UR_SET_REPORT;
937                 USETW2(req.wValue,
938                     (uint8_t)0x03 /* type */, (uint8_t)0x00 /* id */);
939                 USETW(req.wIndex, 0);
940                 USETW(req.wLength, MODE_LENGTH);
941
942                 pc = usbd_xfer_get_frame(xfer, 0);
943                 usbd_copy_in(pc, 0, &req, sizeof(req));
944                 pc = usbd_xfer_get_frame(xfer, 1);
945                 usbd_copy_in(pc, 0, sc->sc_mode_bytes, MODE_LENGTH);
946
947                 usbd_xfer_set_frame_len(xfer, 0, sizeof(req));
948                 usbd_xfer_set_frame_len(xfer, 1, MODE_LENGTH);
949                 usbd_xfer_set_frames(xfer, 2);
950                 usbd_transfer_submit(xfer);
951                 break;
952
953         case USB_ST_TRANSFERRED:
954         default:
955                 break;
956         }
957 }
958
959 static int
960 atp_enable(struct atp_softc *sc)
961 {
962         if (sc->sc_state & ATP_ENABLED)
963                 return (0);
964
965         /* reset status */
966         memset(&sc->sc_status, 0, sizeof(sc->sc_status));
967
968         atp_init_stroke_pool(sc);
969
970         sc->sc_state |= ATP_ENABLED;
971
972         DPRINTFN(ATP_LLEVEL_INFO, "enabled atp\n");
973         return (0);
974 }
975
976 static void
977 atp_disable(struct atp_softc *sc)
978 {
979         sc->sc_state &= ~(ATP_ENABLED | ATP_VALID);
980         DPRINTFN(ATP_LLEVEL_INFO, "disabled atp\n");
981 }
982
983 static void
984 fg_interpret_sensor_data(struct atp_softc *sc, u_int data_len)
985 {
986         u_int n_xpspans = 0;
987         u_int n_ypspans = 0;
988         uint8_t status_bits;
989
990         const struct fg_dev_params *params =
991             (const struct fg_dev_params *)sc->sc_params;
992
993         fg_extract_sensor_data(sc->sc_sensor_data, params->n_xsensors, X,
994             sc->sc_cur_x, params->prot);
995         fg_extract_sensor_data(sc->sc_sensor_data, params->n_ysensors, Y,
996             sc->sc_cur_y, params->prot);
997
998         /*
999          * If this is the initial update (from an untouched
1000          * pad), we should set the base values for the sensor
1001          * data; deltas with respect to these base values can
1002          * be used as pressure readings subsequently.
1003          */
1004         status_bits = sc->sc_sensor_data[params->data_len - 1];
1005         if (((params->prot == FG_TRACKPAD_TYPE_GEYSER3) ||
1006              (params->prot == FG_TRACKPAD_TYPE_GEYSER4))  &&
1007             ((sc->sc_state & ATP_VALID) == 0)) {
1008                 if (status_bits & FG_STATUS_BASE_UPDATE) {
1009                         memcpy(sc->sc_base_x, sc->sc_cur_x,
1010                             params->n_xsensors * sizeof(*sc->sc_base_x));
1011                         memcpy(sc->sc_base_y, sc->sc_cur_y,
1012                             params->n_ysensors * sizeof(*sc->sc_base_y));
1013                         sc->sc_state |= ATP_VALID;
1014                         return;
1015                 }
1016         }
1017
1018         /* Get pressure readings and detect p-spans for both axes. */
1019         fg_get_pressures(sc->sc_pressure_x, sc->sc_cur_x, sc->sc_base_x,
1020             params->n_xsensors);
1021         fg_detect_pspans(sc->sc_pressure_x, params->n_xsensors,
1022             FG_MAX_PSPANS_PER_AXIS, sc->sc_pspans_x, &n_xpspans);
1023         fg_get_pressures(sc->sc_pressure_y, sc->sc_cur_y, sc->sc_base_y,
1024             params->n_ysensors);
1025         fg_detect_pspans(sc->sc_pressure_y, params->n_ysensors,
1026             FG_MAX_PSPANS_PER_AXIS, sc->sc_pspans_y, &n_ypspans);
1027
1028         /* Update strokes with new pspans to detect movements. */
1029         if (fg_update_strokes(sc, sc->sc_pspans_x, n_xpspans, sc->sc_pspans_y, n_ypspans))
1030                 sc->sc_status.flags |= MOUSE_POSCHANGED;
1031
1032         sc->sc_ibtn = (status_bits & FG_STATUS_BUTTON) ? MOUSE_BUTTON1DOWN : 0;
1033         sc->sc_status.button = sc->sc_ibtn;
1034
1035         /*
1036          * The Fountain/Geyser device continues to trigger interrupts
1037          * at a fast rate even after touchpad activity has
1038          * stopped. Upon detecting that the device has remained idle
1039          * beyond a threshold, we reinitialize it to silence the
1040          * interrupts.
1041          */
1042         if ((sc->sc_status.flags  == 0) && (sc->sc_n_strokes == 0)) {
1043                 sc->sc_idlecount++;
1044                 if (sc->sc_idlecount >= ATP_IDLENESS_THRESHOLD) {
1045                         /*
1046                          * Use the last frame before we go idle for
1047                          * calibration on pads which do not send
1048                          * calibration frames.
1049                          */
1050                         const struct fg_dev_params *params =
1051                             (const struct fg_dev_params *)sc->sc_params;
1052
1053                         DPRINTFN(ATP_LLEVEL_INFO, "idle\n");
1054
1055                         if (params->prot < FG_TRACKPAD_TYPE_GEYSER3) {
1056                                 memcpy(sc->sc_base_x, sc->sc_cur_x,
1057                                     params->n_xsensors * sizeof(*(sc->sc_base_x)));
1058                                 memcpy(sc->sc_base_y, sc->sc_cur_y,
1059                                     params->n_ysensors * sizeof(*(sc->sc_base_y)));
1060                         }
1061
1062                         sc->sc_idlecount = 0;
1063                         usbd_transfer_start(sc->sc_xfer[ATP_RESET]);
1064                 }
1065         } else {
1066                 sc->sc_idlecount = 0;
1067         }
1068 }
1069
1070 /*
1071  * Interpret the data from the X and Y pressure sensors. This function
1072  * is called separately for the X and Y sensor arrays. The data in the
1073  * USB packet is laid out in the following manner:
1074  *
1075  * sensor_data:
1076  *            --,--,Y1,Y2,--,Y3,Y4,--,Y5,...,Y10, ... X1,X2,--,X3,X4
1077  *  indices:   0  1  2  3  4  5  6  7  8 ...  15  ... 20 21 22 23 24
1078  *
1079  * '--' (in the above) indicates that the value is unimportant.
1080  *
1081  * Information about the above layout was obtained from the
1082  * implementation of the AppleTouch driver in Linux.
1083  *
1084  * parameters:
1085  *   sensor_data
1086  *       raw sensor data from the USB packet.
1087  *   num
1088  *       The number of elements in the array 'arr'.
1089  *   axis
1090  *       Axis of data to fetch
1091  *   arr
1092  *       The array to be initialized with the readings.
1093  *   prot
1094  *       The protocol to use to interpret the data
1095  */
1096 static void
1097 fg_extract_sensor_data(const int8_t *sensor_data, u_int num, atp_axis axis,
1098     int *arr, enum fountain_geyser_trackpad_type prot)
1099 {
1100         u_int i;
1101         u_int di;   /* index into sensor data */
1102
1103         switch (prot) {
1104         case FG_TRACKPAD_TYPE_GEYSER1:
1105                 /*
1106                  * For Geyser 1, the sensors are laid out in pairs
1107                  * every 5 bytes.
1108                  */
1109                 for (i = 0, di = (axis == Y) ? 1 : 2; i < 8; di += 5, i++) {
1110                         arr[i] = sensor_data[di];
1111                         arr[i+8] = sensor_data[di+2];
1112                         if ((axis == X) && (num > 16))
1113                                 arr[i+16] = sensor_data[di+40];
1114                 }
1115
1116                 break;
1117         case FG_TRACKPAD_TYPE_GEYSER2:
1118                 for (i = 0, di = (axis == Y) ? 1 : 19; i < num; /* empty */ ) {
1119                         arr[i++] = sensor_data[di++];
1120                         arr[i++] = sensor_data[di++];
1121                         di++;
1122                 }
1123                 break;
1124         case FG_TRACKPAD_TYPE_GEYSER3:
1125         case FG_TRACKPAD_TYPE_GEYSER4:
1126                 for (i = 0, di = (axis == Y) ? 2 : 20; i < num; /* empty */ ) {
1127                         arr[i++] = sensor_data[di++];
1128                         arr[i++] = sensor_data[di++];
1129                         di++;
1130                 }
1131                 break;
1132         default:
1133                 break;
1134         }
1135 }
1136
1137 static void
1138 fg_get_pressures(int *p, const int *cur, const int *base, int n)
1139 {
1140         int i;
1141
1142         for (i = 0; i < n; i++) {
1143                 p[i] = cur[i] - base[i];
1144                 if (p[i] > 127)
1145                         p[i] -= 256;
1146                 if (p[i] < -127)
1147                         p[i] += 256;
1148                 if (p[i] < 0)
1149                         p[i] = 0;
1150
1151                 /*
1152                  * Shave off pressures below the noise-pressure
1153                  * threshold; this will reduce the contribution from
1154                  * lower pressure readings.
1155                  */
1156                 if ((u_int)p[i] <= FG_SENSOR_NOISE_THRESHOLD)
1157                         p[i] = 0; /* filter away noise */
1158                 else
1159                         p[i] -= FG_SENSOR_NOISE_THRESHOLD;
1160         }
1161 }
1162
1163 static void
1164 fg_detect_pspans(int *p, u_int num_sensors,
1165     u_int      max_spans, /* max # of pspans permitted */
1166     fg_pspan  *spans,     /* finger spans */
1167     u_int     *nspans_p)  /* num spans detected */
1168 {
1169         u_int i;
1170         int   maxp;             /* max pressure seen within a span */
1171         u_int num_spans = 0;
1172
1173         enum fg_pspan_state {
1174                 ATP_PSPAN_INACTIVE,
1175                 ATP_PSPAN_INCREASING,
1176                 ATP_PSPAN_DECREASING,
1177         } state; /* state of the pressure span */
1178
1179         /*
1180          * The following is a simple state machine to track
1181          * the phase of the pressure span.
1182          */
1183         memset(spans, 0, max_spans * sizeof(fg_pspan));
1184         maxp = 0;
1185         state = ATP_PSPAN_INACTIVE;
1186         for (i = 0; i < num_sensors; i++) {
1187                 if (num_spans >= max_spans)
1188                         break;
1189
1190                 if (p[i] == 0) {
1191                         if (state == ATP_PSPAN_INACTIVE) {
1192                                 /*
1193                                  * There is no pressure information for this
1194                                  * sensor, and we aren't tracking a finger.
1195                                  */
1196                                 continue;
1197                         } else {
1198                                 state = ATP_PSPAN_INACTIVE;
1199                                 maxp = 0;
1200                                 num_spans++;
1201                         }
1202                 } else {
1203                         switch (state) {
1204                         case ATP_PSPAN_INACTIVE:
1205                                 state = ATP_PSPAN_INCREASING;
1206                                 maxp  = p[i];
1207                                 break;
1208
1209                         case ATP_PSPAN_INCREASING:
1210                                 if (p[i] > maxp)
1211                                         maxp = p[i];
1212                                 else if (p[i] <= (maxp >> 1))
1213                                         state = ATP_PSPAN_DECREASING;
1214                                 break;
1215
1216                         case ATP_PSPAN_DECREASING:
1217                                 if (p[i] > p[i - 1]) {
1218                                         /*
1219                                          * This is the beginning of
1220                                          * another span; change state
1221                                          * to give the appearance that
1222                                          * we're starting from an
1223                                          * inactive span, and then
1224                                          * re-process this reading in
1225                                          * the next iteration.
1226                                          */
1227                                         num_spans++;
1228                                         state = ATP_PSPAN_INACTIVE;
1229                                         maxp  = 0;
1230                                         i--;
1231                                         continue;
1232                                 }
1233                                 break;
1234                         }
1235
1236                         /* Update the finger span with this reading. */
1237                         spans[num_spans].width++;
1238                         spans[num_spans].cum += p[i];
1239                         spans[num_spans].cog += p[i] * (i + 1);
1240                 }
1241         }
1242         if (state != ATP_PSPAN_INACTIVE)
1243                 num_spans++;    /* close the last finger span */
1244
1245         /* post-process the spans */
1246         for (i = 0; i < num_spans; i++) {
1247                 /* filter away unwanted pressure spans */
1248                 if ((spans[i].cum < FG_PSPAN_MIN_CUM_PRESSURE) ||
1249                     (spans[i].width > FG_PSPAN_MAX_WIDTH)) {
1250                         if ((i + 1) < num_spans) {
1251                                 memcpy(&spans[i], &spans[i + 1],
1252                                     (num_spans - i - 1) * sizeof(fg_pspan));
1253                                 i--;
1254                         }
1255                         num_spans--;
1256                         continue;
1257                 }
1258
1259                 /* compute this span's representative location */
1260                 spans[i].loc = spans[i].cog * FG_SCALE_FACTOR /
1261                         spans[i].cum;
1262
1263                 spans[i].matched = false; /* not yet matched against a stroke */
1264         }
1265
1266         *nspans_p = num_spans;
1267 }
1268
1269 static void
1270 wsp_interpret_sensor_data(struct atp_softc *sc, u_int data_len)
1271 {
1272         const struct wsp_dev_params *params = sc->sc_params;
1273         wsp_finger_t fingers[WSP_MAX_FINGERS];
1274         struct wsp_finger_sensor_data *source_fingerp;
1275         u_int n_source_fingers;
1276         u_int n_fingers;
1277         u_int i;
1278
1279         /* validate sensor data length */
1280         if ((data_len < params->finger_data_offset) ||
1281             ((data_len - params->finger_data_offset) %
1282              WSP_SIZEOF_FINGER_SENSOR_DATA) != 0)
1283                 return;
1284
1285         /* compute number of source fingers */
1286         n_source_fingers = (data_len - params->finger_data_offset) /
1287             WSP_SIZEOF_FINGER_SENSOR_DATA;
1288
1289         if (n_source_fingers > WSP_MAX_FINGERS)
1290                 n_source_fingers = WSP_MAX_FINGERS;
1291
1292         /* iterate over the source data collecting useful fingers */
1293         n_fingers = 0;
1294         source_fingerp = (struct wsp_finger_sensor_data *)(sc->sc_sensor_data +
1295              params->finger_data_offset);
1296
1297         for (i = 0; i < n_source_fingers; i++, source_fingerp++) {
1298                 /* swap endianness, if any */
1299                 if (le16toh(0x1234) != 0x1234) {
1300                         source_fingerp->origin      = le16toh((uint16_t)source_fingerp->origin);
1301                         source_fingerp->abs_x       = le16toh((uint16_t)source_fingerp->abs_x);
1302                         source_fingerp->abs_y       = le16toh((uint16_t)source_fingerp->abs_y);
1303                         source_fingerp->rel_x       = le16toh((uint16_t)source_fingerp->rel_x);
1304                         source_fingerp->rel_y       = le16toh((uint16_t)source_fingerp->rel_y);
1305                         source_fingerp->tool_major  = le16toh((uint16_t)source_fingerp->tool_major);
1306                         source_fingerp->tool_minor  = le16toh((uint16_t)source_fingerp->tool_minor);
1307                         source_fingerp->orientation = le16toh((uint16_t)source_fingerp->orientation);
1308                         source_fingerp->touch_major = le16toh((uint16_t)source_fingerp->touch_major);
1309                         source_fingerp->touch_minor = le16toh((uint16_t)source_fingerp->touch_minor);
1310                         source_fingerp->multi       = le16toh((uint16_t)source_fingerp->multi);
1311                 }
1312
1313                 /* check for minium threshold */
1314                 if (source_fingerp->touch_major == 0)
1315                         continue;
1316
1317                 fingers[n_fingers].matched = false;
1318                 fingers[n_fingers].x       = source_fingerp->abs_x;
1319                 fingers[n_fingers].y       = -source_fingerp->abs_y;
1320
1321                 n_fingers++;
1322         }
1323
1324         if ((sc->sc_n_strokes == 0) && (n_fingers == 0))
1325                 return;
1326
1327         if (wsp_update_strokes(sc, fingers, n_fingers))
1328                 sc->sc_status.flags |= MOUSE_POSCHANGED;
1329
1330         switch(params->tp_type) {
1331         case WSP_TRACKPAD_TYPE2:
1332                 sc->sc_ibtn = sc->sc_sensor_data[WSP_TYPE2_BUTTON_DATA_OFFSET];
1333                 break;
1334         case WSP_TRACKPAD_TYPE3:
1335                 sc->sc_ibtn = sc->sc_sensor_data[WSP_TYPE3_BUTTON_DATA_OFFSET];
1336                 break;
1337         default:
1338                 break;
1339         }
1340         sc->sc_status.button = sc->sc_ibtn ? MOUSE_BUTTON1DOWN : 0;
1341 }
1342
1343 /*
1344  * Match a pressure-span against a stroke-component. If there is a
1345  * match, update the component's state and return true.
1346  */
1347 static boolean_t
1348 fg_match_stroke_component(fg_stroke_component_t *component,
1349     const fg_pspan *pspan, atp_stroke_type stroke_type)
1350 {
1351         int   delta_mickeys;
1352         u_int min_pressure;
1353
1354         delta_mickeys = pspan->loc - component->loc;
1355
1356         if (abs(delta_mickeys) > (int)FG_MAX_DELTA_MICKEYS)
1357                 return (false); /* the finger span is too far out; no match */
1358
1359         component->loc = pspan->loc;
1360
1361         /*
1362          * A sudden and significant increase in a pspan's cumulative
1363          * pressure indicates the incidence of a new finger
1364          * contact. This usually revises the pspan's
1365          * centre-of-gravity, and hence the location of any/all
1366          * matching stroke component(s). But such a change should
1367          * *not* be interpreted as a movement.
1368          */
1369         if (pspan->cum > ((3 * component->cum_pressure) >> 1))
1370                 delta_mickeys = 0;
1371
1372         component->cum_pressure = pspan->cum;
1373         if (pspan->cum > component->max_cum_pressure)
1374                 component->max_cum_pressure = pspan->cum;
1375
1376         /*
1377          * Disregard the component's movement if its cumulative
1378          * pressure drops below a fraction of the maximum; this
1379          * fraction is determined based on the stroke's type.
1380          */
1381         if (stroke_type == ATP_STROKE_TOUCH)
1382                 min_pressure = (3 * component->max_cum_pressure) >> 2;
1383         else
1384                 min_pressure = component->max_cum_pressure >> 2;
1385         if (component->cum_pressure < min_pressure)
1386                 delta_mickeys = 0;
1387
1388         component->delta_mickeys = delta_mickeys;
1389         return (true);
1390 }
1391
1392 static void
1393 fg_match_strokes_against_pspans(struct atp_softc *sc, atp_axis axis,
1394     fg_pspan *pspans, u_int n_pspans, u_int repeat_count)
1395 {
1396         atp_stroke_t *strokep;
1397         u_int repeat_index = 0;
1398         u_int i;
1399
1400         /* Determine the index of the multi-span. */
1401         if (repeat_count) {
1402                 for (i = 0; i < n_pspans; i++) {
1403                         if (pspans[i].cum > pspans[repeat_index].cum)
1404                                 repeat_index = i;
1405                 }
1406         }
1407
1408         TAILQ_FOREACH(strokep, &sc->sc_stroke_used, entry) {
1409                 if (strokep->components[axis].matched)
1410                         continue; /* skip matched components */
1411
1412                 for (i = 0; i < n_pspans; i++) {
1413                         if (pspans[i].matched)
1414                                 continue; /* skip matched pspans */
1415
1416                         if (fg_match_stroke_component(
1417                             &strokep->components[axis], &pspans[i],
1418                             strokep->type)) {
1419                                 /* There is a match. */
1420                                 strokep->components[axis].matched = true;
1421
1422                                 /* Take care to repeat at the multi-span. */
1423                                 if ((repeat_count > 0) && (i == repeat_index))
1424                                         repeat_count--;
1425                                 else
1426                                         pspans[i].matched = true;
1427
1428                                 break; /* skip to the next strokep */
1429                         }
1430                 } /* loop over pspans */
1431         } /* loop over strokes */
1432 }
1433
1434 static boolean_t
1435 wsp_match_strokes_against_fingers(struct atp_softc *sc,
1436     wsp_finger_t *fingers, u_int n_fingers)
1437 {
1438         boolean_t movement = false;
1439         atp_stroke_t *strokep;
1440         u_int i;
1441
1442         /* reset the matched status for all strokes */
1443         TAILQ_FOREACH(strokep, &sc->sc_stroke_used, entry)
1444                 strokep->matched = false;
1445
1446         for (i = 0; i != n_fingers; i++) {
1447                 u_int least_distance_sq = WSP_MAX_ALLOWED_MATCH_DISTANCE_SQ;
1448                 atp_stroke_t *strokep_best = NULL;
1449
1450                 TAILQ_FOREACH(strokep, &sc->sc_stroke_used, entry) {
1451                         int instantaneous_dx;
1452                         int instantaneous_dy;
1453                         u_int d_squared;
1454
1455                         if (strokep->matched)
1456                                 continue;
1457
1458                         instantaneous_dx = fingers[i].x - strokep->x;
1459                         instantaneous_dy = fingers[i].y - strokep->y;
1460
1461                         /* skip strokes which are far away */
1462                         d_squared =
1463                             (instantaneous_dx * instantaneous_dx) +
1464                             (instantaneous_dy * instantaneous_dy);
1465
1466                         if (d_squared < least_distance_sq) {
1467                                 least_distance_sq = d_squared;
1468                                 strokep_best = strokep;
1469                         }
1470                 }
1471
1472                 strokep = strokep_best;
1473
1474                 if (strokep != NULL) {
1475                         fingers[i].matched = true;
1476
1477                         strokep->matched          = true;
1478                         strokep->instantaneous_dx = fingers[i].x - strokep->x;
1479                         strokep->instantaneous_dy = fingers[i].y - strokep->y;
1480                         strokep->x                = fingers[i].x;
1481                         strokep->y                = fingers[i].y;
1482
1483                         atp_advance_stroke_state(sc, strokep, &movement);
1484                 }
1485         }
1486         return (movement);
1487 }
1488
1489 /*
1490  * Update strokes by matching against current pressure-spans.
1491  * Return true if any movement is detected.
1492  */
1493 static boolean_t
1494 fg_update_strokes(struct atp_softc *sc, fg_pspan *pspans_x,
1495     u_int n_xpspans, fg_pspan *pspans_y, u_int n_ypspans)
1496 {
1497         atp_stroke_t *strokep;
1498         atp_stroke_t *strokep_next;
1499         boolean_t movement = false;
1500         u_int repeat_count = 0;
1501         u_int i;
1502         u_int j;
1503
1504         /* Reset X and Y components of all strokes as unmatched. */
1505         TAILQ_FOREACH(strokep, &sc->sc_stroke_used, entry) {
1506                 strokep->components[X].matched = false;
1507                 strokep->components[Y].matched = false;
1508         }
1509
1510         /*
1511          * Usually, the X and Y pspans come in pairs (the common case
1512          * being a single pair). It is possible, however, that
1513          * multiple contacts resolve to a single pspan along an
1514          * axis, as illustrated in the following:
1515          *
1516          *   F = finger-contact
1517          *
1518          *                pspan  pspan
1519          *        +-----------------------+
1520          *        |         .      .      |
1521          *        |         .      .      |
1522          *        |         .      .      |
1523          *        |         .      .      |
1524          *  pspan |.........F......F      |
1525          *        |                       |
1526          *        |                       |
1527          *        |                       |
1528          *        +-----------------------+
1529          *
1530          *
1531          * The above case can be detected by a difference in the
1532          * number of X and Y pspans. When this happens, X and Y pspans
1533          * aren't easy to pair or match against strokes.
1534          *
1535          * When X and Y pspans differ in number, the axis with the
1536          * smaller number of pspans is regarded as having a repeating
1537          * pspan (or a multi-pspan)--in the above illustration, the
1538          * Y-axis has a repeating pspan. Our approach is to try to
1539          * match the multi-pspan repeatedly against strokes. The
1540          * difference between the number of X and Y pspans gives us a
1541          * crude repeat_count for matching multi-pspans--i.e. the
1542          * multi-pspan along the Y axis (above) has a repeat_count of 1.
1543          */
1544         repeat_count = abs(n_xpspans - n_ypspans);
1545
1546         fg_match_strokes_against_pspans(sc, X, pspans_x, n_xpspans,
1547             (((repeat_count != 0) && ((n_xpspans < n_ypspans))) ?
1548                 repeat_count : 0));
1549         fg_match_strokes_against_pspans(sc, Y, pspans_y, n_ypspans,
1550             (((repeat_count != 0) && (n_ypspans < n_xpspans)) ?
1551                 repeat_count : 0));
1552
1553         /* Update the state of strokes based on the above pspan matches. */
1554         TAILQ_FOREACH_SAFE(strokep, &sc->sc_stroke_used, entry, strokep_next) {
1555                 if (strokep->components[X].matched &&
1556                     strokep->components[Y].matched) {
1557                         strokep->matched = true;
1558                         strokep->instantaneous_dx =
1559                             strokep->components[X].delta_mickeys;
1560                         strokep->instantaneous_dy =
1561                             strokep->components[Y].delta_mickeys;
1562                         atp_advance_stroke_state(sc, strokep, &movement);
1563                 } else {
1564                         /*
1565                          * At least one component of this stroke
1566                          * didn't match against current pspans;
1567                          * terminate it.
1568                          */
1569                         atp_terminate_stroke(sc, strokep);
1570                 }
1571         }
1572
1573         /* Add new strokes for pairs of unmatched pspans */
1574         for (i = 0; i < n_xpspans; i++) {
1575                 if (pspans_x[i].matched == false) break;
1576         }
1577         for (j = 0; j < n_ypspans; j++) {
1578                 if (pspans_y[j].matched == false) break;
1579         }
1580         if ((i < n_xpspans) && (j < n_ypspans)) {
1581 #ifdef USB_DEBUG
1582                 if (atp_debug >= ATP_LLEVEL_INFO) {
1583                         printf("unmatched pspans:");
1584                         for (; i < n_xpspans; i++) {
1585                                 if (pspans_x[i].matched)
1586                                         continue;
1587                                 printf(" X:[loc:%u,cum:%u]",
1588                                     pspans_x[i].loc, pspans_x[i].cum);
1589                         }
1590                         for (; j < n_ypspans; j++) {
1591                                 if (pspans_y[j].matched)
1592                                         continue;
1593                                 printf(" Y:[loc:%u,cum:%u]",
1594                                     pspans_y[j].loc, pspans_y[j].cum);
1595                         }
1596                         printf("\n");
1597                 }
1598 #endif /* USB_DEBUG */
1599                 if ((n_xpspans == 1) && (n_ypspans == 1))
1600                         /* The common case of a single pair of new pspans. */
1601                         fg_add_stroke(sc, &pspans_x[0], &pspans_y[0]);
1602                 else
1603                         fg_add_new_strokes(sc, pspans_x, n_xpspans,
1604                             pspans_y, n_ypspans);
1605         }
1606
1607 #ifdef USB_DEBUG
1608         if (atp_debug >= ATP_LLEVEL_INFO) {
1609                 TAILQ_FOREACH(strokep, &sc->sc_stroke_used, entry) {
1610                         printf(" %s%clc:%u,dm:%d,cum:%d,max:%d,%c"
1611                             ",%clc:%u,dm:%d,cum:%d,max:%d,%c",
1612                             (strokep->flags & ATSF_ZOMBIE) ? "zomb:" : "",
1613                             (strokep->type == ATP_STROKE_TOUCH) ? '[' : '<',
1614                             strokep->components[X].loc,
1615                             strokep->components[X].delta_mickeys,
1616                             strokep->components[X].cum_pressure,
1617                             strokep->components[X].max_cum_pressure,
1618                             (strokep->type == ATP_STROKE_TOUCH) ? ']' : '>',
1619                             (strokep->type == ATP_STROKE_TOUCH) ? '[' : '<',
1620                             strokep->components[Y].loc,
1621                             strokep->components[Y].delta_mickeys,
1622                             strokep->components[Y].cum_pressure,
1623                             strokep->components[Y].max_cum_pressure,
1624                             (strokep->type == ATP_STROKE_TOUCH) ? ']' : '>');
1625                 }
1626                 if (TAILQ_FIRST(&sc->sc_stroke_used) != NULL)
1627                         printf("\n");
1628         }
1629 #endif /* USB_DEBUG */
1630         return (movement);
1631 }
1632
1633 /*
1634  * Update strokes by matching against current pressure-spans.
1635  * Return true if any movement is detected.
1636  */
1637 static boolean_t
1638 wsp_update_strokes(struct atp_softc *sc, wsp_finger_t *fingers, u_int n_fingers)
1639 {
1640         boolean_t movement = false;
1641         atp_stroke_t *strokep_next;
1642         atp_stroke_t *strokep;
1643         u_int i;
1644
1645         if (sc->sc_n_strokes > 0) {
1646                 movement = wsp_match_strokes_against_fingers(
1647                     sc, fingers, n_fingers);
1648
1649                 /* handle zombie strokes */
1650                 TAILQ_FOREACH_SAFE(strokep, &sc->sc_stroke_used, entry, strokep_next) {
1651                         if (strokep->matched)
1652                                 continue;
1653                         atp_terminate_stroke(sc, strokep);
1654                 }
1655         }
1656
1657         /* initialize unmatched fingers as strokes */
1658         for (i = 0; i != n_fingers; i++) {
1659                 if (fingers[i].matched)
1660                         continue;
1661
1662                 wsp_add_stroke(sc, fingers + i);
1663         }
1664         return (movement);
1665 }
1666
1667 /* Initialize a stroke using a pressure-span. */
1668 static void
1669 fg_add_stroke(struct atp_softc *sc, const fg_pspan *pspan_x,
1670     const fg_pspan *pspan_y)
1671 {
1672         atp_stroke_t *strokep;
1673
1674         strokep = atp_alloc_stroke(sc);
1675         if (strokep == NULL)
1676                 return;
1677
1678         /*
1679          * Strokes begin as potential touches. If a stroke survives
1680          * longer than a threshold, or if it records significant
1681          * cumulative movement, then it is considered a 'slide'.
1682          */
1683         strokep->type    = ATP_STROKE_TOUCH;
1684         strokep->matched = false;
1685         microtime(&strokep->ctime);
1686         strokep->age     = 1;           /* number of interrupts */
1687         strokep->x       = pspan_x->loc;
1688         strokep->y       = pspan_y->loc;
1689
1690         strokep->components[X].loc              = pspan_x->loc;
1691         strokep->components[X].cum_pressure     = pspan_x->cum;
1692         strokep->components[X].max_cum_pressure = pspan_x->cum;
1693         strokep->components[X].matched          = true;
1694
1695         strokep->components[Y].loc              = pspan_y->loc;
1696         strokep->components[Y].cum_pressure     = pspan_y->cum;
1697         strokep->components[Y].max_cum_pressure = pspan_y->cum;
1698         strokep->components[Y].matched          = true;
1699
1700         if (sc->sc_n_strokes > 1) {
1701                 /* Reset double-tap-n-drag if we have more than one strokes. */
1702                 sc->sc_state &= ~ATP_DOUBLE_TAP_DRAG;
1703         }
1704
1705         DPRINTFN(ATP_LLEVEL_INFO, "[%u,%u], time: %u,%ld\n",
1706             strokep->components[X].loc,
1707             strokep->components[Y].loc,
1708             (u_int)strokep->ctime.tv_sec,
1709             (unsigned long int)strokep->ctime.tv_usec);
1710 }
1711
1712 static void
1713 fg_add_new_strokes(struct atp_softc *sc, fg_pspan *pspans_x,
1714     u_int n_xpspans, fg_pspan *pspans_y, u_int n_ypspans)
1715 {
1716         fg_pspan spans[2][FG_MAX_PSPANS_PER_AXIS];
1717         u_int nspans[2];
1718         u_int i;
1719         u_int j;
1720
1721         /* Copy unmatched pspans into the local arrays. */
1722         for (i = 0, nspans[X] = 0; i < n_xpspans; i++) {
1723                 if (pspans_x[i].matched == false) {
1724                         spans[X][nspans[X]] = pspans_x[i];
1725                         nspans[X]++;
1726                 }
1727         }
1728         for (j = 0, nspans[Y] = 0; j < n_ypspans; j++) {
1729                 if (pspans_y[j].matched == false) {
1730                         spans[Y][nspans[Y]] = pspans_y[j];
1731                         nspans[Y]++;
1732                 }
1733         }
1734
1735         if (nspans[X] == nspans[Y]) {
1736                 /* Create new strokes from pairs of unmatched pspans */
1737                 for (i = 0, j = 0; (i < nspans[X]) && (j < nspans[Y]); i++, j++)
1738                         fg_add_stroke(sc, &spans[X][i], &spans[Y][j]);
1739         } else {
1740                 u_int    cum = 0;
1741                 atp_axis repeat_axis;      /* axis with multi-pspans */
1742                 u_int    repeat_count;     /* repeat count for the multi-pspan*/
1743                 u_int    repeat_index = 0; /* index of the multi-span */
1744
1745                 repeat_axis  = (nspans[X] > nspans[Y]) ? Y : X;
1746                 repeat_count = abs(nspans[X] - nspans[Y]);
1747                 for (i = 0; i < nspans[repeat_axis]; i++) {
1748                         if (spans[repeat_axis][i].cum > cum) {
1749                                 repeat_index = i;
1750                                 cum = spans[repeat_axis][i].cum;
1751                         }
1752                 }
1753
1754                 /* Create new strokes from pairs of unmatched pspans */
1755                 i = 0, j = 0;
1756                 for (; (i < nspans[X]) && (j < nspans[Y]); i++, j++) {
1757                         fg_add_stroke(sc, &spans[X][i], &spans[Y][j]);
1758
1759                         /* Take care to repeat at the multi-pspan. */
1760                         if (repeat_count > 0) {
1761                                 if ((repeat_axis == X) &&
1762                                     (repeat_index == i)) {
1763                                         i--; /* counter loop increment */
1764                                         repeat_count--;
1765                                 } else if ((repeat_axis == Y) &&
1766                                     (repeat_index == j)) {
1767                                         j--; /* counter loop increment */
1768                                         repeat_count--;
1769                                 }
1770                         }
1771                 }
1772         }
1773 }
1774
1775 /* Initialize a stroke from an unmatched finger. */
1776 static void
1777 wsp_add_stroke(struct atp_softc *sc, const wsp_finger_t *fingerp)
1778 {
1779         atp_stroke_t *strokep;
1780
1781         strokep = atp_alloc_stroke(sc);
1782         if (strokep == NULL)
1783                 return;
1784
1785         /*
1786          * Strokes begin as potential touches. If a stroke survives
1787          * longer than a threshold, or if it records significant
1788          * cumulative movement, then it is considered a 'slide'.
1789          */
1790         strokep->type    = ATP_STROKE_TOUCH;
1791         strokep->matched = true;
1792         microtime(&strokep->ctime);
1793         strokep->age = 1;       /* number of interrupts */
1794         strokep->x = fingerp->x;
1795         strokep->y = fingerp->y;
1796
1797         /* Reset double-tap-n-drag if we have more than one strokes. */
1798         if (sc->sc_n_strokes > 1)
1799                 sc->sc_state &= ~ATP_DOUBLE_TAP_DRAG;
1800
1801         DPRINTFN(ATP_LLEVEL_INFO, "[%d,%d]\n", strokep->x, strokep->y);
1802 }
1803
1804 static void
1805 atp_advance_stroke_state(struct atp_softc *sc, atp_stroke_t *strokep,
1806     boolean_t *movementp)
1807 {
1808         /* Revitalize stroke if it had previously been marked as a zombie. */
1809         if (strokep->flags & ATSF_ZOMBIE)
1810                 strokep->flags &= ~ATSF_ZOMBIE;
1811
1812         strokep->age++;
1813         if (strokep->age <= atp_stroke_maturity_threshold) {
1814                 /* Avoid noise from immature strokes. */
1815                 strokep->instantaneous_dx = 0;
1816                 strokep->instantaneous_dy = 0;
1817         }
1818
1819         if (atp_compute_stroke_movement(strokep))
1820                 *movementp = true;
1821
1822         if (strokep->type != ATP_STROKE_TOUCH)
1823                 return;
1824
1825         /* Convert touch strokes to slides upon detecting movement or age. */
1826         if ((abs(strokep->cum_movement_x) > atp_slide_min_movement) ||
1827             (abs(strokep->cum_movement_y) > atp_slide_min_movement))
1828                 atp_convert_to_slide(sc, strokep);
1829         else {
1830                 /* Compute the stroke's age. */
1831                 struct timeval tdiff;
1832                 getmicrotime(&tdiff);
1833                 if (timevalcmp(&tdiff, &strokep->ctime, >)) {
1834                         timevalsub(&tdiff, &strokep->ctime);
1835
1836                         if ((tdiff.tv_sec > (atp_touch_timeout / 1000000)) ||
1837                             ((tdiff.tv_sec == (atp_touch_timeout / 1000000)) &&
1838                              (tdiff.tv_usec >= (atp_touch_timeout % 1000000))))
1839                                 atp_convert_to_slide(sc, strokep);
1840                 }
1841         }
1842 }
1843
1844 static boolean_t
1845 atp_stroke_has_small_movement(const atp_stroke_t *strokep)
1846 {
1847         return (((u_int)abs(strokep->instantaneous_dx) <=
1848                  atp_small_movement_threshold) &&
1849                 ((u_int)abs(strokep->instantaneous_dy) <=
1850                  atp_small_movement_threshold));
1851 }
1852
1853 /*
1854  * Accumulate instantaneous changes into the stroke's 'pending' bucket; if
1855  * the aggregate exceeds the small_movement_threshold, then retain
1856  * instantaneous changes for later.
1857  */
1858 static void
1859 atp_update_pending_mickeys(atp_stroke_t *strokep)
1860 {
1861         /* accumulate instantaneous movement */
1862         strokep->pending_dx += strokep->instantaneous_dx;
1863         strokep->pending_dy += strokep->instantaneous_dy;
1864
1865 #define UPDATE_INSTANTANEOUS_AND_PENDING(I, P)                          \
1866         if (abs((P)) <= atp_small_movement_threshold)                   \
1867                 (I) = 0; /* clobber small movement */                   \
1868         else {                                                          \
1869                 if ((I) > 0) {                                          \
1870                         /*                                              \
1871                          * Round up instantaneous movement to the nearest \
1872                          * ceiling. This helps preserve small mickey    \
1873                          * movements from being lost in following scaling \
1874                          * operation.                                   \
1875                          */                                             \
1876                         (I) = (((I) + (atp_mickeys_scale_factor - 1)) / \
1877                                atp_mickeys_scale_factor) *              \
1878                               atp_mickeys_scale_factor;                 \
1879                                                                         \
1880                         /*                                              \
1881                          * Deduct the rounded mickeys from pending mickeys. \
1882                          * Note: we multiply by 2 to offset the previous \
1883                          * accumulation of instantaneous movement into  \
1884                          * pending.                                     \
1885                          */                                             \
1886                         (P) -= ((I) << 1);                              \
1887                                                                         \
1888                         /* truncate pending to 0 if it becomes negative. */ \
1889                         (P) = imax((P), 0);                             \
1890                 } else {                                                \
1891                         /*                                              \
1892                          * Round down instantaneous movement to the nearest \
1893                          * ceiling. This helps preserve small mickey    \
1894                          * movements from being lost in following scaling \
1895                          * operation.                                   \
1896                          */                                             \
1897                         (I) = (((I) - (atp_mickeys_scale_factor - 1)) / \
1898                                atp_mickeys_scale_factor) *              \
1899                               atp_mickeys_scale_factor;                 \
1900                                                                         \
1901                         /*                                              \
1902                          * Deduct the rounded mickeys from pending mickeys. \
1903                          * Note: we multiply by 2 to offset the previous \
1904                          * accumulation of instantaneous movement into  \
1905                          * pending.                                     \
1906                          */                                             \
1907                         (P) -= ((I) << 1);                              \
1908                                                                         \
1909                         /* truncate pending to 0 if it becomes positive. */ \
1910                         (P) = imin((P), 0);                             \
1911                 }                                                       \
1912         }
1913
1914         UPDATE_INSTANTANEOUS_AND_PENDING(strokep->instantaneous_dx,
1915             strokep->pending_dx);
1916         UPDATE_INSTANTANEOUS_AND_PENDING(strokep->instantaneous_dy,
1917             strokep->pending_dy);
1918 }
1919
1920 /*
1921  * Compute a smoothened value for the stroke's movement from
1922  * instantaneous changes in the X and Y components.
1923  */
1924 static boolean_t
1925 atp_compute_stroke_movement(atp_stroke_t *strokep)
1926 {
1927         /*
1928          * Short movements are added first to the 'pending' bucket,
1929          * and then acted upon only when their aggregate exceeds a
1930          * threshold. This has the effect of filtering away movement
1931          * noise.
1932          */
1933         if (atp_stroke_has_small_movement(strokep))
1934                 atp_update_pending_mickeys(strokep);
1935         else {                /* large movement */
1936                 /* clear away any pending mickeys if there are large movements*/
1937                 strokep->pending_dx = 0;
1938                 strokep->pending_dy = 0;
1939         }
1940
1941         /* scale movement */
1942         strokep->movement_dx = (strokep->instantaneous_dx) /
1943             (int)atp_mickeys_scale_factor;
1944         strokep->movement_dy = (strokep->instantaneous_dy) /
1945             (int)atp_mickeys_scale_factor;
1946
1947         if ((abs(strokep->instantaneous_dx) >= ATP_FAST_MOVEMENT_TRESHOLD) ||
1948             (abs(strokep->instantaneous_dy) >= ATP_FAST_MOVEMENT_TRESHOLD)) {
1949                 strokep->movement_dx <<= 1;
1950                 strokep->movement_dy <<= 1;
1951         }
1952
1953         strokep->cum_movement_x += strokep->movement_dx;
1954         strokep->cum_movement_y += strokep->movement_dy;
1955
1956         return ((strokep->movement_dx != 0) || (strokep->movement_dy != 0));
1957 }
1958
1959 /*
1960  * Terminate a stroke. Aside from immature strokes, a slide or touch is
1961  * retained as a zombies so as to reap all their termination siblings
1962  * together; this helps establish the number of fingers involved at the
1963  * end of a multi-touch gesture.
1964  */
1965 static void
1966 atp_terminate_stroke(struct atp_softc *sc, atp_stroke_t *strokep)
1967 {
1968         if (strokep->flags & ATSF_ZOMBIE)
1969                 return;
1970
1971         /* Drop immature strokes rightaway. */
1972         if (strokep->age <= atp_stroke_maturity_threshold) {
1973                 atp_free_stroke(sc, strokep);
1974                 return;
1975         }
1976
1977         strokep->flags |= ATSF_ZOMBIE;
1978         sc->sc_state |= ATP_ZOMBIES_EXIST;
1979
1980         callout_reset(&sc->sc_callout, ATP_ZOMBIE_STROKE_REAP_INTERVAL,
1981             atp_reap_sibling_zombies, sc);
1982
1983         /*
1984          * Reset the double-click-n-drag at the termination of any
1985          * slide stroke.
1986          */
1987         if (strokep->type == ATP_STROKE_SLIDE)
1988                 sc->sc_state &= ~ATP_DOUBLE_TAP_DRAG;
1989 }
1990
1991 static boolean_t
1992 atp_is_horizontal_scroll(const atp_stroke_t *strokep)
1993 {
1994         if (abs(strokep->cum_movement_x) < atp_slide_min_movement)
1995                 return (false);
1996         if (strokep->cum_movement_y == 0)
1997                 return (true);
1998         return (abs(strokep->cum_movement_x / strokep->cum_movement_y) >= 4);
1999 }
2000
2001 static boolean_t
2002 atp_is_vertical_scroll(const atp_stroke_t *strokep)
2003 {
2004         if (abs(strokep->cum_movement_y) < atp_slide_min_movement)
2005                 return (false);
2006         if (strokep->cum_movement_x == 0)
2007                 return (true);
2008         return (abs(strokep->cum_movement_y / strokep->cum_movement_x) >= 4);
2009 }
2010
2011 static void
2012 atp_reap_sibling_zombies(void *arg)
2013 {
2014         struct atp_softc *sc = (struct atp_softc *)arg;
2015         u_int8_t n_touches_reaped = 0;
2016         u_int8_t n_slides_reaped = 0;
2017         u_int8_t n_horizontal_scrolls = 0;
2018         u_int8_t n_vertical_scrolls = 0;
2019         int horizontal_scroll = 0;
2020         int vertical_scroll = 0;
2021         atp_stroke_t *strokep;
2022         atp_stroke_t *strokep_next;
2023
2024         DPRINTFN(ATP_LLEVEL_INFO, "\n");
2025
2026         TAILQ_FOREACH_SAFE(strokep, &sc->sc_stroke_used, entry, strokep_next) {
2027                 if ((strokep->flags & ATSF_ZOMBIE) == 0)
2028                         continue;
2029
2030                 if (strokep->type == ATP_STROKE_TOUCH) {
2031                         n_touches_reaped++;
2032                 } else {
2033                         n_slides_reaped++;
2034
2035                         if (atp_is_horizontal_scroll(strokep)) {
2036                                 n_horizontal_scrolls++;
2037                                 horizontal_scroll += strokep->cum_movement_x;
2038                         } else if (atp_is_vertical_scroll(strokep)) {
2039                                 n_vertical_scrolls++;
2040                                 vertical_scroll +=  strokep->cum_movement_y;
2041                         }
2042                 }
2043
2044                 atp_free_stroke(sc, strokep);
2045         }
2046
2047         DPRINTFN(ATP_LLEVEL_INFO, "reaped %u zombies\n",
2048             n_touches_reaped + n_slides_reaped);
2049         sc->sc_state &= ~ATP_ZOMBIES_EXIST;
2050
2051         /* No further processing necessary if physical button is depressed. */
2052         if (sc->sc_ibtn != 0)
2053                 return;
2054
2055         if ((n_touches_reaped == 0) && (n_slides_reaped == 0))
2056                 return;
2057
2058         /* Add a pair of virtual button events (button-down and button-up) if
2059          * the physical button isn't pressed. */
2060         if (n_touches_reaped != 0) {
2061                 if (n_touches_reaped < atp_tap_minimum)
2062                         return;
2063
2064                 switch (n_touches_reaped) {
2065                 case 1:
2066                         atp_add_to_queue(sc, 0, 0, 0, MOUSE_BUTTON1DOWN);
2067                         microtime(&sc->sc_touch_reap_time); /* remember this time */
2068                         break;
2069                 case 2:
2070                         atp_add_to_queue(sc, 0, 0, 0, MOUSE_BUTTON3DOWN);
2071                         break;
2072                 case 3:
2073                         atp_add_to_queue(sc, 0, 0, 0, MOUSE_BUTTON2DOWN);
2074                         break;
2075                 default:
2076                         /* we handle taps of only up to 3 fingers */
2077                         return;
2078                 }
2079                 atp_add_to_queue(sc, 0, 0, 0, 0); /* button release */
2080
2081         } else if ((n_slides_reaped == 2) && (n_horizontal_scrolls == 2)) {
2082                 if (horizontal_scroll < 0)
2083                         atp_add_to_queue(sc, 0, 0, 0, MOUSE_BUTTON4DOWN);
2084                 else
2085                         atp_add_to_queue(sc, 0, 0, 0, MOUSE_BUTTON5DOWN);
2086                 atp_add_to_queue(sc, 0, 0, 0, 0); /* button release */
2087         }
2088 }
2089
2090 /* Switch a given touch stroke to being a slide. */
2091 static void
2092 atp_convert_to_slide(struct atp_softc *sc, atp_stroke_t *strokep)
2093 {
2094         strokep->type = ATP_STROKE_SLIDE;
2095
2096         /* Are we at the beginning of a double-click-n-drag? */
2097         if ((sc->sc_n_strokes == 1) &&
2098             ((sc->sc_state & ATP_ZOMBIES_EXIST) == 0) &&
2099             timevalcmp(&strokep->ctime, &sc->sc_touch_reap_time, >)) {
2100                 struct timeval delta;
2101                 struct timeval window = {
2102                         atp_double_tap_threshold / 1000000,
2103                         atp_double_tap_threshold % 1000000
2104                 };
2105
2106                 delta = strokep->ctime;
2107                 timevalsub(&delta, &sc->sc_touch_reap_time);
2108                 if (timevalcmp(&delta, &window, <=))
2109                         sc->sc_state |= ATP_DOUBLE_TAP_DRAG;
2110         }
2111 }
2112
2113 static void
2114 atp_reset_buf(struct atp_softc *sc)
2115 {
2116         /* reset read queue */
2117         usb_fifo_reset(sc->sc_fifo.fp[USB_FIFO_RX]);
2118 }
2119
2120 static void
2121 atp_add_to_queue(struct atp_softc *sc, int dx, int dy, int dz,
2122     uint32_t buttons_in)
2123 {
2124         uint32_t buttons_out;
2125         uint8_t  buf[8];
2126
2127         dx = imin(dx,  254); dx = imax(dx, -256);
2128         dy = imin(dy,  254); dy = imax(dy, -256);
2129         dz = imin(dz,  126); dz = imax(dz, -128);
2130
2131         buttons_out = MOUSE_MSC_BUTTONS;
2132         if (buttons_in & MOUSE_BUTTON1DOWN)
2133                 buttons_out &= ~MOUSE_MSC_BUTTON1UP;
2134         else if (buttons_in & MOUSE_BUTTON2DOWN)
2135                 buttons_out &= ~MOUSE_MSC_BUTTON2UP;
2136         else if (buttons_in & MOUSE_BUTTON3DOWN)
2137                 buttons_out &= ~MOUSE_MSC_BUTTON3UP;
2138
2139         DPRINTFN(ATP_LLEVEL_INFO, "dx=%d, dy=%d, buttons=%x\n",
2140             dx, dy, buttons_out);
2141
2142         /* Encode the mouse data in standard format; refer to mouse(4) */
2143         buf[0] = sc->sc_mode.syncmask[1];
2144         buf[0] |= buttons_out;
2145         buf[1] = dx >> 1;
2146         buf[2] = dy >> 1;
2147         buf[3] = dx - (dx >> 1);
2148         buf[4] = dy - (dy >> 1);
2149         /* Encode extra bytes for level 1 */
2150         if (sc->sc_mode.level == 1) {
2151                 buf[5] = dz >> 1;
2152                 buf[6] = dz - (dz >> 1);
2153                 buf[7] = (((~buttons_in) >> 3) & MOUSE_SYS_EXTBUTTONS);
2154         }
2155
2156         usb_fifo_put_data_linear(sc->sc_fifo.fp[USB_FIFO_RX], buf,
2157             sc->sc_mode.packetsize, 1);
2158 }
2159
2160 static int
2161 atp_probe(device_t self)
2162 {
2163         struct usb_attach_arg *uaa = device_get_ivars(self);
2164
2165         if (uaa->usb_mode != USB_MODE_HOST)
2166                 return (ENXIO);
2167
2168         if (uaa->info.bInterfaceClass != UICLASS_HID)
2169                 return (ENXIO);
2170         /*
2171          * Note: for some reason, the check
2172          * (uaa->info.bInterfaceProtocol == UIPROTO_MOUSE) doesn't hold true
2173          * for wellspring trackpads, so we've removed it from the common path.
2174          */
2175
2176         if ((usbd_lookup_id_by_uaa(fg_devs, sizeof(fg_devs), uaa)) == 0)
2177                 return ((uaa->info.bInterfaceProtocol == UIPROTO_MOUSE) ?
2178                         BUS_PROBE_DEFAULT : ENXIO);
2179
2180         if ((usbd_lookup_id_by_uaa(wsp_devs, sizeof(wsp_devs), uaa)) == 0)
2181                 if (uaa->info.bIfaceIndex == WELLSPRING_INTERFACE_INDEX)
2182                         return (BUS_PROBE_DEFAULT);
2183
2184         return (ENXIO);
2185 }
2186
2187 static int
2188 atp_attach(device_t dev)
2189 {
2190         struct atp_softc      *sc  = device_get_softc(dev);
2191         struct usb_attach_arg *uaa = device_get_ivars(dev);
2192         usb_error_t            err;
2193         void *descriptor_ptr = NULL;
2194         uint16_t descriptor_len;
2195         unsigned long di;
2196
2197         DPRINTFN(ATP_LLEVEL_INFO, "sc=%p\n", sc);
2198
2199         sc->sc_dev        = dev;
2200         sc->sc_usb_device = uaa->device;
2201
2202         /* Get HID descriptor */
2203         if (usbd_req_get_hid_desc(uaa->device, NULL, &descriptor_ptr,
2204             &descriptor_len, M_TEMP, uaa->info.bIfaceIndex) !=
2205             USB_ERR_NORMAL_COMPLETION)
2206                 return (ENXIO);
2207
2208         /* Get HID report descriptor length */
2209         sc->sc_expected_sensor_data_len = hid_report_size_max(descriptor_ptr,
2210             descriptor_len, hid_input, NULL);
2211         free(descriptor_ptr, M_TEMP);
2212
2213         if ((sc->sc_expected_sensor_data_len <= 0) ||
2214             (sc->sc_expected_sensor_data_len > ATP_SENSOR_DATA_BUF_MAX)) {
2215                 DPRINTF("atp_attach: datalength invalid or too large: %d\n",
2216                         sc->sc_expected_sensor_data_len);
2217                 return (ENXIO);
2218         }
2219
2220         di = USB_GET_DRIVER_INFO(uaa);
2221         sc->sc_family = DECODE_FAMILY_FROM_DRIVER_INFO(di);
2222
2223         /*
2224          * By default the touchpad behaves like an HID device, sending
2225          * packets with reportID = 2. Such reports contain only
2226          * limited information--they encode movement deltas and button
2227          * events,--but do not include data from the pressure
2228          * sensors. The device input mode can be switched from HID
2229          * reports to raw sensor data using vendor-specific USB
2230          * control commands.
2231          * FOUNTAIN devices will give an error when trying to switch
2232          * input mode, so we skip this command
2233          */
2234         if ((sc->sc_family == TRACKPAD_FAMILY_FOUNTAIN_GEYSER) &&
2235                 (DECODE_PRODUCT_FROM_DRIVER_INFO(di) == FOUNTAIN))
2236                 DPRINTF("device mode switch skipped: Fountain device\n");
2237         else if ((err = atp_set_device_mode(sc, RAW_SENSOR_MODE)) != 0) {
2238                 DPRINTF("failed to set mode to 'RAW_SENSOR' (%d)\n", err);
2239                 return (ENXIO);
2240         }
2241
2242         mtx_init(&sc->sc_mutex, "atpmtx", NULL, MTX_DEF | MTX_RECURSE);
2243
2244         switch(sc->sc_family) {
2245         case TRACKPAD_FAMILY_FOUNTAIN_GEYSER:
2246                 sc->sc_params =
2247                     &fg_dev_params[DECODE_PRODUCT_FROM_DRIVER_INFO(di)];
2248                 sc->sensor_data_interpreter = fg_interpret_sensor_data;
2249                 break;
2250         case TRACKPAD_FAMILY_WELLSPRING:
2251                 sc->sc_params =
2252                     &wsp_dev_params[DECODE_PRODUCT_FROM_DRIVER_INFO(di)];
2253                 sc->sensor_data_interpreter = wsp_interpret_sensor_data;
2254                 break;
2255         default:
2256                 goto detach;
2257         }
2258
2259         err = usbd_transfer_setup(uaa->device,
2260             &uaa->info.bIfaceIndex, sc->sc_xfer, atp_xfer_config,
2261             ATP_N_TRANSFER, sc, &sc->sc_mutex);
2262         if (err) {
2263                 DPRINTF("error=%s\n", usbd_errstr(err));
2264                 goto detach;
2265         }
2266
2267         if (usb_fifo_attach(sc->sc_usb_device, sc, &sc->sc_mutex,
2268             &atp_fifo_methods, &sc->sc_fifo,
2269             device_get_unit(dev), -1, uaa->info.bIfaceIndex,
2270             UID_ROOT, GID_OPERATOR, 0644)) {
2271                 goto detach;
2272         }
2273
2274         device_set_usb_desc(dev);
2275
2276         sc->sc_hw.buttons       = 3;
2277         sc->sc_hw.iftype        = MOUSE_IF_USB;
2278         sc->sc_hw.type          = MOUSE_PAD;
2279         sc->sc_hw.model         = MOUSE_MODEL_GENERIC;
2280         sc->sc_hw.hwid          = 0;
2281         sc->sc_mode.protocol    = MOUSE_PROTO_MSC;
2282         sc->sc_mode.rate        = -1;
2283         sc->sc_mode.resolution  = MOUSE_RES_UNKNOWN;
2284         sc->sc_mode.packetsize  = MOUSE_MSC_PACKETSIZE;
2285         sc->sc_mode.syncmask[0] = MOUSE_MSC_SYNCMASK;
2286         sc->sc_mode.syncmask[1] = MOUSE_MSC_SYNC;
2287         sc->sc_mode.accelfactor = 0;
2288         sc->sc_mode.level       = 0;
2289
2290         sc->sc_state            = 0;
2291         sc->sc_ibtn             = 0;
2292
2293         callout_init_mtx(&sc->sc_callout, &sc->sc_mutex, 0);
2294
2295         return (0);
2296
2297 detach:
2298         atp_detach(dev);
2299         return (ENOMEM);
2300 }
2301
2302 static int
2303 atp_detach(device_t dev)
2304 {
2305         struct atp_softc *sc;
2306
2307         sc = device_get_softc(dev);
2308         atp_set_device_mode(sc, HID_MODE);
2309
2310         mtx_lock(&sc->sc_mutex);
2311         callout_drain(&sc->sc_callout);
2312         if (sc->sc_state & ATP_ENABLED)
2313                 atp_disable(sc);
2314         mtx_unlock(&sc->sc_mutex);
2315
2316         usb_fifo_detach(&sc->sc_fifo);
2317
2318         usbd_transfer_unsetup(sc->sc_xfer, ATP_N_TRANSFER);
2319
2320         mtx_destroy(&sc->sc_mutex);
2321
2322         return (0);
2323 }
2324
2325 static void
2326 atp_intr(struct usb_xfer *xfer, usb_error_t error)
2327 {
2328         struct atp_softc      *sc = usbd_xfer_softc(xfer);
2329         struct usb_page_cache *pc;
2330         int len;
2331
2332         usbd_xfer_status(xfer, &len, NULL, NULL, NULL);
2333
2334         switch (USB_GET_STATE(xfer)) {
2335         case USB_ST_TRANSFERRED:
2336                 pc = usbd_xfer_get_frame(xfer, 0);
2337                 usbd_copy_out(pc, 0, sc->sc_sensor_data, len);
2338                 if (len < sc->sc_expected_sensor_data_len) {
2339                         /* make sure we don't process old data */
2340                         memset(sc->sc_sensor_data + len, 0,
2341                             sc->sc_expected_sensor_data_len - len);
2342                 }
2343
2344                 sc->sc_status.flags &= ~(MOUSE_STDBUTTONSCHANGED |
2345                     MOUSE_POSCHANGED);
2346                 sc->sc_status.obutton = sc->sc_status.button;
2347
2348                 (sc->sensor_data_interpreter)(sc, len);
2349
2350                 if (sc->sc_status.button != 0) {
2351                         /* Reset DOUBLE_TAP_N_DRAG if the button is pressed. */
2352                         sc->sc_state &= ~ATP_DOUBLE_TAP_DRAG;
2353                 } else if (sc->sc_state & ATP_DOUBLE_TAP_DRAG) {
2354                         /* Assume a button-press with DOUBLE_TAP_N_DRAG. */
2355                         sc->sc_status.button = MOUSE_BUTTON1DOWN;
2356                 }
2357
2358                 sc->sc_status.flags |=
2359                     sc->sc_status.button ^ sc->sc_status.obutton;
2360                 if (sc->sc_status.flags & MOUSE_STDBUTTONSCHANGED) {
2361                     DPRINTFN(ATP_LLEVEL_INFO, "button %s\n",
2362                         ((sc->sc_status.button & MOUSE_BUTTON1DOWN) ?
2363                         "pressed" : "released"));
2364                 }
2365
2366                 if (sc->sc_status.flags & (MOUSE_POSCHANGED |
2367                     MOUSE_STDBUTTONSCHANGED)) {
2368                         atp_stroke_t *strokep;
2369                         u_int8_t n_movements = 0;
2370                         int dx = 0;
2371                         int dy = 0;
2372                         int dz = 0;
2373
2374                         TAILQ_FOREACH(strokep, &sc->sc_stroke_used, entry) {
2375                                 if (strokep->flags & ATSF_ZOMBIE)
2376                                         continue;
2377
2378                                 dx += strokep->movement_dx;
2379                                 dy += strokep->movement_dy;
2380                                 if (strokep->movement_dx ||
2381                                     strokep->movement_dy)
2382                                         n_movements++;
2383                         }
2384
2385                         /* average movement if multiple strokes record motion.*/
2386                         if (n_movements > 1) {
2387                                 dx /= (int)n_movements;
2388                                 dy /= (int)n_movements;
2389                         }
2390
2391                         /* detect multi-finger vertical scrolls */
2392                         if (n_movements >= 2) {
2393                                 boolean_t all_vertical_scrolls = true;
2394                                 TAILQ_FOREACH(strokep, &sc->sc_stroke_used, entry) {
2395                                         if (strokep->flags & ATSF_ZOMBIE)
2396                                                 continue;
2397
2398                                         if (!atp_is_vertical_scroll(strokep))
2399                                                 all_vertical_scrolls = false;
2400                                 }
2401                                 if (all_vertical_scrolls) {
2402                                         dz = dy;
2403                                         dy = dx = 0;
2404                                 }
2405                         }
2406
2407                         sc->sc_status.dx += dx;
2408                         sc->sc_status.dy += dy;
2409                         sc->sc_status.dz += dz;
2410                         atp_add_to_queue(sc, dx, -dy, -dz, sc->sc_status.button);
2411                 }
2412
2413         case USB_ST_SETUP:
2414         tr_setup:
2415                 /* check if we can put more data into the FIFO */
2416                 if (usb_fifo_put_bytes_max(sc->sc_fifo.fp[USB_FIFO_RX]) != 0) {
2417                         usbd_xfer_set_frame_len(xfer, 0,
2418                             sc->sc_expected_sensor_data_len);
2419                         usbd_transfer_submit(xfer);
2420                 }
2421                 break;
2422
2423         default:                        /* Error */
2424                 if (error != USB_ERR_CANCELLED) {
2425                         /* try clear stall first */
2426                         usbd_xfer_set_stall(xfer);
2427                         goto tr_setup;
2428                 }
2429                 break;
2430         }
2431 }
2432
2433 static void
2434 atp_start_read(struct usb_fifo *fifo)
2435 {
2436         struct atp_softc *sc = usb_fifo_softc(fifo);
2437         int rate;
2438
2439         /* Check if we should override the default polling interval */
2440         rate = sc->sc_pollrate;
2441         /* Range check rate */
2442         if (rate > 1000)
2443                 rate = 1000;
2444         /* Check for set rate */
2445         if ((rate > 0) && (sc->sc_xfer[ATP_INTR_DT] != NULL)) {
2446                 /* Stop current transfer, if any */
2447                 usbd_transfer_stop(sc->sc_xfer[ATP_INTR_DT]);
2448                 /* Set new interval */
2449                 usbd_xfer_set_interval(sc->sc_xfer[ATP_INTR_DT], 1000 / rate);
2450                 /* Only set pollrate once */
2451                 sc->sc_pollrate = 0;
2452         }
2453
2454         usbd_transfer_start(sc->sc_xfer[ATP_INTR_DT]);
2455 }
2456
2457 static void
2458 atp_stop_read(struct usb_fifo *fifo)
2459 {
2460         struct atp_softc *sc = usb_fifo_softc(fifo);
2461         usbd_transfer_stop(sc->sc_xfer[ATP_INTR_DT]);
2462 }
2463
2464 static int
2465 atp_open(struct usb_fifo *fifo, int fflags)
2466 {
2467         struct atp_softc *sc = usb_fifo_softc(fifo);
2468
2469         /* check for duplicate open, should not happen */
2470         if (sc->sc_fflags & fflags)
2471                 return (EBUSY);
2472
2473         /* check for first open */
2474         if (sc->sc_fflags == 0) {
2475                 int rc;
2476                 if ((rc = atp_enable(sc)) != 0)
2477                         return (rc);
2478         }
2479
2480         if (fflags & FREAD) {
2481                 if (usb_fifo_alloc_buffer(fifo,
2482                     ATP_FIFO_BUF_SIZE, ATP_FIFO_QUEUE_MAXLEN)) {
2483                         return (ENOMEM);
2484                 }
2485         }
2486
2487         sc->sc_fflags |= (fflags & (FREAD | FWRITE));
2488         return (0);
2489 }
2490
2491 static void
2492 atp_close(struct usb_fifo *fifo, int fflags)
2493 {
2494         struct atp_softc *sc = usb_fifo_softc(fifo);
2495         if (fflags & FREAD)
2496                 usb_fifo_free_buffer(fifo);
2497
2498         sc->sc_fflags &= ~(fflags & (FREAD | FWRITE));
2499         if (sc->sc_fflags == 0) {
2500                 atp_disable(sc);
2501         }
2502 }
2503
2504 static int
2505 atp_ioctl(struct usb_fifo *fifo, u_long cmd, void *addr, int fflags)
2506 {
2507         struct atp_softc *sc = usb_fifo_softc(fifo);
2508         mousemode_t mode;
2509         int error = 0;
2510
2511         mtx_lock(&sc->sc_mutex);
2512
2513         switch(cmd) {
2514         case MOUSE_GETHWINFO:
2515                 *(mousehw_t *)addr = sc->sc_hw;
2516                 break;
2517         case MOUSE_GETMODE:
2518                 *(mousemode_t *)addr = sc->sc_mode;
2519                 break;
2520         case MOUSE_SETMODE:
2521                 mode = *(mousemode_t *)addr;
2522
2523                 if (mode.level == -1)
2524                         /* Don't change the current setting */
2525                         ;
2526                 else if ((mode.level < 0) || (mode.level > 1)) {
2527                         error = EINVAL;
2528                         break;
2529                 }
2530                 sc->sc_mode.level = mode.level;
2531                 sc->sc_pollrate   = mode.rate;
2532                 sc->sc_hw.buttons = 3;
2533
2534                 if (sc->sc_mode.level == 0) {
2535                         sc->sc_mode.protocol    = MOUSE_PROTO_MSC;
2536                         sc->sc_mode.packetsize  = MOUSE_MSC_PACKETSIZE;
2537                         sc->sc_mode.syncmask[0] = MOUSE_MSC_SYNCMASK;
2538                         sc->sc_mode.syncmask[1] = MOUSE_MSC_SYNC;
2539                 } else if (sc->sc_mode.level == 1) {
2540                         sc->sc_mode.protocol    = MOUSE_PROTO_SYSMOUSE;
2541                         sc->sc_mode.packetsize  = MOUSE_SYS_PACKETSIZE;
2542                         sc->sc_mode.syncmask[0] = MOUSE_SYS_SYNCMASK;
2543                         sc->sc_mode.syncmask[1] = MOUSE_SYS_SYNC;
2544                 }
2545                 atp_reset_buf(sc);
2546                 break;
2547         case MOUSE_GETLEVEL:
2548                 *(int *)addr = sc->sc_mode.level;
2549                 break;
2550         case MOUSE_SETLEVEL:
2551                 if ((*(int *)addr < 0) || (*(int *)addr > 1)) {
2552                         error = EINVAL;
2553                         break;
2554                 }
2555                 sc->sc_mode.level = *(int *)addr;
2556                 sc->sc_hw.buttons = 3;
2557
2558                 if (sc->sc_mode.level == 0) {
2559                         sc->sc_mode.protocol    = MOUSE_PROTO_MSC;
2560                         sc->sc_mode.packetsize  = MOUSE_MSC_PACKETSIZE;
2561                         sc->sc_mode.syncmask[0] = MOUSE_MSC_SYNCMASK;
2562                         sc->sc_mode.syncmask[1] = MOUSE_MSC_SYNC;
2563                 } else if (sc->sc_mode.level == 1) {
2564                         sc->sc_mode.protocol    = MOUSE_PROTO_SYSMOUSE;
2565                         sc->sc_mode.packetsize  = MOUSE_SYS_PACKETSIZE;
2566                         sc->sc_mode.syncmask[0] = MOUSE_SYS_SYNCMASK;
2567                         sc->sc_mode.syncmask[1] = MOUSE_SYS_SYNC;
2568                 }
2569                 atp_reset_buf(sc);
2570                 break;
2571         case MOUSE_GETSTATUS: {
2572                 mousestatus_t *status = (mousestatus_t *)addr;
2573
2574                 *status = sc->sc_status;
2575                 sc->sc_status.obutton = sc->sc_status.button;
2576                 sc->sc_status.button  = 0;
2577                 sc->sc_status.dx      = 0;
2578                 sc->sc_status.dy      = 0;
2579                 sc->sc_status.dz      = 0;
2580
2581                 if (status->dx || status->dy || status->dz)
2582                         status->flags |= MOUSE_POSCHANGED;
2583                 if (status->button != status->obutton)
2584                         status->flags |= MOUSE_BUTTONSCHANGED;
2585                 break;
2586         }
2587
2588         default:
2589                 error = ENOTTY;
2590                 break;
2591         }
2592
2593         mtx_unlock(&sc->sc_mutex);
2594         return (error);
2595 }
2596
2597 static int
2598 atp_sysctl_scale_factor_handler(SYSCTL_HANDLER_ARGS)
2599 {
2600         int error;
2601         u_int tmp;
2602
2603         tmp = atp_mickeys_scale_factor;
2604         error = sysctl_handle_int(oidp, &tmp, 0, req);
2605         if (error != 0 || req->newptr == NULL)
2606                 return (error);
2607
2608         if (tmp == atp_mickeys_scale_factor)
2609                 return (0);     /* no change */
2610         if ((tmp == 0) || (tmp > (10 * ATP_SCALE_FACTOR)))
2611                 return (EINVAL);
2612
2613         atp_mickeys_scale_factor = tmp;
2614         DPRINTFN(ATP_LLEVEL_INFO, "%s: resetting mickeys_scale_factor to %u\n",
2615             ATP_DRIVER_NAME, tmp);
2616
2617         return (0);
2618 }
2619
2620 static devclass_t atp_devclass;
2621
2622 static device_method_t atp_methods[] = {
2623         DEVMETHOD(device_probe,  atp_probe),
2624         DEVMETHOD(device_attach, atp_attach),
2625         DEVMETHOD(device_detach, atp_detach),
2626
2627         DEVMETHOD_END
2628 };
2629
2630 static driver_t atp_driver = {
2631         .name    = ATP_DRIVER_NAME,
2632         .methods = atp_methods,
2633         .size    = sizeof(struct atp_softc)
2634 };
2635
2636 DRIVER_MODULE(atp, uhub, atp_driver, atp_devclass, NULL, 0);
2637 MODULE_DEPEND(atp, usb, 1, 1, 1);
2638 MODULE_DEPEND(atp, hid, 1, 1, 1);
2639 MODULE_VERSION(atp, 1);
2640 USB_PNP_HOST_INFO(fg_devs);
2641 USB_PNP_HOST_INFO(wsp_devs);