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