1 /* $NetBSD: ihidev.c,v 1.19 2021/04/24 23:36:54 thorpej 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.19 2021/04/24 23:36:54 thorpej Exp $"); 58 59 #include <sys/param.h> 60 #include <sys/systm.h> 61 #include <sys/device.h> 62 #include <sys/kmem.h> 63 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 ihiddev_intr_init(struct ihidev_softc *); 114 static void ihiddev_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_softintr(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_intr_lock, MUTEX_DEFAULT, IPL_VM); 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 (! ihiddev_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 CFARG_SUBMATCH, ihidev_submatch, 223 CFARG_LOCATORS, locs, 224 CFARG_EOL); 225 if (dev != NULL) { 226 for (repid = 0; repid < sc->sc_nrepid; repid++) 227 sc->sc_subdevs[repid] = device_private(dev); 228 return; 229 } 230 231 for (repid = 0; repid < sc->sc_nrepid; repid++) { 232 if (hid_report_size(sc->sc_report, sc->sc_reportlen, hid_input, 233 repid) == 0 && 234 hid_report_size(sc->sc_report, sc->sc_reportlen, 235 hid_output, repid) == 0 && 236 hid_report_size(sc->sc_report, sc->sc_reportlen, 237 hid_feature, repid) == 0) 238 continue; 239 240 iha.reportid = repid; 241 locs[IHIDBUSCF_REPORTID] = repid; 242 dev = config_found(self, &iha, ihidev_print, 243 CFARG_SUBMATCH, ihidev_submatch, 244 CFARG_LOCATORS, locs, 245 CFARG_EOL); 246 sc->sc_subdevs[repid] = device_private(dev); 247 } 248 249 /* power down until we're opened */ 250 if (ihidev_hid_command(sc, I2C_HID_CMD_SET_POWER, &I2C_HID_POWER_OFF, false)) { 251 aprint_error_dev(sc->sc_dev, "failed to power down\n"); 252 return; 253 } 254 if (!pmf_device_register(self, ihidev_suspend, ihidev_resume)) 255 aprint_error_dev(self, "couldn't establish power handler\n"); 256 } 257 258 static int 259 ihidev_detach(device_t self, int flags) 260 { 261 struct ihidev_softc *sc = device_private(self); 262 263 mutex_enter(&sc->sc_intr_lock); 264 ihiddev_intr_fini(sc); 265 if (ihidev_hid_command(sc, I2C_HID_CMD_SET_POWER, 266 &I2C_HID_POWER_OFF, true)) 267 aprint_error_dev(sc->sc_dev, "failed to power down\n"); 268 mutex_exit(&sc->sc_intr_lock); 269 if (sc->sc_ibuf != NULL) { 270 kmem_free(sc->sc_ibuf, sc->sc_isize); 271 sc->sc_ibuf = NULL; 272 } 273 274 if (sc->sc_report != NULL) 275 kmem_free(sc->sc_report, sc->sc_reportlen); 276 277 pmf_device_deregister(self); 278 return (0); 279 } 280 281 static bool 282 ihidev_suspend(device_t self, const pmf_qual_t *q) 283 { 284 struct ihidev_softc *sc = device_private(self); 285 286 mutex_enter(&sc->sc_intr_lock); 287 if (sc->sc_refcnt > 0) { 288 printf("ihidev power off\n"); 289 if (ihidev_hid_command(sc, I2C_HID_CMD_SET_POWER, 290 &I2C_HID_POWER_OFF, true)) 291 aprint_error_dev(sc->sc_dev, "failed to power down\n"); 292 } 293 mutex_exit(&sc->sc_intr_lock); 294 return true; 295 } 296 297 static bool 298 ihidev_resume(device_t self, const pmf_qual_t *q) 299 { 300 struct ihidev_softc *sc = device_private(self); 301 302 mutex_enter(&sc->sc_intr_lock); 303 if (sc->sc_refcnt > 0) { 304 printf("ihidev power reset\n"); 305 ihidev_reset(sc, true); 306 } 307 mutex_exit(&sc->sc_intr_lock); 308 return true; 309 } 310 311 static int 312 ihidev_hid_command(struct ihidev_softc *sc, int hidcmd, void *arg, bool poll) 313 { 314 int i, res = 1; 315 int flags = poll ? I2C_F_POLL : 0; 316 317 iic_acquire_bus(sc->sc_tag, flags); 318 319 switch (hidcmd) { 320 case I2C_HID_CMD_DESCR: { 321 /* 322 * 5.2.2 - HID Descriptor Retrieval 323 * register is passed from the controller 324 */ 325 uint8_t cmd[] = { 326 htole16(sc->sc_hid_desc_addr) & 0xff, 327 htole16(sc->sc_hid_desc_addr) >> 8, 328 }; 329 330 DPRINTF(("%s: HID command I2C_HID_CMD_DESCR at 0x%x\n", 331 sc->sc_dev.dv_xname, htole16(sc->sc_hid_desc_addr))); 332 333 /* 20 00 */ 334 res = iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_addr, 335 &cmd, sizeof(cmd), &sc->hid_desc_buf, 336 sizeof(struct i2c_hid_desc), flags); 337 338 DPRINTF(("%s: HID descriptor:", sc->sc_dev.dv_xname)); 339 for (i = 0; i < sizeof(struct i2c_hid_desc); i++) 340 DPRINTF((" %.2x", sc->hid_desc_buf[i])); 341 DPRINTF(("\n")); 342 343 break; 344 } 345 case I2C_HID_CMD_RESET: { 346 uint8_t cmd[] = { 347 htole16(sc->hid_desc.wCommandRegister) & 0xff, 348 htole16(sc->hid_desc.wCommandRegister) >> 8, 349 0, 350 I2C_HID_CMD_RESET, 351 }; 352 353 DPRINTF(("%s: HID command I2C_HID_CMD_RESET\n", 354 sc->sc_dev.dv_xname)); 355 356 /* 22 00 00 01 */ 357 res = iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP, sc->sc_addr, 358 &cmd, sizeof(cmd), NULL, 0, flags); 359 360 break; 361 } 362 case I2C_HID_CMD_GET_REPORT: { 363 struct i2c_hid_report_request *rreq = 364 (struct i2c_hid_report_request *)arg; 365 366 uint8_t cmd[] = { 367 htole16(sc->hid_desc.wCommandRegister) & 0xff, 368 htole16(sc->hid_desc.wCommandRegister) >> 8, 369 0, 370 I2C_HID_CMD_GET_REPORT, 371 0, 0, 0, 372 }; 373 int cmdlen = 7; 374 int dataoff = 4; 375 int report_id = rreq->id; 376 int report_id_len = 1; 377 int report_len = rreq->len + 2; 378 int d; 379 uint8_t *tmprep; 380 381 DPRINTF(("%s: HID command I2C_HID_CMD_GET_REPORT %d " 382 "(type %d, len %d)\n", sc->sc_dev.dv_xname, report_id, 383 rreq->type, rreq->len)); 384 385 /* 386 * 7.2.2.4 - "The protocol is optimized for Report < 15. If a 387 * report ID >= 15 is necessary, then the Report ID in the Low 388 * Byte must be set to 1111 and a Third Byte is appended to the 389 * protocol. This Third Byte contains the entire/actual report 390 * ID." 391 */ 392 if (report_id >= 15) { 393 cmd[dataoff++] = report_id; 394 report_id = 15; 395 report_id_len = 2; 396 } else 397 cmdlen--; 398 399 cmd[2] = report_id | rreq->type << 4; 400 401 cmd[dataoff++] = sc->hid_desc.wDataRegister & 0xff; 402 cmd[dataoff] = sc->hid_desc.wDataRegister >> 8; 403 404 /* 405 * 7.2.2.2 - Response will be a 2-byte length value, the report 406 * id with length determined above, and then the report. 407 * Allocate rreq->len + 2 + 2 bytes, read into that temporary 408 * buffer, and then copy only the report back out to 409 * rreq->data. 410 */ 411 report_len += report_id_len; 412 tmprep = kmem_zalloc(report_len, KM_NOSLEEP); 413 414 /* type 3 id 8: 22 00 38 02 23 00 */ 415 res = iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_addr, 416 &cmd, cmdlen, tmprep, report_len, flags); 417 418 d = tmprep[0] | tmprep[1] << 8; 419 if (d != report_len) { 420 DPRINTF(("%s: response size %d != expected length %d\n", 421 sc->sc_dev.dv_xname, d, report_len)); 422 } 423 424 if (report_id_len == 2) 425 d = tmprep[2] | tmprep[3] << 8; 426 else 427 d = tmprep[2]; 428 429 if (d != rreq->id) { 430 DPRINTF(("%s: response report id %d != %d\n", 431 sc->sc_dev.dv_xname, d, rreq->id)); 432 iic_release_bus(sc->sc_tag, 0); 433 kmem_free(tmprep, report_len); 434 return (1); 435 } 436 437 DPRINTF(("%s: response:", sc->sc_dev.dv_xname)); 438 for (i = 0; i < report_len; i++) 439 DPRINTF((" %.2x", tmprep[i])); 440 DPRINTF(("\n")); 441 442 memcpy(rreq->data, tmprep + 2 + report_id_len, rreq->len); 443 kmem_free(tmprep, report_len); 444 445 break; 446 } 447 case I2C_HID_CMD_SET_REPORT: { 448 struct i2c_hid_report_request *rreq = 449 (struct i2c_hid_report_request *)arg; 450 451 uint8_t cmd[] = { 452 htole16(sc->hid_desc.wCommandRegister) & 0xff, 453 htole16(sc->hid_desc.wCommandRegister) >> 8, 454 0, 455 I2C_HID_CMD_SET_REPORT, 456 0, 0, 0, 0, 0, 0, 457 }; 458 int cmdlen = 10; 459 int report_id = rreq->id; 460 int report_len = 2 + (report_id ? 1 : 0) + rreq->len; 461 int dataoff; 462 uint8_t *finalcmd; 463 464 DPRINTF(("%s: HID command I2C_HID_CMD_SET_REPORT %d " 465 "(type %d, len %d):", sc->sc_dev.dv_xname, report_id, 466 rreq->type, rreq->len)); 467 for (i = 0; i < rreq->len; i++) 468 DPRINTF((" %.2x", ((uint8_t *)rreq->data)[i])); 469 DPRINTF(("\n")); 470 471 /* 472 * 7.2.2.4 - "The protocol is optimized for Report < 15. If a 473 * report ID >= 15 is necessary, then the Report ID in the Low 474 * Byte must be set to 1111 and a Third Byte is appended to the 475 * protocol. This Third Byte contains the entire/actual report 476 * ID." 477 */ 478 dataoff = 4; 479 if (report_id >= 15) { 480 cmd[dataoff++] = report_id; 481 report_id = 15; 482 } else 483 cmdlen--; 484 485 cmd[2] = report_id | rreq->type << 4; 486 487 if (rreq->type == I2C_HID_REPORT_TYPE_FEATURE) { 488 cmd[dataoff++] = htole16(sc->hid_desc.wDataRegister) 489 & 0xff; 490 cmd[dataoff++] = htole16(sc->hid_desc.wDataRegister) 491 >> 8; 492 } else { 493 cmd[dataoff++] = htole16(sc->hid_desc.wOutputRegister) 494 & 0xff; 495 cmd[dataoff++] = htole16(sc->hid_desc.wOutputRegister) 496 >> 8; 497 } 498 499 cmd[dataoff++] = report_len & 0xff; 500 cmd[dataoff++] = report_len >> 8; 501 cmd[dataoff] = rreq->id; 502 503 finalcmd = kmem_zalloc(cmdlen + rreq->len, KM_NOSLEEP); 504 505 memcpy(finalcmd, cmd, cmdlen); 506 memcpy(finalcmd + cmdlen, rreq->data, rreq->len); 507 508 /* type 3 id 4: 22 00 34 03 23 00 04 00 04 03 */ 509 res = iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP, sc->sc_addr, 510 finalcmd, cmdlen + rreq->len, NULL, 0, flags); 511 kmem_free(finalcmd, cmdlen + rreq->len); 512 513 break; 514 } 515 516 case I2C_HID_CMD_SET_POWER: { 517 int power = *(int *)arg; 518 uint8_t cmd[] = { 519 htole16(sc->hid_desc.wCommandRegister) & 0xff, 520 htole16(sc->hid_desc.wCommandRegister) >> 8, 521 power, 522 I2C_HID_CMD_SET_POWER, 523 }; 524 525 DPRINTF(("%s: HID command I2C_HID_CMD_SET_POWER(%d)\n", 526 sc->sc_dev.dv_xname, power)); 527 528 /* 22 00 00 08 */ 529 res = iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP, sc->sc_addr, 530 &cmd, sizeof(cmd), NULL, 0, flags); 531 532 break; 533 } 534 case I2C_HID_REPORT_DESCR: { 535 uint8_t cmd[] = { 536 htole16(sc->hid_desc.wReportDescRegister) & 0xff, 537 htole16(sc->hid_desc.wReportDescRegister) >> 8, 538 }; 539 540 DPRINTF(("%s: HID command I2C_HID_REPORT_DESCR at 0x%x with " 541 "size %d\n", sc->sc_dev.dv_xname, cmd[0], 542 sc->sc_reportlen)); 543 544 /* 20 00 */ 545 res = iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_addr, 546 &cmd, sizeof(cmd), sc->sc_report, sc->sc_reportlen, flags); 547 548 DPRINTF(("%s: HID report descriptor:", sc->sc_dev.dv_xname)); 549 for (i = 0; i < sc->sc_reportlen; i++) 550 DPRINTF((" %.2x", sc->sc_report[i])); 551 DPRINTF(("\n")); 552 553 break; 554 } 555 default: 556 aprint_error_dev(sc->sc_dev, "unknown command %d\n", 557 hidcmd); 558 } 559 560 iic_release_bus(sc->sc_tag, flags); 561 562 return (res); 563 } 564 565 static int 566 ihidev_reset(struct ihidev_softc *sc, bool poll) 567 { 568 DPRINTF(("%s: resetting\n", sc->sc_dev.dv_xname)); 569 570 if (ihidev_hid_command(sc, I2C_HID_CMD_SET_POWER, 571 &I2C_HID_POWER_ON, poll)) { 572 aprint_error_dev(sc->sc_dev, "failed to power on\n"); 573 return (1); 574 } 575 576 DELAY(1000); 577 578 if (ihidev_hid_command(sc, I2C_HID_CMD_RESET, 0, poll)) { 579 aprint_error_dev(sc->sc_dev, "failed to reset hardware\n"); 580 581 ihidev_hid_command(sc, I2C_HID_CMD_SET_POWER, 582 &I2C_HID_POWER_OFF, poll); 583 584 return (1); 585 } 586 587 DELAY(1000); 588 589 return (0); 590 } 591 592 /* 593 * 5.2.2 - HID Descriptor Retrieval 594 * 595 * parse HID Descriptor that has already been read into hid_desc with 596 * I2C_HID_CMD_DESCR 597 */ 598 static int 599 ihidev_hid_desc_parse(struct ihidev_softc *sc) 600 { 601 int retries = 3; 602 603 /* must be v01.00 */ 604 if (le16toh(sc->hid_desc.bcdVersion) != 0x0100) { 605 aprint_error_dev(sc->sc_dev, 606 "bad HID descriptor bcdVersion (0x%x)\n", 607 le16toh(sc->hid_desc.bcdVersion)); 608 return (1); 609 } 610 611 /* must be 30 bytes for v1.00 */ 612 if (le16toh(sc->hid_desc.wHIDDescLength != 613 sizeof(struct i2c_hid_desc))) { 614 aprint_error_dev(sc->sc_dev, 615 "bad HID descriptor size (%d != %zu)\n", 616 le16toh(sc->hid_desc.wHIDDescLength), 617 sizeof(struct i2c_hid_desc)); 618 return (1); 619 } 620 621 if (le16toh(sc->hid_desc.wReportDescLength) <= 0) { 622 aprint_error_dev(sc->sc_dev, 623 "bad HID report descriptor size (%d)\n", 624 le16toh(sc->hid_desc.wReportDescLength)); 625 return (1); 626 } 627 628 while (retries-- > 0) { 629 if (ihidev_reset(sc, false)) { 630 if (retries == 0) 631 return(1); 632 633 DELAY(1000); 634 } 635 else 636 break; 637 } 638 639 sc->sc_reportlen = le16toh(sc->hid_desc.wReportDescLength); 640 sc->sc_report = kmem_zalloc(sc->sc_reportlen, KM_NOSLEEP); 641 642 if (ihidev_hid_command(sc, I2C_HID_REPORT_DESCR, 0, false)) { 643 aprint_error_dev(sc->sc_dev, "failed fetching HID report\n"); 644 return (1); 645 } 646 647 return (0); 648 } 649 650 static bool 651 ihiddev_intr_init(struct ihidev_softc *sc) 652 { 653 #if NACPICA > 0 654 ACPI_HANDLE hdl = (void *)(uintptr_t)sc->sc_phandle; 655 struct acpi_resources res; 656 ACPI_STATUS rv; 657 char buf[100]; 658 659 rv = acpi_resource_parse(sc->sc_dev, hdl, "_CRS", &res, 660 &acpi_resource_parse_ops_quiet); 661 if (ACPI_FAILURE(rv)) { 662 aprint_error_dev(sc->sc_dev, "can't parse '_CRS'\n"); 663 return false; 664 } 665 666 const struct acpi_irq * const irq = acpi_res_irq(&res, 0); 667 if (irq == NULL) { 668 aprint_error_dev(sc->sc_dev, "no IRQ resource\n"); 669 acpi_resource_cleanup(&res); 670 return false; 671 } 672 673 sc->sc_intr_type = 674 irq->ar_type == ACPI_EDGE_SENSITIVE ? IST_EDGE : IST_LEVEL; 675 676 acpi_resource_cleanup(&res); 677 678 sc->sc_ih = acpi_intr_establish(sc->sc_dev, sc->sc_phandle, IPL_TTY, 679 false, ihidev_intr, sc, device_xname(sc->sc_dev)); 680 if (sc->sc_ih == NULL) { 681 aprint_error_dev(sc->sc_dev, "can't establish interrupt\n"); 682 return false; 683 } 684 aprint_normal_dev(sc->sc_dev, "interrupting at %s\n", 685 acpi_intr_string(sc->sc_ih, buf, sizeof(buf))); 686 687 sc->sc_sih = softint_establish(SOFTINT_SERIAL, ihidev_softintr, sc); 688 if (sc->sc_sih == NULL) { 689 aprint_error_dev(sc->sc_dev, 690 "can't establish soft interrupt\n"); 691 return false; 692 } 693 694 return true; 695 #else 696 aprint_error_dev(sc->sc_dev, "can't establish interrupt\n"); 697 return false; 698 #endif 699 } 700 701 static void 702 ihiddev_intr_fini(struct ihidev_softc *sc) 703 { 704 #if NACPICA > 0 705 if (sc->sc_ih != NULL) { 706 acpi_intr_disestablish(sc->sc_ih); 707 } 708 if (sc->sc_sih != NULL) { 709 softint_disestablish(sc->sc_sih); 710 } 711 #endif 712 } 713 714 static void 715 ihidev_intr_mask(struct ihidev_softc * const sc) 716 { 717 718 if (sc->sc_intr_type == IST_LEVEL) { 719 #if NACPICA > 0 720 acpi_intr_mask(sc->sc_ih); 721 #endif 722 } 723 } 724 725 static void 726 ihidev_intr_unmask(struct ihidev_softc * const sc) 727 { 728 729 if (sc->sc_intr_type == IST_LEVEL) { 730 #if NACPICA > 0 731 acpi_intr_unmask(sc->sc_ih); 732 #endif 733 } 734 } 735 736 static int 737 ihidev_intr(void *arg) 738 { 739 struct ihidev_softc * const sc = arg; 740 741 mutex_enter(&sc->sc_intr_lock); 742 743 /* 744 * Schedule our soft interrupt handler. If we're using a level- 745 * triggered interrupt, we have to mask it off while we wait 746 * for service. 747 */ 748 softint_schedule(sc->sc_sih); 749 ihidev_intr_mask(sc); 750 751 mutex_exit(&sc->sc_intr_lock); 752 753 return 1; 754 } 755 756 static void 757 ihidev_softintr(void *arg) 758 { 759 struct ihidev_softc * const sc = arg; 760 struct ihidev *scd; 761 u_int psize; 762 int res, i; 763 u_char *p; 764 u_int rep = 0; 765 766 mutex_enter(&sc->sc_intr_lock); 767 iic_acquire_bus(sc->sc_tag, 0); 768 res = iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_addr, NULL, 0, 769 sc->sc_ibuf, sc->sc_isize, 0); 770 iic_release_bus(sc->sc_tag, 0); 771 mutex_exit(&sc->sc_intr_lock); 772 773 if (res != 0) 774 goto out; 775 776 /* 777 * 6.1.1 - First two bytes are the packet length, which must be less 778 * than or equal to wMaxInputLength 779 */ 780 psize = sc->sc_ibuf[0] | sc->sc_ibuf[1] << 8; 781 if (!psize || psize > sc->sc_isize) { 782 DPRINTF(("%s: %s: invalid packet size (%d vs. %d)\n", 783 sc->sc_dev.dv_xname, __func__, psize, sc->sc_isize)); 784 goto out; 785 } 786 787 /* 3rd byte is the report id */ 788 p = sc->sc_ibuf + 2; 789 psize -= 2; 790 if (sc->sc_nrepid != 1) 791 rep = *p++, psize--; 792 793 if (rep >= sc->sc_nrepid) { 794 aprint_error_dev(sc->sc_dev, "%s: bad report id %d\n", 795 __func__, rep); 796 goto out; 797 } 798 799 DPRINTF(("%s: %s: hid input (rep %d):", sc->sc_dev.dv_xname, 800 __func__, rep)); 801 for (i = 0; i < sc->sc_isize; i++) 802 DPRINTF((" %.2x", sc->sc_ibuf[i])); 803 DPRINTF(("\n")); 804 805 scd = sc->sc_subdevs[rep]; 806 if (scd == NULL || !(scd->sc_state & IHIDEV_OPEN)) 807 goto out; 808 809 scd->sc_intr(scd, p, psize); 810 811 out: 812 /* 813 * If our interrupt is level-triggered, re-enable it now. 814 */ 815 ihidev_intr_unmask(sc); 816 } 817 818 static int 819 ihidev_maxrepid(void *buf, int len) 820 { 821 struct hid_data *d; 822 struct hid_item h; 823 int maxid; 824 825 maxid = -1; 826 h.report_ID = 0; 827 for (d = hid_start_parse(buf, len, hid_none); hid_get_item(d, &h); ) 828 if ((int)h.report_ID > maxid) 829 maxid = h.report_ID; 830 hid_end_parse(d); 831 832 return (maxid); 833 } 834 835 static int 836 ihidev_print(void *aux, const char *pnp) 837 { 838 struct ihidev_attach_arg *iha = aux; 839 840 if (iha->reportid == IHIDEV_CLAIM_ALLREPORTID) 841 return (QUIET); 842 843 if (pnp) 844 aprint_normal("hid at %s", pnp); 845 846 if (iha->reportid != 0) 847 aprint_normal(" reportid %d", iha->reportid); 848 849 return (UNCONF); 850 } 851 852 static int 853 ihidev_submatch(device_t parent, cfdata_t cf, const int *locs, void *aux) 854 { 855 struct ihidev_attach_arg *iha = aux; 856 857 if (cf->ihidevcf_reportid != IHIDEV_UNK_REPORTID && 858 cf->ihidevcf_reportid != iha->reportid) 859 return (0); 860 861 return config_match(parent, cf, aux); 862 } 863 864 int 865 ihidev_open(struct ihidev *scd) 866 { 867 struct ihidev_softc *sc = scd->sc_parent; 868 869 DPRINTF(("%s: %s: state=%d refcnt=%d\n", sc->sc_dev.dv_xname, 870 __func__, scd->sc_state, sc->sc_refcnt)); 871 872 if (scd->sc_state & IHIDEV_OPEN) 873 return (EBUSY); 874 875 scd->sc_state |= IHIDEV_OPEN; 876 877 if (sc->sc_refcnt++ || sc->sc_isize == 0) 878 return (0); 879 880 /* power on */ 881 ihidev_reset(sc, false); 882 883 return (0); 884 } 885 886 void 887 ihidev_close(struct ihidev *scd) 888 { 889 struct ihidev_softc *sc = scd->sc_parent; 890 891 DPRINTF(("%s: %s: state=%d refcnt=%d\n", sc->sc_dev.dv_xname, 892 __func__, scd->sc_state, sc->sc_refcnt)); 893 894 if (!(scd->sc_state & IHIDEV_OPEN)) 895 return; 896 897 scd->sc_state &= ~IHIDEV_OPEN; 898 899 if (--sc->sc_refcnt) 900 return; 901 902 if (ihidev_hid_command(sc, I2C_HID_CMD_SET_POWER, 903 &I2C_HID_POWER_OFF, false)) 904 aprint_error_dev(sc->sc_dev, "failed to power down\n"); 905 } 906 907 void 908 ihidev_get_report_desc(struct ihidev_softc *sc, void **desc, int *size) 909 { 910 *desc = sc->sc_report; 911 *size = sc->sc_reportlen; 912 } 913 914 /* convert hid_* constants used throughout HID code to i2c HID equivalents */ 915 int 916 ihidev_report_type_conv(int hid_type_id) 917 { 918 switch (hid_type_id) { 919 case hid_input: 920 return I2C_HID_REPORT_TYPE_INPUT; 921 case hid_output: 922 return I2C_HID_REPORT_TYPE_OUTPUT; 923 case hid_feature: 924 return I2C_HID_REPORT_TYPE_FEATURE; 925 default: 926 return -1; 927 } 928 } 929 930 int 931 ihidev_get_report(struct device *dev, int type, int id, void *data, int len) 932 { 933 struct ihidev_softc *sc = (struct ihidev_softc *)dev; 934 struct i2c_hid_report_request rreq; 935 int ctype; 936 937 if ((ctype = ihidev_report_type_conv(type)) < 0) 938 return (1); 939 940 rreq.type = ctype; 941 rreq.id = id; 942 rreq.data = data; 943 rreq.len = len; 944 945 if (ihidev_hid_command(sc, I2C_HID_CMD_GET_REPORT, &rreq, false)) { 946 aprint_error_dev(sc->sc_dev, "failed fetching report\n"); 947 return (1); 948 } 949 950 return 0; 951 } 952 953 int 954 ihidev_set_report(struct device *dev, int type, int id, void *data, 955 int len) 956 { 957 struct ihidev_softc *sc = (struct ihidev_softc *)dev; 958 struct i2c_hid_report_request rreq; 959 int ctype; 960 961 if ((ctype = ihidev_report_type_conv(type)) < 0) 962 return (1); 963 964 rreq.type = ctype; 965 rreq.id = id; 966 rreq.data = data; 967 rreq.len = len; 968 969 if (ihidev_hid_command(sc, I2C_HID_CMD_SET_REPORT, &rreq, false)) { 970 aprint_error_dev(sc->sc_dev, "failed setting report\n"); 971 return (1); 972 } 973 974 return 0; 975 } 976 977 static bool 978 ihidev_acpi_get_info(struct ihidev_softc *sc) 979 { 980 ACPI_HANDLE hdl = (void *)(uintptr_t)sc->sc_phandle; 981 ACPI_STATUS status; 982 ACPI_INTEGER val; 983 984 /* 3cdff6f7-4267-4555-ad05-b30a3d8938de */ 985 uint8_t i2c_hid_guid[] = { 986 0xF7, 0xF6, 0xDF, 0x3C, 987 0x67, 0x42, 988 0x55, 0x45, 989 0xAD, 0x05, 990 0xB3, 0x0A, 0x3D, 0x89, 0x38, 0xDE, 991 }; 992 993 status = acpi_dsm_integer(hdl, i2c_hid_guid, 1, 1, NULL, &val); 994 if (ACPI_FAILURE(status)) { 995 aprint_error_dev(sc->sc_dev, 996 "failed to get HidDescriptorAddress: %s\n", 997 AcpiFormatException(status)); 998 return false; 999 } 1000 1001 sc->sc_hid_desc_addr = (u_int)val; 1002 1003 return true; 1004 } 1005