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