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