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 */
171static SYSCTL_NODE(_hw_usb, OID_AUTO, atp, CTLFLAG_RW, 0, "USB ATP");
172
173#ifdef USB_DEBUG
174enum 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};
180static int atp_debug = ATP_LLEVEL_ERROR; /* the default is to only log errors */
181SYSCTL_INT(_hw_usb_atp, OID_AUTO, debug, CTLFLAG_RWTUN,
182    &atp_debug, ATP_LLEVEL_ERROR, "ATP debug level");
183#endif /* USB_DEBUG */
184
185static u_int atp_touch_timeout = ATP_TOUCH_TIMEOUT;
186SYSCTL_UINT(_hw_usb_atp, OID_AUTO, touch_timeout, CTLFLAG_RWTUN,
187    &atp_touch_timeout, 125000, "age threshold in microseconds for a touch");
188
189static u_int atp_double_tap_threshold = ATP_DOUBLE_TAP_N_DRAG_THRESHOLD;
190SYSCTL_UINT(_hw_usb_atp, OID_AUTO, double_tap_threshold, CTLFLAG_RWTUN,
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
195static u_int atp_mickeys_scale_factor = ATP_SCALE_FACTOR;
196static int atp_sysctl_scale_factor_handler(SYSCTL_HANDLER_ARGS);
197SYSCTL_PROC(_hw_usb_atp, OID_AUTO, scale_factor, CTLTYPE_UINT | CTLFLAG_RWTUN,
198    &atp_mickeys_scale_factor, sizeof(atp_mickeys_scale_factor),
199    atp_sysctl_scale_factor_handler, "IU", "movement scale factor");
200
201static u_int atp_small_movement_threshold = ATP_SMALL_MOVEMENT_THRESHOLD;
202SYSCTL_UINT(_hw_usb_atp, OID_AUTO, small_movement, CTLFLAG_RWTUN,
203    &atp_small_movement_threshold, ATP_SMALL_MOVEMENT_THRESHOLD,
204    "the small movement black-hole for filtering noise");
205
206static u_int atp_tap_minimum = 1;
207SYSCTL_UINT(_hw_usb_atp, OID_AUTO, tap_minimum, CTLFLAG_RWTUN,
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 */
215static u_int atp_slide_min_movement = 2 * ATP_SMALL_MOVEMENT_THRESHOLD;
216SYSCTL_UINT(_hw_usb_atp, OID_AUTO, slide_min_movement, CTLFLAG_RWTUN,
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 */
224static u_int atp_stroke_maturity_threshold = 4;
225SYSCTL_UINT(_hw_usb_atp, OID_AUTO, stroke_maturity_threshold, CTLFLAG_RWTUN,
226    &atp_stroke_maturity_threshold, 4,
227    "the minimum age of a stroke for it to be considered mature");
228
229typedef 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
235enum 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
245enum 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 */
262enum 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};
268enum 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 */
295typedef 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 */
321struct 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
336typedef 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 */
364struct 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};
370struct 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
376static 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
415static 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
447static 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 */
513static 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
576typedef enum atp_stroke_type {
577	ATP_STROKE_TOUCH,
578	ATP_STROKE_SLIDE,
579} atp_stroke_type;
580
581typedef 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
590enum {
591	ATP_INTR_DT,
592	ATP_RESET,
593	ATP_N_TRANSFER,
594};
595
596typedef 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 */
610typedef 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
650struct atp_softc; /* forward declaration */
651typedef void (*sensor_data_interpreter_t)(struct atp_softc *sc, u_int len);
652
653struct 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 */
723enum 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
728typedef 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 */
737static usb_fifo_cmd_t   atp_start_read;
738static usb_fifo_cmd_t   atp_stop_read;
739static usb_fifo_open_t  atp_open;
740static usb_fifo_close_t atp_close;
741static usb_fifo_ioctl_t atp_ioctl;
742
743static 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 */
753static usb_error_t   atp_set_device_mode(struct atp_softc *, interface_mode);
754static void	     atp_reset_callback(struct usb_xfer *, usb_error_t);
755static int	     atp_enable(struct atp_softc *);
756static void	     atp_disable(struct atp_softc *);
757
758/* sensor interpretation */
759static void	     fg_interpret_sensor_data(struct atp_softc *, u_int);
760static void	     fg_extract_sensor_data(const int8_t *, u_int, atp_axis,
761    int *, enum fountain_geyser_trackpad_type);
762static void	     fg_get_pressures(int *, const int *, const int *, int);
763static void	     fg_detect_pspans(int *, u_int, u_int, fg_pspan *, u_int *);
764static void	     wsp_interpret_sensor_data(struct atp_softc *, u_int);
765
766/* movement detection */
767static boolean_t     fg_match_stroke_component(fg_stroke_component_t *,
768    const fg_pspan *, atp_stroke_type);
769static void	     fg_match_strokes_against_pspans(struct atp_softc *,
770    atp_axis, fg_pspan *, u_int, u_int);
771static boolean_t     wsp_match_strokes_against_fingers(struct atp_softc *,
772    wsp_finger_t *, u_int);
773static boolean_t     fg_update_strokes(struct atp_softc *, fg_pspan *, u_int,
774    fg_pspan *, u_int);
775static boolean_t     wsp_update_strokes(struct atp_softc *,
776    wsp_finger_t [WSP_MAX_FINGERS], u_int);
777static void fg_add_stroke(struct atp_softc *, const fg_pspan *, const fg_pspan *);
778static void	     fg_add_new_strokes(struct atp_softc *, fg_pspan *,
779    u_int, fg_pspan *, u_int);
780static void wsp_add_stroke(struct atp_softc *, const wsp_finger_t *);
781static void	     atp_advance_stroke_state(struct atp_softc *,
782    atp_stroke_t *, boolean_t *);
783static boolean_t atp_stroke_has_small_movement(const atp_stroke_t *);
784static void	     atp_update_pending_mickeys(atp_stroke_t *);
785static boolean_t     atp_compute_stroke_movement(atp_stroke_t *);
786static void	     atp_terminate_stroke(struct atp_softc *, atp_stroke_t *);
787
788/* tap detection */
789static boolean_t atp_is_horizontal_scroll(const atp_stroke_t *);
790static boolean_t atp_is_vertical_scroll(const atp_stroke_t *);
791static void	     atp_reap_sibling_zombies(void *);
792static void	     atp_convert_to_slide(struct atp_softc *, atp_stroke_t *);
793
794/* updating fifo */
795static void	     atp_reset_buf(struct atp_softc *);
796static void	     atp_add_to_queue(struct atp_softc *, int, int, int, uint32_t);
797
798/* Device methods. */
799static device_probe_t  atp_probe;
800static device_attach_t atp_attach;
801static device_detach_t atp_detach;
802static usb_callback_t  atp_intr;
803
804static 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
826static atp_stroke_t *
827atp_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++;
840done:
841	return (pstroke);
842}
843
844static void
845atp_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
856static void
857atp_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
874static usb_error_t
875atp_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
914static void
915atp_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
954static int
955atp_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
971static void
972atp_disable(struct atp_softc *sc)
973{
974	sc->sc_state &= ~(ATP_ENABLED | ATP_VALID);
975	DPRINTFN(ATP_LLEVEL_INFO, "disabled atp\n");
976}
977
978static void
979fg_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 */
1091static void
1092fg_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
1132static void
1133fg_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
1158static void
1159fg_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
1264static void
1265wsp_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 */
1342static boolean_t
1343fg_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
1387static void
1388fg_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
1430static boolean_t
1431wsp_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 */
1489static boolean_t
1490fg_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 */
1634static boolean_t
1635wsp_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. */
1665static void
1666fg_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
1709static void
1710fg_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. */
1773static void
1774wsp_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
1801static void
1802atp_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
1841static boolean_t
1842atp_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 */
1855static void
1856atp_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 */
1921static boolean_t
1922atp_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 */
1962static void
1963atp_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
1988static boolean_t
1989atp_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
1998static boolean_t
1999atp_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
2008static void
2009atp_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. */
2088static void
2089atp_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
2110static void
2111atp_reset_buf(struct atp_softc *sc)
2112{
2113	/* reset read queue */
2114	usb_fifo_reset(sc->sc_fifo.fp[USB_FIFO_RX]);
2115}
2116
2117static void
2118atp_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
2157static int
2158atp_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
2184static int
2185atp_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
2290detach:
2291	atp_detach(dev);
2292	return (ENOMEM);
2293}
2294
2295static int
2296atp_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
2318static void
2319atp_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
2427static void
2428atp_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
2451static void
2452atp_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
2458static int
2459atp_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
2485static void
2486atp_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
2498static int
2499atp_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
2591static int
2592atp_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
2614static devclass_t atp_devclass;
2615
2616static 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
2624static driver_t atp_driver = {
2625	.name    = ATP_DRIVER_NAME,
2626	.methods = atp_methods,
2627	.size    = sizeof(struct atp_softc)
2628};
2629
2630DRIVER_MODULE(atp, uhub, atp_driver, atp_devclass, NULL, 0);
2631MODULE_DEPEND(atp, usb, 1, 1, 1);
2632MODULE_VERSION(atp, 1);
2633USB_PNP_HOST_INFO(fg_devs);
2634USB_PNP_HOST_INFO(wsp_devs);
2635