Lines Matching +full:i2c +full:- +full:hid
1 /*-
2 * Copyright (c) 2018-2019 Marc Priggemeyer <marc.priggemeyer@gmail.com>
3 * Copyright (c) 2019-2020 Vladimir Kondratyev <wulf@FreeBSD.org>
28 * I2C HID transport backend.
55 #include <dev/hid/hid.h>
56 #include <dev/hid/hidquirk.h>
67 static SYSCTL_NODE(_hw, OID_AUTO, iichid, CTLFLAG_RW, 0, "I2C HID");
73 device_printf((sc)->dev, __VA_ARGS__); \
82 #define IICHID_SIZE_MAX (UINT16_MAX - 2)
113 /* 5.1.1 - HID Descriptor Format */
131 #define IICHID_REG_NONE -1
215 for (ids = iichid_ids; ids->id != NULL; ids++) {
216 if (acpi_MatchHid(handle, ids->id)) {
217 reg = ids->reg;
221 if (ids->id == NULL)
244 * the configuration register of the HID device.
246 /* 3cdff6f7-4267-4555-ad05-b30a3d8938de */
259 *config_reg = result->Integer.Value & 0xFFFF;
270 * 6.1.3 - Retrieval of Input Reports
276 { sc->addr, IIC_M_RD | IIC_M_NOSTOP, sizeof(actbuf), actbuf },
281 error = iicbus_transfer(sc->dev, msgs, nitems(msgs));
287 /* Read and discard 1 byte to send I2C STOP condition. */
289 { sc->addr, IIC_M_RD | IIC_M_NOSTART, 1, actbuf };
292 actlen -= 2;
300 { sc->addr, IIC_M_RD | IIC_M_NOSTART, actlen, buf };
303 error = iicbus_transfer(sc->dev, msgs, 1);
308 "%*D - %*D\n", 2, actbuf, " ", msgs[0].len, msgs[0].buf, " ");
316 /* 6.2.3 - Sending Output Reports. */
317 uint8_t *cmdreg = (uint8_t *)&sc->desc.wOutputRegister;
321 {sc->addr, IIC_M_WR | IIC_M_NOSTOP, sizeof(cmd), cmd},
322 {sc->addr, IIC_M_WR | IIC_M_NOSTART, len, __DECONST(void *, buf)},
325 if (le16toh(sc->desc.wMaxOutputLength) == 0)
330 DPRINTF(sc, "HID command I2C_HID_CMD_WRITE (len %d): "
333 return (iicbus_transfer(sc->dev, msgs, nitems(msgs)));
341 * 5.2.2 - HID Descriptor Retrieval
346 { sc->addr, IIC_M_WR | IIC_M_NOSTOP, 2, (uint8_t *)&cmd },
347 { sc->addr, IIC_M_RD, sizeof(*hid_desc), (uint8_t *)hid_desc },
351 DPRINTF(sc, "HID command I2C_HID_CMD_DESCR at 0x%x\n", config_reg);
353 error = iicbus_transfer(sc->dev, msgs, nitems(msgs));
357 DPRINTF(sc, "HID descriptor: %*D\n",
366 uint8_t *cmdreg = (uint8_t *)&sc->desc.wCommandRegister;
369 { sc->addr, IIC_M_WR, sizeof(cmd), cmd },
372 DPRINTF(sc, "HID command I2C_HID_CMD_SET_POWER(%d)\n", param);
374 return (iicbus_transfer(sc->dev, msgs, nitems(msgs)));
380 uint8_t *cmdreg = (uint8_t *)&sc->desc.wCommandRegister;
383 { sc->addr, IIC_M_WR, sizeof(cmd), cmd },
386 DPRINTF(sc, "HID command I2C_HID_CMD_RESET\n");
388 return (iicbus_transfer(sc->dev, msgs, nitems(msgs)));
395 uint16_t cmd = sc->desc.wReportDescRegister;
397 { sc->addr, IIC_M_WR | IIC_M_NOSTOP, 2, (uint8_t *)&cmd },
398 { sc->addr, IIC_M_RD, len, buf },
402 DPRINTF(sc, "HID command I2C_HID_REPORT_DESCR at 0x%x with size %d\n",
405 error = iicbus_transfer(sc->dev, msgs, nitems(msgs));
409 DPRINTF(sc, "HID report descriptor: %*D\n", len, buf, " ");
419 * 7.2.2.4 - "The protocol is optimized for Report < 15. If a
424 uint8_t *dtareg = (uint8_t *)&sc->desc.wDataRegister;
425 uint8_t *cmdreg = (uint8_t *)&sc->desc.wCommandRegister;
440 { sc->addr, IIC_M_WR | IIC_M_NOSTOP, cmdlen, cmd },
441 { sc->addr, IIC_M_RD | IIC_M_NOSTOP, 2, actbuf },
442 { sc->addr, IIC_M_RD | IIC_M_NOSTART, maxlen, buf },
448 DPRINTF(sc, "HID command I2C_HID_CMD_GET_REPORT %d "
452 * 7.2.2.2 - Response will be a 2-byte length value, the report
455 error = iicbus_transfer(sc->dev, msgs, nitems(msgs));
473 actlen -= 2;
489 * 7.2.2.4 - "The protocol is optimized for Report < 15. If a
494 uint8_t *dtareg = (uint8_t *)&sc->desc.wDataRegister;
495 uint8_t *cmdreg = (uint8_t *)&sc->desc.wCommandRegister;
510 {sc->addr, IIC_M_WR | IIC_M_NOSTOP, cmdlen, cmd},
511 {sc->addr, IIC_M_WR | IIC_M_NOSTART, len, __DECONST(void *, buf)},
514 DPRINTF(sc, "HID command I2C_HID_CMD_SET_REPORT %d (type %d, len %d): "
517 return (iicbus_transfer(sc->dev, msgs, nitems(msgs)));
531 parent = device_get_parent(sc->dev);
534 if (iicbus_request_bus(parent, sc->dev, IIC_WAIT) != 0)
538 if (!sc->power_on)
541 error = iichid_cmd_read(sc, sc->intr_buf, sc->intr_bufsize, &actual);
544 sc->intr_handler(sc->intr_ctx, sc->intr_buf, actual);
545 sc->missing_samples = 0;
546 if (sc->dup_size != actual ||
547 memcmp(sc->dup_buf, sc->intr_buf, actual) != 0) {
548 sc->dup_size = actual;
549 memcpy(sc->dup_buf, sc->intr_buf, actual);
550 sc->dup_samples = 0;
552 ++sc->dup_samples;
554 if (++sc->missing_samples == 1)
555 sc->intr_handler(sc->intr_ctx, sc->intr_buf, 0);
556 sc->dup_samples = 0;
562 if (sc->callout_setup && sc->sampling_rate_slow > 0) {
563 if (sc->missing_samples >= sc->sampling_hysteresis ||
564 sc->dup_samples >= sc->sampling_hysteresis)
565 rate = sc->sampling_rate_slow;
567 rate = sc->sampling_rate_fast;
568 taskqueue_enqueue_timeout_sbt(sc->taskqueue, &sc->sampling_task,
573 iicbus_release_bus(parent, sc->dev);
586 parent = device_get_parent(sc->dev);
589 * Designware(IG4) driver-specific hack.
590 * Requesting of an I2C bus with IIC_DONTWAIT parameter enables polled
594 if (iicbus_request_bus(parent, sc->dev, IIC_DONTWAIT) != 0)
598 * Reading of input reports of I2C devices residing in SLEEP state is
604 maxlen = sc->power_on ? sc->intr_bufsize : 0;
605 error = iichid_cmd_read(sc, sc->intr_buf, maxlen, &actual);
607 if (sc->power_on) {
609 sc->intr_handler(sc->intr_ctx, sc->intr_buf,
617 iicbus_release_bus(parent, sc->dev);
631 * Request iicbus early as sc->suspend and sc->power_on
634 parent = device_get_parent(sc->dev);
637 error = iicbus_request_bus(parent, sc->dev, how_request);
643 sc->open = true;
646 sc->open = false;
655 sc->suspend = false;
658 sc->suspend = true;
665 power_on = sc->open & !sc->suspend;
667 if (power_on != sc->power_on) {
671 sc->power_on = power_on;
673 if (sc->sampling_rate_slow >= 0 && sc->intr_handler != NULL) {
683 iicbus_release_bus(parent, sc->dev);
691 sc->irq_cookie = 0;
693 int error = bus_setup_intr(sc->dev, sc->irq_res,
694 INTR_TYPE_TTY|INTR_MPSAFE, NULL, iichid_intr, sc, &sc->irq_cookie);
706 if (sc->irq_cookie)
707 bus_teardown_intr(sc->dev, sc->irq_res, sc->irq_cookie);
709 sc->irq_cookie = 0;
717 if (sc->sampling_rate_slow < 0) {
722 sc->callout_setup = true;
731 if (sc->sampling_rate_slow <= 0) {
737 if (!sc->callout_setup)
741 sc->missing_samples = sc->sampling_hysteresis;
742 sc->dup_samples = 0;
743 sc->dup_size = 0;
744 taskqueue_enqueue_timeout(sc->taskqueue, &sc->sampling_task, 0);
753 sc->callout_setup = false;
754 taskqueue_cancel_timeout(sc->taskqueue, &sc->sampling_task, NULL);
767 value = sc->sampling_rate_slow;
770 if (error != 0 || req->newptr == NULL ||
771 value == sc->sampling_rate_slow)
775 if (sc->irq_res == NULL && value < 0)
778 parent = device_get_parent(sc->dev);
779 error = iicbus_request_bus(parent, sc->dev, IIC_WAIT);
783 oldval = sc->sampling_rate_slow;
784 sc->sampling_rate_slow = value;
788 if (sc->power_on)
791 if (sc->power_on)
796 if (sc->power_on && value > 0)
799 iicbus_release_bus(parent, sc->dev);
821 rdesc->rdsize = rdesc->isize;
822 /* Write and get/set_report sizes are limited by I2C-HID protocol. */
823 rdesc->grsize = rdesc->srsize = IICHID_SIZE_MAX;
824 rdesc->wrsize = IICHID_SIZE_MAX;
826 sc->intr_handler = intr;
827 sc->intr_ctx = context;
828 sc->intr_buf = malloc(rdesc->rdsize, M_DEVBUF, M_WAITOK | M_ZERO);
829 sc->intr_bufsize = rdesc->rdsize;
831 sc->dup_buf = malloc(rdesc->rdsize, M_DEVBUF, M_WAITOK | M_ZERO);
832 taskqueue_start_threads(&sc->taskqueue, 1, PI_TTY,
833 "%s taskq", device_get_nameunit(sc->dev));
844 taskqueue_drain_all(sc->taskqueue);
845 free(sc->dup_buf, M_DEVBUF);
847 free(sc->intr_buf, M_DEVBUF);
870 * 8.2 - The HOST determines that there are no active applications
871 * that are currently using the specific HID DEVICE. The HOST
888 error = iichid_cmd_read(sc, sc->intr_buf, sc->intr_bufsize, &actual);
890 sc->intr_handler(sc->intr_ctx, sc->intr_buf, actual);
894 * HID interface
922 parent = device_get_parent(sc->dev);
923 error = iicbus_request_bus(parent, sc->dev, IIC_WAIT);
926 iicbus_release_bus(parent, sc->dev);
990 ((struct iic_rdwr_data *)data)->msgs,
991 ((struct iic_rdwr_data *)data)->nmsgs));
1006 hw->idBus = BUS_I2C;
1007 hw->idVendor = le16toh(desc->wVendorID);
1008 hw->idProduct = le16toh(desc->wProductID);
1009 hw->idVersion = le16toh(desc->wVersionID);
1011 /* get ACPI HID. It is a base part of the device name. */
1015 if (device_info->Valid & ACPI_VALID_HID)
1016 strlcpy(hw->idPnP, device_info->HardwareId.String,
1018 snprintf(hw->name, sizeof(hw->name), "%s:%02lX %04X:%04X",
1019 (device_info->Valid & ACPI_VALID_HID) ?
1020 device_info->HardwareId.String : "Unknown",
1021 (device_info->Valid & ACPI_VALID_UID) ?
1022 strtoul(device_info->UniqueId.String, NULL, 10) : 0UL,
1023 le16toh(desc->wVendorID), le16toh(desc->wProductID));
1027 strlcpy(hw->serial, "", sizeof(hw->serial));
1028 hw->rdescsize = le16toh(desc->wReportDescLength);
1029 if (desc->wOutputRegister == 0 || desc->wMaxOutputLength == 0)
1044 sc->dev = dev;
1045 if (sc->probe_done)
1048 sc->probe_done = true;
1049 sc->probe_result = ENXIO;
1054 sc->addr = iicbus_get_addr(dev) << 1;
1055 if (sc->addr == 0)
1072 DPRINTF(sc, " IICbus addr : 0x%02X\n", sc->addr >> 1);
1073 DPRINTF(sc, " HID descriptor reg: 0x%02X\n", config_reg);
1075 error = iichid_cmd_get_hid_desc(sc, config_reg, &sc->desc);
1077 DPRINTF(sc, "could not retrieve HID descriptor from the "
1082 if (le16toh(sc->desc.wHIDDescLength) != 30 ||
1083 le16toh(sc->desc.bcdVersion) != 0x100) {
1084 DPRINTF(sc, "HID descriptor is broken\n");
1089 if (iichid_fill_device_info(&sc->desc, handle, &sc->hw) != 0) {
1094 if (hid_test_quirk(&sc->hw, HQ_HID_IGNORE))
1097 sc->probe_result = BUS_PROBE_DEFAULT;
1099 if (sc->probe_result <= BUS_PROBE_SPECIFIC)
1100 device_set_descf(dev, "%s I2C HID device", sc->hw.name);
1101 return (sc->probe_result);
1130 sc->power_on = true;
1132 TASK_INIT(&sc->suspend_task, 0, iichid_suspend_task, sc);
1134 sc->taskqueue = taskqueue_create_fast("iichid_tq", M_WAITOK | M_ZERO,
1135 taskqueue_thread_enqueue, &sc->taskqueue);
1136 TIMEOUT_TASK_INIT(sc->taskqueue, &sc->sampling_task, 0,
1139 sc->sampling_rate_slow = -1;
1140 sc->sampling_rate_fast = IICHID_SAMPLING_RATE_FAST;
1141 sc->sampling_hysteresis = IICHID_SAMPLING_HYSTERESIS;
1144 sc->irq_rid = 0;
1145 sc->irq_res = bus_alloc_resource_any(sc->dev, SYS_RES_IRQ,
1146 &sc->irq_rid, RF_ACTIVE);
1148 if (sc->irq_res != NULL) {
1150 sc->irq_res, sc->irq_rid);
1154 if (sc->irq_res == NULL || error != 0) {
1156 device_printf(sc->dev,
1158 sc->sampling_rate_slow = IICHID_SAMPLING_RATE_SLOW;
1160 device_printf(sc->dev, "Interrupt setup failed\n");
1161 if (sc->irq_res != NULL)
1162 bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid,
1163 sc->irq_res);
1170 SYSCTL_ADD_PROC(device_get_sysctl_ctx(sc->dev),
1171 SYSCTL_CHILDREN(device_get_sysctl_tree(sc->dev)),
1175 SYSCTL_ADD_INT(device_get_sysctl_ctx(sc->dev),
1176 SYSCTL_CHILDREN(device_get_sysctl_tree(sc->dev)),
1178 &sc->sampling_rate_fast, 0,
1180 SYSCTL_ADD_INT(device_get_sysctl_ctx(sc->dev),
1181 SYSCTL_CHILDREN(device_get_sysctl_tree(sc->dev)),
1183 &sc->sampling_hysteresis, 0,
1185 hid_add_dynamic_quirk(&sc->hw, HQ_IICHID_SAMPLING);
1187 if (sc->sampling_rate_slow >= 0) {
1195 device_printf(sc->dev, "Could not add I2C device\n");
1201 device_set_ivars(child, &sc->hw);
1206 if (!sc->open) {
1208 sc->power_on = false;
1225 if (sc->irq_res != NULL)
1226 bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid,
1227 sc->irq_res);
1229 if (sc->taskqueue != NULL)
1230 taskqueue_free(sc->taskqueue);
1231 sc->taskqueue = NULL;
1253 * 8.2 - The HOST is going into a deep power optimized state and wishes
1266 if (sc->sampling_rate_slow < 0)
1275 #define suspend_thread sc->taskqueue
1279 taskqueue_enqueue(suspend_thread, &sc->suspend_task);
1280 taskqueue_drain(suspend_thread, &sc->suspend_task);
1294 if (sc->sampling_rate_slow < 0)
1322 /* HID interface */
1344 MODULE_DEPEND(iichid, hid, 1, 1, 1);