1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright (c) 2014-2020 Vladimir Kondratyev <wulf@FreeBSD.org> 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 */ 27 28 #include <sys/cdefs.h> 29 __FBSDID("$FreeBSD$"); 30 31 /* 32 * MS Windows 7/8/10 compatible HID Multi-touch Device driver. 33 * https://msdn.microsoft.com/en-us/library/windows/hardware/jj151569(v=vs.85).aspx 34 * http://download.microsoft.com/download/7/d/d/7dd44bb7-2a7a-4505-ac1c-7227d3d96d5b/hid-over-i2c-protocol-spec-v1-0.docx 35 * https://www.kernel.org/doc/Documentation/input/multi-touch-protocol.txt 36 */ 37 38 #include <sys/param.h> 39 #include <sys/bus.h> 40 #include <sys/kernel.h> 41 #include <sys/lock.h> 42 #include <sys/malloc.h> 43 #include <sys/module.h> 44 #include <sys/mutex.h> 45 #include <sys/sysctl.h> 46 #include <sys/systm.h> 47 48 #include <dev/evdev/evdev.h> 49 #include <dev/evdev/input.h> 50 51 #define HID_DEBUG_VAR hmt_debug 52 #include <dev/hid/hid.h> 53 #include <dev/hid/hidbus.h> 54 #include <dev/hid/hidquirk.h> 55 56 #include <dev/hid/hconf.h> 57 58 static SYSCTL_NODE(_hw_hid, OID_AUTO, hmt, CTLFLAG_RW, 0, 59 "MSWindows 7/8/10 compatible HID Multi-touch Device"); 60 #ifdef HID_DEBUG 61 static int hmt_debug = 0; 62 SYSCTL_INT(_hw_hid_hmt, OID_AUTO, debug, CTLFLAG_RWTUN, 63 &hmt_debug, 1, "Debug level"); 64 #endif 65 static bool hmt_timestamps = 0; 66 SYSCTL_BOOL(_hw_hid_hmt, OID_AUTO, timestamps, CTLFLAG_RDTUN, 67 &hmt_timestamps, 1, "Enable hardware timestamp reporting"); 68 69 #define HMT_BTN_MAX 8 /* Number of buttons supported */ 70 71 enum hmt_type { 72 HMT_TYPE_UNKNOWN = 0, /* HID report descriptor is not probed */ 73 HMT_TYPE_UNSUPPORTED, /* Repdescr does not belong to MT device */ 74 HMT_TYPE_TOUCHPAD, 75 HMT_TYPE_TOUCHSCREEN, 76 }; 77 78 enum { 79 HMT_TIP_SWITCH, 80 #define HMT_SLOT HMT_TIP_SWITCH 81 HMT_WIDTH, 82 #define HMT_MAJOR HMT_WIDTH 83 HMT_HEIGHT, 84 #define HMT_MINOR HMT_HEIGHT 85 HMT_ORIENTATION, 86 HMT_X, 87 HMT_Y, 88 HMT_CONTACTID, 89 HMT_PRESSURE, 90 HMT_IN_RANGE, 91 HMT_CONFIDENCE, 92 HMT_TOOL_X, 93 HMT_TOOL_Y, 94 HMT_N_USAGES, 95 }; 96 97 #define HMT_NO_CODE (ABS_MAX + 10) 98 #define HMT_NO_USAGE -1 99 100 struct hmt_hid_map_item { 101 char name[5]; 102 int32_t usage; /* HID usage */ 103 uint32_t code; /* Evdev event code */ 104 bool required; /* Required for MT Digitizers */ 105 }; 106 107 static const struct hmt_hid_map_item hmt_hid_map[HMT_N_USAGES] = { 108 [HMT_TIP_SWITCH] = { /* HMT_SLOT */ 109 .name = "TIP", 110 .usage = HID_USAGE2(HUP_DIGITIZERS, HUD_TIP_SWITCH), 111 .code = ABS_MT_SLOT, 112 .required = true, 113 }, 114 [HMT_WIDTH] = { /* HMT_MAJOR */ 115 .name = "WDTH", 116 .usage = HID_USAGE2(HUP_DIGITIZERS, HUD_WIDTH), 117 .code = ABS_MT_TOUCH_MAJOR, 118 .required = false, 119 }, 120 [HMT_HEIGHT] = { /* HMT_MINOR */ 121 .name = "HGHT", 122 .usage = HID_USAGE2(HUP_DIGITIZERS, HUD_HEIGHT), 123 .code = ABS_MT_TOUCH_MINOR, 124 .required = false, 125 }, 126 [HMT_ORIENTATION] = { 127 .name = "ORIE", 128 .usage = HMT_NO_USAGE, 129 .code = ABS_MT_ORIENTATION, 130 .required = false, 131 }, 132 [HMT_X] = { 133 .name = "X", 134 .usage = HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_X), 135 .code = ABS_MT_POSITION_X, 136 .required = true, 137 }, 138 [HMT_Y] = { 139 .name = "Y", 140 .usage = HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_Y), 141 .code = ABS_MT_POSITION_Y, 142 .required = true, 143 }, 144 [HMT_CONTACTID] = { 145 .name = "C_ID", 146 .usage = HID_USAGE2(HUP_DIGITIZERS, HUD_CONTACTID), 147 .code = ABS_MT_TRACKING_ID, 148 .required = true, 149 }, 150 [HMT_PRESSURE] = { 151 .name = "PRES", 152 .usage = HID_USAGE2(HUP_DIGITIZERS, HUD_TIP_PRESSURE), 153 .code = ABS_MT_PRESSURE, 154 .required = false, 155 }, 156 [HMT_IN_RANGE] = { 157 .name = "RANG", 158 .usage = HID_USAGE2(HUP_DIGITIZERS, HUD_IN_RANGE), 159 .code = ABS_MT_DISTANCE, 160 .required = false, 161 }, 162 [HMT_CONFIDENCE] = { 163 .name = "CONF", 164 .usage = HID_USAGE2(HUP_DIGITIZERS, HUD_CONFIDENCE), 165 .code = HMT_NO_CODE, 166 .required = false, 167 }, 168 [HMT_TOOL_X] = { /* Shares HID usage with HMT_X */ 169 .name = "TL_X", 170 .usage = HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_X), 171 .code = ABS_MT_TOOL_X, 172 .required = false, 173 }, 174 [HMT_TOOL_Y] = { /* Shares HID usage with HMT_Y */ 175 .name = "TL_Y", 176 .usage = HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_Y), 177 .code = ABS_MT_TOOL_Y, 178 .required = false, 179 }, 180 }; 181 182 struct hmt_softc { 183 device_t dev; 184 enum hmt_type type; 185 186 struct hid_absinfo ai[HMT_N_USAGES]; 187 struct hid_location locs[MAX_MT_SLOTS][HMT_N_USAGES]; 188 struct hid_location cont_count_loc; 189 struct hid_location btn_loc[HMT_BTN_MAX]; 190 struct hid_location int_btn_loc; 191 struct hid_location scan_time_loc; 192 int32_t scan_time_max; 193 int32_t scan_time; 194 int32_t timestamp; 195 bool touch; 196 bool prev_touch; 197 198 struct evdev_dev *evdev; 199 200 uint32_t slot_data[HMT_N_USAGES]; 201 uint8_t caps[howmany(HMT_N_USAGES, 8)]; 202 uint8_t buttons[howmany(HMT_BTN_MAX, 8)]; 203 uint32_t nconts_per_report; 204 uint32_t nconts_todo; 205 uint8_t report_id; 206 uint32_t max_button; 207 bool has_int_button; 208 bool is_clickpad; 209 bool do_timestamps; 210 bool iichid_sampling; 211 212 struct hid_location cont_max_loc; 213 uint32_t cont_max_rlen; 214 uint8_t cont_max_rid; 215 struct hid_location btn_type_loc; 216 uint32_t btn_type_rlen; 217 uint8_t btn_type_rid; 218 uint32_t thqa_cert_rlen; 219 uint8_t thqa_cert_rid; 220 }; 221 222 #define HMT_FOREACH_USAGE(caps, usage) \ 223 for ((usage) = 0; (usage) < HMT_N_USAGES; ++(usage)) \ 224 if (isset((caps), (usage))) 225 226 static enum hmt_type hmt_hid_parse(struct hmt_softc *, const void *, 227 hid_size_t, uint32_t, uint8_t); 228 static int hmt_set_input_mode(struct hmt_softc *, enum hconf_input_mode); 229 230 static hid_intr_t hmt_intr; 231 232 static device_probe_t hmt_probe; 233 static device_attach_t hmt_attach; 234 static device_detach_t hmt_detach; 235 236 static evdev_open_t hmt_ev_open; 237 static evdev_close_t hmt_ev_close; 238 239 static const struct evdev_methods hmt_evdev_methods = { 240 .ev_open = &hmt_ev_open, 241 .ev_close = &hmt_ev_close, 242 }; 243 244 static const struct hid_device_id hmt_devs[] = { 245 { HID_TLC(HUP_DIGITIZERS, HUD_TOUCHSCREEN) }, 246 { HID_TLC(HUP_DIGITIZERS, HUD_TOUCHPAD) }, 247 }; 248 249 static int 250 hmt_ev_close(struct evdev_dev *evdev) 251 { 252 return (hidbus_intr_stop(evdev_get_softc(evdev))); 253 } 254 255 static int 256 hmt_ev_open(struct evdev_dev *evdev) 257 { 258 return (hidbus_intr_start(evdev_get_softc(evdev))); 259 } 260 261 static int 262 hmt_probe(device_t dev) 263 { 264 struct hmt_softc *sc = device_get_softc(dev); 265 void *d_ptr; 266 hid_size_t d_len; 267 int err; 268 269 err = HIDBUS_LOOKUP_DRIVER_INFO(dev, hmt_devs); 270 if (err != 0) 271 return (err); 272 273 err = hid_get_report_descr(dev, &d_ptr, &d_len); 274 if (err != 0) { 275 device_printf(dev, "could not retrieve report descriptor from " 276 "device: %d\n", err); 277 return (ENXIO); 278 } 279 280 /* Check if report descriptor belongs to a HID multitouch device */ 281 if (sc->type == HMT_TYPE_UNKNOWN) 282 sc->type = hmt_hid_parse(sc, d_ptr, d_len, 283 hidbus_get_usage(dev), hidbus_get_index(dev)); 284 if (sc->type == HMT_TYPE_UNSUPPORTED) 285 return (ENXIO); 286 287 hidbus_set_desc(dev, 288 sc->type == HMT_TYPE_TOUCHPAD ? "TouchPad" : "TouchScreen"); 289 290 return (BUS_PROBE_DEFAULT); 291 } 292 293 static int 294 hmt_attach(device_t dev) 295 { 296 struct hmt_softc *sc = device_get_softc(dev); 297 const struct hid_device_info *hw = hid_get_device_info(dev); 298 void *d_ptr; 299 uint8_t *fbuf = NULL; 300 hid_size_t d_len, fsize; 301 uint32_t cont_count_max; 302 int nbuttons, btn; 303 size_t i; 304 int err; 305 306 err = hid_get_report_descr(dev, &d_ptr, &d_len); 307 if (err != 0) { 308 device_printf(dev, "could not retrieve report descriptor from " 309 "device: %d\n", err); 310 return (ENXIO); 311 } 312 313 sc->dev = dev; 314 315 fsize = hid_report_size_max(d_ptr, d_len, hid_feature, NULL); 316 if (fsize != 0) 317 fbuf = malloc(fsize, M_TEMP, M_WAITOK | M_ZERO); 318 319 /* Fetch and parse "Contact count maximum" feature report */ 320 if (sc->cont_max_rlen > 1) { 321 err = hid_get_report(dev, fbuf, sc->cont_max_rlen, NULL, 322 HID_FEATURE_REPORT, sc->cont_max_rid); 323 if (err == 0) { 324 cont_count_max = hid_get_udata(fbuf + 1, 325 sc->cont_max_rlen - 1, &sc->cont_max_loc); 326 /* 327 * Feature report is a primary source of 328 * 'Contact Count Maximum' 329 */ 330 if (cont_count_max > 0) 331 sc->ai[HMT_SLOT].max = cont_count_max - 1; 332 } else 333 DPRINTF("hid_get_report error=%d\n", err); 334 } else 335 DPRINTF("Feature report %hhu size invalid: %u\n", 336 sc->cont_max_rid, sc->cont_max_rlen); 337 338 /* Fetch and parse "Button type" feature report */ 339 if (sc->btn_type_rlen > 1 && sc->btn_type_rid != sc->cont_max_rid) { 340 bzero(fbuf, fsize); 341 err = hid_get_report(dev, fbuf, sc->btn_type_rlen, NULL, 342 HID_FEATURE_REPORT, sc->btn_type_rid); 343 } 344 if (sc->btn_type_rlen > 1) { 345 if (err == 0) 346 sc->is_clickpad = hid_get_udata(fbuf + 1, 347 sc->btn_type_rlen - 1, &sc->btn_type_loc) == 0; 348 else 349 DPRINTF("hid_get_report error=%d\n", err); 350 } 351 352 /* Fetch THQA certificate to enable some devices like WaveShare */ 353 if (sc->thqa_cert_rlen > 1 && sc->thqa_cert_rid != sc->cont_max_rid) 354 (void)hid_get_report(dev, fbuf, sc->thqa_cert_rlen, NULL, 355 HID_FEATURE_REPORT, sc->thqa_cert_rid); 356 357 free(fbuf, M_TEMP); 358 359 /* Switch touchpad in to absolute multitouch mode */ 360 if (sc->type == HMT_TYPE_TOUCHPAD) { 361 err = hmt_set_input_mode(sc, HCONF_INPUT_MODE_MT_TOUCHPAD); 362 if (err != 0) 363 DPRINTF("Failed to set input mode: %d\n", err); 364 } 365 366 /* Cap contact count maximum to MAX_MT_SLOTS */ 367 if (sc->ai[HMT_SLOT].max >= MAX_MT_SLOTS) { 368 DPRINTF("Hardware reported %d contacts while only %d is " 369 "supported\n", (int)sc->ai[HMT_SLOT].max+1, MAX_MT_SLOTS); 370 sc->ai[HMT_SLOT].max = MAX_MT_SLOTS - 1; 371 } 372 373 if (hid_test_quirk(hw, HQ_MT_TIMESTAMP) || hmt_timestamps) 374 sc->do_timestamps = true; 375 if (hid_test_quirk(hw, HQ_IICHID_SAMPLING)) 376 sc->iichid_sampling = true; 377 378 hidbus_set_intr(dev, hmt_intr, sc); 379 380 sc->evdev = evdev_alloc(); 381 evdev_set_name(sc->evdev, device_get_desc(dev)); 382 evdev_set_phys(sc->evdev, device_get_nameunit(dev)); 383 evdev_set_id(sc->evdev, hw->idBus, hw->idVendor, hw->idProduct, 384 hw->idVersion); 385 evdev_set_serial(sc->evdev, hw->serial); 386 evdev_set_methods(sc->evdev, dev, &hmt_evdev_methods); 387 evdev_set_flag(sc->evdev, EVDEV_FLAG_MT_STCOMPAT); 388 evdev_set_flag(sc->evdev, EVDEV_FLAG_EXT_EPOCH); /* hidbus child */ 389 switch (sc->type) { 390 case HMT_TYPE_TOUCHSCREEN: 391 evdev_support_prop(sc->evdev, INPUT_PROP_DIRECT); 392 break; 393 case HMT_TYPE_TOUCHPAD: 394 evdev_support_prop(sc->evdev, INPUT_PROP_POINTER); 395 if (sc->is_clickpad) 396 evdev_support_prop(sc->evdev, INPUT_PROP_BUTTONPAD); 397 break; 398 default: 399 KASSERT(0, ("hmt_attach: unsupported touch device type")); 400 } 401 evdev_support_event(sc->evdev, EV_SYN); 402 evdev_support_event(sc->evdev, EV_ABS); 403 if (sc->do_timestamps) { 404 evdev_support_event(sc->evdev, EV_MSC); 405 evdev_support_msc(sc->evdev, MSC_TIMESTAMP); 406 } 407 if (sc->iichid_sampling) 408 evdev_set_flag(sc->evdev, EVDEV_FLAG_MT_AUTOREL); 409 nbuttons = 0; 410 if (sc->max_button != 0 || sc->has_int_button) { 411 evdev_support_event(sc->evdev, EV_KEY); 412 if (sc->has_int_button) 413 evdev_support_key(sc->evdev, BTN_LEFT); 414 for (btn = 0; btn < sc->max_button; ++btn) { 415 if (isset(sc->buttons, btn)) { 416 evdev_support_key(sc->evdev, BTN_MOUSE + btn); 417 nbuttons++; 418 } 419 } 420 } 421 HMT_FOREACH_USAGE(sc->caps, i) { 422 if (hmt_hid_map[i].code != HMT_NO_CODE) 423 evdev_support_abs(sc->evdev, hmt_hid_map[i].code, 424 sc->ai[i].min, sc->ai[i].max, 0, 0, sc->ai[i].res); 425 } 426 427 err = evdev_register(sc->evdev); 428 if (err) { 429 hmt_detach(dev); 430 return (ENXIO); 431 } 432 433 /* Announce information about the touch device */ 434 device_printf(sc->dev, "Multitouch %s with %d external button%s%s\n", 435 sc->type == HMT_TYPE_TOUCHSCREEN ? "touchscreen" : "touchpad", 436 nbuttons, nbuttons != 1 ? "s" : "", 437 sc->is_clickpad ? ", click-pad" : ""); 438 device_printf(sc->dev, 439 "%d contacts with [%s%s%s%s%s] properties. Report range [%d:%d] - [%d:%d]\n", 440 (int)sc->ai[HMT_SLOT].max + 1, 441 isset(sc->caps, HMT_IN_RANGE) ? "R" : "", 442 isset(sc->caps, HMT_CONFIDENCE) ? "C" : "", 443 isset(sc->caps, HMT_WIDTH) ? "W" : "", 444 isset(sc->caps, HMT_HEIGHT) ? "H" : "", 445 isset(sc->caps, HMT_PRESSURE) ? "P" : "", 446 (int)sc->ai[HMT_X].min, (int)sc->ai[HMT_Y].min, 447 (int)sc->ai[HMT_X].max, (int)sc->ai[HMT_Y].max); 448 449 return (0); 450 } 451 452 static int 453 hmt_detach(device_t dev) 454 { 455 struct hmt_softc *sc = device_get_softc(dev); 456 457 evdev_free(sc->evdev); 458 459 return (0); 460 } 461 462 static void 463 hmt_intr(void *context, void *buf, hid_size_t len) 464 { 465 struct hmt_softc *sc = context; 466 size_t usage; 467 uint32_t *slot_data = sc->slot_data; 468 uint32_t cont, btn; 469 uint32_t cont_count; 470 uint32_t width; 471 uint32_t height; 472 uint32_t int_btn = 0; 473 uint32_t left_btn = 0; 474 int32_t slot; 475 uint32_t scan_time; 476 int32_t delta; 477 uint8_t id; 478 479 /* 480 * Special packet of zero length is generated by iichid driver running 481 * in polling mode at the start of inactivity period to workaround 482 * "stuck touch" problem caused by miss of finger release events. 483 * This snippet is to be removed after GPIO interrupt support is added. 484 */ 485 if (sc->iichid_sampling && len == 0) { 486 sc->prev_touch = false; 487 sc->timestamp = 0; 488 for (slot = 0; slot <= sc->ai[HMT_SLOT].max; slot++) { 489 evdev_push_abs(sc->evdev, ABS_MT_SLOT, slot); 490 evdev_push_abs(sc->evdev, ABS_MT_TRACKING_ID, -1); 491 } 492 evdev_sync(sc->evdev); 493 return; 494 } 495 496 /* Ignore irrelevant reports */ 497 id = sc->report_id != 0 ? *(uint8_t *)buf : 0; 498 if (sc->report_id != id) { 499 DPRINTF("Skip report with unexpected ID: %hhu\n", id); 500 return; 501 } 502 503 /* Strip leading "report ID" byte */ 504 if (sc->report_id != 0) { 505 len--; 506 buf = (uint8_t *)buf + 1; 507 } 508 509 /* 510 * "In Parallel mode, devices report all contact information in a 511 * single packet. Each physical contact is represented by a logical 512 * collection that is embedded in the top-level collection." 513 * 514 * Since additional contacts that were not present will still be in the 515 * report with contactid=0 but contactids are zero-based, find 516 * contactcount first. 517 */ 518 cont_count = hid_get_udata(buf, len, &sc->cont_count_loc); 519 /* 520 * "In Hybrid mode, the number of contacts that can be reported in one 521 * report is less than the maximum number of contacts that the device 522 * supports. For example, a device that supports a maximum of 523 * 4 concurrent physical contacts, can set up its top-level collection 524 * to deliver a maximum of two contacts in one report. If four contact 525 * points are present, the device can break these up into two serial 526 * reports that deliver two contacts each. 527 * 528 * "When a device delivers data in this manner, the Contact Count usage 529 * value in the first report should reflect the total number of 530 * contacts that are being delivered in the hybrid reports. The other 531 * serial reports should have a contact count of zero (0)." 532 */ 533 if (cont_count != 0) 534 sc->nconts_todo = cont_count; 535 536 #ifdef HID_DEBUG 537 DPRINTFN(6, "cont_count:%2u", (unsigned)cont_count); 538 if (hmt_debug >= 6) { 539 HMT_FOREACH_USAGE(sc->caps, usage) { 540 if (hmt_hid_map[usage].usage != HMT_NO_USAGE) 541 printf(" %-4s", hmt_hid_map[usage].name); 542 } 543 printf("\n"); 544 } 545 #endif 546 547 /* Find the number of contacts reported in current report */ 548 cont_count = MIN(sc->nconts_todo, sc->nconts_per_report); 549 550 /* Use protocol Type B for reporting events */ 551 for (cont = 0; cont < cont_count; cont++) { 552 bzero(slot_data, sizeof(sc->slot_data)); 553 HMT_FOREACH_USAGE(sc->caps, usage) { 554 if (sc->locs[cont][usage].size > 0) 555 slot_data[usage] = hid_get_udata( 556 buf, len, &sc->locs[cont][usage]); 557 } 558 559 slot = evdev_get_mt_slot_by_tracking_id(sc->evdev, 560 slot_data[HMT_CONTACTID]); 561 562 #ifdef HID_DEBUG 563 DPRINTFN(6, "cont%01x: data = ", cont); 564 if (hmt_debug >= 6) { 565 HMT_FOREACH_USAGE(sc->caps, usage) { 566 if (hmt_hid_map[usage].usage != HMT_NO_USAGE) 567 printf("%04x ", slot_data[usage]); 568 } 569 printf("slot = %d\n", (int)slot); 570 } 571 #endif 572 573 if (slot == -1) { 574 DPRINTF("Slot overflow for contact_id %u\n", 575 (unsigned)slot_data[HMT_CONTACTID]); 576 continue; 577 } 578 579 if (slot_data[HMT_TIP_SWITCH] != 0 && 580 !(isset(sc->caps, HMT_CONFIDENCE) && 581 slot_data[HMT_CONFIDENCE] == 0)) { 582 /* This finger is in proximity of the sensor */ 583 sc->touch = true; 584 slot_data[HMT_SLOT] = slot; 585 slot_data[HMT_IN_RANGE] = !slot_data[HMT_IN_RANGE]; 586 /* Divided by two to match visual scale of touch */ 587 width = slot_data[HMT_WIDTH] >> 1; 588 height = slot_data[HMT_HEIGHT] >> 1; 589 slot_data[HMT_ORIENTATION] = width > height; 590 slot_data[HMT_MAJOR] = MAX(width, height); 591 slot_data[HMT_MINOR] = MIN(width, height); 592 593 HMT_FOREACH_USAGE(sc->caps, usage) 594 if (hmt_hid_map[usage].code != HMT_NO_CODE) 595 evdev_push_abs(sc->evdev, 596 hmt_hid_map[usage].code, 597 slot_data[usage]); 598 } else { 599 evdev_push_abs(sc->evdev, ABS_MT_SLOT, slot); 600 evdev_push_abs(sc->evdev, ABS_MT_TRACKING_ID, -1); 601 } 602 } 603 604 sc->nconts_todo -= cont_count; 605 if (sc->do_timestamps && sc->nconts_todo == 0) { 606 /* HUD_SCAN_TIME is measured in 100us, convert to us. */ 607 scan_time = hid_get_udata(buf, len, &sc->scan_time_loc); 608 if (sc->prev_touch) { 609 delta = scan_time - sc->scan_time; 610 if (delta < 0) 611 delta += sc->scan_time_max; 612 } else 613 delta = 0; 614 sc->scan_time = scan_time; 615 sc->timestamp += delta * 100; 616 evdev_push_msc(sc->evdev, MSC_TIMESTAMP, sc->timestamp); 617 sc->prev_touch = sc->touch; 618 sc->touch = false; 619 if (!sc->prev_touch) 620 sc->timestamp = 0; 621 } 622 if (sc->nconts_todo == 0) { 623 /* Report both the click and external left btns as BTN_LEFT */ 624 if (sc->has_int_button) 625 int_btn = hid_get_data(buf, len, &sc->int_btn_loc); 626 if (isset(sc->buttons, 0)) 627 left_btn = hid_get_data(buf, len, &sc->btn_loc[0]); 628 if (sc->has_int_button || isset(sc->buttons, 0)) 629 evdev_push_key(sc->evdev, BTN_LEFT, 630 (int_btn != 0) | (left_btn != 0)); 631 for (btn = 1; btn < sc->max_button; ++btn) { 632 if (isset(sc->buttons, btn)) 633 evdev_push_key(sc->evdev, BTN_MOUSE + btn, 634 hid_get_data(buf, 635 len, 636 &sc->btn_loc[btn]) != 0); 637 } 638 evdev_sync(sc->evdev); 639 } 640 } 641 642 static enum hmt_type 643 hmt_hid_parse(struct hmt_softc *sc, const void *d_ptr, hid_size_t d_len, 644 uint32_t tlc_usage, uint8_t tlc_index) 645 { 646 struct hid_absinfo ai; 647 struct hid_item hi; 648 struct hid_data *hd; 649 uint32_t flags; 650 size_t i; 651 size_t cont = 0; 652 enum hmt_type type; 653 uint32_t left_btn, btn; 654 int32_t cont_count_max = 0; 655 uint8_t report_id = 0; 656 bool finger_coll = false; 657 bool cont_count_found = false; 658 bool scan_time_found = false; 659 bool has_int_button = false; 660 661 #define HMT_HI_ABSOLUTE(hi) \ 662 (((hi).flags & (HIO_CONST|HIO_VARIABLE|HIO_RELATIVE)) == HIO_VARIABLE) 663 #define HUMS_THQA_CERT 0xC5 664 665 /* 666 * Get left button usage taking in account MS Precision Touchpad specs. 667 * For Windows PTP report descriptor assigns buttons in following way: 668 * Button 1 - Indicates Button State for touchpad button integrated 669 * with digitizer. 670 * Button 2 - Indicates Button State for external button for primary 671 * (default left) clicking. 672 * Button 3 - Indicates Button State for external button for secondary 673 * (default right) clicking. 674 * If a device only supports external buttons, it must still use 675 * Button 2 and Button 3 to reference the external buttons. 676 */ 677 switch (tlc_usage) { 678 case HID_USAGE2(HUP_DIGITIZERS, HUD_TOUCHSCREEN): 679 type = HMT_TYPE_TOUCHSCREEN; 680 left_btn = 1; 681 break; 682 case HID_USAGE2(HUP_DIGITIZERS, HUD_TOUCHPAD): 683 type = HMT_TYPE_TOUCHPAD; 684 left_btn = 2; 685 break; 686 default: 687 return (HMT_TYPE_UNSUPPORTED); 688 } 689 690 /* Parse features for mandatory maximum contact count usage */ 691 if (!hidbus_locate(d_ptr, d_len, 692 HID_USAGE2(HUP_DIGITIZERS, HUD_CONTACT_MAX), hid_feature, 693 tlc_index, 0, &sc->cont_max_loc, &flags, &sc->cont_max_rid, &ai) || 694 (flags & (HIO_VARIABLE | HIO_RELATIVE)) != HIO_VARIABLE) 695 return (HMT_TYPE_UNSUPPORTED); 696 697 cont_count_max = ai.max; 698 699 /* Parse features for button type usage */ 700 if (hidbus_locate(d_ptr, d_len, 701 HID_USAGE2(HUP_DIGITIZERS, HUD_BUTTON_TYPE), hid_feature, 702 tlc_index, 0, &sc->btn_type_loc, &flags, &sc->btn_type_rid, NULL) 703 && (flags & (HIO_VARIABLE | HIO_RELATIVE)) != HIO_VARIABLE) 704 sc->btn_type_rid = 0; 705 706 /* Parse features for THQA certificate report ID */ 707 hidbus_locate(d_ptr, d_len, HID_USAGE2(HUP_MICROSOFT, HUMS_THQA_CERT), 708 hid_feature, tlc_index, 0, NULL, NULL, &sc->thqa_cert_rid, NULL); 709 710 /* Parse input for other parameters */ 711 hd = hid_start_parse(d_ptr, d_len, 1 << hid_input); 712 HIDBUS_FOREACH_ITEM(hd, &hi, tlc_index) { 713 switch (hi.kind) { 714 case hid_collection: 715 if (hi.collevel == 2 && 716 hi.usage == HID_USAGE2(HUP_DIGITIZERS, HUD_FINGER)) 717 finger_coll = true; 718 break; 719 case hid_endcollection: 720 if (hi.collevel == 1 && finger_coll) { 721 finger_coll = false; 722 cont++; 723 } 724 break; 725 case hid_input: 726 /* 727 * Ensure that all usages belong to the same report 728 */ 729 if (HMT_HI_ABSOLUTE(hi) && 730 (report_id == 0 || report_id == hi.report_ID)) 731 report_id = hi.report_ID; 732 else 733 break; 734 735 if (hi.collevel == 1 && left_btn == 2 && 736 hi.usage == HID_USAGE2(HUP_BUTTON, 1)) { 737 has_int_button = true; 738 sc->int_btn_loc = hi.loc; 739 break; 740 } 741 if (hi.collevel == 1 && 742 hi.usage >= HID_USAGE2(HUP_BUTTON, left_btn) && 743 hi.usage <= HID_USAGE2(HUP_BUTTON, HMT_BTN_MAX)) { 744 btn = (hi.usage & 0xFFFF) - left_btn; 745 setbit(sc->buttons, btn); 746 sc->btn_loc[btn] = hi.loc; 747 if (btn >= sc->max_button) 748 sc->max_button = btn + 1; 749 break; 750 } 751 if (hi.collevel == 1 && hi.usage == 752 HID_USAGE2(HUP_DIGITIZERS, HUD_CONTACTCOUNT)) { 753 cont_count_found = true; 754 sc->cont_count_loc = hi.loc; 755 break; 756 } 757 /* Scan time is required but clobbered by evdev */ 758 if (hi.collevel == 1 && hi.usage == 759 HID_USAGE2(HUP_DIGITIZERS, HUD_SCAN_TIME)) { 760 scan_time_found = true; 761 sc->scan_time_loc = hi.loc; 762 sc->scan_time_max = hi.logical_maximum; 763 break; 764 } 765 766 if (!finger_coll || hi.collevel != 2) 767 break; 768 if (cont >= MAX_MT_SLOTS) { 769 DPRINTF("Finger %zu ignored\n", cont); 770 break; 771 } 772 773 for (i = 0; i < HMT_N_USAGES; i++) { 774 if (hi.usage == hmt_hid_map[i].usage) { 775 /* 776 * HUG_X usage is an array mapped to 777 * both ABS_MT_POSITION and ABS_MT_TOOL 778 * events. So don`t stop search if we 779 * already have HUG_X mapping done. 780 */ 781 if (sc->locs[cont][i].size) 782 continue; 783 sc->locs[cont][i] = hi.loc; 784 /* 785 * Hid parser returns valid logical and 786 * physical sizes for first finger only 787 * at least on ElanTS 0x04f3:0x0012. 788 */ 789 if (cont > 0) 790 break; 791 setbit(sc->caps, i); 792 sc->ai[i] = (struct hid_absinfo) { 793 .max = hi.logical_maximum, 794 .min = hi.logical_minimum, 795 .res = hid_item_resolution(&hi), 796 }; 797 break; 798 } 799 } 800 break; 801 default: 802 break; 803 } 804 } 805 hid_end_parse(hd); 806 807 /* Check for required HID Usages */ 808 if (!cont_count_found || !scan_time_found || cont == 0) 809 return (HMT_TYPE_UNSUPPORTED); 810 for (i = 0; i < HMT_N_USAGES; i++) { 811 if (hmt_hid_map[i].required && isclr(sc->caps, i)) 812 return (HMT_TYPE_UNSUPPORTED); 813 } 814 815 /* Touchpads must have at least one button */ 816 if (type == HMT_TYPE_TOUCHPAD && !sc->max_button && !has_int_button) 817 return (HMT_TYPE_UNSUPPORTED); 818 819 /* 820 * According to specifications 'Contact Count Maximum' should be read 821 * from Feature Report rather than from HID descriptor. Set sane 822 * default value now to handle the case of 'Get Report' request failure 823 */ 824 if (cont_count_max < 1) 825 cont_count_max = cont; 826 827 /* Set number of MT protocol type B slots */ 828 sc->ai[HMT_SLOT] = (struct hid_absinfo) { 829 .min = 0, 830 .max = cont_count_max - 1, 831 .res = 0, 832 }; 833 834 /* Report touch orientation if both width and height are supported */ 835 if (isset(sc->caps, HMT_WIDTH) && isset(sc->caps, HMT_HEIGHT)) { 836 setbit(sc->caps, HMT_ORIENTATION); 837 sc->ai[HMT_ORIENTATION].max = 1; 838 } 839 840 sc->cont_max_rlen = hid_report_size(d_ptr, d_len, hid_feature, 841 sc->cont_max_rid); 842 if (sc->btn_type_rid > 0) 843 sc->btn_type_rlen = hid_report_size(d_ptr, d_len, 844 hid_feature, sc->btn_type_rid); 845 if (sc->thqa_cert_rid > 0) 846 sc->thqa_cert_rlen = hid_report_size(d_ptr, d_len, 847 hid_feature, sc->thqa_cert_rid); 848 849 sc->report_id = report_id; 850 sc->nconts_per_report = cont; 851 sc->has_int_button = has_int_button; 852 853 return (type); 854 } 855 856 static int 857 hmt_set_input_mode(struct hmt_softc *sc, enum hconf_input_mode mode) 858 { 859 devclass_t hconf_devclass; 860 device_t hconf; 861 int err; 862 863 GIANT_REQUIRED; 864 865 /* Find touchpad's configuration TLC */ 866 hconf = hidbus_find_child(device_get_parent(sc->dev), 867 HID_USAGE2(HUP_DIGITIZERS, HUD_CONFIG)); 868 if (hconf == NULL) 869 return (ENXIO); 870 871 /* Ensure that hconf driver is attached to configuration TLC */ 872 if (device_is_alive(hconf) == 0) 873 device_probe_and_attach(hconf); 874 if (device_is_attached(hconf) == 0) 875 return (ENXIO); 876 hconf_devclass = devclass_find("hconf"); 877 if (device_get_devclass(hconf) != hconf_devclass) 878 return (ENXIO); 879 880 /* hconf_set_input_mode can drop the Giant while sleeping */ 881 device_busy(hconf); 882 err = hconf_set_input_mode(hconf, mode); 883 device_unbusy(hconf); 884 885 return (err); 886 } 887 888 static devclass_t hmt_devclass; 889 890 static device_method_t hmt_methods[] = { 891 DEVMETHOD(device_probe, hmt_probe), 892 DEVMETHOD(device_attach, hmt_attach), 893 DEVMETHOD(device_detach, hmt_detach), 894 895 DEVMETHOD_END 896 }; 897 898 static driver_t hmt_driver = { 899 .name = "hmt", 900 .methods = hmt_methods, 901 .size = sizeof(struct hmt_softc), 902 }; 903 904 DRIVER_MODULE(hmt, hidbus, hmt_driver, hmt_devclass, NULL, 0); 905 MODULE_DEPEND(hmt, hidbus, 1, 1, 1); 906 MODULE_DEPEND(hmt, hid, 1, 1, 1); 907 MODULE_DEPEND(hmt, hconf, 1, 1, 1); 908 MODULE_DEPEND(hmt, evdev, 1, 1, 1); 909 MODULE_VERSION(hmt, 1); 910 HID_PNP_INFO(hmt_devs); 911