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/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 515 #define ATP_DEV(v,p,i) { USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, i) } 516 517 /* TODO: STRUCT_USB_HOST_ID */ 518 static const struct usb_device_id wsp_devs[] = { 519 /* MacbookAir1.1 */ 520 ATP_DEV(APPLE, WELLSPRING_ANSI, WELLSPRING_DRIVER_INFO(WELLSPRING1)), 521 ATP_DEV(APPLE, WELLSPRING_ISO, WELLSPRING_DRIVER_INFO(WELLSPRING1)), 522 ATP_DEV(APPLE, WELLSPRING_JIS, WELLSPRING_DRIVER_INFO(WELLSPRING1)), 523 524 /* MacbookProPenryn, aka wellspring2 */ 525 ATP_DEV(APPLE, WELLSPRING2_ANSI, WELLSPRING_DRIVER_INFO(WELLSPRING2)), 526 ATP_DEV(APPLE, WELLSPRING2_ISO, WELLSPRING_DRIVER_INFO(WELLSPRING2)), 527 ATP_DEV(APPLE, WELLSPRING2_JIS, WELLSPRING_DRIVER_INFO(WELLSPRING2)), 528 529 /* Macbook5,1 (unibody), aka wellspring3 */ 530 ATP_DEV(APPLE, WELLSPRING3_ANSI, WELLSPRING_DRIVER_INFO(WELLSPRING3)), 531 ATP_DEV(APPLE, WELLSPRING3_ISO, WELLSPRING_DRIVER_INFO(WELLSPRING3)), 532 ATP_DEV(APPLE, WELLSPRING3_JIS, WELLSPRING_DRIVER_INFO(WELLSPRING3)), 533 534 /* MacbookAir3,2 (unibody), aka wellspring4 */ 535 ATP_DEV(APPLE, WELLSPRING4_ANSI, WELLSPRING_DRIVER_INFO(WELLSPRING4)), 536 ATP_DEV(APPLE, WELLSPRING4_ISO, WELLSPRING_DRIVER_INFO(WELLSPRING4)), 537 ATP_DEV(APPLE, WELLSPRING4_JIS, WELLSPRING_DRIVER_INFO(WELLSPRING4)), 538 539 /* MacbookAir3,1 (unibody), aka wellspring4 */ 540 ATP_DEV(APPLE, WELLSPRING4A_ANSI, WELLSPRING_DRIVER_INFO(WELLSPRING4A)), 541 ATP_DEV(APPLE, WELLSPRING4A_ISO, WELLSPRING_DRIVER_INFO(WELLSPRING4A)), 542 ATP_DEV(APPLE, WELLSPRING4A_JIS, WELLSPRING_DRIVER_INFO(WELLSPRING4A)), 543 544 /* Macbook8 (unibody, March 2011) */ 545 ATP_DEV(APPLE, WELLSPRING5_ANSI, WELLSPRING_DRIVER_INFO(WELLSPRING5)), 546 ATP_DEV(APPLE, WELLSPRING5_ISO, WELLSPRING_DRIVER_INFO(WELLSPRING5)), 547 ATP_DEV(APPLE, WELLSPRING5_JIS, WELLSPRING_DRIVER_INFO(WELLSPRING5)), 548 549 /* MacbookAir4,1 (unibody, July 2011) */ 550 ATP_DEV(APPLE, WELLSPRING6A_ANSI, WELLSPRING_DRIVER_INFO(WELLSPRING6A)), 551 ATP_DEV(APPLE, WELLSPRING6A_ISO, WELLSPRING_DRIVER_INFO(WELLSPRING6A)), 552 ATP_DEV(APPLE, WELLSPRING6A_JIS, WELLSPRING_DRIVER_INFO(WELLSPRING6A)), 553 554 /* MacbookAir4,2 (unibody, July 2011) */ 555 ATP_DEV(APPLE, WELLSPRING6_ANSI, WELLSPRING_DRIVER_INFO(WELLSPRING6)), 556 ATP_DEV(APPLE, WELLSPRING6_ISO, WELLSPRING_DRIVER_INFO(WELLSPRING6)), 557 ATP_DEV(APPLE, WELLSPRING6_JIS, WELLSPRING_DRIVER_INFO(WELLSPRING6)), 558 559 /* Macbook8,2 (unibody) */ 560 ATP_DEV(APPLE, WELLSPRING5A_ANSI, WELLSPRING_DRIVER_INFO(WELLSPRING5A)), 561 ATP_DEV(APPLE, WELLSPRING5A_ISO, WELLSPRING_DRIVER_INFO(WELLSPRING5A)), 562 ATP_DEV(APPLE, WELLSPRING5A_JIS, WELLSPRING_DRIVER_INFO(WELLSPRING5A)), 563 564 /* MacbookPro10,1 (unibody, June 2012) */ 565 /* MacbookPro11,? (unibody, June 2013) */ 566 ATP_DEV(APPLE, WELLSPRING7_ANSI, WELLSPRING_DRIVER_INFO(WELLSPRING7)), 567 ATP_DEV(APPLE, WELLSPRING7_ISO, WELLSPRING_DRIVER_INFO(WELLSPRING7)), 568 ATP_DEV(APPLE, WELLSPRING7_JIS, WELLSPRING_DRIVER_INFO(WELLSPRING7)), 569 570 /* MacbookPro10,2 (unibody, October 2012) */ 571 ATP_DEV(APPLE, WELLSPRING7A_ANSI, WELLSPRING_DRIVER_INFO(WELLSPRING7A)), 572 ATP_DEV(APPLE, WELLSPRING7A_ISO, WELLSPRING_DRIVER_INFO(WELLSPRING7A)), 573 ATP_DEV(APPLE, WELLSPRING7A_JIS, WELLSPRING_DRIVER_INFO(WELLSPRING7A)), 574 575 /* MacbookAir6,2 (unibody, June 2013) */ 576 ATP_DEV(APPLE, WELLSPRING8_ANSI, WELLSPRING_DRIVER_INFO(WELLSPRING8)), 577 ATP_DEV(APPLE, WELLSPRING8_ISO, WELLSPRING_DRIVER_INFO(WELLSPRING8)), 578 ATP_DEV(APPLE, WELLSPRING8_JIS, WELLSPRING_DRIVER_INFO(WELLSPRING8)), 579 }; 580 581 typedef enum atp_stroke_type { 582 ATP_STROKE_TOUCH, 583 ATP_STROKE_SLIDE, 584 } atp_stroke_type; 585 586 typedef enum atp_axis { 587 X = 0, 588 Y = 1, 589 NUM_AXES 590 } atp_axis; 591 592 #define ATP_FIFO_BUF_SIZE 8 /* bytes */ 593 #define ATP_FIFO_QUEUE_MAXLEN 50 /* units */ 594 595 enum { 596 ATP_INTR_DT, 597 ATP_RESET, 598 ATP_N_TRANSFER, 599 }; 600 601 typedef struct fg_stroke_component { 602 /* Fields encapsulating the pressure-span. */ 603 u_int loc; /* location (scaled) */ 604 u_int cum_pressure; /* cumulative compression */ 605 u_int max_cum_pressure; /* max cumulative compression */ 606 boolean_t matched; /*to track components as they match against pspans.*/ 607 608 int delta_mickeys; /* change in location (un-smoothened movement)*/ 609 } fg_stroke_component_t; 610 611 /* 612 * The following structure captures a finger contact with the 613 * touchpad. A stroke comprises two p-span components and some state. 614 */ 615 typedef struct atp_stroke { 616 TAILQ_ENTRY(atp_stroke) entry; 617 618 atp_stroke_type type; 619 uint32_t flags; /* the state of this stroke */ 620 #define ATSF_ZOMBIE 0x1 621 boolean_t matched; /* to track match against fingers.*/ 622 623 struct timeval ctime; /* create time; for coincident siblings. */ 624 625 /* 626 * Unit: interrupts; we maintain this value in 627 * addition to 'ctime' in order to avoid the 628 * expensive call to microtime() at every 629 * interrupt. 630 */ 631 uint32_t age; 632 633 /* Location */ 634 int x; 635 int y; 636 637 /* Fields containing information about movement. */ 638 int instantaneous_dx; /* curr. change in X location (un-smoothened) */ 639 int instantaneous_dy; /* curr. change in Y location (un-smoothened) */ 640 int pending_dx; /* cum. of pending short movements */ 641 int pending_dy; /* cum. of pending short movements */ 642 int movement_dx; /* interpreted smoothened movement */ 643 int movement_dy; /* interpreted smoothened movement */ 644 int cum_movement_x; /* cum. horizontal movement */ 645 int cum_movement_y; /* cum. vertical movement */ 646 647 /* 648 * The following member is relevant only for fountain-geyser trackpads. 649 * For these, there is the need to track pressure-spans and cumulative 650 * pressures for stroke components. 651 */ 652 fg_stroke_component_t components[NUM_AXES]; 653 } atp_stroke_t; 654 655 struct atp_softc; /* forward declaration */ 656 typedef void (*sensor_data_interpreter_t)(struct atp_softc *sc, u_int len); 657 658 struct atp_softc { 659 device_t sc_dev; 660 struct usb_device *sc_usb_device; 661 struct mtx sc_mutex; /* for synchronization */ 662 struct usb_fifo_sc sc_fifo; 663 664 #define MODE_LENGTH 8 665 char sc_mode_bytes[MODE_LENGTH]; /* device mode */ 666 667 trackpad_family_t sc_family; 668 const void *sc_params; /* device configuration */ 669 sensor_data_interpreter_t sensor_data_interpreter; 670 671 mousehw_t sc_hw; 672 mousemode_t sc_mode; 673 mousestatus_t sc_status; 674 675 u_int sc_state; 676 #define ATP_ENABLED 0x01 677 #define ATP_ZOMBIES_EXIST 0x02 678 #define ATP_DOUBLE_TAP_DRAG 0x04 679 #define ATP_VALID 0x08 680 681 struct usb_xfer *sc_xfer[ATP_N_TRANSFER]; 682 683 u_int sc_pollrate; 684 int sc_fflags; 685 686 atp_stroke_t sc_strokes_data[ATP_MAX_STROKES]; 687 TAILQ_HEAD(,atp_stroke) sc_stroke_free; 688 TAILQ_HEAD(,atp_stroke) sc_stroke_used; 689 u_int sc_n_strokes; 690 691 struct callout sc_callout; 692 693 /* 694 * button status. Set to non-zero if the mouse-button is physically 695 * pressed. This state variable is exposed through softc to allow 696 * reap_sibling_zombies to avoid registering taps while the trackpad 697 * button is pressed. 698 */ 699 uint8_t sc_ibtn; 700 701 /* 702 * Time when touch zombies were last reaped; useful for detecting 703 * double-touch-n-drag. 704 */ 705 struct timeval sc_touch_reap_time; 706 707 u_int sc_idlecount; 708 709 /* Regarding the data transferred from t-pad in USB INTR packets. */ 710 u_int sc_expected_sensor_data_len; 711 uint8_t sc_sensor_data[ATP_SENSOR_DATA_BUF_MAX] __aligned(4); 712 713 int sc_cur_x[FG_MAX_XSENSORS]; /* current sensor readings */ 714 int sc_cur_y[FG_MAX_YSENSORS]; 715 int sc_base_x[FG_MAX_XSENSORS]; /* base sensor readings */ 716 int sc_base_y[FG_MAX_YSENSORS]; 717 int sc_pressure_x[FG_MAX_XSENSORS]; /* computed pressures */ 718 int sc_pressure_y[FG_MAX_YSENSORS]; 719 fg_pspan sc_pspans_x[FG_MAX_PSPANS_PER_AXIS]; 720 fg_pspan sc_pspans_y[FG_MAX_PSPANS_PER_AXIS]; 721 }; 722 723 /* 724 * The last byte of the fountain-geyser sensor data contains status bits; the 725 * following values define the meanings of these bits. 726 * (only Geyser 3/4) 727 */ 728 enum geyser34_status_bits { 729 FG_STATUS_BUTTON = (uint8_t)0x01, /* The button was pressed */ 730 FG_STATUS_BASE_UPDATE = (uint8_t)0x04, /* Data from an untouched pad.*/ 731 }; 732 733 typedef enum interface_mode { 734 RAW_SENSOR_MODE = (uint8_t)0x01, 735 HID_MODE = (uint8_t)0x08 736 } interface_mode; 737 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 1420 /* There is a match. */ 1421 strokep->components[axis].matched = true; 1422 1423 /* Take care to repeat at the multi-span. */ 1424 if ((repeat_count > 0) && (i == repeat_index)) 1425 repeat_count--; 1426 else 1427 pspans[i].matched = true; 1428 1429 break; /* skip to the next strokep */ 1430 } 1431 } /* loop over pspans */ 1432 } /* loop over strokes */ 1433 } 1434 1435 static boolean_t 1436 wsp_match_strokes_against_fingers(struct atp_softc *sc, 1437 wsp_finger_t *fingers, u_int n_fingers) 1438 { 1439 boolean_t movement = false; 1440 atp_stroke_t *strokep; 1441 u_int i; 1442 1443 /* reset the matched status for all strokes */ 1444 TAILQ_FOREACH(strokep, &sc->sc_stroke_used, entry) 1445 strokep->matched = false; 1446 1447 for (i = 0; i != n_fingers; i++) { 1448 u_int least_distance_sq = WSP_MAX_ALLOWED_MATCH_DISTANCE_SQ; 1449 atp_stroke_t *strokep_best = NULL; 1450 1451 TAILQ_FOREACH(strokep, &sc->sc_stroke_used, entry) { 1452 int instantaneous_dx; 1453 int instantaneous_dy; 1454 u_int d_squared; 1455 1456 if (strokep->matched) 1457 continue; 1458 1459 instantaneous_dx = fingers[i].x - strokep->x; 1460 instantaneous_dy = fingers[i].y - strokep->y; 1461 1462 /* skip strokes which are far away */ 1463 d_squared = 1464 (instantaneous_dx * instantaneous_dx) + 1465 (instantaneous_dy * instantaneous_dy); 1466 1467 if (d_squared < least_distance_sq) { 1468 least_distance_sq = d_squared; 1469 strokep_best = strokep; 1470 } 1471 } 1472 1473 strokep = strokep_best; 1474 1475 if (strokep != NULL) { 1476 fingers[i].matched = true; 1477 1478 strokep->matched = true; 1479 strokep->instantaneous_dx = fingers[i].x - strokep->x; 1480 strokep->instantaneous_dy = fingers[i].y - strokep->y; 1481 strokep->x = fingers[i].x; 1482 strokep->y = fingers[i].y; 1483 1484 atp_advance_stroke_state(sc, strokep, &movement); 1485 } 1486 } 1487 return (movement); 1488 } 1489 1490 /* 1491 * Update strokes by matching against current pressure-spans. 1492 * Return true if any movement is detected. 1493 */ 1494 static boolean_t 1495 fg_update_strokes(struct atp_softc *sc, fg_pspan *pspans_x, 1496 u_int n_xpspans, fg_pspan *pspans_y, u_int n_ypspans) 1497 { 1498 atp_stroke_t *strokep; 1499 atp_stroke_t *strokep_next; 1500 boolean_t movement = false; 1501 u_int repeat_count = 0; 1502 u_int i; 1503 u_int j; 1504 1505 /* Reset X and Y components of all strokes as unmatched. */ 1506 TAILQ_FOREACH(strokep, &sc->sc_stroke_used, entry) { 1507 strokep->components[X].matched = false; 1508 strokep->components[Y].matched = false; 1509 } 1510 1511 /* 1512 * Usually, the X and Y pspans come in pairs (the common case 1513 * being a single pair). It is possible, however, that 1514 * multiple contacts resolve to a single pspan along an 1515 * axis, as illustrated in the following: 1516 * 1517 * F = finger-contact 1518 * 1519 * pspan pspan 1520 * +-----------------------+ 1521 * | . . | 1522 * | . . | 1523 * | . . | 1524 * | . . | 1525 * pspan |.........F......F | 1526 * | | 1527 * | | 1528 * | | 1529 * +-----------------------+ 1530 * 1531 * 1532 * The above case can be detected by a difference in the 1533 * number of X and Y pspans. When this happens, X and Y pspans 1534 * aren't easy to pair or match against strokes. 1535 * 1536 * When X and Y pspans differ in number, the axis with the 1537 * smaller number of pspans is regarded as having a repeating 1538 * pspan (or a multi-pspan)--in the above illustration, the 1539 * Y-axis has a repeating pspan. Our approach is to try to 1540 * match the multi-pspan repeatedly against strokes. The 1541 * difference between the number of X and Y pspans gives us a 1542 * crude repeat_count for matching multi-pspans--i.e. the 1543 * multi-pspan along the Y axis (above) has a repeat_count of 1. 1544 */ 1545 repeat_count = abs(n_xpspans - n_ypspans); 1546 1547 fg_match_strokes_against_pspans(sc, X, pspans_x, n_xpspans, 1548 (((repeat_count != 0) && ((n_xpspans < n_ypspans))) ? 1549 repeat_count : 0)); 1550 fg_match_strokes_against_pspans(sc, Y, pspans_y, n_ypspans, 1551 (((repeat_count != 0) && (n_ypspans < n_xpspans)) ? 1552 repeat_count : 0)); 1553 1554 /* Update the state of strokes based on the above pspan matches. */ 1555 TAILQ_FOREACH_SAFE(strokep, &sc->sc_stroke_used, entry, strokep_next) { 1556 1557 if (strokep->components[X].matched && 1558 strokep->components[Y].matched) { 1559 strokep->matched = true; 1560 strokep->instantaneous_dx = 1561 strokep->components[X].delta_mickeys; 1562 strokep->instantaneous_dy = 1563 strokep->components[Y].delta_mickeys; 1564 atp_advance_stroke_state(sc, strokep, &movement); 1565 } else { 1566 /* 1567 * At least one component of this stroke 1568 * didn't match against current pspans; 1569 * terminate it. 1570 */ 1571 atp_terminate_stroke(sc, strokep); 1572 } 1573 } 1574 1575 /* Add new strokes for pairs of unmatched pspans */ 1576 for (i = 0; i < n_xpspans; i++) { 1577 if (pspans_x[i].matched == false) break; 1578 } 1579 for (j = 0; j < n_ypspans; j++) { 1580 if (pspans_y[j].matched == false) break; 1581 } 1582 if ((i < n_xpspans) && (j < n_ypspans)) { 1583 #ifdef USB_DEBUG 1584 if (atp_debug >= ATP_LLEVEL_INFO) { 1585 printf("unmatched pspans:"); 1586 for (; i < n_xpspans; i++) { 1587 if (pspans_x[i].matched) 1588 continue; 1589 printf(" X:[loc:%u,cum:%u]", 1590 pspans_x[i].loc, pspans_x[i].cum); 1591 } 1592 for (; j < n_ypspans; j++) { 1593 if (pspans_y[j].matched) 1594 continue; 1595 printf(" Y:[loc:%u,cum:%u]", 1596 pspans_y[j].loc, pspans_y[j].cum); 1597 } 1598 printf("\n"); 1599 } 1600 #endif /* USB_DEBUG */ 1601 if ((n_xpspans == 1) && (n_ypspans == 1)) 1602 /* The common case of a single pair of new pspans. */ 1603 fg_add_stroke(sc, &pspans_x[0], &pspans_y[0]); 1604 else 1605 fg_add_new_strokes(sc, pspans_x, n_xpspans, 1606 pspans_y, n_ypspans); 1607 } 1608 1609 #ifdef USB_DEBUG 1610 if (atp_debug >= ATP_LLEVEL_INFO) { 1611 TAILQ_FOREACH(strokep, &sc->sc_stroke_used, entry) { 1612 printf(" %s%clc:%u,dm:%d,cum:%d,max:%d,%c" 1613 ",%clc:%u,dm:%d,cum:%d,max:%d,%c", 1614 (strokep->flags & ATSF_ZOMBIE) ? "zomb:" : "", 1615 (strokep->type == ATP_STROKE_TOUCH) ? '[' : '<', 1616 strokep->components[X].loc, 1617 strokep->components[X].delta_mickeys, 1618 strokep->components[X].cum_pressure, 1619 strokep->components[X].max_cum_pressure, 1620 (strokep->type == ATP_STROKE_TOUCH) ? ']' : '>', 1621 (strokep->type == ATP_STROKE_TOUCH) ? '[' : '<', 1622 strokep->components[Y].loc, 1623 strokep->components[Y].delta_mickeys, 1624 strokep->components[Y].cum_pressure, 1625 strokep->components[Y].max_cum_pressure, 1626 (strokep->type == ATP_STROKE_TOUCH) ? ']' : '>'); 1627 } 1628 if (TAILQ_FIRST(&sc->sc_stroke_used) != NULL) 1629 printf("\n"); 1630 } 1631 #endif /* USB_DEBUG */ 1632 return (movement); 1633 } 1634 1635 /* 1636 * Update strokes by matching against current pressure-spans. 1637 * Return true if any movement is detected. 1638 */ 1639 static boolean_t 1640 wsp_update_strokes(struct atp_softc *sc, wsp_finger_t *fingers, u_int n_fingers) 1641 { 1642 boolean_t movement = false; 1643 atp_stroke_t *strokep_next; 1644 atp_stroke_t *strokep; 1645 u_int i; 1646 1647 if (sc->sc_n_strokes > 0) { 1648 movement = wsp_match_strokes_against_fingers( 1649 sc, fingers, n_fingers); 1650 1651 /* handle zombie strokes */ 1652 TAILQ_FOREACH_SAFE(strokep, &sc->sc_stroke_used, entry, strokep_next) { 1653 if (strokep->matched) 1654 continue; 1655 atp_terminate_stroke(sc, strokep); 1656 } 1657 } 1658 1659 /* initialize unmatched fingers as strokes */ 1660 for (i = 0; i != n_fingers; i++) { 1661 if (fingers[i].matched) 1662 continue; 1663 1664 wsp_add_stroke(sc, fingers + i); 1665 } 1666 return (movement); 1667 } 1668 1669 /* Initialize a stroke using a pressure-span. */ 1670 static void 1671 fg_add_stroke(struct atp_softc *sc, const fg_pspan *pspan_x, 1672 const fg_pspan *pspan_y) 1673 { 1674 atp_stroke_t *strokep; 1675 1676 strokep = atp_alloc_stroke(sc); 1677 if (strokep == NULL) 1678 return; 1679 1680 /* 1681 * Strokes begin as potential touches. If a stroke survives 1682 * longer than a threshold, or if it records significant 1683 * cumulative movement, then it is considered a 'slide'. 1684 */ 1685 strokep->type = ATP_STROKE_TOUCH; 1686 strokep->matched = false; 1687 microtime(&strokep->ctime); 1688 strokep->age = 1; /* number of interrupts */ 1689 strokep->x = pspan_x->loc; 1690 strokep->y = pspan_y->loc; 1691 1692 strokep->components[X].loc = pspan_x->loc; 1693 strokep->components[X].cum_pressure = pspan_x->cum; 1694 strokep->components[X].max_cum_pressure = pspan_x->cum; 1695 strokep->components[X].matched = true; 1696 1697 strokep->components[Y].loc = pspan_y->loc; 1698 strokep->components[Y].cum_pressure = pspan_y->cum; 1699 strokep->components[Y].max_cum_pressure = pspan_y->cum; 1700 strokep->components[Y].matched = true; 1701 1702 if (sc->sc_n_strokes > 1) { 1703 /* Reset double-tap-n-drag if we have more than one strokes. */ 1704 sc->sc_state &= ~ATP_DOUBLE_TAP_DRAG; 1705 } 1706 1707 DPRINTFN(ATP_LLEVEL_INFO, "[%u,%u], time: %u,%ld\n", 1708 strokep->components[X].loc, 1709 strokep->components[Y].loc, 1710 (u_int)strokep->ctime.tv_sec, 1711 (unsigned long int)strokep->ctime.tv_usec); 1712 } 1713 1714 static void 1715 fg_add_new_strokes(struct atp_softc *sc, fg_pspan *pspans_x, 1716 u_int n_xpspans, fg_pspan *pspans_y, u_int n_ypspans) 1717 { 1718 fg_pspan spans[2][FG_MAX_PSPANS_PER_AXIS]; 1719 u_int nspans[2]; 1720 u_int i; 1721 u_int j; 1722 1723 /* Copy unmatched pspans into the local arrays. */ 1724 for (i = 0, nspans[X] = 0; i < n_xpspans; i++) { 1725 if (pspans_x[i].matched == false) { 1726 spans[X][nspans[X]] = pspans_x[i]; 1727 nspans[X]++; 1728 } 1729 } 1730 for (j = 0, nspans[Y] = 0; j < n_ypspans; j++) { 1731 if (pspans_y[j].matched == false) { 1732 spans[Y][nspans[Y]] = pspans_y[j]; 1733 nspans[Y]++; 1734 } 1735 } 1736 1737 if (nspans[X] == nspans[Y]) { 1738 /* Create new strokes from pairs of unmatched pspans */ 1739 for (i = 0, j = 0; (i < nspans[X]) && (j < nspans[Y]); i++, j++) 1740 fg_add_stroke(sc, &spans[X][i], &spans[Y][j]); 1741 } else { 1742 u_int cum = 0; 1743 atp_axis repeat_axis; /* axis with multi-pspans */ 1744 u_int repeat_count; /* repeat count for the multi-pspan*/ 1745 u_int repeat_index = 0; /* index of the multi-span */ 1746 1747 repeat_axis = (nspans[X] > nspans[Y]) ? Y : X; 1748 repeat_count = abs(nspans[X] - nspans[Y]); 1749 for (i = 0; i < nspans[repeat_axis]; i++) { 1750 if (spans[repeat_axis][i].cum > cum) { 1751 repeat_index = i; 1752 cum = spans[repeat_axis][i].cum; 1753 } 1754 } 1755 1756 /* Create new strokes from pairs of unmatched pspans */ 1757 i = 0, j = 0; 1758 for (; (i < nspans[X]) && (j < nspans[Y]); i++, j++) { 1759 fg_add_stroke(sc, &spans[X][i], &spans[Y][j]); 1760 1761 /* Take care to repeat at the multi-pspan. */ 1762 if (repeat_count > 0) { 1763 if ((repeat_axis == X) && 1764 (repeat_index == i)) { 1765 i--; /* counter loop increment */ 1766 repeat_count--; 1767 } else if ((repeat_axis == Y) && 1768 (repeat_index == j)) { 1769 j--; /* counter loop increment */ 1770 repeat_count--; 1771 } 1772 } 1773 } 1774 } 1775 } 1776 1777 /* Initialize a stroke from an unmatched finger. */ 1778 static void 1779 wsp_add_stroke(struct atp_softc *sc, const wsp_finger_t *fingerp) 1780 { 1781 atp_stroke_t *strokep; 1782 1783 strokep = atp_alloc_stroke(sc); 1784 if (strokep == NULL) 1785 return; 1786 1787 /* 1788 * Strokes begin as potential touches. If a stroke survives 1789 * longer than a threshold, or if it records significant 1790 * cumulative movement, then it is considered a 'slide'. 1791 */ 1792 strokep->type = ATP_STROKE_TOUCH; 1793 strokep->matched = true; 1794 microtime(&strokep->ctime); 1795 strokep->age = 1; /* number of interrupts */ 1796 strokep->x = fingerp->x; 1797 strokep->y = fingerp->y; 1798 1799 /* Reset double-tap-n-drag if we have more than one strokes. */ 1800 if (sc->sc_n_strokes > 1) 1801 sc->sc_state &= ~ATP_DOUBLE_TAP_DRAG; 1802 1803 DPRINTFN(ATP_LLEVEL_INFO, "[%d,%d]\n", strokep->x, strokep->y); 1804 } 1805 1806 static void 1807 atp_advance_stroke_state(struct atp_softc *sc, atp_stroke_t *strokep, 1808 boolean_t *movementp) 1809 { 1810 /* Revitalize stroke if it had previously been marked as a zombie. */ 1811 if (strokep->flags & ATSF_ZOMBIE) 1812 strokep->flags &= ~ATSF_ZOMBIE; 1813 1814 strokep->age++; 1815 if (strokep->age <= atp_stroke_maturity_threshold) { 1816 /* Avoid noise from immature strokes. */ 1817 strokep->instantaneous_dx = 0; 1818 strokep->instantaneous_dy = 0; 1819 } 1820 1821 if (atp_compute_stroke_movement(strokep)) 1822 *movementp = true; 1823 1824 if (strokep->type != ATP_STROKE_TOUCH) 1825 return; 1826 1827 /* Convert touch strokes to slides upon detecting movement or age. */ 1828 if ((abs(strokep->cum_movement_x) > atp_slide_min_movement) || 1829 (abs(strokep->cum_movement_y) > atp_slide_min_movement)) 1830 atp_convert_to_slide(sc, strokep); 1831 else { 1832 /* Compute the stroke's age. */ 1833 struct timeval tdiff; 1834 getmicrotime(&tdiff); 1835 if (timevalcmp(&tdiff, &strokep->ctime, >)) { 1836 timevalsub(&tdiff, &strokep->ctime); 1837 1838 if ((tdiff.tv_sec > (atp_touch_timeout / 1000000)) || 1839 ((tdiff.tv_sec == (atp_touch_timeout / 1000000)) && 1840 (tdiff.tv_usec >= (atp_touch_timeout % 1000000)))) 1841 atp_convert_to_slide(sc, strokep); 1842 } 1843 } 1844 } 1845 1846 static boolean_t 1847 atp_stroke_has_small_movement(const atp_stroke_t *strokep) 1848 { 1849 return (((u_int)abs(strokep->instantaneous_dx) <= 1850 atp_small_movement_threshold) && 1851 ((u_int)abs(strokep->instantaneous_dy) <= 1852 atp_small_movement_threshold)); 1853 } 1854 1855 /* 1856 * Accumulate instantaneous changes into the stroke's 'pending' bucket; if 1857 * the aggregate exceeds the small_movement_threshold, then retain 1858 * instantaneous changes for later. 1859 */ 1860 static void 1861 atp_update_pending_mickeys(atp_stroke_t *strokep) 1862 { 1863 /* accumulate instantaneous movement */ 1864 strokep->pending_dx += strokep->instantaneous_dx; 1865 strokep->pending_dy += strokep->instantaneous_dy; 1866 1867 #define UPDATE_INSTANTANEOUS_AND_PENDING(I, P) \ 1868 if (abs((P)) <= atp_small_movement_threshold) \ 1869 (I) = 0; /* clobber small movement */ \ 1870 else { \ 1871 if ((I) > 0) { \ 1872 /* \ 1873 * Round up instantaneous movement to the nearest \ 1874 * ceiling. This helps preserve small mickey \ 1875 * movements from being lost in following scaling \ 1876 * operation. \ 1877 */ \ 1878 (I) = (((I) + (atp_mickeys_scale_factor - 1)) / \ 1879 atp_mickeys_scale_factor) * \ 1880 atp_mickeys_scale_factor; \ 1881 \ 1882 /* \ 1883 * Deduct the rounded mickeys from pending mickeys. \ 1884 * Note: we multiply by 2 to offset the previous \ 1885 * accumulation of instantaneous movement into \ 1886 * pending. \ 1887 */ \ 1888 (P) -= ((I) << 1); \ 1889 \ 1890 /* truncate pending to 0 if it becomes negative. */ \ 1891 (P) = imax((P), 0); \ 1892 } else { \ 1893 /* \ 1894 * Round down instantaneous movement to the nearest \ 1895 * ceiling. This helps preserve small mickey \ 1896 * movements from being lost in following scaling \ 1897 * operation. \ 1898 */ \ 1899 (I) = (((I) - (atp_mickeys_scale_factor - 1)) / \ 1900 atp_mickeys_scale_factor) * \ 1901 atp_mickeys_scale_factor; \ 1902 \ 1903 /* \ 1904 * Deduct the rounded mickeys from pending mickeys. \ 1905 * Note: we multiply by 2 to offset the previous \ 1906 * accumulation of instantaneous movement into \ 1907 * pending. \ 1908 */ \ 1909 (P) -= ((I) << 1); \ 1910 \ 1911 /* truncate pending to 0 if it becomes positive. */ \ 1912 (P) = imin((P), 0); \ 1913 } \ 1914 } 1915 1916 UPDATE_INSTANTANEOUS_AND_PENDING(strokep->instantaneous_dx, 1917 strokep->pending_dx); 1918 UPDATE_INSTANTANEOUS_AND_PENDING(strokep->instantaneous_dy, 1919 strokep->pending_dy); 1920 } 1921 1922 /* 1923 * Compute a smoothened value for the stroke's movement from 1924 * instantaneous changes in the X and Y components. 1925 */ 1926 static boolean_t 1927 atp_compute_stroke_movement(atp_stroke_t *strokep) 1928 { 1929 /* 1930 * Short movements are added first to the 'pending' bucket, 1931 * and then acted upon only when their aggregate exceeds a 1932 * threshold. This has the effect of filtering away movement 1933 * noise. 1934 */ 1935 if (atp_stroke_has_small_movement(strokep)) 1936 atp_update_pending_mickeys(strokep); 1937 else { /* large movement */ 1938 /* clear away any pending mickeys if there are large movements*/ 1939 strokep->pending_dx = 0; 1940 strokep->pending_dy = 0; 1941 } 1942 1943 /* scale movement */ 1944 strokep->movement_dx = (strokep->instantaneous_dx) / 1945 (int)atp_mickeys_scale_factor; 1946 strokep->movement_dy = (strokep->instantaneous_dy) / 1947 (int)atp_mickeys_scale_factor; 1948 1949 if ((abs(strokep->instantaneous_dx) >= ATP_FAST_MOVEMENT_TRESHOLD) || 1950 (abs(strokep->instantaneous_dy) >= ATP_FAST_MOVEMENT_TRESHOLD)) { 1951 strokep->movement_dx <<= 1; 1952 strokep->movement_dy <<= 1; 1953 } 1954 1955 strokep->cum_movement_x += strokep->movement_dx; 1956 strokep->cum_movement_y += strokep->movement_dy; 1957 1958 return ((strokep->movement_dx != 0) || (strokep->movement_dy != 0)); 1959 } 1960 1961 /* 1962 * Terminate a stroke. Aside from immature strokes, a slide or touch is 1963 * retained as a zombies so as to reap all their termination siblings 1964 * together; this helps establish the number of fingers involved at the 1965 * end of a multi-touch gesture. 1966 */ 1967 static void 1968 atp_terminate_stroke(struct atp_softc *sc, atp_stroke_t *strokep) 1969 { 1970 if (strokep->flags & ATSF_ZOMBIE) 1971 return; 1972 1973 /* Drop immature strokes rightaway. */ 1974 if (strokep->age <= atp_stroke_maturity_threshold) { 1975 atp_free_stroke(sc, strokep); 1976 return; 1977 } 1978 1979 strokep->flags |= ATSF_ZOMBIE; 1980 sc->sc_state |= ATP_ZOMBIES_EXIST; 1981 1982 callout_reset(&sc->sc_callout, ATP_ZOMBIE_STROKE_REAP_INTERVAL, 1983 atp_reap_sibling_zombies, sc); 1984 1985 /* 1986 * Reset the double-click-n-drag at the termination of any 1987 * slide stroke. 1988 */ 1989 if (strokep->type == ATP_STROKE_SLIDE) 1990 sc->sc_state &= ~ATP_DOUBLE_TAP_DRAG; 1991 } 1992 1993 static boolean_t 1994 atp_is_horizontal_scroll(const atp_stroke_t *strokep) 1995 { 1996 if (abs(strokep->cum_movement_x) < atp_slide_min_movement) 1997 return (false); 1998 if (strokep->cum_movement_y == 0) 1999 return (true); 2000 return (abs(strokep->cum_movement_x / strokep->cum_movement_y) >= 4); 2001 } 2002 2003 static boolean_t 2004 atp_is_vertical_scroll(const atp_stroke_t *strokep) 2005 { 2006 if (abs(strokep->cum_movement_y) < atp_slide_min_movement) 2007 return (false); 2008 if (strokep->cum_movement_x == 0) 2009 return (true); 2010 return (abs(strokep->cum_movement_y / strokep->cum_movement_x) >= 4); 2011 } 2012 2013 static void 2014 atp_reap_sibling_zombies(void *arg) 2015 { 2016 struct atp_softc *sc = (struct atp_softc *)arg; 2017 u_int8_t n_touches_reaped = 0; 2018 u_int8_t n_slides_reaped = 0; 2019 u_int8_t n_horizontal_scrolls = 0; 2020 u_int8_t n_vertical_scrolls = 0; 2021 int horizontal_scroll = 0; 2022 int vertical_scroll = 0; 2023 atp_stroke_t *strokep; 2024 atp_stroke_t *strokep_next; 2025 2026 DPRINTFN(ATP_LLEVEL_INFO, "\n"); 2027 2028 TAILQ_FOREACH_SAFE(strokep, &sc->sc_stroke_used, entry, strokep_next) { 2029 if ((strokep->flags & ATSF_ZOMBIE) == 0) 2030 continue; 2031 2032 if (strokep->type == ATP_STROKE_TOUCH) { 2033 n_touches_reaped++; 2034 } else { 2035 n_slides_reaped++; 2036 2037 if (atp_is_horizontal_scroll(strokep)) { 2038 n_horizontal_scrolls++; 2039 horizontal_scroll += strokep->cum_movement_x; 2040 } else if (atp_is_vertical_scroll(strokep)) { 2041 n_vertical_scrolls++; 2042 vertical_scroll += strokep->cum_movement_y; 2043 } 2044 } 2045 2046 atp_free_stroke(sc, strokep); 2047 } 2048 2049 DPRINTFN(ATP_LLEVEL_INFO, "reaped %u zombies\n", 2050 n_touches_reaped + n_slides_reaped); 2051 sc->sc_state &= ~ATP_ZOMBIES_EXIST; 2052 2053 /* No further processing necessary if physical button is depressed. */ 2054 if (sc->sc_ibtn != 0) 2055 return; 2056 2057 if ((n_touches_reaped == 0) && (n_slides_reaped == 0)) 2058 return; 2059 2060 /* Add a pair of virtual button events (button-down and button-up) if 2061 * the physical button isn't pressed. */ 2062 if (n_touches_reaped != 0) { 2063 if (n_touches_reaped < atp_tap_minimum) 2064 return; 2065 2066 switch (n_touches_reaped) { 2067 case 1: 2068 atp_add_to_queue(sc, 0, 0, 0, MOUSE_BUTTON1DOWN); 2069 microtime(&sc->sc_touch_reap_time); /* remember this time */ 2070 break; 2071 case 2: 2072 atp_add_to_queue(sc, 0, 0, 0, MOUSE_BUTTON3DOWN); 2073 break; 2074 case 3: 2075 atp_add_to_queue(sc, 0, 0, 0, MOUSE_BUTTON2DOWN); 2076 break; 2077 default: 2078 /* we handle taps of only up to 3 fingers */ 2079 return; 2080 } 2081 atp_add_to_queue(sc, 0, 0, 0, 0); /* button release */ 2082 2083 } else if ((n_slides_reaped == 2) && (n_horizontal_scrolls == 2)) { 2084 if (horizontal_scroll < 0) 2085 atp_add_to_queue(sc, 0, 0, 0, MOUSE_BUTTON4DOWN); 2086 else 2087 atp_add_to_queue(sc, 0, 0, 0, MOUSE_BUTTON5DOWN); 2088 atp_add_to_queue(sc, 0, 0, 0, 0); /* button release */ 2089 } 2090 } 2091 2092 /* Switch a given touch stroke to being a slide. */ 2093 static void 2094 atp_convert_to_slide(struct atp_softc *sc, atp_stroke_t *strokep) 2095 { 2096 strokep->type = ATP_STROKE_SLIDE; 2097 2098 /* Are we at the beginning of a double-click-n-drag? */ 2099 if ((sc->sc_n_strokes == 1) && 2100 ((sc->sc_state & ATP_ZOMBIES_EXIST) == 0) && 2101 timevalcmp(&strokep->ctime, &sc->sc_touch_reap_time, >)) { 2102 struct timeval delta; 2103 struct timeval window = { 2104 atp_double_tap_threshold / 1000000, 2105 atp_double_tap_threshold % 1000000 2106 }; 2107 2108 delta = strokep->ctime; 2109 timevalsub(&delta, &sc->sc_touch_reap_time); 2110 if (timevalcmp(&delta, &window, <=)) 2111 sc->sc_state |= ATP_DOUBLE_TAP_DRAG; 2112 } 2113 } 2114 2115 static void 2116 atp_reset_buf(struct atp_softc *sc) 2117 { 2118 /* reset read queue */ 2119 usb_fifo_reset(sc->sc_fifo.fp[USB_FIFO_RX]); 2120 } 2121 2122 static void 2123 atp_add_to_queue(struct atp_softc *sc, int dx, int dy, int dz, 2124 uint32_t buttons_in) 2125 { 2126 uint32_t buttons_out; 2127 uint8_t buf[8]; 2128 2129 dx = imin(dx, 254); dx = imax(dx, -256); 2130 dy = imin(dy, 254); dy = imax(dy, -256); 2131 dz = imin(dz, 126); dz = imax(dz, -128); 2132 2133 buttons_out = MOUSE_MSC_BUTTONS; 2134 if (buttons_in & MOUSE_BUTTON1DOWN) 2135 buttons_out &= ~MOUSE_MSC_BUTTON1UP; 2136 else if (buttons_in & MOUSE_BUTTON2DOWN) 2137 buttons_out &= ~MOUSE_MSC_BUTTON2UP; 2138 else if (buttons_in & MOUSE_BUTTON3DOWN) 2139 buttons_out &= ~MOUSE_MSC_BUTTON3UP; 2140 2141 DPRINTFN(ATP_LLEVEL_INFO, "dx=%d, dy=%d, buttons=%x\n", 2142 dx, dy, buttons_out); 2143 2144 /* Encode the mouse data in standard format; refer to mouse(4) */ 2145 buf[0] = sc->sc_mode.syncmask[1]; 2146 buf[0] |= buttons_out; 2147 buf[1] = dx >> 1; 2148 buf[2] = dy >> 1; 2149 buf[3] = dx - (dx >> 1); 2150 buf[4] = dy - (dy >> 1); 2151 /* Encode extra bytes for level 1 */ 2152 if (sc->sc_mode.level == 1) { 2153 buf[5] = dz >> 1; 2154 buf[6] = dz - (dz >> 1); 2155 buf[7] = (((~buttons_in) >> 3) & MOUSE_SYS_EXTBUTTONS); 2156 } 2157 2158 usb_fifo_put_data_linear(sc->sc_fifo.fp[USB_FIFO_RX], buf, 2159 sc->sc_mode.packetsize, 1); 2160 } 2161 2162 static int 2163 atp_probe(device_t self) 2164 { 2165 struct usb_attach_arg *uaa = device_get_ivars(self); 2166 2167 if (uaa->usb_mode != USB_MODE_HOST) 2168 return (ENXIO); 2169 2170 if (uaa->info.bInterfaceClass != UICLASS_HID) 2171 return (ENXIO); 2172 /* 2173 * Note: for some reason, the check 2174 * (uaa->info.bInterfaceProtocol == UIPROTO_MOUSE) doesn't hold true 2175 * for wellspring trackpads, so we've removed it from the common path. 2176 */ 2177 2178 if ((usbd_lookup_id_by_uaa(fg_devs, sizeof(fg_devs), uaa)) == 0) 2179 return ((uaa->info.bInterfaceProtocol == UIPROTO_MOUSE) ? 2180 0 : ENXIO); 2181 2182 if ((usbd_lookup_id_by_uaa(wsp_devs, sizeof(wsp_devs), uaa)) == 0) 2183 if (uaa->info.bIfaceIndex == WELLSPRING_INTERFACE_INDEX) 2184 return (0); 2185 2186 return (ENXIO); 2187 } 2188 2189 static int 2190 atp_attach(device_t dev) 2191 { 2192 struct atp_softc *sc = device_get_softc(dev); 2193 struct usb_attach_arg *uaa = device_get_ivars(dev); 2194 usb_error_t err; 2195 void *descriptor_ptr = NULL; 2196 uint16_t descriptor_len; 2197 unsigned long di; 2198 2199 DPRINTFN(ATP_LLEVEL_INFO, "sc=%p\n", sc); 2200 2201 sc->sc_dev = dev; 2202 sc->sc_usb_device = uaa->device; 2203 2204 /* Get HID descriptor */ 2205 if (usbd_req_get_hid_desc(uaa->device, NULL, &descriptor_ptr, 2206 &descriptor_len, M_TEMP, uaa->info.bIfaceIndex) != 2207 USB_ERR_NORMAL_COMPLETION) 2208 return (ENXIO); 2209 2210 /* Get HID report descriptor length */ 2211 sc->sc_expected_sensor_data_len = hid_report_size(descriptor_ptr, 2212 descriptor_len, hid_input, NULL); 2213 free(descriptor_ptr, M_TEMP); 2214 2215 if ((sc->sc_expected_sensor_data_len <= 0) || 2216 (sc->sc_expected_sensor_data_len > ATP_SENSOR_DATA_BUF_MAX)) { 2217 DPRINTF("atp_attach: datalength invalid or too large: %d\n", 2218 sc->sc_expected_sensor_data_len); 2219 return (ENXIO); 2220 } 2221 2222 di = USB_GET_DRIVER_INFO(uaa); 2223 sc->sc_family = DECODE_FAMILY_FROM_DRIVER_INFO(di); 2224 2225 /* 2226 * By default the touchpad behaves like an HID device, sending 2227 * packets with reportID = 2. Such reports contain only 2228 * limited information--they encode movement deltas and button 2229 * events,--but do not include data from the pressure 2230 * sensors. The device input mode can be switched from HID 2231 * reports to raw sensor data using vendor-specific USB 2232 * control commands. 2233 * FOUNTAIN devices will give an error when trying to switch 2234 * input mode, so we skip this command 2235 */ 2236 if ((sc->sc_family == TRACKPAD_FAMILY_FOUNTAIN_GEYSER) && 2237 (DECODE_PRODUCT_FROM_DRIVER_INFO(di) == FOUNTAIN)) 2238 DPRINTF("device mode switch skipped: Fountain device\n"); 2239 else if ((err = atp_set_device_mode(sc, RAW_SENSOR_MODE)) != 0) { 2240 DPRINTF("failed to set mode to 'RAW_SENSOR' (%d)\n", err); 2241 return (ENXIO); 2242 } 2243 2244 mtx_init(&sc->sc_mutex, "atpmtx", NULL, MTX_DEF | MTX_RECURSE); 2245 2246 switch(sc->sc_family) { 2247 case TRACKPAD_FAMILY_FOUNTAIN_GEYSER: 2248 sc->sc_params = 2249 &fg_dev_params[DECODE_PRODUCT_FROM_DRIVER_INFO(di)]; 2250 sc->sensor_data_interpreter = fg_interpret_sensor_data; 2251 break; 2252 case TRACKPAD_FAMILY_WELLSPRING: 2253 sc->sc_params = 2254 &wsp_dev_params[DECODE_PRODUCT_FROM_DRIVER_INFO(di)]; 2255 sc->sensor_data_interpreter = wsp_interpret_sensor_data; 2256 break; 2257 default: 2258 goto detach; 2259 } 2260 2261 err = usbd_transfer_setup(uaa->device, 2262 &uaa->info.bIfaceIndex, sc->sc_xfer, atp_xfer_config, 2263 ATP_N_TRANSFER, sc, &sc->sc_mutex); 2264 if (err) { 2265 DPRINTF("error=%s\n", usbd_errstr(err)); 2266 goto detach; 2267 } 2268 2269 if (usb_fifo_attach(sc->sc_usb_device, sc, &sc->sc_mutex, 2270 &atp_fifo_methods, &sc->sc_fifo, 2271 device_get_unit(dev), -1, uaa->info.bIfaceIndex, 2272 UID_ROOT, GID_OPERATOR, 0644)) { 2273 goto detach; 2274 } 2275 2276 device_set_usb_desc(dev); 2277 2278 sc->sc_hw.buttons = 3; 2279 sc->sc_hw.iftype = MOUSE_IF_USB; 2280 sc->sc_hw.type = MOUSE_PAD; 2281 sc->sc_hw.model = MOUSE_MODEL_GENERIC; 2282 sc->sc_hw.hwid = 0; 2283 sc->sc_mode.protocol = MOUSE_PROTO_MSC; 2284 sc->sc_mode.rate = -1; 2285 sc->sc_mode.resolution = MOUSE_RES_UNKNOWN; 2286 sc->sc_mode.packetsize = MOUSE_MSC_PACKETSIZE; 2287 sc->sc_mode.syncmask[0] = MOUSE_MSC_SYNCMASK; 2288 sc->sc_mode.syncmask[1] = MOUSE_MSC_SYNC; 2289 sc->sc_mode.accelfactor = 0; 2290 sc->sc_mode.level = 0; 2291 2292 sc->sc_state = 0; 2293 sc->sc_ibtn = 0; 2294 2295 callout_init_mtx(&sc->sc_callout, &sc->sc_mutex, 0); 2296 2297 return (0); 2298 2299 detach: 2300 atp_detach(dev); 2301 return (ENOMEM); 2302 } 2303 2304 static int 2305 atp_detach(device_t dev) 2306 { 2307 struct atp_softc *sc; 2308 2309 sc = device_get_softc(dev); 2310 atp_set_device_mode(sc, HID_MODE); 2311 2312 mtx_lock(&sc->sc_mutex); 2313 callout_drain(&sc->sc_callout); 2314 if (sc->sc_state & ATP_ENABLED) 2315 atp_disable(sc); 2316 mtx_unlock(&sc->sc_mutex); 2317 2318 usb_fifo_detach(&sc->sc_fifo); 2319 2320 usbd_transfer_unsetup(sc->sc_xfer, ATP_N_TRANSFER); 2321 2322 mtx_destroy(&sc->sc_mutex); 2323 2324 return (0); 2325 } 2326 2327 static void 2328 atp_intr(struct usb_xfer *xfer, usb_error_t error) 2329 { 2330 struct atp_softc *sc = usbd_xfer_softc(xfer); 2331 struct usb_page_cache *pc; 2332 int len; 2333 2334 usbd_xfer_status(xfer, &len, NULL, NULL, NULL); 2335 2336 switch (USB_GET_STATE(xfer)) { 2337 case USB_ST_TRANSFERRED: 2338 pc = usbd_xfer_get_frame(xfer, 0); 2339 usbd_copy_out(pc, 0, sc->sc_sensor_data, len); 2340 if (len < sc->sc_expected_sensor_data_len) { 2341 /* make sure we don't process old data */ 2342 memset(sc->sc_sensor_data + len, 0, 2343 sc->sc_expected_sensor_data_len - len); 2344 } 2345 2346 sc->sc_status.flags &= ~(MOUSE_STDBUTTONSCHANGED | 2347 MOUSE_POSCHANGED); 2348 sc->sc_status.obutton = sc->sc_status.button; 2349 2350 (sc->sensor_data_interpreter)(sc, len); 2351 2352 if (sc->sc_status.button != 0) { 2353 /* Reset DOUBLE_TAP_N_DRAG if the button is pressed. */ 2354 sc->sc_state &= ~ATP_DOUBLE_TAP_DRAG; 2355 } else if (sc->sc_state & ATP_DOUBLE_TAP_DRAG) { 2356 /* Assume a button-press with DOUBLE_TAP_N_DRAG. */ 2357 sc->sc_status.button = MOUSE_BUTTON1DOWN; 2358 } 2359 2360 sc->sc_status.flags |= 2361 sc->sc_status.button ^ sc->sc_status.obutton; 2362 if (sc->sc_status.flags & MOUSE_STDBUTTONSCHANGED) { 2363 DPRINTFN(ATP_LLEVEL_INFO, "button %s\n", 2364 ((sc->sc_status.button & MOUSE_BUTTON1DOWN) ? 2365 "pressed" : "released")); 2366 } 2367 2368 if (sc->sc_status.flags & (MOUSE_POSCHANGED | 2369 MOUSE_STDBUTTONSCHANGED)) { 2370 2371 atp_stroke_t *strokep; 2372 u_int8_t n_movements = 0; 2373 int dx = 0; 2374 int dy = 0; 2375 int dz = 0; 2376 2377 TAILQ_FOREACH(strokep, &sc->sc_stroke_used, entry) { 2378 if (strokep->flags & ATSF_ZOMBIE) 2379 continue; 2380 2381 dx += strokep->movement_dx; 2382 dy += strokep->movement_dy; 2383 if (strokep->movement_dx || 2384 strokep->movement_dy) 2385 n_movements++; 2386 } 2387 2388 /* average movement if multiple strokes record motion.*/ 2389 if (n_movements > 1) { 2390 dx /= (int)n_movements; 2391 dy /= (int)n_movements; 2392 } 2393 2394 /* detect multi-finger vertical scrolls */ 2395 if (n_movements >= 2) { 2396 boolean_t all_vertical_scrolls = true; 2397 TAILQ_FOREACH(strokep, &sc->sc_stroke_used, entry) { 2398 if (strokep->flags & ATSF_ZOMBIE) 2399 continue; 2400 2401 if (!atp_is_vertical_scroll(strokep)) 2402 all_vertical_scrolls = false; 2403 } 2404 if (all_vertical_scrolls) { 2405 dz = dy; 2406 dy = dx = 0; 2407 } 2408 } 2409 2410 sc->sc_status.dx += dx; 2411 sc->sc_status.dy += dy; 2412 sc->sc_status.dz += dz; 2413 atp_add_to_queue(sc, dx, -dy, -dz, sc->sc_status.button); 2414 } 2415 2416 case USB_ST_SETUP: 2417 tr_setup: 2418 /* check if we can put more data into the FIFO */ 2419 if (usb_fifo_put_bytes_max(sc->sc_fifo.fp[USB_FIFO_RX]) != 0) { 2420 usbd_xfer_set_frame_len(xfer, 0, 2421 sc->sc_expected_sensor_data_len); 2422 usbd_transfer_submit(xfer); 2423 } 2424 break; 2425 2426 default: /* Error */ 2427 if (error != USB_ERR_CANCELLED) { 2428 /* try clear stall first */ 2429 usbd_xfer_set_stall(xfer); 2430 goto tr_setup; 2431 } 2432 break; 2433 } 2434 } 2435 2436 static void 2437 atp_start_read(struct usb_fifo *fifo) 2438 { 2439 struct atp_softc *sc = usb_fifo_softc(fifo); 2440 int rate; 2441 2442 /* Check if we should override the default polling interval */ 2443 rate = sc->sc_pollrate; 2444 /* Range check rate */ 2445 if (rate > 1000) 2446 rate = 1000; 2447 /* Check for set rate */ 2448 if ((rate > 0) && (sc->sc_xfer[ATP_INTR_DT] != NULL)) { 2449 /* Stop current transfer, if any */ 2450 usbd_transfer_stop(sc->sc_xfer[ATP_INTR_DT]); 2451 /* Set new interval */ 2452 usbd_xfer_set_interval(sc->sc_xfer[ATP_INTR_DT], 1000 / rate); 2453 /* Only set pollrate once */ 2454 sc->sc_pollrate = 0; 2455 } 2456 2457 usbd_transfer_start(sc->sc_xfer[ATP_INTR_DT]); 2458 } 2459 2460 static void 2461 atp_stop_read(struct usb_fifo *fifo) 2462 { 2463 struct atp_softc *sc = usb_fifo_softc(fifo); 2464 usbd_transfer_stop(sc->sc_xfer[ATP_INTR_DT]); 2465 } 2466 2467 static int 2468 atp_open(struct usb_fifo *fifo, int fflags) 2469 { 2470 struct atp_softc *sc = usb_fifo_softc(fifo); 2471 2472 /* check for duplicate open, should not happen */ 2473 if (sc->sc_fflags & fflags) 2474 return (EBUSY); 2475 2476 /* check for first open */ 2477 if (sc->sc_fflags == 0) { 2478 int rc; 2479 if ((rc = atp_enable(sc)) != 0) 2480 return (rc); 2481 } 2482 2483 if (fflags & FREAD) { 2484 if (usb_fifo_alloc_buffer(fifo, 2485 ATP_FIFO_BUF_SIZE, ATP_FIFO_QUEUE_MAXLEN)) { 2486 return (ENOMEM); 2487 } 2488 } 2489 2490 sc->sc_fflags |= (fflags & (FREAD | FWRITE)); 2491 return (0); 2492 } 2493 2494 static void 2495 atp_close(struct usb_fifo *fifo, int fflags) 2496 { 2497 struct atp_softc *sc = usb_fifo_softc(fifo); 2498 if (fflags & FREAD) 2499 usb_fifo_free_buffer(fifo); 2500 2501 sc->sc_fflags &= ~(fflags & (FREAD | FWRITE)); 2502 if (sc->sc_fflags == 0) { 2503 atp_disable(sc); 2504 } 2505 } 2506 2507 static int 2508 atp_ioctl(struct usb_fifo *fifo, u_long cmd, void *addr, int fflags) 2509 { 2510 struct atp_softc *sc = usb_fifo_softc(fifo); 2511 mousemode_t mode; 2512 int error = 0; 2513 2514 mtx_lock(&sc->sc_mutex); 2515 2516 switch(cmd) { 2517 case MOUSE_GETHWINFO: 2518 *(mousehw_t *)addr = sc->sc_hw; 2519 break; 2520 case MOUSE_GETMODE: 2521 *(mousemode_t *)addr = sc->sc_mode; 2522 break; 2523 case MOUSE_SETMODE: 2524 mode = *(mousemode_t *)addr; 2525 2526 if (mode.level == -1) 2527 /* Don't change the current setting */ 2528 ; 2529 else if ((mode.level < 0) || (mode.level > 1)) { 2530 error = EINVAL; 2531 break; 2532 } 2533 sc->sc_mode.level = mode.level; 2534 sc->sc_pollrate = mode.rate; 2535 sc->sc_hw.buttons = 3; 2536 2537 if (sc->sc_mode.level == 0) { 2538 sc->sc_mode.protocol = MOUSE_PROTO_MSC; 2539 sc->sc_mode.packetsize = MOUSE_MSC_PACKETSIZE; 2540 sc->sc_mode.syncmask[0] = MOUSE_MSC_SYNCMASK; 2541 sc->sc_mode.syncmask[1] = MOUSE_MSC_SYNC; 2542 } else if (sc->sc_mode.level == 1) { 2543 sc->sc_mode.protocol = MOUSE_PROTO_SYSMOUSE; 2544 sc->sc_mode.packetsize = MOUSE_SYS_PACKETSIZE; 2545 sc->sc_mode.syncmask[0] = MOUSE_SYS_SYNCMASK; 2546 sc->sc_mode.syncmask[1] = MOUSE_SYS_SYNC; 2547 } 2548 atp_reset_buf(sc); 2549 break; 2550 case MOUSE_GETLEVEL: 2551 *(int *)addr = sc->sc_mode.level; 2552 break; 2553 case MOUSE_SETLEVEL: 2554 if ((*(int *)addr < 0) || (*(int *)addr > 1)) { 2555 error = EINVAL; 2556 break; 2557 } 2558 sc->sc_mode.level = *(int *)addr; 2559 sc->sc_hw.buttons = 3; 2560 2561 if (sc->sc_mode.level == 0) { 2562 sc->sc_mode.protocol = MOUSE_PROTO_MSC; 2563 sc->sc_mode.packetsize = MOUSE_MSC_PACKETSIZE; 2564 sc->sc_mode.syncmask[0] = MOUSE_MSC_SYNCMASK; 2565 sc->sc_mode.syncmask[1] = MOUSE_MSC_SYNC; 2566 } else if (sc->sc_mode.level == 1) { 2567 sc->sc_mode.protocol = MOUSE_PROTO_SYSMOUSE; 2568 sc->sc_mode.packetsize = MOUSE_SYS_PACKETSIZE; 2569 sc->sc_mode.syncmask[0] = MOUSE_SYS_SYNCMASK; 2570 sc->sc_mode.syncmask[1] = MOUSE_SYS_SYNC; 2571 } 2572 atp_reset_buf(sc); 2573 break; 2574 case MOUSE_GETSTATUS: { 2575 mousestatus_t *status = (mousestatus_t *)addr; 2576 2577 *status = sc->sc_status; 2578 sc->sc_status.obutton = sc->sc_status.button; 2579 sc->sc_status.button = 0; 2580 sc->sc_status.dx = 0; 2581 sc->sc_status.dy = 0; 2582 sc->sc_status.dz = 0; 2583 2584 if (status->dx || status->dy || status->dz) 2585 status->flags |= MOUSE_POSCHANGED; 2586 if (status->button != status->obutton) 2587 status->flags |= MOUSE_BUTTONSCHANGED; 2588 break; 2589 } 2590 2591 default: 2592 error = ENOTTY; 2593 break; 2594 } 2595 2596 mtx_unlock(&sc->sc_mutex); 2597 return (error); 2598 } 2599 2600 static int 2601 atp_sysctl_scale_factor_handler(SYSCTL_HANDLER_ARGS) 2602 { 2603 int error; 2604 u_int tmp; 2605 2606 tmp = atp_mickeys_scale_factor; 2607 error = sysctl_handle_int(oidp, &tmp, 0, req); 2608 if (error != 0 || req->newptr == NULL) 2609 return (error); 2610 2611 if (tmp == atp_mickeys_scale_factor) 2612 return (0); /* no change */ 2613 if ((tmp == 0) || (tmp > (10 * ATP_SCALE_FACTOR))) 2614 return (EINVAL); 2615 2616 atp_mickeys_scale_factor = tmp; 2617 DPRINTFN(ATP_LLEVEL_INFO, "%s: resetting mickeys_scale_factor to %u\n", 2618 ATP_DRIVER_NAME, tmp); 2619 2620 return (0); 2621 } 2622 2623 static devclass_t atp_devclass; 2624 2625 static device_method_t atp_methods[] = { 2626 DEVMETHOD(device_probe, atp_probe), 2627 DEVMETHOD(device_attach, atp_attach), 2628 DEVMETHOD(device_detach, atp_detach), 2629 2630 DEVMETHOD_END 2631 }; 2632 2633 static driver_t atp_driver = { 2634 .name = ATP_DRIVER_NAME, 2635 .methods = atp_methods, 2636 .size = sizeof(struct atp_softc) 2637 }; 2638 2639 DRIVER_MODULE(atp, uhub, atp_driver, atp_devclass, NULL, 0); 2640 MODULE_DEPEND(atp, usb, 1, 1, 1); 2641 MODULE_VERSION(atp, 1); 2642 USB_PNP_HOST_INFO(fg_devs); 2643 USB_PNP_HOST_INFO(wsp_devs); 2644