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