1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2014 Rohit Grover 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 /* 30 * Some tables, structures, definitions and constant values for the 31 * touchpad protocol has been copied from Linux's 32 * "drivers/input/mouse/bcm5974.c" which has the following copyright 33 * holders under GPLv2. All device specific code in this driver has 34 * been written from scratch. The decoding algorithm is based on 35 * output from FreeBSD's usbdump. 36 * 37 * Copyright (C) 2008 Henrik Rydberg (rydberg@euromail.se) 38 * Copyright (C) 2008 Scott Shawcroft (scott.shawcroft@gmail.com) 39 * Copyright (C) 2001-2004 Greg Kroah-Hartman (greg@kroah.com) 40 * Copyright (C) 2005 Johannes Berg (johannes@sipsolutions.net) 41 * Copyright (C) 2005 Stelian Pop (stelian@popies.net) 42 * Copyright (C) 2005 Frank Arnold (frank@scirocco-5v-turbo.de) 43 * Copyright (C) 2005 Peter Osterlund (petero2@telia.com) 44 * Copyright (C) 2005 Michael Hanselmann (linux-kernel@hansmi.ch) 45 * Copyright (C) 2006 Nicolas Boichat (nicolas@boichat.ch) 46 */ 47 48 /* 49 * Author's note: 'atp' supports two distinct families of Apple trackpad 50 * products: the older Fountain/Geyser and the latest Wellspring trackpads. 51 * The first version made its appearance with FreeBSD 8 and worked only with 52 * the Fountain/Geyser hardware. A fork of this driver for Wellspring was 53 * contributed by Huang Wen Hui. This driver unifies the Wellspring effort 54 * and also improves upon the original work. 55 * 56 * I'm grateful to Stephan Scheunig, Angela Naegele, and Nokia IT-support 57 * for helping me with access to hardware. Thanks also go to Nokia for 58 * giving me an opportunity to do this work. 59 */ 60 61 #include <sys/cdefs.h> 62 #include <sys/stdint.h> 63 #include <sys/stddef.h> 64 #include <sys/param.h> 65 #include <sys/types.h> 66 #include <sys/systm.h> 67 #include <sys/kernel.h> 68 #include <sys/bus.h> 69 #include <sys/module.h> 70 #include <sys/lock.h> 71 #include <sys/mutex.h> 72 #include <sys/sysctl.h> 73 #include <sys/malloc.h> 74 #include <sys/conf.h> 75 #include <sys/fcntl.h> 76 #include <sys/file.h> 77 #include <sys/selinfo.h> 78 #include <sys/poll.h> 79 80 #include <dev/hid/hid.h> 81 82 #include <dev/usb/usb.h> 83 #include <dev/usb/usbdi.h> 84 #include <dev/usb/usbdi_util.h> 85 #include <dev/usb/usbhid.h> 86 87 #include "usbdevs.h" 88 89 #define USB_DEBUG_VAR atp_debug 90 #include <dev/usb/usb_debug.h> 91 92 #include <sys/mouse.h> 93 94 #define ATP_DRIVER_NAME "atp" 95 96 /* 97 * Driver specific options: the following options may be set by 98 * `options' statements in the kernel configuration file. 99 */ 100 101 /* The divisor used to translate sensor reported positions to mickeys. */ 102 #ifndef ATP_SCALE_FACTOR 103 #define ATP_SCALE_FACTOR 16 104 #endif 105 106 /* Threshold for small movement noise (in mickeys) */ 107 #ifndef ATP_SMALL_MOVEMENT_THRESHOLD 108 #define ATP_SMALL_MOVEMENT_THRESHOLD 30 109 #endif 110 111 /* Threshold of instantaneous deltas beyond which movement is considered fast.*/ 112 #ifndef ATP_FAST_MOVEMENT_TRESHOLD 113 #define ATP_FAST_MOVEMENT_TRESHOLD 150 114 #endif 115 116 /* 117 * This is the age in microseconds beyond which a touch is considered 118 * to be a slide; and therefore a tap event isn't registered. 119 */ 120 #ifndef ATP_TOUCH_TIMEOUT 121 #define ATP_TOUCH_TIMEOUT 125000 122 #endif 123 124 #ifndef ATP_IDLENESS_THRESHOLD 125 #define ATP_IDLENESS_THRESHOLD 10 126 #endif 127 128 #ifndef FG_SENSOR_NOISE_THRESHOLD 129 #define FG_SENSOR_NOISE_THRESHOLD 2 130 #endif 131 132 /* 133 * A double-tap followed by a single-finger slide is treated as a 134 * special gesture. The driver responds to this gesture by assuming a 135 * virtual button-press for the lifetime of the slide. The following 136 * threshold is the maximum time gap (in microseconds) between the two 137 * tap events preceding the slide for such a gesture. 138 */ 139 #ifndef ATP_DOUBLE_TAP_N_DRAG_THRESHOLD 140 #define ATP_DOUBLE_TAP_N_DRAG_THRESHOLD 200000 141 #endif 142 143 /* 144 * The wait duration in ticks after losing a touch contact before 145 * zombied strokes are reaped and turned into button events. 146 */ 147 #define ATP_ZOMBIE_STROKE_REAP_INTERVAL (hz / 20) /* 50 ms */ 148 149 /* The multiplier used to translate sensor reported positions to mickeys. */ 150 #define FG_SCALE_FACTOR 380 151 152 /* 153 * The movement threshold for a stroke; this is the maximum difference 154 * in position which will be resolved as a continuation of a stroke 155 * component. 156 */ 157 #define FG_MAX_DELTA_MICKEYS ((3 * (FG_SCALE_FACTOR)) >> 1) 158 159 /* Distance-squared threshold for matching a finger with a known stroke */ 160 #ifndef WSP_MAX_ALLOWED_MATCH_DISTANCE_SQ 161 #define WSP_MAX_ALLOWED_MATCH_DISTANCE_SQ 1000000 162 #endif 163 164 /* Ignore pressure spans with cumulative press. below this value. */ 165 #define FG_PSPAN_MIN_CUM_PRESSURE 10 166 167 /* Maximum allowed width for pressure-spans.*/ 168 #define FG_PSPAN_MAX_WIDTH 4 169 170 /* end of driver specific options */ 171 172 /* Tunables */ 173 static SYSCTL_NODE(_hw_usb, OID_AUTO, atp, CTLFLAG_RW | CTLFLAG_MPSAFE, 0, 174 "USB ATP"); 175 176 #ifdef USB_DEBUG 177 enum atp_log_level { 178 ATP_LLEVEL_DISABLED = 0, 179 ATP_LLEVEL_ERROR, 180 ATP_LLEVEL_DEBUG, /* for troubleshooting */ 181 ATP_LLEVEL_INFO, /* for diagnostics */ 182 }; 183 static int atp_debug = ATP_LLEVEL_ERROR; /* the default is to only log errors */ 184 SYSCTL_INT(_hw_usb_atp, OID_AUTO, debug, CTLFLAG_RWTUN, 185 &atp_debug, ATP_LLEVEL_ERROR, "ATP debug level"); 186 #endif /* USB_DEBUG */ 187 188 static u_int atp_touch_timeout = ATP_TOUCH_TIMEOUT; 189 SYSCTL_UINT(_hw_usb_atp, OID_AUTO, touch_timeout, CTLFLAG_RWTUN, 190 &atp_touch_timeout, 125000, "age threshold in microseconds for a touch"); 191 192 static u_int atp_double_tap_threshold = ATP_DOUBLE_TAP_N_DRAG_THRESHOLD; 193 SYSCTL_UINT(_hw_usb_atp, OID_AUTO, double_tap_threshold, CTLFLAG_RWTUN, 194 &atp_double_tap_threshold, ATP_DOUBLE_TAP_N_DRAG_THRESHOLD, 195 "maximum time in microseconds to allow association between a double-tap and " 196 "drag gesture"); 197 198 static u_int atp_mickeys_scale_factor = ATP_SCALE_FACTOR; 199 static int atp_sysctl_scale_factor_handler(SYSCTL_HANDLER_ARGS); 200 SYSCTL_PROC(_hw_usb_atp, OID_AUTO, scale_factor, 201 CTLTYPE_UINT | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, 202 &atp_mickeys_scale_factor, sizeof(atp_mickeys_scale_factor), 203 atp_sysctl_scale_factor_handler, "IU", 204 "movement scale factor"); 205 206 static u_int atp_small_movement_threshold = ATP_SMALL_MOVEMENT_THRESHOLD; 207 SYSCTL_UINT(_hw_usb_atp, OID_AUTO, small_movement, CTLFLAG_RWTUN, 208 &atp_small_movement_threshold, ATP_SMALL_MOVEMENT_THRESHOLD, 209 "the small movement black-hole for filtering noise"); 210 211 static u_int atp_tap_minimum = 1; 212 SYSCTL_UINT(_hw_usb_atp, OID_AUTO, tap_minimum, CTLFLAG_RWTUN, 213 &atp_tap_minimum, 1, "Minimum number of taps before detection"); 214 215 /* 216 * Strokes which accumulate at least this amount of absolute movement 217 * from the aggregate of their components are considered as 218 * slides. Unit: mickeys. 219 */ 220 static u_int atp_slide_min_movement = 2 * ATP_SMALL_MOVEMENT_THRESHOLD; 221 SYSCTL_UINT(_hw_usb_atp, OID_AUTO, slide_min_movement, CTLFLAG_RWTUN, 222 &atp_slide_min_movement, 2 * ATP_SMALL_MOVEMENT_THRESHOLD, 223 "strokes with at least this amt. of movement are considered slides"); 224 225 /* 226 * The minimum age of a stroke for it to be considered mature; this 227 * helps filter movements (noise) from immature strokes. Units: interrupts. 228 */ 229 static u_int atp_stroke_maturity_threshold = 4; 230 SYSCTL_UINT(_hw_usb_atp, OID_AUTO, stroke_maturity_threshold, CTLFLAG_RWTUN, 231 &atp_stroke_maturity_threshold, 4, 232 "the minimum age of a stroke for it to be considered mature"); 233 234 typedef enum atp_trackpad_family { 235 TRACKPAD_FAMILY_FOUNTAIN_GEYSER, 236 TRACKPAD_FAMILY_WELLSPRING, 237 TRACKPAD_FAMILY_MAX /* keep this at the tail end of the enumeration */ 238 } trackpad_family_t; 239 240 enum fountain_geyser_product { 241 FOUNTAIN, 242 GEYSER1, 243 GEYSER1_17inch, 244 GEYSER2, 245 GEYSER3, 246 GEYSER4, 247 FOUNTAIN_GEYSER_PRODUCT_MAX /* keep this at the end */ 248 }; 249 250 enum wellspring_product { 251 WELLSPRING1, 252 WELLSPRING2, 253 WELLSPRING3, 254 WELLSPRING4, 255 WELLSPRING4A, 256 WELLSPRING5, 257 WELLSPRING6A, 258 WELLSPRING6, 259 WELLSPRING5A, 260 WELLSPRING7, 261 WELLSPRING7A, 262 WELLSPRING8, 263 WELLSPRING_PRODUCT_MAX /* keep this at the end of the enumeration */ 264 }; 265 266 /* trackpad header types */ 267 enum fountain_geyser_trackpad_type { 268 FG_TRACKPAD_TYPE_GEYSER1, 269 FG_TRACKPAD_TYPE_GEYSER2, 270 FG_TRACKPAD_TYPE_GEYSER3, 271 FG_TRACKPAD_TYPE_GEYSER4, 272 }; 273 enum wellspring_trackpad_type { 274 WSP_TRACKPAD_TYPE1, /* plain trackpad */ 275 WSP_TRACKPAD_TYPE2, /* button integrated in trackpad */ 276 WSP_TRACKPAD_TYPE3 /* additional header fields since June 2013 */ 277 }; 278 279 /* 280 * Trackpad family and product and family are encoded together in the 281 * driver_info value associated with a trackpad product. 282 */ 283 #define N_PROD_BITS 8 /* Number of bits used to encode product */ 284 #define ENCODE_DRIVER_INFO(FAMILY, PROD) \ 285 (((FAMILY) << N_PROD_BITS) | (PROD)) 286 #define DECODE_FAMILY_FROM_DRIVER_INFO(INFO) ((INFO) >> N_PROD_BITS) 287 #define DECODE_PRODUCT_FROM_DRIVER_INFO(INFO) \ 288 ((INFO) & ((1 << N_PROD_BITS) - 1)) 289 290 #define FG_DRIVER_INFO(PRODUCT) \ 291 ENCODE_DRIVER_INFO(TRACKPAD_FAMILY_FOUNTAIN_GEYSER, PRODUCT) 292 #define WELLSPRING_DRIVER_INFO(PRODUCT) \ 293 ENCODE_DRIVER_INFO(TRACKPAD_FAMILY_WELLSPRING, PRODUCT) 294 295 /* 296 * The following structure captures the state of a pressure span along 297 * an axis. Each contact with the touchpad results in separate 298 * pressure spans along the two axes. 299 */ 300 typedef struct fg_pspan { 301 u_int width; /* in units of sensors */ 302 u_int cum; /* cumulative compression (from all sensors) */ 303 u_int cog; /* center of gravity */ 304 u_int loc; /* location (scaled using the mickeys factor) */ 305 boolean_t matched; /* to track pspans as they match against strokes. */ 306 } fg_pspan; 307 308 #define FG_MAX_PSPANS_PER_AXIS 3 309 #define FG_MAX_STROKES (2 * FG_MAX_PSPANS_PER_AXIS) 310 311 #define WELLSPRING_INTERFACE_INDEX 1 312 313 /* trackpad finger data offsets, le16-aligned */ 314 #define WSP_TYPE1_FINGER_DATA_OFFSET (13 * 2) 315 #define WSP_TYPE2_FINGER_DATA_OFFSET (15 * 2) 316 #define WSP_TYPE3_FINGER_DATA_OFFSET (19 * 2) 317 318 /* trackpad button data offsets */ 319 #define WSP_TYPE2_BUTTON_DATA_OFFSET 15 320 #define WSP_TYPE3_BUTTON_DATA_OFFSET 23 321 322 /* list of device capability bits */ 323 #define HAS_INTEGRATED_BUTTON 1 324 325 /* trackpad finger structure - little endian */ 326 struct wsp_finger_sensor_data { 327 int16_t origin; /* zero when switching track finger */ 328 int16_t abs_x; /* absolute x coordinate */ 329 int16_t abs_y; /* absolute y coordinate */ 330 int16_t rel_x; /* relative x coordinate */ 331 int16_t rel_y; /* relative y coordinate */ 332 int16_t tool_major; /* tool area, major axis */ 333 int16_t tool_minor; /* tool area, minor axis */ 334 int16_t orientation; /* 16384 when point, else 15 bit angle */ 335 int16_t touch_major; /* touch area, major axis */ 336 int16_t touch_minor; /* touch area, minor axis */ 337 int16_t unused[3]; /* zeros */ 338 int16_t multi; /* one finger: varies, more fingers: constant */ 339 } __packed; 340 341 typedef struct wsp_finger { 342 /* to track fingers as they match against strokes. */ 343 boolean_t matched; 344 345 /* location (scaled using the mickeys factor) */ 346 int x; 347 int y; 348 } wsp_finger_t; 349 350 #define WSP_MAX_FINGERS 16 351 #define WSP_SIZEOF_FINGER_SENSOR_DATA sizeof(struct wsp_finger_sensor_data) 352 #define WSP_SIZEOF_ALL_FINGER_DATA (WSP_MAX_FINGERS * \ 353 WSP_SIZEOF_FINGER_SENSOR_DATA) 354 #define WSP_MAX_FINGER_ORIENTATION 16384 355 356 #define ATP_SENSOR_DATA_BUF_MAX 1024 357 #if (ATP_SENSOR_DATA_BUF_MAX < ((WSP_MAX_FINGERS * 14 * 2) + \ 358 WSP_TYPE3_FINGER_DATA_OFFSET)) 359 /* note: 14 * 2 in the above is based on sizeof(struct wsp_finger_sensor_data)*/ 360 #error "ATP_SENSOR_DATA_BUF_MAX is too small" 361 #endif 362 363 #define ATP_MAX_STROKES MAX(WSP_MAX_FINGERS, FG_MAX_STROKES) 364 365 #define FG_MAX_XSENSORS 26 366 #define FG_MAX_YSENSORS 16 367 368 /* device-specific configuration */ 369 struct fg_dev_params { 370 u_int data_len; /* for sensor data */ 371 u_int n_xsensors; 372 u_int n_ysensors; 373 enum fountain_geyser_trackpad_type prot; 374 }; 375 struct wsp_dev_params { 376 uint8_t caps; /* device capability bitmask */ 377 uint8_t tp_type; /* type of trackpad interface */ 378 uint8_t finger_data_offset; /* offset to trackpad finger data */ 379 }; 380 381 static const struct fg_dev_params fg_dev_params[FOUNTAIN_GEYSER_PRODUCT_MAX] = { 382 [FOUNTAIN] = { 383 .data_len = 81, 384 .n_xsensors = 16, 385 .n_ysensors = 16, 386 .prot = FG_TRACKPAD_TYPE_GEYSER1 387 }, 388 [GEYSER1] = { 389 .data_len = 81, 390 .n_xsensors = 16, 391 .n_ysensors = 16, 392 .prot = FG_TRACKPAD_TYPE_GEYSER1 393 }, 394 [GEYSER1_17inch] = { 395 .data_len = 81, 396 .n_xsensors = 26, 397 .n_ysensors = 16, 398 .prot = FG_TRACKPAD_TYPE_GEYSER1 399 }, 400 [GEYSER2] = { 401 .data_len = 64, 402 .n_xsensors = 15, 403 .n_ysensors = 9, 404 .prot = FG_TRACKPAD_TYPE_GEYSER2 405 }, 406 [GEYSER3] = { 407 .data_len = 64, 408 .n_xsensors = 20, 409 .n_ysensors = 10, 410 .prot = FG_TRACKPAD_TYPE_GEYSER3 411 }, 412 [GEYSER4] = { 413 .data_len = 64, 414 .n_xsensors = 20, 415 .n_ysensors = 10, 416 .prot = FG_TRACKPAD_TYPE_GEYSER4 417 } 418 }; 419 420 static const STRUCT_USB_HOST_ID fg_devs[] = { 421 /* PowerBooks Feb 2005, iBooks G4 */ 422 { USB_VPI(USB_VENDOR_APPLE, 0x020e, FG_DRIVER_INFO(FOUNTAIN)) }, 423 { USB_VPI(USB_VENDOR_APPLE, 0x020f, FG_DRIVER_INFO(FOUNTAIN)) }, 424 { USB_VPI(USB_VENDOR_APPLE, 0x0210, FG_DRIVER_INFO(FOUNTAIN)) }, 425 { USB_VPI(USB_VENDOR_APPLE, 0x030a, FG_DRIVER_INFO(FOUNTAIN)) }, 426 { USB_VPI(USB_VENDOR_APPLE, 0x030b, FG_DRIVER_INFO(GEYSER1)) }, 427 428 /* PowerBooks Oct 2005 */ 429 { USB_VPI(USB_VENDOR_APPLE, 0x0214, FG_DRIVER_INFO(GEYSER2)) }, 430 { USB_VPI(USB_VENDOR_APPLE, 0x0215, FG_DRIVER_INFO(GEYSER2)) }, 431 { USB_VPI(USB_VENDOR_APPLE, 0x0216, FG_DRIVER_INFO(GEYSER2)) }, 432 433 /* Core Duo MacBook & MacBook Pro */ 434 { USB_VPI(USB_VENDOR_APPLE, 0x0217, FG_DRIVER_INFO(GEYSER3)) }, 435 { USB_VPI(USB_VENDOR_APPLE, 0x0218, FG_DRIVER_INFO(GEYSER3)) }, 436 { USB_VPI(USB_VENDOR_APPLE, 0x0219, FG_DRIVER_INFO(GEYSER3)) }, 437 438 /* Core2 Duo MacBook & MacBook Pro */ 439 { USB_VPI(USB_VENDOR_APPLE, 0x021a, FG_DRIVER_INFO(GEYSER4)) }, 440 { USB_VPI(USB_VENDOR_APPLE, 0x021b, FG_DRIVER_INFO(GEYSER4)) }, 441 { USB_VPI(USB_VENDOR_APPLE, 0x021c, FG_DRIVER_INFO(GEYSER4)) }, 442 443 /* Core2 Duo MacBook3,1 */ 444 { USB_VPI(USB_VENDOR_APPLE, 0x0229, FG_DRIVER_INFO(GEYSER4)) }, 445 { USB_VPI(USB_VENDOR_APPLE, 0x022a, FG_DRIVER_INFO(GEYSER4)) }, 446 { USB_VPI(USB_VENDOR_APPLE, 0x022b, FG_DRIVER_INFO(GEYSER4)) }, 447 448 /* 17 inch PowerBook */ 449 { USB_VPI(USB_VENDOR_APPLE, 0x020d, FG_DRIVER_INFO(GEYSER1_17inch)) }, 450 }; 451 452 static const struct wsp_dev_params wsp_dev_params[WELLSPRING_PRODUCT_MAX] = { 453 [WELLSPRING1] = { 454 .caps = 0, 455 .tp_type = WSP_TRACKPAD_TYPE1, 456 .finger_data_offset = WSP_TYPE1_FINGER_DATA_OFFSET, 457 }, 458 [WELLSPRING2] = { 459 .caps = 0, 460 .tp_type = WSP_TRACKPAD_TYPE1, 461 .finger_data_offset = WSP_TYPE1_FINGER_DATA_OFFSET, 462 }, 463 [WELLSPRING3] = { 464 .caps = HAS_INTEGRATED_BUTTON, 465 .tp_type = WSP_TRACKPAD_TYPE2, 466 .finger_data_offset = WSP_TYPE2_FINGER_DATA_OFFSET, 467 }, 468 [WELLSPRING4] = { 469 .caps = HAS_INTEGRATED_BUTTON, 470 .tp_type = WSP_TRACKPAD_TYPE2, 471 .finger_data_offset = WSP_TYPE2_FINGER_DATA_OFFSET, 472 }, 473 [WELLSPRING4A] = { 474 .caps = HAS_INTEGRATED_BUTTON, 475 .tp_type = WSP_TRACKPAD_TYPE2, 476 .finger_data_offset = WSP_TYPE2_FINGER_DATA_OFFSET, 477 }, 478 [WELLSPRING5] = { 479 .caps = HAS_INTEGRATED_BUTTON, 480 .tp_type = WSP_TRACKPAD_TYPE2, 481 .finger_data_offset = WSP_TYPE2_FINGER_DATA_OFFSET, 482 }, 483 [WELLSPRING6] = { 484 .caps = HAS_INTEGRATED_BUTTON, 485 .tp_type = WSP_TRACKPAD_TYPE2, 486 .finger_data_offset = WSP_TYPE2_FINGER_DATA_OFFSET, 487 }, 488 [WELLSPRING5A] = { 489 .caps = HAS_INTEGRATED_BUTTON, 490 .tp_type = WSP_TRACKPAD_TYPE2, 491 .finger_data_offset = WSP_TYPE2_FINGER_DATA_OFFSET, 492 }, 493 [WELLSPRING6A] = { 494 .caps = HAS_INTEGRATED_BUTTON, 495 .tp_type = WSP_TRACKPAD_TYPE2, 496 .finger_data_offset = WSP_TYPE2_FINGER_DATA_OFFSET, 497 }, 498 [WELLSPRING7] = { 499 .caps = HAS_INTEGRATED_BUTTON, 500 .tp_type = WSP_TRACKPAD_TYPE2, 501 .finger_data_offset = WSP_TYPE2_FINGER_DATA_OFFSET, 502 }, 503 [WELLSPRING7A] = { 504 .caps = HAS_INTEGRATED_BUTTON, 505 .tp_type = WSP_TRACKPAD_TYPE2, 506 .finger_data_offset = WSP_TYPE2_FINGER_DATA_OFFSET, 507 }, 508 [WELLSPRING8] = { 509 .caps = HAS_INTEGRATED_BUTTON, 510 .tp_type = WSP_TRACKPAD_TYPE3, 511 .finger_data_offset = WSP_TYPE3_FINGER_DATA_OFFSET, 512 }, 513 }; 514 #define ATP_DEV(v,p,i) { USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, i) } 515 516 /* TODO: STRUCT_USB_HOST_ID */ 517 static const struct usb_device_id wsp_devs[] = { 518 /* MacbookAir1.1 */ 519 ATP_DEV(APPLE, WELLSPRING_ANSI, WELLSPRING_DRIVER_INFO(WELLSPRING1)), 520 ATP_DEV(APPLE, WELLSPRING_ISO, WELLSPRING_DRIVER_INFO(WELLSPRING1)), 521 ATP_DEV(APPLE, WELLSPRING_JIS, WELLSPRING_DRIVER_INFO(WELLSPRING1)), 522 523 /* MacbookProPenryn, aka wellspring2 */ 524 ATP_DEV(APPLE, WELLSPRING2_ANSI, WELLSPRING_DRIVER_INFO(WELLSPRING2)), 525 ATP_DEV(APPLE, WELLSPRING2_ISO, WELLSPRING_DRIVER_INFO(WELLSPRING2)), 526 ATP_DEV(APPLE, WELLSPRING2_JIS, WELLSPRING_DRIVER_INFO(WELLSPRING2)), 527 528 /* Macbook5,1 (unibody), aka wellspring3 */ 529 ATP_DEV(APPLE, WELLSPRING3_ANSI, WELLSPRING_DRIVER_INFO(WELLSPRING3)), 530 ATP_DEV(APPLE, WELLSPRING3_ISO, WELLSPRING_DRIVER_INFO(WELLSPRING3)), 531 ATP_DEV(APPLE, WELLSPRING3_JIS, WELLSPRING_DRIVER_INFO(WELLSPRING3)), 532 533 /* MacbookAir3,2 (unibody), aka wellspring4 */ 534 ATP_DEV(APPLE, WELLSPRING4_ANSI, WELLSPRING_DRIVER_INFO(WELLSPRING4)), 535 ATP_DEV(APPLE, WELLSPRING4_ISO, WELLSPRING_DRIVER_INFO(WELLSPRING4)), 536 ATP_DEV(APPLE, WELLSPRING4_JIS, WELLSPRING_DRIVER_INFO(WELLSPRING4)), 537 538 /* MacbookAir3,1 (unibody), aka wellspring4 */ 539 ATP_DEV(APPLE, WELLSPRING4A_ANSI, WELLSPRING_DRIVER_INFO(WELLSPRING4A)), 540 ATP_DEV(APPLE, WELLSPRING4A_ISO, WELLSPRING_DRIVER_INFO(WELLSPRING4A)), 541 ATP_DEV(APPLE, WELLSPRING4A_JIS, WELLSPRING_DRIVER_INFO(WELLSPRING4A)), 542 543 /* Macbook8 (unibody, March 2011) */ 544 ATP_DEV(APPLE, WELLSPRING5_ANSI, WELLSPRING_DRIVER_INFO(WELLSPRING5)), 545 ATP_DEV(APPLE, WELLSPRING5_ISO, WELLSPRING_DRIVER_INFO(WELLSPRING5)), 546 ATP_DEV(APPLE, WELLSPRING5_JIS, WELLSPRING_DRIVER_INFO(WELLSPRING5)), 547 548 /* MacbookAir4,1 (unibody, July 2011) */ 549 ATP_DEV(APPLE, WELLSPRING6A_ANSI, WELLSPRING_DRIVER_INFO(WELLSPRING6A)), 550 ATP_DEV(APPLE, WELLSPRING6A_ISO, WELLSPRING_DRIVER_INFO(WELLSPRING6A)), 551 ATP_DEV(APPLE, WELLSPRING6A_JIS, WELLSPRING_DRIVER_INFO(WELLSPRING6A)), 552 553 /* MacbookAir4,2 (unibody, July 2011) */ 554 ATP_DEV(APPLE, WELLSPRING6_ANSI, WELLSPRING_DRIVER_INFO(WELLSPRING6)), 555 ATP_DEV(APPLE, WELLSPRING6_ISO, WELLSPRING_DRIVER_INFO(WELLSPRING6)), 556 ATP_DEV(APPLE, WELLSPRING6_JIS, WELLSPRING_DRIVER_INFO(WELLSPRING6)), 557 558 /* Macbook8,2 (unibody) */ 559 ATP_DEV(APPLE, WELLSPRING5A_ANSI, WELLSPRING_DRIVER_INFO(WELLSPRING5A)), 560 ATP_DEV(APPLE, WELLSPRING5A_ISO, WELLSPRING_DRIVER_INFO(WELLSPRING5A)), 561 ATP_DEV(APPLE, WELLSPRING5A_JIS, WELLSPRING_DRIVER_INFO(WELLSPRING5A)), 562 563 /* MacbookPro10,1 (unibody, June 2012) */ 564 /* MacbookPro11,? (unibody, June 2013) */ 565 ATP_DEV(APPLE, WELLSPRING7_ANSI, WELLSPRING_DRIVER_INFO(WELLSPRING7)), 566 ATP_DEV(APPLE, WELLSPRING7_ISO, WELLSPRING_DRIVER_INFO(WELLSPRING7)), 567 ATP_DEV(APPLE, WELLSPRING7_JIS, WELLSPRING_DRIVER_INFO(WELLSPRING7)), 568 569 /* MacbookPro10,2 (unibody, October 2012) */ 570 ATP_DEV(APPLE, WELLSPRING7A_ANSI, WELLSPRING_DRIVER_INFO(WELLSPRING7A)), 571 ATP_DEV(APPLE, WELLSPRING7A_ISO, WELLSPRING_DRIVER_INFO(WELLSPRING7A)), 572 ATP_DEV(APPLE, WELLSPRING7A_JIS, WELLSPRING_DRIVER_INFO(WELLSPRING7A)), 573 574 /* MacbookAir6,2 (unibody, June 2013) */ 575 ATP_DEV(APPLE, WELLSPRING8_ANSI, WELLSPRING_DRIVER_INFO(WELLSPRING8)), 576 ATP_DEV(APPLE, WELLSPRING8_ISO, WELLSPRING_DRIVER_INFO(WELLSPRING8)), 577 ATP_DEV(APPLE, WELLSPRING8_JIS, WELLSPRING_DRIVER_INFO(WELLSPRING8)), 578 }; 579 580 typedef enum atp_stroke_type { 581 ATP_STROKE_TOUCH, 582 ATP_STROKE_SLIDE, 583 } atp_stroke_type; 584 585 typedef enum atp_axis { 586 X = 0, 587 Y = 1, 588 NUM_AXES 589 } atp_axis; 590 591 #define ATP_FIFO_BUF_SIZE 8 /* bytes */ 592 #define ATP_FIFO_QUEUE_MAXLEN 50 /* units */ 593 594 enum { 595 ATP_INTR_DT, 596 ATP_RESET, 597 ATP_N_TRANSFER, 598 }; 599 600 typedef struct fg_stroke_component { 601 /* Fields encapsulating the pressure-span. */ 602 u_int loc; /* location (scaled) */ 603 u_int cum_pressure; /* cumulative compression */ 604 u_int max_cum_pressure; /* max cumulative compression */ 605 boolean_t matched; /*to track components as they match against pspans.*/ 606 607 int delta_mickeys; /* change in location (un-smoothened movement)*/ 608 } fg_stroke_component_t; 609 610 /* 611 * The following structure captures a finger contact with the 612 * touchpad. A stroke comprises two p-span components and some state. 613 */ 614 typedef struct atp_stroke { 615 TAILQ_ENTRY(atp_stroke) entry; 616 617 atp_stroke_type type; 618 uint32_t flags; /* the state of this stroke */ 619 #define ATSF_ZOMBIE 0x1 620 boolean_t matched; /* to track match against fingers.*/ 621 622 struct timeval ctime; /* create time; for coincident siblings. */ 623 624 /* 625 * Unit: interrupts; we maintain this value in 626 * addition to 'ctime' in order to avoid the 627 * expensive call to microtime() at every 628 * interrupt. 629 */ 630 uint32_t age; 631 632 /* Location */ 633 int x; 634 int y; 635 636 /* Fields containing information about movement. */ 637 int instantaneous_dx; /* curr. change in X location (un-smoothened) */ 638 int instantaneous_dy; /* curr. change in Y location (un-smoothened) */ 639 int pending_dx; /* cum. of pending short movements */ 640 int pending_dy; /* cum. of pending short movements */ 641 int movement_dx; /* interpreted smoothened movement */ 642 int movement_dy; /* interpreted smoothened movement */ 643 int cum_movement_x; /* cum. horizontal movement */ 644 int cum_movement_y; /* cum. vertical movement */ 645 646 /* 647 * The following member is relevant only for fountain-geyser trackpads. 648 * For these, there is the need to track pressure-spans and cumulative 649 * pressures for stroke components. 650 */ 651 fg_stroke_component_t components[NUM_AXES]; 652 } atp_stroke_t; 653 654 struct atp_softc; /* forward declaration */ 655 typedef void (*sensor_data_interpreter_t)(struct atp_softc *sc, u_int len); 656 657 struct atp_softc { 658 device_t sc_dev; 659 struct usb_device *sc_usb_device; 660 struct mtx sc_mutex; /* for synchronization */ 661 struct usb_fifo_sc sc_fifo; 662 663 #define MODE_LENGTH 8 664 char sc_mode_bytes[MODE_LENGTH]; /* device mode */ 665 666 trackpad_family_t sc_family; 667 const void *sc_params; /* device configuration */ 668 sensor_data_interpreter_t sensor_data_interpreter; 669 670 mousehw_t sc_hw; 671 mousemode_t sc_mode; 672 mousestatus_t sc_status; 673 674 u_int sc_state; 675 #define ATP_ENABLED 0x01 676 #define ATP_ZOMBIES_EXIST 0x02 677 #define ATP_DOUBLE_TAP_DRAG 0x04 678 #define ATP_VALID 0x08 679 680 struct usb_xfer *sc_xfer[ATP_N_TRANSFER]; 681 682 u_int sc_pollrate; 683 int sc_fflags; 684 685 atp_stroke_t sc_strokes_data[ATP_MAX_STROKES]; 686 TAILQ_HEAD(,atp_stroke) sc_stroke_free; 687 TAILQ_HEAD(,atp_stroke) sc_stroke_used; 688 u_int sc_n_strokes; 689 690 struct callout sc_callout; 691 692 /* 693 * button status. Set to non-zero if the mouse-button is physically 694 * pressed. This state variable is exposed through softc to allow 695 * reap_sibling_zombies to avoid registering taps while the trackpad 696 * button is pressed. 697 */ 698 uint8_t sc_ibtn; 699 700 /* 701 * Time when touch zombies were last reaped; useful for detecting 702 * double-touch-n-drag. 703 */ 704 struct timeval sc_touch_reap_time; 705 706 u_int sc_idlecount; 707 708 /* Regarding the data transferred from t-pad in USB INTR packets. */ 709 u_int sc_expected_sensor_data_len; 710 uint8_t sc_sensor_data[ATP_SENSOR_DATA_BUF_MAX] __aligned(4); 711 712 int sc_cur_x[FG_MAX_XSENSORS]; /* current sensor readings */ 713 int sc_cur_y[FG_MAX_YSENSORS]; 714 int sc_base_x[FG_MAX_XSENSORS]; /* base sensor readings */ 715 int sc_base_y[FG_MAX_YSENSORS]; 716 int sc_pressure_x[FG_MAX_XSENSORS]; /* computed pressures */ 717 int sc_pressure_y[FG_MAX_YSENSORS]; 718 fg_pspan sc_pspans_x[FG_MAX_PSPANS_PER_AXIS]; 719 fg_pspan sc_pspans_y[FG_MAX_PSPANS_PER_AXIS]; 720 }; 721 722 /* 723 * The last byte of the fountain-geyser sensor data contains status bits; the 724 * following values define the meanings of these bits. 725 * (only Geyser 3/4) 726 */ 727 enum geyser34_status_bits { 728 FG_STATUS_BUTTON = (uint8_t)0x01, /* The button was pressed */ 729 FG_STATUS_BASE_UPDATE = (uint8_t)0x04, /* Data from an untouched pad.*/ 730 }; 731 732 typedef enum interface_mode { 733 RAW_SENSOR_MODE = (uint8_t)0x01, 734 HID_MODE = (uint8_t)0x08 735 } interface_mode; 736 737 /* 738 * function prototypes 739 */ 740 static usb_fifo_cmd_t atp_start_read; 741 static usb_fifo_cmd_t atp_stop_read; 742 static usb_fifo_open_t atp_open; 743 static usb_fifo_close_t atp_close; 744 static usb_fifo_ioctl_t atp_ioctl; 745 746 static struct usb_fifo_methods atp_fifo_methods = { 747 .f_open = &atp_open, 748 .f_close = &atp_close, 749 .f_ioctl = &atp_ioctl, 750 .f_start_read = &atp_start_read, 751 .f_stop_read = &atp_stop_read, 752 .basename[0] = ATP_DRIVER_NAME, 753 }; 754 755 /* device initialization and shutdown */ 756 static usb_error_t atp_set_device_mode(struct atp_softc *, interface_mode); 757 static void atp_reset_callback(struct usb_xfer *, usb_error_t); 758 static int atp_enable(struct atp_softc *); 759 static void atp_disable(struct atp_softc *); 760 761 /* sensor interpretation */ 762 static void fg_interpret_sensor_data(struct atp_softc *, u_int); 763 static void fg_extract_sensor_data(const int8_t *, u_int, atp_axis, 764 int *, enum fountain_geyser_trackpad_type); 765 static void fg_get_pressures(int *, const int *, const int *, int); 766 static void fg_detect_pspans(int *, u_int, u_int, fg_pspan *, u_int *); 767 static void wsp_interpret_sensor_data(struct atp_softc *, u_int); 768 769 /* movement detection */ 770 static boolean_t fg_match_stroke_component(fg_stroke_component_t *, 771 const fg_pspan *, atp_stroke_type); 772 static void fg_match_strokes_against_pspans(struct atp_softc *, 773 atp_axis, fg_pspan *, u_int, u_int); 774 static boolean_t wsp_match_strokes_against_fingers(struct atp_softc *, 775 wsp_finger_t *, u_int); 776 static boolean_t fg_update_strokes(struct atp_softc *, fg_pspan *, u_int, 777 fg_pspan *, u_int); 778 static boolean_t wsp_update_strokes(struct atp_softc *, 779 wsp_finger_t [WSP_MAX_FINGERS], u_int); 780 static void fg_add_stroke(struct atp_softc *, const fg_pspan *, const fg_pspan *); 781 static void fg_add_new_strokes(struct atp_softc *, fg_pspan *, 782 u_int, fg_pspan *, u_int); 783 static void wsp_add_stroke(struct atp_softc *, const wsp_finger_t *); 784 static void atp_advance_stroke_state(struct atp_softc *, 785 atp_stroke_t *, boolean_t *); 786 static boolean_t atp_stroke_has_small_movement(const atp_stroke_t *); 787 static void atp_update_pending_mickeys(atp_stroke_t *); 788 static boolean_t atp_compute_stroke_movement(atp_stroke_t *); 789 static void atp_terminate_stroke(struct atp_softc *, atp_stroke_t *); 790 791 /* tap detection */ 792 static boolean_t atp_is_horizontal_scroll(const atp_stroke_t *); 793 static boolean_t atp_is_vertical_scroll(const atp_stroke_t *); 794 static void atp_reap_sibling_zombies(void *); 795 static void atp_convert_to_slide(struct atp_softc *, atp_stroke_t *); 796 797 /* updating fifo */ 798 static void atp_reset_buf(struct atp_softc *); 799 static void atp_add_to_queue(struct atp_softc *, int, int, int, uint32_t); 800 801 /* Device methods. */ 802 static device_probe_t atp_probe; 803 static device_attach_t atp_attach; 804 static device_detach_t atp_detach; 805 static usb_callback_t atp_intr; 806 807 static const struct usb_config atp_xfer_config[ATP_N_TRANSFER] = { 808 [ATP_INTR_DT] = { 809 .type = UE_INTERRUPT, 810 .endpoint = UE_ADDR_ANY, 811 .direction = UE_DIR_IN, 812 .flags = { 813 .pipe_bof = 1, /* block pipe on failure */ 814 .short_xfer_ok = 1, 815 }, 816 .bufsize = ATP_SENSOR_DATA_BUF_MAX, 817 .callback = &atp_intr, 818 }, 819 [ATP_RESET] = { 820 .type = UE_CONTROL, 821 .endpoint = 0, /* Control pipe */ 822 .direction = UE_DIR_ANY, 823 .bufsize = sizeof(struct usb_device_request) + MODE_LENGTH, 824 .callback = &atp_reset_callback, 825 .interval = 0, /* no pre-delay */ 826 }, 827 }; 828 829 static atp_stroke_t * 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[WSP_MAX_FINGERS], 1637 u_int n_fingers) 1638 { 1639 boolean_t movement = false; 1640 atp_stroke_t *strokep_next; 1641 atp_stroke_t *strokep; 1642 u_int i; 1643 1644 if (sc->sc_n_strokes > 0) { 1645 movement = wsp_match_strokes_against_fingers( 1646 sc, fingers, n_fingers); 1647 1648 /* handle zombie strokes */ 1649 TAILQ_FOREACH_SAFE(strokep, &sc->sc_stroke_used, entry, strokep_next) { 1650 if (strokep->matched) 1651 continue; 1652 atp_terminate_stroke(sc, strokep); 1653 } 1654 } 1655 1656 /* initialize unmatched fingers as strokes */ 1657 for (i = 0; i != n_fingers; i++) { 1658 if (fingers[i].matched) 1659 continue; 1660 1661 wsp_add_stroke(sc, fingers + i); 1662 } 1663 return (movement); 1664 } 1665 1666 /* Initialize a stroke using a pressure-span. */ 1667 static void 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 int horizontal_scroll = 0; 2018 atp_stroke_t *strokep; 2019 atp_stroke_t *strokep_next; 2020 2021 DPRINTFN(ATP_LLEVEL_INFO, "\n"); 2022 2023 TAILQ_FOREACH_SAFE(strokep, &sc->sc_stroke_used, entry, strokep_next) { 2024 if ((strokep->flags & ATSF_ZOMBIE) == 0) 2025 continue; 2026 2027 if (strokep->type == ATP_STROKE_TOUCH) { 2028 n_touches_reaped++; 2029 } else { 2030 n_slides_reaped++; 2031 2032 if (atp_is_horizontal_scroll(strokep)) { 2033 n_horizontal_scrolls++; 2034 horizontal_scroll += strokep->cum_movement_x; 2035 } 2036 } 2037 2038 atp_free_stroke(sc, strokep); 2039 } 2040 2041 DPRINTFN(ATP_LLEVEL_INFO, "reaped %u zombies\n", 2042 n_touches_reaped + n_slides_reaped); 2043 sc->sc_state &= ~ATP_ZOMBIES_EXIST; 2044 2045 /* No further processing necessary if physical button is depressed. */ 2046 if (sc->sc_ibtn != 0) 2047 return; 2048 2049 if ((n_touches_reaped == 0) && (n_slides_reaped == 0)) 2050 return; 2051 2052 /* Add a pair of virtual button events (button-down and button-up) if 2053 * the physical button isn't pressed. */ 2054 if (n_touches_reaped != 0) { 2055 if (n_touches_reaped < atp_tap_minimum) 2056 return; 2057 2058 switch (n_touches_reaped) { 2059 case 1: 2060 atp_add_to_queue(sc, 0, 0, 0, MOUSE_BUTTON1DOWN); 2061 microtime(&sc->sc_touch_reap_time); /* remember this time */ 2062 break; 2063 case 2: 2064 atp_add_to_queue(sc, 0, 0, 0, MOUSE_BUTTON3DOWN); 2065 break; 2066 case 3: 2067 atp_add_to_queue(sc, 0, 0, 0, MOUSE_BUTTON2DOWN); 2068 break; 2069 default: 2070 /* we handle taps of only up to 3 fingers */ 2071 return; 2072 } 2073 atp_add_to_queue(sc, 0, 0, 0, 0); /* button release */ 2074 2075 } else if ((n_slides_reaped == 2) && (n_horizontal_scrolls == 2)) { 2076 if (horizontal_scroll < 0) 2077 atp_add_to_queue(sc, 0, 0, 0, MOUSE_BUTTON4DOWN); 2078 else 2079 atp_add_to_queue(sc, 0, 0, 0, MOUSE_BUTTON5DOWN); 2080 atp_add_to_queue(sc, 0, 0, 0, 0); /* button release */ 2081 } 2082 } 2083 2084 /* Switch a given touch stroke to being a slide. */ 2085 static void 2086 atp_convert_to_slide(struct atp_softc *sc, atp_stroke_t *strokep) 2087 { 2088 strokep->type = ATP_STROKE_SLIDE; 2089 2090 /* Are we at the beginning of a double-click-n-drag? */ 2091 if ((sc->sc_n_strokes == 1) && 2092 ((sc->sc_state & ATP_ZOMBIES_EXIST) == 0) && 2093 timevalcmp(&strokep->ctime, &sc->sc_touch_reap_time, >)) { 2094 struct timeval delta; 2095 struct timeval window = { 2096 atp_double_tap_threshold / 1000000, 2097 atp_double_tap_threshold % 1000000 2098 }; 2099 2100 delta = strokep->ctime; 2101 timevalsub(&delta, &sc->sc_touch_reap_time); 2102 if (timevalcmp(&delta, &window, <=)) 2103 sc->sc_state |= ATP_DOUBLE_TAP_DRAG; 2104 } 2105 } 2106 2107 static void 2108 atp_reset_buf(struct atp_softc *sc) 2109 { 2110 /* reset read queue */ 2111 usb_fifo_reset(sc->sc_fifo.fp[USB_FIFO_RX]); 2112 } 2113 2114 static void 2115 atp_add_to_queue(struct atp_softc *sc, int dx, int dy, int dz, 2116 uint32_t buttons_in) 2117 { 2118 uint32_t buttons_out; 2119 uint8_t buf[8]; 2120 2121 dx = imin(dx, 254); dx = imax(dx, -256); 2122 dy = imin(dy, 254); dy = imax(dy, -256); 2123 dz = imin(dz, 126); dz = imax(dz, -128); 2124 2125 buttons_out = MOUSE_MSC_BUTTONS; 2126 if (buttons_in & MOUSE_BUTTON1DOWN) 2127 buttons_out &= ~MOUSE_MSC_BUTTON1UP; 2128 else if (buttons_in & MOUSE_BUTTON2DOWN) 2129 buttons_out &= ~MOUSE_MSC_BUTTON2UP; 2130 else if (buttons_in & MOUSE_BUTTON3DOWN) 2131 buttons_out &= ~MOUSE_MSC_BUTTON3UP; 2132 2133 DPRINTFN(ATP_LLEVEL_INFO, "dx=%d, dy=%d, buttons=%x\n", 2134 dx, dy, buttons_out); 2135 2136 /* Encode the mouse data in standard format; refer to mouse(4) */ 2137 buf[0] = sc->sc_mode.syncmask[1]; 2138 buf[0] |= buttons_out; 2139 buf[1] = dx >> 1; 2140 buf[2] = dy >> 1; 2141 buf[3] = dx - (dx >> 1); 2142 buf[4] = dy - (dy >> 1); 2143 /* Encode extra bytes for level 1 */ 2144 if (sc->sc_mode.level == 1) { 2145 buf[5] = dz >> 1; 2146 buf[6] = dz - (dz >> 1); 2147 buf[7] = (((~buttons_in) >> 3) & MOUSE_SYS_EXTBUTTONS); 2148 } 2149 2150 usb_fifo_put_data_linear(sc->sc_fifo.fp[USB_FIFO_RX], buf, 2151 sc->sc_mode.packetsize, 1); 2152 } 2153 2154 static int 2155 atp_probe(device_t self) 2156 { 2157 struct usb_attach_arg *uaa = device_get_ivars(self); 2158 2159 if (uaa->usb_mode != USB_MODE_HOST) 2160 return (ENXIO); 2161 2162 if (uaa->info.bInterfaceClass != UICLASS_HID) 2163 return (ENXIO); 2164 /* 2165 * Note: for some reason, the check 2166 * (uaa->info.bInterfaceProtocol == UIPROTO_MOUSE) doesn't hold true 2167 * for wellspring trackpads, so we've removed it from the common path. 2168 */ 2169 2170 if ((usbd_lookup_id_by_uaa(fg_devs, sizeof(fg_devs), uaa)) == 0) 2171 return ((uaa->info.bInterfaceProtocol == UIPROTO_MOUSE) ? 2172 BUS_PROBE_DEFAULT : ENXIO); 2173 2174 if ((usbd_lookup_id_by_uaa(wsp_devs, sizeof(wsp_devs), uaa)) == 0) 2175 if (uaa->info.bIfaceIndex == WELLSPRING_INTERFACE_INDEX) 2176 return (BUS_PROBE_DEFAULT); 2177 2178 return (ENXIO); 2179 } 2180 2181 static int 2182 atp_attach(device_t dev) 2183 { 2184 struct atp_softc *sc = device_get_softc(dev); 2185 struct usb_attach_arg *uaa = device_get_ivars(dev); 2186 usb_error_t err; 2187 void *descriptor_ptr = NULL; 2188 uint16_t descriptor_len; 2189 unsigned long di; 2190 2191 DPRINTFN(ATP_LLEVEL_INFO, "sc=%p\n", sc); 2192 2193 sc->sc_dev = dev; 2194 sc->sc_usb_device = uaa->device; 2195 2196 /* Get HID descriptor */ 2197 if (usbd_req_get_hid_desc(uaa->device, NULL, &descriptor_ptr, 2198 &descriptor_len, M_TEMP, uaa->info.bIfaceIndex) != 2199 USB_ERR_NORMAL_COMPLETION) 2200 return (ENXIO); 2201 2202 /* Get HID report descriptor length */ 2203 sc->sc_expected_sensor_data_len = hid_report_size_max(descriptor_ptr, 2204 descriptor_len, hid_input, NULL); 2205 free(descriptor_ptr, M_TEMP); 2206 2207 if ((sc->sc_expected_sensor_data_len <= 0) || 2208 (sc->sc_expected_sensor_data_len > ATP_SENSOR_DATA_BUF_MAX)) { 2209 DPRINTF("atp_attach: datalength invalid or too large: %d\n", 2210 sc->sc_expected_sensor_data_len); 2211 return (ENXIO); 2212 } 2213 2214 di = USB_GET_DRIVER_INFO(uaa); 2215 sc->sc_family = DECODE_FAMILY_FROM_DRIVER_INFO(di); 2216 2217 /* 2218 * By default the touchpad behaves like an HID device, sending 2219 * packets with reportID = 2. Such reports contain only 2220 * limited information--they encode movement deltas and button 2221 * events,--but do not include data from the pressure 2222 * sensors. The device input mode can be switched from HID 2223 * reports to raw sensor data using vendor-specific USB 2224 * control commands. 2225 * FOUNTAIN devices will give an error when trying to switch 2226 * input mode, so we skip this command 2227 */ 2228 if ((sc->sc_family == TRACKPAD_FAMILY_FOUNTAIN_GEYSER) && 2229 (DECODE_PRODUCT_FROM_DRIVER_INFO(di) == FOUNTAIN)) 2230 DPRINTF("device mode switch skipped: Fountain device\n"); 2231 else if ((err = atp_set_device_mode(sc, RAW_SENSOR_MODE)) != 0) { 2232 DPRINTF("failed to set mode to 'RAW_SENSOR' (%d)\n", err); 2233 return (ENXIO); 2234 } 2235 2236 mtx_init(&sc->sc_mutex, "atpmtx", NULL, MTX_DEF | MTX_RECURSE); 2237 2238 switch(sc->sc_family) { 2239 case TRACKPAD_FAMILY_FOUNTAIN_GEYSER: 2240 sc->sc_params = 2241 &fg_dev_params[DECODE_PRODUCT_FROM_DRIVER_INFO(di)]; 2242 sc->sensor_data_interpreter = fg_interpret_sensor_data; 2243 break; 2244 case TRACKPAD_FAMILY_WELLSPRING: 2245 sc->sc_params = 2246 &wsp_dev_params[DECODE_PRODUCT_FROM_DRIVER_INFO(di)]; 2247 sc->sensor_data_interpreter = wsp_interpret_sensor_data; 2248 break; 2249 default: 2250 goto detach; 2251 } 2252 2253 err = usbd_transfer_setup(uaa->device, 2254 &uaa->info.bIfaceIndex, sc->sc_xfer, atp_xfer_config, 2255 ATP_N_TRANSFER, sc, &sc->sc_mutex); 2256 if (err) { 2257 DPRINTF("error=%s\n", usbd_errstr(err)); 2258 goto detach; 2259 } 2260 2261 if (usb_fifo_attach(sc->sc_usb_device, sc, &sc->sc_mutex, 2262 &atp_fifo_methods, &sc->sc_fifo, 2263 device_get_unit(dev), -1, uaa->info.bIfaceIndex, 2264 UID_ROOT, GID_OPERATOR, 0644)) { 2265 goto detach; 2266 } 2267 2268 device_set_usb_desc(dev); 2269 2270 sc->sc_hw.buttons = 3; 2271 sc->sc_hw.iftype = MOUSE_IF_USB; 2272 sc->sc_hw.type = MOUSE_PAD; 2273 sc->sc_hw.model = MOUSE_MODEL_GENERIC; 2274 sc->sc_hw.hwid = 0; 2275 sc->sc_mode.protocol = MOUSE_PROTO_MSC; 2276 sc->sc_mode.rate = -1; 2277 sc->sc_mode.resolution = MOUSE_RES_UNKNOWN; 2278 sc->sc_mode.packetsize = MOUSE_MSC_PACKETSIZE; 2279 sc->sc_mode.syncmask[0] = MOUSE_MSC_SYNCMASK; 2280 sc->sc_mode.syncmask[1] = MOUSE_MSC_SYNC; 2281 sc->sc_mode.accelfactor = 0; 2282 sc->sc_mode.level = 0; 2283 2284 sc->sc_state = 0; 2285 sc->sc_ibtn = 0; 2286 2287 callout_init_mtx(&sc->sc_callout, &sc->sc_mutex, 0); 2288 2289 return (0); 2290 2291 detach: 2292 atp_detach(dev); 2293 return (ENOMEM); 2294 } 2295 2296 static int 2297 atp_detach(device_t dev) 2298 { 2299 struct atp_softc *sc; 2300 2301 sc = device_get_softc(dev); 2302 atp_set_device_mode(sc, HID_MODE); 2303 2304 mtx_lock(&sc->sc_mutex); 2305 callout_drain(&sc->sc_callout); 2306 if (sc->sc_state & ATP_ENABLED) 2307 atp_disable(sc); 2308 mtx_unlock(&sc->sc_mutex); 2309 2310 usb_fifo_detach(&sc->sc_fifo); 2311 2312 usbd_transfer_unsetup(sc->sc_xfer, ATP_N_TRANSFER); 2313 2314 mtx_destroy(&sc->sc_mutex); 2315 2316 return (0); 2317 } 2318 2319 static void 2320 atp_intr(struct usb_xfer *xfer, usb_error_t error) 2321 { 2322 struct atp_softc *sc = usbd_xfer_softc(xfer); 2323 struct usb_page_cache *pc; 2324 int len; 2325 2326 usbd_xfer_status(xfer, &len, NULL, NULL, NULL); 2327 2328 switch (USB_GET_STATE(xfer)) { 2329 case USB_ST_TRANSFERRED: 2330 pc = usbd_xfer_get_frame(xfer, 0); 2331 usbd_copy_out(pc, 0, sc->sc_sensor_data, len); 2332 if (len < sc->sc_expected_sensor_data_len) { 2333 /* make sure we don't process old data */ 2334 memset(sc->sc_sensor_data + len, 0, 2335 sc->sc_expected_sensor_data_len - len); 2336 } 2337 2338 sc->sc_status.flags &= ~(MOUSE_STDBUTTONSCHANGED | 2339 MOUSE_POSCHANGED); 2340 sc->sc_status.obutton = sc->sc_status.button; 2341 2342 (sc->sensor_data_interpreter)(sc, len); 2343 2344 if (sc->sc_status.button != 0) { 2345 /* Reset DOUBLE_TAP_N_DRAG if the button is pressed. */ 2346 sc->sc_state &= ~ATP_DOUBLE_TAP_DRAG; 2347 } else if (sc->sc_state & ATP_DOUBLE_TAP_DRAG) { 2348 /* Assume a button-press with DOUBLE_TAP_N_DRAG. */ 2349 sc->sc_status.button = MOUSE_BUTTON1DOWN; 2350 } 2351 2352 sc->sc_status.flags |= 2353 sc->sc_status.button ^ sc->sc_status.obutton; 2354 if (sc->sc_status.flags & MOUSE_STDBUTTONSCHANGED) { 2355 DPRINTFN(ATP_LLEVEL_INFO, "button %s\n", 2356 ((sc->sc_status.button & MOUSE_BUTTON1DOWN) ? 2357 "pressed" : "released")); 2358 } 2359 2360 if (sc->sc_status.flags & (MOUSE_POSCHANGED | 2361 MOUSE_STDBUTTONSCHANGED)) { 2362 atp_stroke_t *strokep; 2363 u_int8_t n_movements = 0; 2364 int dx = 0; 2365 int dy = 0; 2366 int dz = 0; 2367 2368 TAILQ_FOREACH(strokep, &sc->sc_stroke_used, entry) { 2369 if (strokep->flags & ATSF_ZOMBIE) 2370 continue; 2371 2372 dx += strokep->movement_dx; 2373 dy += strokep->movement_dy; 2374 if (strokep->movement_dx || 2375 strokep->movement_dy) 2376 n_movements++; 2377 } 2378 2379 /* average movement if multiple strokes record motion.*/ 2380 if (n_movements > 1) { 2381 dx /= (int)n_movements; 2382 dy /= (int)n_movements; 2383 } 2384 2385 /* detect multi-finger vertical scrolls */ 2386 if (n_movements >= 2) { 2387 boolean_t all_vertical_scrolls = true; 2388 TAILQ_FOREACH(strokep, &sc->sc_stroke_used, entry) { 2389 if (strokep->flags & ATSF_ZOMBIE) 2390 continue; 2391 2392 if (!atp_is_vertical_scroll(strokep)) 2393 all_vertical_scrolls = false; 2394 } 2395 if (all_vertical_scrolls) { 2396 dz = dy; 2397 dy = dx = 0; 2398 } 2399 } 2400 2401 sc->sc_status.dx += dx; 2402 sc->sc_status.dy += dy; 2403 sc->sc_status.dz += dz; 2404 atp_add_to_queue(sc, dx, -dy, -dz, sc->sc_status.button); 2405 } 2406 2407 case USB_ST_SETUP: 2408 tr_setup: 2409 /* check if we can put more data into the FIFO */ 2410 if (usb_fifo_put_bytes_max(sc->sc_fifo.fp[USB_FIFO_RX]) != 0) { 2411 usbd_xfer_set_frame_len(xfer, 0, 2412 sc->sc_expected_sensor_data_len); 2413 usbd_transfer_submit(xfer); 2414 } 2415 break; 2416 2417 default: /* Error */ 2418 if (error != USB_ERR_CANCELLED) { 2419 /* try clear stall first */ 2420 usbd_xfer_set_stall(xfer); 2421 goto tr_setup; 2422 } 2423 break; 2424 } 2425 } 2426 2427 static void 2428 atp_start_read(struct usb_fifo *fifo) 2429 { 2430 struct atp_softc *sc = usb_fifo_softc(fifo); 2431 int rate; 2432 2433 /* Check if we should override the default polling interval */ 2434 rate = sc->sc_pollrate; 2435 /* Range check rate */ 2436 if (rate > 1000) 2437 rate = 1000; 2438 /* Check for set rate */ 2439 if ((rate > 0) && (sc->sc_xfer[ATP_INTR_DT] != NULL)) { 2440 /* Stop current transfer, if any */ 2441 usbd_transfer_stop(sc->sc_xfer[ATP_INTR_DT]); 2442 /* Set new interval */ 2443 usbd_xfer_set_interval(sc->sc_xfer[ATP_INTR_DT], 1000 / rate); 2444 /* Only set pollrate once */ 2445 sc->sc_pollrate = 0; 2446 } 2447 2448 usbd_transfer_start(sc->sc_xfer[ATP_INTR_DT]); 2449 } 2450 2451 static void 2452 atp_stop_read(struct usb_fifo *fifo) 2453 { 2454 struct atp_softc *sc = usb_fifo_softc(fifo); 2455 usbd_transfer_stop(sc->sc_xfer[ATP_INTR_DT]); 2456 } 2457 2458 static int 2459 atp_open(struct usb_fifo *fifo, int fflags) 2460 { 2461 struct atp_softc *sc = usb_fifo_softc(fifo); 2462 2463 /* check for duplicate open, should not happen */ 2464 if (sc->sc_fflags & fflags) 2465 return (EBUSY); 2466 2467 /* check for first open */ 2468 if (sc->sc_fflags == 0) { 2469 int rc; 2470 if ((rc = atp_enable(sc)) != 0) 2471 return (rc); 2472 } 2473 2474 if (fflags & FREAD) { 2475 if (usb_fifo_alloc_buffer(fifo, 2476 ATP_FIFO_BUF_SIZE, ATP_FIFO_QUEUE_MAXLEN)) { 2477 return (ENOMEM); 2478 } 2479 } 2480 2481 sc->sc_fflags |= (fflags & (FREAD | FWRITE)); 2482 return (0); 2483 } 2484 2485 static void 2486 atp_close(struct usb_fifo *fifo, int fflags) 2487 { 2488 struct atp_softc *sc = usb_fifo_softc(fifo); 2489 if (fflags & FREAD) 2490 usb_fifo_free_buffer(fifo); 2491 2492 sc->sc_fflags &= ~(fflags & (FREAD | FWRITE)); 2493 if (sc->sc_fflags == 0) { 2494 atp_disable(sc); 2495 } 2496 } 2497 2498 static int 2499 atp_ioctl(struct usb_fifo *fifo, u_long cmd, void *addr, int fflags) 2500 { 2501 struct atp_softc *sc = usb_fifo_softc(fifo); 2502 mousemode_t mode; 2503 int error = 0; 2504 2505 mtx_lock(&sc->sc_mutex); 2506 2507 switch(cmd) { 2508 case MOUSE_GETHWINFO: 2509 *(mousehw_t *)addr = sc->sc_hw; 2510 break; 2511 case MOUSE_GETMODE: 2512 *(mousemode_t *)addr = sc->sc_mode; 2513 break; 2514 case MOUSE_SETMODE: 2515 mode = *(mousemode_t *)addr; 2516 2517 if (mode.level == -1) 2518 /* Don't change the current setting */ 2519 ; 2520 else if ((mode.level < 0) || (mode.level > 1)) { 2521 error = EINVAL; 2522 break; 2523 } 2524 sc->sc_mode.level = mode.level; 2525 sc->sc_pollrate = mode.rate; 2526 sc->sc_hw.buttons = 3; 2527 2528 if (sc->sc_mode.level == 0) { 2529 sc->sc_mode.protocol = MOUSE_PROTO_MSC; 2530 sc->sc_mode.packetsize = MOUSE_MSC_PACKETSIZE; 2531 sc->sc_mode.syncmask[0] = MOUSE_MSC_SYNCMASK; 2532 sc->sc_mode.syncmask[1] = MOUSE_MSC_SYNC; 2533 } else if (sc->sc_mode.level == 1) { 2534 sc->sc_mode.protocol = MOUSE_PROTO_SYSMOUSE; 2535 sc->sc_mode.packetsize = MOUSE_SYS_PACKETSIZE; 2536 sc->sc_mode.syncmask[0] = MOUSE_SYS_SYNCMASK; 2537 sc->sc_mode.syncmask[1] = MOUSE_SYS_SYNC; 2538 } 2539 atp_reset_buf(sc); 2540 break; 2541 case MOUSE_GETLEVEL: 2542 *(int *)addr = sc->sc_mode.level; 2543 break; 2544 case MOUSE_SETLEVEL: 2545 if ((*(int *)addr < 0) || (*(int *)addr > 1)) { 2546 error = EINVAL; 2547 break; 2548 } 2549 sc->sc_mode.level = *(int *)addr; 2550 sc->sc_hw.buttons = 3; 2551 2552 if (sc->sc_mode.level == 0) { 2553 sc->sc_mode.protocol = MOUSE_PROTO_MSC; 2554 sc->sc_mode.packetsize = MOUSE_MSC_PACKETSIZE; 2555 sc->sc_mode.syncmask[0] = MOUSE_MSC_SYNCMASK; 2556 sc->sc_mode.syncmask[1] = MOUSE_MSC_SYNC; 2557 } else if (sc->sc_mode.level == 1) { 2558 sc->sc_mode.protocol = MOUSE_PROTO_SYSMOUSE; 2559 sc->sc_mode.packetsize = MOUSE_SYS_PACKETSIZE; 2560 sc->sc_mode.syncmask[0] = MOUSE_SYS_SYNCMASK; 2561 sc->sc_mode.syncmask[1] = MOUSE_SYS_SYNC; 2562 } 2563 atp_reset_buf(sc); 2564 break; 2565 case MOUSE_GETSTATUS: { 2566 mousestatus_t *status = (mousestatus_t *)addr; 2567 2568 *status = sc->sc_status; 2569 sc->sc_status.obutton = sc->sc_status.button; 2570 sc->sc_status.button = 0; 2571 sc->sc_status.dx = 0; 2572 sc->sc_status.dy = 0; 2573 sc->sc_status.dz = 0; 2574 2575 if (status->dx || status->dy || status->dz) 2576 status->flags |= MOUSE_POSCHANGED; 2577 if (status->button != status->obutton) 2578 status->flags |= MOUSE_BUTTONSCHANGED; 2579 break; 2580 } 2581 2582 default: 2583 error = ENOTTY; 2584 break; 2585 } 2586 2587 mtx_unlock(&sc->sc_mutex); 2588 return (error); 2589 } 2590 2591 static int 2592 atp_sysctl_scale_factor_handler(SYSCTL_HANDLER_ARGS) 2593 { 2594 int error; 2595 u_int tmp; 2596 2597 tmp = atp_mickeys_scale_factor; 2598 error = sysctl_handle_int(oidp, &tmp, 0, req); 2599 if (error != 0 || req->newptr == NULL) 2600 return (error); 2601 2602 if (tmp == atp_mickeys_scale_factor) 2603 return (0); /* no change */ 2604 if ((tmp == 0) || (tmp > (10 * ATP_SCALE_FACTOR))) 2605 return (EINVAL); 2606 2607 atp_mickeys_scale_factor = tmp; 2608 DPRINTFN(ATP_LLEVEL_INFO, "%s: resetting mickeys_scale_factor to %u\n", 2609 ATP_DRIVER_NAME, tmp); 2610 2611 return (0); 2612 } 2613 2614 static device_method_t atp_methods[] = { 2615 DEVMETHOD(device_probe, atp_probe), 2616 DEVMETHOD(device_attach, atp_attach), 2617 DEVMETHOD(device_detach, atp_detach), 2618 2619 DEVMETHOD_END 2620 }; 2621 2622 static driver_t atp_driver = { 2623 .name = ATP_DRIVER_NAME, 2624 .methods = atp_methods, 2625 .size = sizeof(struct atp_softc) 2626 }; 2627 2628 DRIVER_MODULE(atp, uhub, atp_driver, NULL, NULL); 2629 MODULE_DEPEND(atp, usb, 1, 1, 1); 2630 MODULE_DEPEND(atp, hid, 1, 1, 1); 2631 MODULE_VERSION(atp, 1); 2632 USB_PNP_HOST_INFO(fg_devs); 2633 USB_PNP_HOST_INFO(wsp_devs); 2634