1/* $NetBSD: ihidev.c,v 1.30 2024/04/29 21:25:34 andvar 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.30 2024/04/29 21:25:34 andvar 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 */ 89enum { 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 104static int I2C_HID_POWER_ON = 0x0; 105static int I2C_HID_POWER_OFF = 0x1; 106 107static int ihidev_match(device_t, cfdata_t, void *); 108static void ihidev_attach(device_t, device_t, void *); 109static int ihidev_detach(device_t, int); 110CFATTACH_DECL_NEW(ihidev, sizeof(struct ihidev_softc), 111 ihidev_match, ihidev_attach, ihidev_detach, NULL); 112 113static bool ihidev_intr_init(struct ihidev_softc *); 114static void ihidev_intr_fini(struct ihidev_softc *); 115 116static bool ihidev_suspend(device_t, const pmf_qual_t *); 117static bool ihidev_resume(device_t, const pmf_qual_t *); 118static int ihidev_hid_command(struct ihidev_softc *, int, void *, bool); 119#if NACPICA > 0 120static int ihidev_intr(void *); 121static void ihidev_work(struct work *, void *); 122#endif 123static int ihidev_reset(struct ihidev_softc *, bool); 124static int ihidev_hid_desc_parse(struct ihidev_softc *); 125 126static int ihidev_maxrepid(void *, int); 127static int ihidev_print(void *, const char *); 128static int ihidev_submatch(device_t, cfdata_t, const int *, void *); 129 130static bool ihidev_acpi_get_info(struct ihidev_softc *); 131 132static const struct device_compatible_entry compat_data[] = { 133 { .compat = "PNP0C50" }, 134 { .compat = "ACPI0C50" }, 135 { .compat = "hid-over-i2c" }, 136 DEVICE_COMPAT_EOL 137}; 138 139static int 140ihidev_match(device_t parent, cfdata_t match, void *aux) 141{ 142 struct i2c_attach_args * const ia = aux; 143 int match_result; 144 145 if (iic_use_direct_match(ia, match, compat_data, &match_result)) 146 return match_result; 147 148 return 0; 149} 150 151static void 152ihidev_attach(device_t parent, device_t self, void *aux) 153{ 154 struct ihidev_softc *sc = device_private(self); 155 struct i2c_attach_args *ia = aux; 156 struct ihidev_attach_arg iha; 157 device_t dev; 158 int repid, repsz; 159 int isize; 160 int locs[IHIDBUSCF_NLOCS]; 161 162 sc->sc_dev = self; 163 sc->sc_tag = ia->ia_tag; 164 sc->sc_addr = ia->ia_addr; 165 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE); 166 167 sc->sc_phandle = ia->ia_cookie; 168 if (ia->ia_cookietype != I2C_COOKIE_ACPI) { 169 aprint_error(": unsupported device tree type\n"); 170 return; 171 } 172 if (!ihidev_acpi_get_info(sc)) { 173 return; 174 } 175 176 if (ihidev_hid_command(sc, I2C_HID_CMD_DESCR, NULL, false) || 177 ihidev_hid_desc_parse(sc)) { 178 aprint_error(": failed fetching initial HID descriptor\n"); 179 return; 180 } 181 182 aprint_naive("\n"); 183 aprint_normal(": vendor 0x%x product 0x%x, %s\n", 184 le16toh(sc->hid_desc.wVendorID), le16toh(sc->hid_desc.wProductID), 185 ia->ia_name); 186 187 sc->sc_nrepid = ihidev_maxrepid(sc->sc_report, sc->sc_reportlen); 188 if (sc->sc_nrepid < 0) 189 return; 190 191 aprint_normal_dev(self, "%d report id%s\n", sc->sc_nrepid, 192 sc->sc_nrepid > 1 ? "s" : ""); 193 194 sc->sc_nrepid++; 195 sc->sc_subdevs = kmem_zalloc(sc->sc_nrepid * sizeof(struct ihidev *), 196 KM_SLEEP); 197 198 /* find largest report size and allocate memory for input buffer */ 199 sc->sc_isize = le16toh(sc->hid_desc.wMaxInputLength); 200 for (repid = 0; repid < sc->sc_nrepid; repid++) { 201 repsz = hid_report_size(sc->sc_report, sc->sc_reportlen, 202 hid_input, repid); 203 204 isize = repsz + 2; /* two bytes for the length */ 205 isize += (sc->sc_nrepid != 1); /* one byte for the report ID */ 206 if (isize > sc->sc_isize) 207 sc->sc_isize = isize; 208 209 DPRINTF(("%s: repid %d size %d\n", 210 device_xname(sc->sc_dev), repid, repsz)); 211 } 212 sc->sc_ibuf = kmem_zalloc(sc->sc_isize, KM_SLEEP); 213 if (!ihidev_intr_init(sc)) { 214 return; 215 } 216 217 iha.iaa = ia; 218 iha.parent = sc; 219 220 /* Look for a driver claiming all report IDs first. */ 221 iha.reportid = IHIDEV_CLAIM_ALLREPORTID; 222 locs[IHIDBUSCF_REPORTID] = IHIDEV_CLAIM_ALLREPORTID; 223 dev = config_found(self, &iha, ihidev_print, 224 CFARGS(.submatch = ihidev_submatch, 225 .locators = locs)); 226 if (dev != NULL) { 227 for (repid = 0; repid < sc->sc_nrepid; repid++) 228 sc->sc_subdevs[repid] = device_private(dev); 229 return; 230 } 231 232 for (repid = 0; repid < sc->sc_nrepid; repid++) { 233 if (hid_report_size(sc->sc_report, sc->sc_reportlen, hid_input, 234 repid) == 0 && 235 hid_report_size(sc->sc_report, sc->sc_reportlen, 236 hid_output, repid) == 0 && 237 hid_report_size(sc->sc_report, sc->sc_reportlen, 238 hid_feature, repid) == 0) 239 continue; 240 241 iha.reportid = repid; 242 locs[IHIDBUSCF_REPORTID] = repid; 243 dev = config_found(self, &iha, ihidev_print, 244 CFARGS(.submatch = ihidev_submatch, 245 .locators = locs)); 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, 251 false)) { 252 aprint_error_dev(sc->sc_dev, "failed to power down\n"); 253 return; 254 } 255 if (!pmf_device_register(self, ihidev_suspend, ihidev_resume)) 256 aprint_error_dev(self, "couldn't establish power handler\n"); 257} 258 259static int 260ihidev_detach(device_t self, int flags) 261{ 262 struct ihidev_softc *sc = device_private(self); 263 int error; 264 265 error = config_detach_children(self, flags); 266 if (error) 267 return error; 268 269 pmf_device_deregister(self); 270 ihidev_intr_fini(sc); 271 272 if (ihidev_hid_command(sc, I2C_HID_CMD_SET_POWER, &I2C_HID_POWER_OFF, 273 true)) 274 aprint_error_dev(sc->sc_dev, "failed to power down\n"); 275 276 if (sc->sc_ibuf != NULL) { 277 kmem_free(sc->sc_ibuf, sc->sc_isize); 278 sc->sc_ibuf = NULL; 279 } 280 281 if (sc->sc_report != NULL) 282 kmem_free(sc->sc_report, sc->sc_reportlen); 283 284 mutex_destroy(&sc->sc_lock); 285 286 return 0; 287} 288 289static bool 290ihidev_suspend(device_t self, const pmf_qual_t *q) 291{ 292 struct ihidev_softc *sc = device_private(self); 293 294 mutex_enter(&sc->sc_lock); 295 if (sc->sc_refcnt > 0) { 296 printf("ihidev power off\n"); 297 if (ihidev_hid_command(sc, I2C_HID_CMD_SET_POWER, 298 &I2C_HID_POWER_OFF, true)) 299 aprint_error_dev(sc->sc_dev, "failed to power down\n"); 300 } 301 mutex_exit(&sc->sc_lock); 302 return true; 303} 304 305static bool 306ihidev_resume(device_t self, const pmf_qual_t *q) 307{ 308 struct ihidev_softc *sc = device_private(self); 309 310 mutex_enter(&sc->sc_lock); 311 if (sc->sc_refcnt > 0) { 312 printf("ihidev power reset\n"); 313 ihidev_reset(sc, true); 314 } 315 mutex_exit(&sc->sc_lock); 316 return true; 317} 318 319static int 320ihidev_hid_command(struct ihidev_softc *sc, int hidcmd, void *arg, bool poll) 321{ 322 int i, res = 1; 323 int flags = poll ? I2C_F_POLL : 0; 324 325 iic_acquire_bus(sc->sc_tag, flags); 326 327 switch (hidcmd) { 328 case I2C_HID_CMD_DESCR: { 329 /* 330 * 5.2.2 - HID Descriptor Retrieval 331 * register is passed from the controller 332 */ 333 uint8_t cmd[] = { 334 htole16(sc->sc_hid_desc_addr) & 0xff, 335 htole16(sc->sc_hid_desc_addr) >> 8, 336 }; 337 338 DPRINTF(("%s: HID command I2C_HID_CMD_DESCR at 0x%x\n", 339 device_xname(sc->sc_dev), htole16(sc->sc_hid_desc_addr))); 340 341 /* 20 00 */ 342 res = iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_addr, 343 &cmd, sizeof(cmd), &sc->hid_desc_buf, 344 sizeof(struct i2c_hid_desc), flags); 345 346 DPRINTF(("%s: HID descriptor:", device_xname(sc->sc_dev))); 347 for (i = 0; i < sizeof(struct i2c_hid_desc); i++) 348 DPRINTF((" %.2x", sc->hid_desc_buf[i])); 349 DPRINTF(("\n")); 350 351 break; 352 } 353 case I2C_HID_CMD_RESET: { 354 uint8_t cmd[] = { 355 htole16(sc->hid_desc.wCommandRegister) & 0xff, 356 htole16(sc->hid_desc.wCommandRegister) >> 8, 357 0, 358 I2C_HID_CMD_RESET, 359 }; 360 361 DPRINTF(("%s: HID command I2C_HID_CMD_RESET\n", 362 device_xname(sc->sc_dev))); 363 364 /* 22 00 00 01 */ 365 res = iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP, sc->sc_addr, 366 &cmd, sizeof(cmd), NULL, 0, flags); 367 368 break; 369 } 370 case I2C_HID_CMD_GET_REPORT: { 371 struct i2c_hid_report_request *rreq = 372 (struct i2c_hid_report_request *)arg; 373 374 uint8_t cmd[] = { 375 htole16(sc->hid_desc.wCommandRegister) & 0xff, 376 htole16(sc->hid_desc.wCommandRegister) >> 8, 377 0, 378 I2C_HID_CMD_GET_REPORT, 379 0, 0, 0, 380 }; 381 int cmdlen = 7; 382 int dataoff = 4; 383 int report_id = rreq->id; 384 int report_id_len = 1; 385 int report_len = rreq->len + 2; 386 int d; 387 uint8_t *tmprep; 388 389 DPRINTF(("%s: HID command I2C_HID_CMD_GET_REPORT %d " 390 "(type %d, len %d)\n", device_xname(sc->sc_dev), report_id, 391 rreq->type, rreq->len)); 392 393 /* 394 * 7.2.2.4 - "The protocol is optimized for Report < 15. If a 395 * report ID >= 15 is necessary, then the Report ID in the Low 396 * Byte must be set to 1111 and a Third Byte is appended to the 397 * protocol. This Third Byte contains the entire/actual report 398 * ID." 399 */ 400 if (report_id >= 15) { 401 cmd[dataoff++] = report_id; 402 report_id = 15; 403 report_id_len = 2; 404 } else 405 cmdlen--; 406 407 cmd[2] = report_id | rreq->type << 4; 408 409 cmd[dataoff++] = sc->hid_desc.wDataRegister & 0xff; 410 cmd[dataoff] = sc->hid_desc.wDataRegister >> 8; 411 412 /* 413 * 7.2.2.2 - Response will be a 2-byte length value, the report 414 * id with length determined above, and then the report. 415 * Allocate rreq->len + 2 + 2 bytes, read into that temporary 416 * buffer, and then copy only the report back out to 417 * rreq->data. 418 */ 419 report_len += report_id_len; 420 tmprep = kmem_zalloc(report_len, KM_NOSLEEP); 421 if (tmprep == NULL) { 422 /* XXX pool or preallocate? */ 423 DPRINTF(("%s: out of memory\n", 424 device_xname(sc->sc_dev))); 425 res = ENOMEM; 426 break; 427 } 428 429 /* type 3 id 8: 22 00 38 02 23 00 */ 430 res = iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_addr, 431 &cmd, cmdlen, tmprep, report_len, flags); 432 433 d = tmprep[0] | tmprep[1] << 8; 434 if (d != report_len) { 435 DPRINTF(("%s: response size %d != expected length %d\n", 436 device_xname(sc->sc_dev), d, report_len)); 437 } 438 439 if (report_id_len == 2) 440 d = tmprep[2] | tmprep[3] << 8; 441 else 442 d = tmprep[2]; 443 444 if (d != rreq->id) { 445 DPRINTF(("%s: response report id %d != %d\n", 446 device_xname(sc->sc_dev), d, rreq->id)); 447 iic_release_bus(sc->sc_tag, 0); 448 kmem_free(tmprep, report_len); 449 return (1); 450 } 451 452 DPRINTF(("%s: response:", device_xname(sc->sc_dev))); 453 for (i = 0; i < report_len; i++) 454 DPRINTF((" %.2x", tmprep[i])); 455 DPRINTF(("\n")); 456 457 memcpy(rreq->data, tmprep + 2 + report_id_len, rreq->len); 458 kmem_free(tmprep, report_len); 459 460 break; 461 } 462 case I2C_HID_CMD_SET_REPORT: { 463 struct i2c_hid_report_request *rreq = 464 (struct i2c_hid_report_request *)arg; 465 466 uint8_t cmd[] = { 467 htole16(sc->hid_desc.wCommandRegister) & 0xff, 468 htole16(sc->hid_desc.wCommandRegister) >> 8, 469 0, 470 I2C_HID_CMD_SET_REPORT, 471 0, 0, 0, 0, 0, 0, 472 }; 473 int cmdlen = 10; 474 int report_id = rreq->id; 475 int report_len = 2 + (report_id ? 1 : 0) + rreq->len; 476 int dataoff; 477 uint8_t *finalcmd; 478 479 DPRINTF(("%s: HID command I2C_HID_CMD_SET_REPORT %d " 480 "(type %d, len %d):", device_xname(sc->sc_dev), report_id, 481 rreq->type, rreq->len)); 482 for (i = 0; i < rreq->len; i++) 483 DPRINTF((" %.2x", ((uint8_t *)rreq->data)[i])); 484 DPRINTF(("\n")); 485 486 /* 487 * 7.2.2.4 - "The protocol is optimized for Report < 15. If a 488 * report ID >= 15 is necessary, then the Report ID in the Low 489 * Byte must be set to 1111 and a Third Byte is appended to the 490 * protocol. This Third Byte contains the entire/actual report 491 * ID." 492 */ 493 dataoff = 4; 494 if (report_id >= 15) { 495 cmd[dataoff++] = report_id; 496 report_id = 15; 497 } else 498 cmdlen--; 499 500 cmd[2] = report_id | rreq->type << 4; 501 502 if (rreq->type == I2C_HID_REPORT_TYPE_FEATURE) { 503 cmd[dataoff++] = htole16(sc->hid_desc.wDataRegister) 504 & 0xff; 505 cmd[dataoff++] = htole16(sc->hid_desc.wDataRegister) 506 >> 8; 507 } else { 508 cmd[dataoff++] = htole16(sc->hid_desc.wOutputRegister) 509 & 0xff; 510 cmd[dataoff++] = htole16(sc->hid_desc.wOutputRegister) 511 >> 8; 512 } 513 514 cmd[dataoff++] = report_len & 0xff; 515 cmd[dataoff++] = report_len >> 8; 516 cmd[dataoff] = rreq->id; 517 518 finalcmd = kmem_zalloc(cmdlen + rreq->len, KM_NOSLEEP); 519 if (finalcmd == NULL) { 520 res = ENOMEM; 521 break; 522 } 523 524 memcpy(finalcmd, cmd, cmdlen); 525 memcpy(finalcmd + cmdlen, rreq->data, rreq->len); 526 527 /* type 3 id 4: 22 00 34 03 23 00 04 00 04 03 */ 528 res = iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP, sc->sc_addr, 529 finalcmd, cmdlen + rreq->len, NULL, 0, flags); 530 kmem_free(finalcmd, cmdlen + rreq->len); 531 532 break; 533 } 534 535 case I2C_HID_CMD_SET_POWER: { 536 int power = *(int *)arg; 537 uint8_t cmd[] = { 538 htole16(sc->hid_desc.wCommandRegister) & 0xff, 539 htole16(sc->hid_desc.wCommandRegister) >> 8, 540 power, 541 I2C_HID_CMD_SET_POWER, 542 }; 543 544 DPRINTF(("%s: HID command I2C_HID_CMD_SET_POWER(%d)\n", 545 device_xname(sc->sc_dev), power)); 546 547 /* 22 00 00 08 */ 548 res = iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP, sc->sc_addr, 549 &cmd, sizeof(cmd), NULL, 0, flags); 550 551 break; 552 } 553 case I2C_HID_REPORT_DESCR: { 554 uint8_t cmd[] = { 555 htole16(sc->hid_desc.wReportDescRegister) & 0xff, 556 htole16(sc->hid_desc.wReportDescRegister) >> 8, 557 }; 558 559 DPRINTF(("%s: HID command I2C_HID_REPORT_DESCR at 0x%x with " 560 "size %d\n", device_xname(sc->sc_dev), cmd[0], 561 sc->sc_reportlen)); 562 563 /* 20 00 */ 564 res = iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_addr, 565 &cmd, sizeof(cmd), sc->sc_report, sc->sc_reportlen, flags); 566 567 DPRINTF(("%s: HID report descriptor:", 568 device_xname(sc->sc_dev))); 569 for (i = 0; i < sc->sc_reportlen; i++) 570 DPRINTF((" %.2x", sc->sc_report[i])); 571 DPRINTF(("\n")); 572 573 break; 574 } 575 default: 576 aprint_error_dev(sc->sc_dev, "unknown command %d\n", 577 hidcmd); 578 } 579 580 iic_release_bus(sc->sc_tag, flags); 581 582 return (res); 583} 584 585static int 586ihidev_reset(struct ihidev_softc *sc, bool poll) 587{ 588 DPRINTF(("%s: resetting\n", device_xname(sc->sc_dev))); 589 590 if (ihidev_hid_command(sc, I2C_HID_CMD_SET_POWER, 591 &I2C_HID_POWER_ON, poll)) { 592 aprint_error_dev(sc->sc_dev, "failed to power on\n"); 593 return (1); 594 } 595 596 DELAY(1000); 597 598 if (ihidev_hid_command(sc, I2C_HID_CMD_RESET, 0, poll)) { 599 aprint_error_dev(sc->sc_dev, "failed to reset hardware\n"); 600 601 ihidev_hid_command(sc, I2C_HID_CMD_SET_POWER, 602 &I2C_HID_POWER_OFF, poll); 603 604 return (1); 605 } 606 607 DELAY(1000); 608 609 return (0); 610} 611 612/* 613 * 5.2.2 - HID Descriptor Retrieval 614 * 615 * parse HID Descriptor that has already been read into hid_desc with 616 * I2C_HID_CMD_DESCR 617 */ 618static int 619ihidev_hid_desc_parse(struct ihidev_softc *sc) 620{ 621 int retries = 3; 622 623 /* must be v01.00 */ 624 if (le16toh(sc->hid_desc.bcdVersion) != 0x0100) { 625 aprint_error_dev(sc->sc_dev, 626 "bad HID descriptor bcdVersion (0x%x)\n", 627 le16toh(sc->hid_desc.bcdVersion)); 628 return (1); 629 } 630 631 /* must be 30 bytes for v1.00 */ 632 if (le16toh(sc->hid_desc.wHIDDescLength != 633 sizeof(struct i2c_hid_desc))) { 634 aprint_error_dev(sc->sc_dev, 635 "bad HID descriptor size (%d != %zu)\n", 636 le16toh(sc->hid_desc.wHIDDescLength), 637 sizeof(struct i2c_hid_desc)); 638 return (1); 639 } 640 641 if (le16toh(sc->hid_desc.wReportDescLength) <= 0) { 642 aprint_error_dev(sc->sc_dev, 643 "bad HID report descriptor size (%d)\n", 644 le16toh(sc->hid_desc.wReportDescLength)); 645 return (1); 646 } 647 648 while (retries-- > 0) { 649 if (ihidev_reset(sc, false)) { 650 if (retries == 0) 651 return(1); 652 653 DELAY(1000); 654 } 655 else 656 break; 657 } 658 659 sc->sc_reportlen = le16toh(sc->hid_desc.wReportDescLength); 660 sc->sc_report = kmem_zalloc(sc->sc_reportlen, KM_SLEEP); 661 662 if (ihidev_hid_command(sc, I2C_HID_REPORT_DESCR, 0, false)) { 663 aprint_error_dev(sc->sc_dev, "failed fetching HID report\n"); 664 return (1); 665 } 666 667 return (0); 668} 669 670static bool 671ihidev_intr_init(struct ihidev_softc *sc) 672{ 673#if NACPICA > 0 674 ACPI_HANDLE hdl = (void *)(uintptr_t)sc->sc_phandle; 675 struct acpi_resources res; 676 ACPI_STATUS rv; 677 char buf[100]; 678 679 rv = acpi_resource_parse(sc->sc_dev, hdl, "_CRS", &res, 680 &acpi_resource_parse_ops_quiet); 681 if (ACPI_FAILURE(rv)) { 682 aprint_error_dev(sc->sc_dev, "can't parse '_CRS'\n"); 683 return false; 684 } 685 686 const struct acpi_irq * const irq = acpi_res_irq(&res, 0); 687 if (irq == NULL) { 688 aprint_error_dev(sc->sc_dev, "no IRQ resource\n"); 689 acpi_resource_cleanup(&res); 690 return false; 691 } 692 693 sc->sc_intr_type = 694 irq->ar_type == ACPI_EDGE_SENSITIVE ? IST_EDGE : IST_LEVEL; 695 696 acpi_resource_cleanup(&res); 697 698 sc->sc_ih = acpi_intr_establish(sc->sc_dev, sc->sc_phandle, IPL_TTY, 699 false, ihidev_intr, sc, device_xname(sc->sc_dev)); 700 if (sc->sc_ih == NULL) { 701 aprint_error_dev(sc->sc_dev, "can't establish interrupt\n"); 702 return false; 703 } 704 aprint_normal_dev(sc->sc_dev, "interrupting at %s\n", 705 acpi_intr_string(sc->sc_ih, buf, sizeof(buf))); 706 707 if (workqueue_create(&sc->sc_wq, device_xname(sc->sc_dev), ihidev_work, 708 sc, PRI_NONE, IPL_TTY, WQ_MPSAFE)) { 709 aprint_error_dev(sc->sc_dev, 710 "can't establish workqueue\n"); 711 return false; 712 } 713 sc->sc_work_pending = 0; 714 715 return true; 716#else 717 aprint_error_dev(sc->sc_dev, "can't establish interrupt\n"); 718 return false; 719#endif 720} 721 722static void 723ihidev_intr_fini(struct ihidev_softc *sc) 724{ 725#if NACPICA > 0 726 if (sc->sc_ih != NULL) { 727 acpi_intr_disestablish(sc->sc_ih); 728 } 729 if (sc->sc_wq != NULL) { 730 workqueue_destroy(sc->sc_wq); 731 } 732#endif 733} 734 735#if NACPICA > 0 736static void 737ihidev_intr_mask(struct ihidev_softc * const sc) 738{ 739 740 if (sc->sc_intr_type == IST_LEVEL) { 741 acpi_intr_mask(sc->sc_ih); 742 } 743} 744 745static void 746ihidev_intr_unmask(struct ihidev_softc * const sc) 747{ 748 749 if (sc->sc_intr_type == IST_LEVEL) { 750 acpi_intr_unmask(sc->sc_ih); 751 } 752} 753 754static int 755ihidev_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 770static void 771ihidev_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 device_xname(sc->sc_dev), __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):", device_xname(sc->sc_dev), 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#endif 835 836static int 837ihidev_maxrepid(void *buf, int len) 838{ 839 struct hid_data *d; 840 struct hid_item h; 841 int maxid; 842 843 maxid = -1; 844 h.report_ID = 0; 845 for (d = hid_start_parse(buf, len, hid_none); hid_get_item(d, &h); ) 846 if ((int)h.report_ID > maxid) 847 maxid = h.report_ID; 848 hid_end_parse(d); 849 850 return (maxid); 851} 852 853static int 854ihidev_print(void *aux, const char *pnp) 855{ 856 struct ihidev_attach_arg *iha = aux; 857 858 if (iha->reportid == IHIDEV_CLAIM_ALLREPORTID) 859 return (QUIET); 860 861 if (pnp) 862 aprint_normal("hid at %s", pnp); 863 864 if (iha->reportid != 0) 865 aprint_normal(" reportid %d", iha->reportid); 866 867 return (UNCONF); 868} 869 870static int 871ihidev_submatch(device_t parent, cfdata_t cf, const int *locs, void *aux) 872{ 873 struct ihidev_attach_arg *iha = aux; 874 875 if (cf->ihidevcf_reportid != IHIDEV_UNK_REPORTID && 876 cf->ihidevcf_reportid != iha->reportid) 877 return (0); 878 879 return config_match(parent, cf, aux); 880} 881 882int 883ihidev_open(struct ihidev *scd) 884{ 885 struct ihidev_softc *sc = scd->sc_parent; 886 int error; 887 888 DPRINTF(("%s: %s: state=%d refcnt=%d\n", device_xname(sc->sc_dev), 889 __func__, scd->sc_state, sc->sc_refcnt)); 890 891 mutex_enter(&sc->sc_lock); 892 893 if (scd->sc_state & IHIDEV_OPEN || sc->sc_refcnt == INT_MAX) { 894 error = EBUSY; 895 goto out; 896 } 897 898 scd->sc_state |= IHIDEV_OPEN; 899 900 if (sc->sc_refcnt++ || sc->sc_isize == 0) { 901 error = 0; 902 goto out; 903 } 904 905 /* power on */ 906 ihidev_reset(sc, false); 907 error = 0; 908 909out: mutex_exit(&sc->sc_lock); 910 return error; 911} 912 913void 914ihidev_close(struct ihidev *scd) 915{ 916 struct ihidev_softc *sc = scd->sc_parent; 917 918 DPRINTF(("%s: %s: state=%d refcnt=%d\n", device_xname(sc->sc_dev), 919 __func__, scd->sc_state, sc->sc_refcnt)); 920 921 mutex_enter(&sc->sc_lock); 922 923 KASSERTMSG(scd->sc_state & IHIDEV_OPEN, 924 "%s: closing %s when not open", 925 device_xname(scd->sc_idev), 926 device_xname(sc->sc_dev)); 927 scd->sc_state &= ~IHIDEV_OPEN; 928 929 if (--sc->sc_refcnt) 930 goto out; 931 932 if (ihidev_hid_command(sc, I2C_HID_CMD_SET_POWER, 933 &I2C_HID_POWER_OFF, false)) 934 aprint_error_dev(sc->sc_dev, "failed to power down\n"); 935 936out: mutex_exit(&sc->sc_lock); 937} 938 939void 940ihidev_get_report_desc(struct ihidev_softc *sc, void **desc, int *size) 941{ 942 *desc = sc->sc_report; 943 *size = sc->sc_reportlen; 944} 945 946/* convert hid_* constants used throughout HID code to i2c HID equivalents */ 947int 948ihidev_report_type_conv(int hid_type_id) 949{ 950 switch (hid_type_id) { 951 case hid_input: 952 return I2C_HID_REPORT_TYPE_INPUT; 953 case hid_output: 954 return I2C_HID_REPORT_TYPE_OUTPUT; 955 case hid_feature: 956 return I2C_HID_REPORT_TYPE_FEATURE; 957 default: 958 return -1; 959 } 960} 961 962int 963ihidev_get_report(struct device *dev, int type, int id, void *data, int len) 964{ 965 struct ihidev_softc *sc = (struct ihidev_softc *)dev; 966 struct i2c_hid_report_request rreq; 967 int ctype; 968 969 if ((ctype = ihidev_report_type_conv(type)) < 0) 970 return (1); 971 972 rreq.type = ctype; 973 rreq.id = id; 974 rreq.data = data; 975 rreq.len = len; 976 977 if (ihidev_hid_command(sc, I2C_HID_CMD_GET_REPORT, &rreq, false)) { 978 aprint_error_dev(sc->sc_dev, "failed fetching report\n"); 979 return (1); 980 } 981 982 return 0; 983} 984 985int 986ihidev_set_report(struct device *dev, int type, int id, void *data, 987 int len) 988{ 989 struct ihidev_softc *sc = (struct ihidev_softc *)dev; 990 struct i2c_hid_report_request rreq; 991 int ctype; 992 993 if ((ctype = ihidev_report_type_conv(type)) < 0) 994 return (1); 995 996 rreq.type = ctype; 997 rreq.id = id; 998 rreq.data = data; 999 rreq.len = len; 1000 1001 if (ihidev_hid_command(sc, I2C_HID_CMD_SET_REPORT, &rreq, false)) { 1002 aprint_error_dev(sc->sc_dev, "failed setting report\n"); 1003 return (1); 1004 } 1005 1006 return 0; 1007} 1008 1009static bool 1010ihidev_acpi_get_info(struct ihidev_softc *sc) 1011{ 1012#if NACPICA > 0 1013 ACPI_HANDLE hdl = (void *)(uintptr_t)sc->sc_phandle; 1014 ACPI_STATUS status; 1015 ACPI_INTEGER val; 1016 1017 /* 3cdff6f7-4267-4555-ad05-b30a3d8938de */ 1018 uint8_t i2c_hid_guid[] = { 1019 0xF7, 0xF6, 0xDF, 0x3C, 1020 0x67, 0x42, 1021 0x55, 0x45, 1022 0xAD, 0x05, 1023 0xB3, 0x0A, 0x3D, 0x89, 0x38, 0xDE, 1024 }; 1025 1026 status = acpi_dsm_integer(hdl, i2c_hid_guid, 1, 1, NULL, &val); 1027 if (ACPI_FAILURE(status)) { 1028 aprint_error_dev(sc->sc_dev, 1029 "failed to get HidDescriptorAddress: %s\n", 1030 AcpiFormatException(status)); 1031 return false; 1032 } 1033 1034 sc->sc_hid_desc_addr = (u_int)val; 1035 1036 return true; 1037#else 1038 return false; 1039#endif 1040} 1041