1 /* $NetBSD: ihidev.c,v 1.23 2022/01/14 22:26:45 riastradh Exp $ */ 2 /* $OpenBSD ihidev.c,v 1.13 2017/04/08 02:57:23 deraadt Exp $ */ 3 4 /*- 5 * Copyright (c) 2017 The NetBSD Foundation, Inc. 6 * All rights reserved. 7 * 8 * This code is derived from software contributed to The NetBSD Foundation 9 * by Manuel Bouyer. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 /* 34 * Copyright (c) 2015, 2016 joshua stein <jcs@openbsd.org> 35 * 36 * Permission to use, copy, modify, and distribute this software for any 37 * purpose with or without fee is hereby granted, provided that the above 38 * copyright notice and this permission notice appear in all copies. 39 * 40 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 41 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 42 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 43 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 44 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 45 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 46 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 47 */ 48 49 /* 50 * HID-over-i2c driver 51 * 52 * https://msdn.microsoft.com/en-us/library/windows/hardware/dn642101%28v=vs.85%29.aspx 53 * 54 */ 55 56 #include <sys/cdefs.h> 57 __KERNEL_RCSID(0, "$NetBSD: ihidev.c,v 1.23 2022/01/14 22:26:45 riastradh Exp $"); 58 59 #include <sys/param.h> 60 #include <sys/systm.h> 61 #include <sys/device.h> 62 #include <sys/kmem.h> 63 #include <sys/workqueue.h> 64 65 #include <dev/i2c/i2cvar.h> 66 #include <dev/i2c/ihidev.h> 67 68 #include <dev/hid/hid.h> 69 70 #if defined(__i386__) || defined(__amd64__) 71 # include "acpica.h" 72 #endif 73 #if NACPICA > 0 74 #include <dev/acpi/acpivar.h> 75 #include <dev/acpi/acpi_intr.h> 76 #endif 77 78 #include "locators.h" 79 80 /* #define IHIDEV_DEBUG */ 81 82 #ifdef IHIDEV_DEBUG 83 #define DPRINTF(x) printf x 84 #else 85 #define DPRINTF(x) 86 #endif 87 88 /* 7.2 */ 89 enum { 90 I2C_HID_CMD_DESCR = 0x0, 91 I2C_HID_CMD_RESET = 0x1, 92 I2C_HID_CMD_GET_REPORT = 0x2, 93 I2C_HID_CMD_SET_REPORT = 0x3, 94 I2C_HID_CMD_GET_IDLE = 0x4, 95 I2C_HID_CMD_SET_IDLE = 0x5, 96 I2C_HID_CMD_GET_PROTO = 0x6, 97 I2C_HID_CMD_SET_PROTO = 0x7, 98 I2C_HID_CMD_SET_POWER = 0x8, 99 100 /* pseudo commands */ 101 I2C_HID_REPORT_DESCR = 0x100, 102 }; 103 104 static int I2C_HID_POWER_ON = 0x0; 105 static int I2C_HID_POWER_OFF = 0x1; 106 107 static int ihidev_match(device_t, cfdata_t, void *); 108 static void ihidev_attach(device_t, device_t, void *); 109 static int ihidev_detach(device_t, int); 110 CFATTACH_DECL_NEW(ihidev, sizeof(struct ihidev_softc), 111 ihidev_match, ihidev_attach, ihidev_detach, NULL); 112 113 static bool ihidev_intr_init(struct ihidev_softc *); 114 static void ihidev_intr_fini(struct ihidev_softc *); 115 116 static bool ihidev_suspend(device_t, const pmf_qual_t *); 117 static bool ihidev_resume(device_t, const pmf_qual_t *); 118 static int ihidev_hid_command(struct ihidev_softc *, int, void *, bool); 119 static int ihidev_intr(void *); 120 static void ihidev_work(struct work *, void *); 121 static int ihidev_reset(struct ihidev_softc *, bool); 122 static int ihidev_hid_desc_parse(struct ihidev_softc *); 123 124 static int ihidev_maxrepid(void *, int); 125 static int ihidev_print(void *, const char *); 126 static int ihidev_submatch(device_t, cfdata_t, const int *, void *); 127 128 static bool ihidev_acpi_get_info(struct ihidev_softc *); 129 130 static const struct device_compatible_entry compat_data[] = { 131 { .compat = "PNP0C50" }, 132 { .compat = "ACPI0C50" }, 133 { .compat = "hid-over-i2c" }, 134 DEVICE_COMPAT_EOL 135 }; 136 137 static int 138 ihidev_match(device_t parent, cfdata_t match, void *aux) 139 { 140 struct i2c_attach_args * const ia = aux; 141 int match_result; 142 143 if (iic_use_direct_match(ia, match, compat_data, &match_result)) 144 return I2C_MATCH_DIRECT_COMPATIBLE; 145 146 return 0; 147 } 148 149 static void 150 ihidev_attach(device_t parent, device_t self, void *aux) 151 { 152 struct ihidev_softc *sc = device_private(self); 153 struct i2c_attach_args *ia = aux; 154 struct ihidev_attach_arg iha; 155 device_t dev; 156 int repid, repsz; 157 int isize; 158 int locs[IHIDBUSCF_NLOCS]; 159 160 sc->sc_dev = self; 161 sc->sc_tag = ia->ia_tag; 162 sc->sc_addr = ia->ia_addr; 163 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE); 164 165 sc->sc_phandle = ia->ia_cookie; 166 if (ia->ia_cookietype != I2C_COOKIE_ACPI) { 167 aprint_error(": unsupported device tree type\n"); 168 return; 169 } 170 if (!ihidev_acpi_get_info(sc)) { 171 return; 172 } 173 174 if (ihidev_hid_command(sc, I2C_HID_CMD_DESCR, NULL, false) || 175 ihidev_hid_desc_parse(sc)) { 176 aprint_error(": failed fetching initial HID descriptor\n"); 177 return; 178 } 179 180 aprint_naive("\n"); 181 aprint_normal(": vendor 0x%x product 0x%x, %s\n", 182 le16toh(sc->hid_desc.wVendorID), le16toh(sc->hid_desc.wProductID), 183 ia->ia_name); 184 185 sc->sc_nrepid = ihidev_maxrepid(sc->sc_report, sc->sc_reportlen); 186 if (sc->sc_nrepid < 0) 187 return; 188 189 aprint_normal_dev(self, "%d report id%s\n", sc->sc_nrepid, 190 sc->sc_nrepid > 1 ? "s" : ""); 191 192 sc->sc_nrepid++; 193 sc->sc_subdevs = kmem_zalloc(sc->sc_nrepid * sizeof(struct ihidev *), 194 KM_SLEEP); 195 196 /* find largest report size and allocate memory for input buffer */ 197 sc->sc_isize = le16toh(sc->hid_desc.wMaxInputLength); 198 for (repid = 0; repid < sc->sc_nrepid; repid++) { 199 repsz = hid_report_size(sc->sc_report, sc->sc_reportlen, 200 hid_input, repid); 201 202 isize = repsz + 2; /* two bytes for the length */ 203 isize += (sc->sc_nrepid != 1); /* one byte for the report ID */ 204 if (isize > sc->sc_isize) 205 sc->sc_isize = isize; 206 207 DPRINTF(("%s: repid %d size %d\n", sc->sc_dev.dv_xname, repid, 208 repsz)); 209 } 210 sc->sc_ibuf = kmem_zalloc(sc->sc_isize, KM_SLEEP); 211 if (!ihidev_intr_init(sc)) { 212 return; 213 } 214 215 iha.iaa = ia; 216 iha.parent = sc; 217 218 /* Look for a driver claiming all report IDs first. */ 219 iha.reportid = IHIDEV_CLAIM_ALLREPORTID; 220 locs[IHIDBUSCF_REPORTID] = IHIDEV_CLAIM_ALLREPORTID; 221 dev = config_found(self, &iha, ihidev_print, 222 CFARGS(.submatch = ihidev_submatch, 223 .locators = locs)); 224 if (dev != NULL) { 225 for (repid = 0; repid < sc->sc_nrepid; repid++) 226 sc->sc_subdevs[repid] = device_private(dev); 227 return; 228 } 229 230 for (repid = 0; repid < sc->sc_nrepid; repid++) { 231 if (hid_report_size(sc->sc_report, sc->sc_reportlen, hid_input, 232 repid) == 0 && 233 hid_report_size(sc->sc_report, sc->sc_reportlen, 234 hid_output, repid) == 0 && 235 hid_report_size(sc->sc_report, sc->sc_reportlen, 236 hid_feature, repid) == 0) 237 continue; 238 239 iha.reportid = repid; 240 locs[IHIDBUSCF_REPORTID] = repid; 241 dev = config_found(self, &iha, ihidev_print, 242 CFARGS(.submatch = ihidev_submatch, 243 .locators = locs)); 244 sc->sc_subdevs[repid] = device_private(dev); 245 } 246 247 /* power down until we're opened */ 248 if (ihidev_hid_command(sc, I2C_HID_CMD_SET_POWER, &I2C_HID_POWER_OFF, 249 false)) { 250 aprint_error_dev(sc->sc_dev, "failed to power down\n"); 251 return; 252 } 253 if (!pmf_device_register(self, ihidev_suspend, ihidev_resume)) 254 aprint_error_dev(self, "couldn't establish power handler\n"); 255 } 256 257 static int 258 ihidev_detach(device_t self, int flags) 259 { 260 struct ihidev_softc *sc = device_private(self); 261 int error; 262 263 error = config_detach_children(self, flags); 264 if (error) 265 return error; 266 267 pmf_device_deregister(self); 268 ihidev_intr_fini(sc); 269 270 if (ihidev_hid_command(sc, I2C_HID_CMD_SET_POWER, &I2C_HID_POWER_OFF, 271 true)) 272 aprint_error_dev(sc->sc_dev, "failed to power down\n"); 273 274 if (sc->sc_ibuf != NULL) { 275 kmem_free(sc->sc_ibuf, sc->sc_isize); 276 sc->sc_ibuf = NULL; 277 } 278 279 if (sc->sc_report != NULL) 280 kmem_free(sc->sc_report, sc->sc_reportlen); 281 282 mutex_destroy(&sc->sc_lock); 283 284 return 0; 285 } 286 287 static bool 288 ihidev_suspend(device_t self, const pmf_qual_t *q) 289 { 290 struct ihidev_softc *sc = device_private(self); 291 292 mutex_enter(&sc->sc_lock); 293 if (sc->sc_refcnt > 0) { 294 printf("ihidev power off\n"); 295 if (ihidev_hid_command(sc, I2C_HID_CMD_SET_POWER, 296 &I2C_HID_POWER_OFF, true)) 297 aprint_error_dev(sc->sc_dev, "failed to power down\n"); 298 } 299 mutex_exit(&sc->sc_lock); 300 return true; 301 } 302 303 static bool 304 ihidev_resume(device_t self, const pmf_qual_t *q) 305 { 306 struct ihidev_softc *sc = device_private(self); 307 308 mutex_enter(&sc->sc_lock); 309 if (sc->sc_refcnt > 0) { 310 printf("ihidev power reset\n"); 311 ihidev_reset(sc, true); 312 } 313 mutex_exit(&sc->sc_lock); 314 return true; 315 } 316 317 static int 318 ihidev_hid_command(struct ihidev_softc *sc, int hidcmd, void *arg, bool poll) 319 { 320 int i, res = 1; 321 int flags = poll ? I2C_F_POLL : 0; 322 323 iic_acquire_bus(sc->sc_tag, flags); 324 325 switch (hidcmd) { 326 case I2C_HID_CMD_DESCR: { 327 /* 328 * 5.2.2 - HID Descriptor Retrieval 329 * register is passed from the controller 330 */ 331 uint8_t cmd[] = { 332 htole16(sc->sc_hid_desc_addr) & 0xff, 333 htole16(sc->sc_hid_desc_addr) >> 8, 334 }; 335 336 DPRINTF(("%s: HID command I2C_HID_CMD_DESCR at 0x%x\n", 337 sc->sc_dev.dv_xname, htole16(sc->sc_hid_desc_addr))); 338 339 /* 20 00 */ 340 res = iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_addr, 341 &cmd, sizeof(cmd), &sc->hid_desc_buf, 342 sizeof(struct i2c_hid_desc), flags); 343 344 DPRINTF(("%s: HID descriptor:", sc->sc_dev.dv_xname)); 345 for (i = 0; i < sizeof(struct i2c_hid_desc); i++) 346 DPRINTF((" %.2x", sc->hid_desc_buf[i])); 347 DPRINTF(("\n")); 348 349 break; 350 } 351 case I2C_HID_CMD_RESET: { 352 uint8_t cmd[] = { 353 htole16(sc->hid_desc.wCommandRegister) & 0xff, 354 htole16(sc->hid_desc.wCommandRegister) >> 8, 355 0, 356 I2C_HID_CMD_RESET, 357 }; 358 359 DPRINTF(("%s: HID command I2C_HID_CMD_RESET\n", 360 sc->sc_dev.dv_xname)); 361 362 /* 22 00 00 01 */ 363 res = iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP, sc->sc_addr, 364 &cmd, sizeof(cmd), NULL, 0, flags); 365 366 break; 367 } 368 case I2C_HID_CMD_GET_REPORT: { 369 struct i2c_hid_report_request *rreq = 370 (struct i2c_hid_report_request *)arg; 371 372 uint8_t cmd[] = { 373 htole16(sc->hid_desc.wCommandRegister) & 0xff, 374 htole16(sc->hid_desc.wCommandRegister) >> 8, 375 0, 376 I2C_HID_CMD_GET_REPORT, 377 0, 0, 0, 378 }; 379 int cmdlen = 7; 380 int dataoff = 4; 381 int report_id = rreq->id; 382 int report_id_len = 1; 383 int report_len = rreq->len + 2; 384 int d; 385 uint8_t *tmprep; 386 387 DPRINTF(("%s: HID command I2C_HID_CMD_GET_REPORT %d " 388 "(type %d, len %d)\n", sc->sc_dev.dv_xname, report_id, 389 rreq->type, rreq->len)); 390 391 /* 392 * 7.2.2.4 - "The protocol is optimized for Report < 15. If a 393 * report ID >= 15 is necessary, then the Report ID in the Low 394 * Byte must be set to 1111 and a Third Byte is appended to the 395 * protocol. This Third Byte contains the entire/actual report 396 * ID." 397 */ 398 if (report_id >= 15) { 399 cmd[dataoff++] = report_id; 400 report_id = 15; 401 report_id_len = 2; 402 } else 403 cmdlen--; 404 405 cmd[2] = report_id | rreq->type << 4; 406 407 cmd[dataoff++] = sc->hid_desc.wDataRegister & 0xff; 408 cmd[dataoff] = sc->hid_desc.wDataRegister >> 8; 409 410 /* 411 * 7.2.2.2 - Response will be a 2-byte length value, the report 412 * id with length determined above, and then the report. 413 * Allocate rreq->len + 2 + 2 bytes, read into that temporary 414 * buffer, and then copy only the report back out to 415 * rreq->data. 416 */ 417 report_len += report_id_len; 418 tmprep = kmem_zalloc(report_len, KM_NOSLEEP); 419 if (tmprep == NULL) { 420 /* XXX pool or preallocate? */ 421 DPRINTF(("%s: out of memory\n", 422 device_xname(sc->sc_dev))); 423 res = ENOMEM; 424 break; 425 } 426 427 /* type 3 id 8: 22 00 38 02 23 00 */ 428 res = iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_addr, 429 &cmd, cmdlen, tmprep, report_len, flags); 430 431 d = tmprep[0] | tmprep[1] << 8; 432 if (d != report_len) { 433 DPRINTF(("%s: response size %d != expected length %d\n", 434 sc->sc_dev.dv_xname, d, report_len)); 435 } 436 437 if (report_id_len == 2) 438 d = tmprep[2] | tmprep[3] << 8; 439 else 440 d = tmprep[2]; 441 442 if (d != rreq->id) { 443 DPRINTF(("%s: response report id %d != %d\n", 444 sc->sc_dev.dv_xname, d, rreq->id)); 445 iic_release_bus(sc->sc_tag, 0); 446 kmem_free(tmprep, report_len); 447 return (1); 448 } 449 450 DPRINTF(("%s: response:", sc->sc_dev.dv_xname)); 451 for (i = 0; i < report_len; i++) 452 DPRINTF((" %.2x", tmprep[i])); 453 DPRINTF(("\n")); 454 455 memcpy(rreq->data, tmprep + 2 + report_id_len, rreq->len); 456 kmem_free(tmprep, report_len); 457 458 break; 459 } 460 case I2C_HID_CMD_SET_REPORT: { 461 struct i2c_hid_report_request *rreq = 462 (struct i2c_hid_report_request *)arg; 463 464 uint8_t cmd[] = { 465 htole16(sc->hid_desc.wCommandRegister) & 0xff, 466 htole16(sc->hid_desc.wCommandRegister) >> 8, 467 0, 468 I2C_HID_CMD_SET_REPORT, 469 0, 0, 0, 0, 0, 0, 470 }; 471 int cmdlen = 10; 472 int report_id = rreq->id; 473 int report_len = 2 + (report_id ? 1 : 0) + rreq->len; 474 int dataoff; 475 uint8_t *finalcmd; 476 477 DPRINTF(("%s: HID command I2C_HID_CMD_SET_REPORT %d " 478 "(type %d, len %d):", sc->sc_dev.dv_xname, report_id, 479 rreq->type, rreq->len)); 480 for (i = 0; i < rreq->len; i++) 481 DPRINTF((" %.2x", ((uint8_t *)rreq->data)[i])); 482 DPRINTF(("\n")); 483 484 /* 485 * 7.2.2.4 - "The protocol is optimized for Report < 15. If a 486 * report ID >= 15 is necessary, then the Report ID in the Low 487 * Byte must be set to 1111 and a Third Byte is appended to the 488 * protocol. This Third Byte contains the entire/actual report 489 * ID." 490 */ 491 dataoff = 4; 492 if (report_id >= 15) { 493 cmd[dataoff++] = report_id; 494 report_id = 15; 495 } else 496 cmdlen--; 497 498 cmd[2] = report_id | rreq->type << 4; 499 500 if (rreq->type == I2C_HID_REPORT_TYPE_FEATURE) { 501 cmd[dataoff++] = htole16(sc->hid_desc.wDataRegister) 502 & 0xff; 503 cmd[dataoff++] = htole16(sc->hid_desc.wDataRegister) 504 >> 8; 505 } else { 506 cmd[dataoff++] = htole16(sc->hid_desc.wOutputRegister) 507 & 0xff; 508 cmd[dataoff++] = htole16(sc->hid_desc.wOutputRegister) 509 >> 8; 510 } 511 512 cmd[dataoff++] = report_len & 0xff; 513 cmd[dataoff++] = report_len >> 8; 514 cmd[dataoff] = rreq->id; 515 516 finalcmd = kmem_zalloc(cmdlen + rreq->len, KM_NOSLEEP); 517 if (finalcmd == NULL) { 518 res = ENOMEM; 519 break; 520 } 521 522 memcpy(finalcmd, cmd, cmdlen); 523 memcpy(finalcmd + cmdlen, rreq->data, rreq->len); 524 525 /* type 3 id 4: 22 00 34 03 23 00 04 00 04 03 */ 526 res = iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP, sc->sc_addr, 527 finalcmd, cmdlen + rreq->len, NULL, 0, flags); 528 kmem_free(finalcmd, cmdlen + rreq->len); 529 530 break; 531 } 532 533 case I2C_HID_CMD_SET_POWER: { 534 int power = *(int *)arg; 535 uint8_t cmd[] = { 536 htole16(sc->hid_desc.wCommandRegister) & 0xff, 537 htole16(sc->hid_desc.wCommandRegister) >> 8, 538 power, 539 I2C_HID_CMD_SET_POWER, 540 }; 541 542 DPRINTF(("%s: HID command I2C_HID_CMD_SET_POWER(%d)\n", 543 sc->sc_dev.dv_xname, power)); 544 545 /* 22 00 00 08 */ 546 res = iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP, sc->sc_addr, 547 &cmd, sizeof(cmd), NULL, 0, flags); 548 549 break; 550 } 551 case I2C_HID_REPORT_DESCR: { 552 uint8_t cmd[] = { 553 htole16(sc->hid_desc.wReportDescRegister) & 0xff, 554 htole16(sc->hid_desc.wReportDescRegister) >> 8, 555 }; 556 557 DPRINTF(("%s: HID command I2C_HID_REPORT_DESCR at 0x%x with " 558 "size %d\n", sc->sc_dev.dv_xname, cmd[0], 559 sc->sc_reportlen)); 560 561 /* 20 00 */ 562 res = iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_addr, 563 &cmd, sizeof(cmd), sc->sc_report, sc->sc_reportlen, flags); 564 565 DPRINTF(("%s: HID report descriptor:", sc->sc_dev.dv_xname)); 566 for (i = 0; i < sc->sc_reportlen; i++) 567 DPRINTF((" %.2x", sc->sc_report[i])); 568 DPRINTF(("\n")); 569 570 break; 571 } 572 default: 573 aprint_error_dev(sc->sc_dev, "unknown command %d\n", 574 hidcmd); 575 } 576 577 iic_release_bus(sc->sc_tag, flags); 578 579 return (res); 580 } 581 582 static int 583 ihidev_reset(struct ihidev_softc *sc, bool poll) 584 { 585 DPRINTF(("%s: resetting\n", sc->sc_dev.dv_xname)); 586 587 if (ihidev_hid_command(sc, I2C_HID_CMD_SET_POWER, 588 &I2C_HID_POWER_ON, poll)) { 589 aprint_error_dev(sc->sc_dev, "failed to power on\n"); 590 return (1); 591 } 592 593 DELAY(1000); 594 595 if (ihidev_hid_command(sc, I2C_HID_CMD_RESET, 0, poll)) { 596 aprint_error_dev(sc->sc_dev, "failed to reset hardware\n"); 597 598 ihidev_hid_command(sc, I2C_HID_CMD_SET_POWER, 599 &I2C_HID_POWER_OFF, poll); 600 601 return (1); 602 } 603 604 DELAY(1000); 605 606 return (0); 607 } 608 609 /* 610 * 5.2.2 - HID Descriptor Retrieval 611 * 612 * parse HID Descriptor that has already been read into hid_desc with 613 * I2C_HID_CMD_DESCR 614 */ 615 static int 616 ihidev_hid_desc_parse(struct ihidev_softc *sc) 617 { 618 int retries = 3; 619 620 /* must be v01.00 */ 621 if (le16toh(sc->hid_desc.bcdVersion) != 0x0100) { 622 aprint_error_dev(sc->sc_dev, 623 "bad HID descriptor bcdVersion (0x%x)\n", 624 le16toh(sc->hid_desc.bcdVersion)); 625 return (1); 626 } 627 628 /* must be 30 bytes for v1.00 */ 629 if (le16toh(sc->hid_desc.wHIDDescLength != 630 sizeof(struct i2c_hid_desc))) { 631 aprint_error_dev(sc->sc_dev, 632 "bad HID descriptor size (%d != %zu)\n", 633 le16toh(sc->hid_desc.wHIDDescLength), 634 sizeof(struct i2c_hid_desc)); 635 return (1); 636 } 637 638 if (le16toh(sc->hid_desc.wReportDescLength) <= 0) { 639 aprint_error_dev(sc->sc_dev, 640 "bad HID report descriptor size (%d)\n", 641 le16toh(sc->hid_desc.wReportDescLength)); 642 return (1); 643 } 644 645 while (retries-- > 0) { 646 if (ihidev_reset(sc, false)) { 647 if (retries == 0) 648 return(1); 649 650 DELAY(1000); 651 } 652 else 653 break; 654 } 655 656 sc->sc_reportlen = le16toh(sc->hid_desc.wReportDescLength); 657 sc->sc_report = kmem_zalloc(sc->sc_reportlen, KM_SLEEP); 658 659 if (ihidev_hid_command(sc, I2C_HID_REPORT_DESCR, 0, false)) { 660 aprint_error_dev(sc->sc_dev, "failed fetching HID report\n"); 661 return (1); 662 } 663 664 return (0); 665 } 666 667 static bool 668 ihidev_intr_init(struct ihidev_softc *sc) 669 { 670 #if NACPICA > 0 671 ACPI_HANDLE hdl = (void *)(uintptr_t)sc->sc_phandle; 672 struct acpi_resources res; 673 ACPI_STATUS rv; 674 char buf[100]; 675 676 rv = acpi_resource_parse(sc->sc_dev, hdl, "_CRS", &res, 677 &acpi_resource_parse_ops_quiet); 678 if (ACPI_FAILURE(rv)) { 679 aprint_error_dev(sc->sc_dev, "can't parse '_CRS'\n"); 680 return false; 681 } 682 683 const struct acpi_irq * const irq = acpi_res_irq(&res, 0); 684 if (irq == NULL) { 685 aprint_error_dev(sc->sc_dev, "no IRQ resource\n"); 686 acpi_resource_cleanup(&res); 687 return false; 688 } 689 690 sc->sc_intr_type = 691 irq->ar_type == ACPI_EDGE_SENSITIVE ? IST_EDGE : IST_LEVEL; 692 693 acpi_resource_cleanup(&res); 694 695 sc->sc_ih = acpi_intr_establish(sc->sc_dev, sc->sc_phandle, IPL_TTY, 696 false, ihidev_intr, sc, device_xname(sc->sc_dev)); 697 if (sc->sc_ih == NULL) { 698 aprint_error_dev(sc->sc_dev, "can't establish interrupt\n"); 699 return false; 700 } 701 aprint_normal_dev(sc->sc_dev, "interrupting at %s\n", 702 acpi_intr_string(sc->sc_ih, buf, sizeof(buf))); 703 704 if (workqueue_create(&sc->sc_wq, device_xname(sc->sc_dev), ihidev_work, 705 sc, PRI_NONE, IPL_TTY, WQ_MPSAFE)) { 706 aprint_error_dev(sc->sc_dev, 707 "can't establish workqueue\n"); 708 return false; 709 } 710 sc->sc_work_pending = 0; 711 712 return true; 713 #else 714 aprint_error_dev(sc->sc_dev, "can't establish interrupt\n"); 715 return false; 716 #endif 717 } 718 719 static void 720 ihidev_intr_fini(struct ihidev_softc *sc) 721 { 722 #if NACPICA > 0 723 if (sc->sc_ih != NULL) { 724 acpi_intr_disestablish(sc->sc_ih); 725 } 726 if (sc->sc_wq != NULL) { 727 workqueue_destroy(sc->sc_wq); 728 } 729 #endif 730 } 731 732 static void 733 ihidev_intr_mask(struct ihidev_softc * const sc) 734 { 735 736 if (sc->sc_intr_type == IST_LEVEL) { 737 #if NACPICA > 0 738 acpi_intr_mask(sc->sc_ih); 739 #endif 740 } 741 } 742 743 static void 744 ihidev_intr_unmask(struct ihidev_softc * const sc) 745 { 746 747 if (sc->sc_intr_type == IST_LEVEL) { 748 #if NACPICA > 0 749 acpi_intr_unmask(sc->sc_ih); 750 #endif 751 } 752 } 753 754 static int 755 ihidev_intr(void *arg) 756 { 757 struct ihidev_softc * const sc = arg; 758 759 /* 760 * Schedule our work. If we're using a level-triggered 761 * interrupt, we have to mask it off while we wait for service. 762 */ 763 if (atomic_swap_uint(&sc->sc_work_pending, 1) == 0) 764 workqueue_enqueue(sc->sc_wq, &sc->sc_work, NULL); 765 ihidev_intr_mask(sc); 766 767 return 1; 768 } 769 770 static void 771 ihidev_work(struct work *wk, void *arg) 772 { 773 struct ihidev_softc * const sc = arg; 774 struct ihidev *scd; 775 u_int psize; 776 int res, i; 777 u_char *p; 778 u_int rep = 0; 779 780 atomic_store_relaxed(&sc->sc_work_pending, 0); 781 782 mutex_enter(&sc->sc_lock); 783 784 iic_acquire_bus(sc->sc_tag, 0); 785 res = iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_addr, NULL, 0, 786 sc->sc_ibuf, sc->sc_isize, 0); 787 iic_release_bus(sc->sc_tag, 0); 788 if (res != 0) 789 goto out; 790 791 /* 792 * 6.1.1 - First two bytes are the packet length, which must be less 793 * than or equal to wMaxInputLength 794 */ 795 psize = sc->sc_ibuf[0] | sc->sc_ibuf[1] << 8; 796 if (!psize || psize > sc->sc_isize) { 797 DPRINTF(("%s: %s: invalid packet size (%d vs. %d)\n", 798 sc->sc_dev.dv_xname, __func__, psize, sc->sc_isize)); 799 goto out; 800 } 801 802 /* 3rd byte is the report id */ 803 p = sc->sc_ibuf + 2; 804 psize -= 2; 805 if (sc->sc_nrepid != 1) 806 rep = *p++, psize--; 807 808 if (rep >= sc->sc_nrepid) { 809 aprint_error_dev(sc->sc_dev, "%s: bad report id %d\n", 810 __func__, rep); 811 goto out; 812 } 813 814 DPRINTF(("%s: %s: hid input (rep %d):", sc->sc_dev.dv_xname, 815 __func__, rep)); 816 for (i = 0; i < sc->sc_isize; i++) 817 DPRINTF((" %.2x", sc->sc_ibuf[i])); 818 DPRINTF(("\n")); 819 820 scd = sc->sc_subdevs[rep]; 821 if (scd == NULL || !(scd->sc_state & IHIDEV_OPEN)) 822 goto out; 823 824 scd->sc_intr(scd, p, psize); 825 826 out: 827 mutex_exit(&sc->sc_lock); 828 829 /* 830 * If our interrupt is level-triggered, re-enable it now. 831 */ 832 ihidev_intr_unmask(sc); 833 } 834 835 static int 836 ihidev_maxrepid(void *buf, int len) 837 { 838 struct hid_data *d; 839 struct hid_item h; 840 int maxid; 841 842 maxid = -1; 843 h.report_ID = 0; 844 for (d = hid_start_parse(buf, len, hid_none); hid_get_item(d, &h); ) 845 if ((int)h.report_ID > maxid) 846 maxid = h.report_ID; 847 hid_end_parse(d); 848 849 return (maxid); 850 } 851 852 static int 853 ihidev_print(void *aux, const char *pnp) 854 { 855 struct ihidev_attach_arg *iha = aux; 856 857 if (iha->reportid == IHIDEV_CLAIM_ALLREPORTID) 858 return (QUIET); 859 860 if (pnp) 861 aprint_normal("hid at %s", pnp); 862 863 if (iha->reportid != 0) 864 aprint_normal(" reportid %d", iha->reportid); 865 866 return (UNCONF); 867 } 868 869 static int 870 ihidev_submatch(device_t parent, cfdata_t cf, const int *locs, void *aux) 871 { 872 struct ihidev_attach_arg *iha = aux; 873 874 if (cf->ihidevcf_reportid != IHIDEV_UNK_REPORTID && 875 cf->ihidevcf_reportid != iha->reportid) 876 return (0); 877 878 return config_match(parent, cf, aux); 879 } 880 881 int 882 ihidev_open(struct ihidev *scd) 883 { 884 struct ihidev_softc *sc = scd->sc_parent; 885 886 DPRINTF(("%s: %s: state=%d refcnt=%d\n", sc->sc_dev.dv_xname, 887 __func__, scd->sc_state, sc->sc_refcnt)); 888 889 if (scd->sc_state & IHIDEV_OPEN) 890 return (EBUSY); 891 892 scd->sc_state |= IHIDEV_OPEN; 893 894 if (sc->sc_refcnt++ || sc->sc_isize == 0) 895 return (0); 896 897 /* power on */ 898 ihidev_reset(sc, false); 899 900 return (0); 901 } 902 903 void 904 ihidev_close(struct ihidev *scd) 905 { 906 struct ihidev_softc *sc = scd->sc_parent; 907 908 DPRINTF(("%s: %s: state=%d refcnt=%d\n", sc->sc_dev.dv_xname, 909 __func__, scd->sc_state, sc->sc_refcnt)); 910 911 if (!(scd->sc_state & IHIDEV_OPEN)) 912 return; 913 914 scd->sc_state &= ~IHIDEV_OPEN; 915 916 if (--sc->sc_refcnt) 917 return; 918 919 if (ihidev_hid_command(sc, I2C_HID_CMD_SET_POWER, 920 &I2C_HID_POWER_OFF, false)) 921 aprint_error_dev(sc->sc_dev, "failed to power down\n"); 922 } 923 924 void 925 ihidev_get_report_desc(struct ihidev_softc *sc, void **desc, int *size) 926 { 927 *desc = sc->sc_report; 928 *size = sc->sc_reportlen; 929 } 930 931 /* convert hid_* constants used throughout HID code to i2c HID equivalents */ 932 int 933 ihidev_report_type_conv(int hid_type_id) 934 { 935 switch (hid_type_id) { 936 case hid_input: 937 return I2C_HID_REPORT_TYPE_INPUT; 938 case hid_output: 939 return I2C_HID_REPORT_TYPE_OUTPUT; 940 case hid_feature: 941 return I2C_HID_REPORT_TYPE_FEATURE; 942 default: 943 return -1; 944 } 945 } 946 947 int 948 ihidev_get_report(struct device *dev, int type, int id, void *data, int len) 949 { 950 struct ihidev_softc *sc = (struct ihidev_softc *)dev; 951 struct i2c_hid_report_request rreq; 952 int ctype; 953 954 if ((ctype = ihidev_report_type_conv(type)) < 0) 955 return (1); 956 957 rreq.type = ctype; 958 rreq.id = id; 959 rreq.data = data; 960 rreq.len = len; 961 962 if (ihidev_hid_command(sc, I2C_HID_CMD_GET_REPORT, &rreq, false)) { 963 aprint_error_dev(sc->sc_dev, "failed fetching report\n"); 964 return (1); 965 } 966 967 return 0; 968 } 969 970 int 971 ihidev_set_report(struct device *dev, int type, int id, void *data, 972 int len) 973 { 974 struct ihidev_softc *sc = (struct ihidev_softc *)dev; 975 struct i2c_hid_report_request rreq; 976 int ctype; 977 978 if ((ctype = ihidev_report_type_conv(type)) < 0) 979 return (1); 980 981 rreq.type = ctype; 982 rreq.id = id; 983 rreq.data = data; 984 rreq.len = len; 985 986 if (ihidev_hid_command(sc, I2C_HID_CMD_SET_REPORT, &rreq, false)) { 987 aprint_error_dev(sc->sc_dev, "failed setting report\n"); 988 return (1); 989 } 990 991 return 0; 992 } 993 994 static bool 995 ihidev_acpi_get_info(struct ihidev_softc *sc) 996 { 997 ACPI_HANDLE hdl = (void *)(uintptr_t)sc->sc_phandle; 998 ACPI_STATUS status; 999 ACPI_INTEGER val; 1000 1001 /* 3cdff6f7-4267-4555-ad05-b30a3d8938de */ 1002 uint8_t i2c_hid_guid[] = { 1003 0xF7, 0xF6, 0xDF, 0x3C, 1004 0x67, 0x42, 1005 0x55, 0x45, 1006 0xAD, 0x05, 1007 0xB3, 0x0A, 0x3D, 0x89, 0x38, 0xDE, 1008 }; 1009 1010 status = acpi_dsm_integer(hdl, i2c_hid_guid, 1, 1, NULL, &val); 1011 if (ACPI_FAILURE(status)) { 1012 aprint_error_dev(sc->sc_dev, 1013 "failed to get HidDescriptorAddress: %s\n", 1014 AcpiFormatException(status)); 1015 return false; 1016 } 1017 1018 sc->sc_hid_desc_addr = (u_int)val; 1019 1020 return true; 1021 } 1022