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