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