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