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