38#include <sys/callout.h>
39#include <sys/endian.h>
40#include <sys/kernel.h>
42#include <sys/malloc.h>
43#include <sys/module.h>
45#include <sys/sysctl.h>
47#include <sys/taskqueue.h>
49#include <machine/resource.h>
51#include <contrib/dev/acpica/include/acpi.h>
52#include <contrib/dev/acpica/include/accommon.h>
53#include <dev/acpica/acpivar.h>
55#include <dev/evdev/input.h>
57#include <dev/hid/hid.h>
58#include <dev/hid/hidquirk.h>
67static int iichid_debug = 0;
69static SYSCTL_NODE(_hw, OID_AUTO, iichid, CTLFLAG_RW, 0,
"I2C HID");
70SYSCTL_INT(_hw_iichid, OID_AUTO, debug, CTLFLAG_RWTUN,
71 &iichid_debug, 1,
"Debug level");
73#define DPRINTFN(sc, n, ...) do { \
74 if (iichid_debug >= (n)) \
75 device_printf((sc)->dev, __VA_ARGS__); \
77#define DPRINTF(sc, ...) DPRINTFN(sc, 1, __VA_ARGS__)
79#define DPRINTFN(...) do {} while (0)
80#define DPRINTF(...) do {} while (0)
84#define IICHID_SIZE_MAX (UINT16_MAX - 2)
99#define I2C_HID_POWER_ON 0x0
100#define I2C_HID_POWER_OFF 0x1
111#define IICHID_SAMPLING_RATE_FAST 60
112#define IICHID_SAMPLING_RATE_SLOW 10
113#define IICHID_SAMPLING_HYSTERESIS 1
133#define IICHID_REG_NONE -1
134#define IICHID_REG_ACPI (UINT16_MAX + 1)
135#define IICHID_REG_ELAN 0x0001
164 struct hid_device_info
hw;
177#ifdef IICHID_SAMPLING
178 int sampling_rate_slow;
179 int sampling_rate_fast;
180 int sampling_hysteresis;
182 struct timeout_task periodic_task;
184 struct taskqueue *taskqueue;
185 struct task event_task;
202#ifdef IICHID_SAMPLING
205static void iichid_teardown_callout(
struct iichid_softc *);
216 if (acpi_MatchHid(handle, ids->
id)) {
228 if (ACPI_FAILURE(acpi_GetInteger(handle,
"_STA", &sta)) ||
229 ACPI_DEVICE_PRESENT(sta))
239 ACPI_BUFFER acpi_buf;
247 static uint8_t dsm_guid[ACPI_UUID_LENGTH] = {
248 0xF7, 0xF6, 0xDF, 0x3C, 0x67, 0x42, 0x55, 0x45,
249 0xAD, 0x05, 0xB3, 0x0A, 0x3D, 0x89, 0x38, 0xDE,
252 status = acpi_EvaluateDSMTyped(handle, dsm_guid, 1, 1, NULL, &acpi_buf,
254 if (ACPI_FAILURE(status)) {
255 printf(
"%s: error evaluating _DSM\n", __func__);
258 result = (ACPI_OBJECT *) acpi_buf.Pointer;
259 *config_reg = result->Integer.Value & 0xFFFF;
273 uint8_t actbuf[2] = { 0, 0 };
285 actlen = actbuf[0] | actbuf[1] << 8;
286 if (actlen <= 2 || actlen == 0xFFFF || maxlen == 0) {
293 if (actlen > maxlen) {
294 DPRINTF(sc,
"input report too big. requested=%d "
295 "received=%d\n", maxlen, actlen);
304 if (error == 0 && actual_len != NULL)
305 *actual_len = actlen;
318 uint16_t replen = 2 +
len;
319 uint8_t cmd[4] = { cmdreg[0], cmdreg[1], replen & 0xFF, replen >> 8 };
325 if (le16toh(sc->desc.wMaxOutputLength) == 0)
330 DPRINTF(sc,
"HID command I2C_HID_CMD_WRITE (len %d): "
344 uint16_t cmd = htole16(config_reg);
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);
357 DPRINTF(sc,
"HID descriptor: %*D\n",
369 { sc->addr,
IIC_M_WR,
sizeof(cmd), cmd },
372 DPRINTF(sc,
"HID command I2C_HID_CMD_SET_POWER(%d)\n", param);
383 { sc->addr,
IIC_M_WR,
sizeof(cmd), cmd },
386 DPRINTF(sc,
"HID command I2C_HID_CMD_RESET\n");
402 DPRINTF(sc,
"HID command I2C_HID_REPORT_DESCR at 0x%x with size %d\n",
429 (
id >= 15 ? 15 | (type << 4):
id | (type << 4)),
431 (
id >= 15 ?
id : dtareg[0] ),
432 (
id >= 15 ? dtareg[0] : dtareg[1] ),
433 (
id >= 15 ? dtareg[1] : 0 ),
435 int cmdlen = (
id >= 15 ? 7 : 6 );
436 uint8_t actbuf[2] = { 0, 0 };
448 DPRINTF(sc,
"HID command I2C_HID_CMD_GET_REPORT %d "
449 "(type %d, len %d)\n",
id, type, maxlen);
459 actlen = actbuf[0] | actbuf[1] << 8;
460 if (actlen != maxlen + 2)
461 DPRINTF(sc,
"response size %d != expected length %d\n",
464 if (actlen <= 2 || actlen == 0xFFFF)
467 d =
id != 0 ? *(uint8_t *)
buf : 0;
469 DPRINTF(sc,
"response report id %d != %d\n", d,
id);
476 if (actual_len != NULL)
477 *actual_len = actlen;
479 DPRINTF(sc,
"response: %*D %*D\n", 2, actbuf,
" ", actlen,
buf,
" ");
496 uint16_t replen = 2 +
len;
500 (
id >= 15 ? 15 | (type << 4):
id | (type << 4)),
502 (
id >= 15 ?
id : dtareg[0] ),
503 (
id >= 15 ? dtareg[0] : dtareg[1] ),
504 (
id >= 15 ? dtareg[1] : replen & 0xff ),
505 (
id >= 15 ? replen & 0xff : replen >> 8 ),
506 (
id >= 15 ? replen >> 8 : 0 ),
508 int cmdlen = (
id >= 15 ? 9 : 8 );
514 DPRINTF(sc,
"HID command I2C_HID_CMD_SET_REPORT %d (type %d, len %d): "
520#ifdef IICHID_SAMPLING
522iichid_event_task(
void *context,
int pending)
531 parent = device_get_parent(sc->
dev);
533 bus_requested =
false;
536 bus_requested =
true;
545 sc->missing_samples = 0;
547 ++sc->missing_samples;
549 DPRINTF(sc,
"read error occured: %d\n", error);
552 if (sc->callout_setup && sc->sampling_rate_slow > 0) {
553 if (sc->missing_samples == sc->sampling_hysteresis)
555 taskqueue_enqueue_timeout(sc->taskqueue, &sc->periodic_task,
556 hz / MAX(sc->missing_samples >= sc->sampling_hysteresis ?
557 sc->sampling_rate_slow : sc->sampling_rate_fast, 1));
574 parent = device_get_parent(sc->
dev);
600 DPRINTF(sc,
"no data received\n");
603 DPRINTF(sc,
"read error occured: %d\n", error);
622 parent = device_get_parent(sc->
dev);
641 switch (how_suspend) {
660#ifdef IICHID_SAMPLING
661 if (sc->sampling_rate_slow >= 0 && sc->
intr_handler != NULL) {
663 iichid_setup_callout(sc);
664 iichid_reset_callout(sc);
666 iichid_teardown_callout(sc);
681 int error = bus_setup_intr(sc->
dev, sc->
irq_res,
684 DPRINTF(sc,
"Could not setup interrupt handler\n");
686 DPRINTF(sc,
"successfully setup interrupt\n");
700#ifdef IICHID_SAMPLING
705 if (sc->sampling_rate_slow < 0) {
706 DPRINTF(sc,
"sampling_rate is below 0, can't setup callout\n");
710 sc->callout_setup =
true;
711 DPRINTF(sc,
"successfully setup callout\n");
719 if (sc->sampling_rate_slow <= 0) {
720 DPRINTF(sc,
"sampling_rate is below or equal to 0, "
721 "can't reset callout\n");
725 if (!sc->callout_setup)
729 sc->missing_samples = sc->sampling_hysteresis;
730 taskqueue_enqueue(sc->taskqueue, &sc->event_task);
739 sc->callout_setup =
false;
740 taskqueue_cancel_timeout(sc->taskqueue, &sc->periodic_task, NULL);
741 DPRINTF(sc,
"tore callout down\n");
745iichid_sysctl_sampling_rate_handler(SYSCTL_HANDLER_ARGS)
749 int error, oldval, value;
753 value = sc->sampling_rate_slow;
754 error = sysctl_handle_int(oidp, &value, 0, req);
756 if (error != 0 || req->newptr == NULL ||
757 value == sc->sampling_rate_slow)
761 if (sc->
irq_res == NULL && value < 0)
764 parent = device_get_parent(sc->
dev);
769 oldval = sc->sampling_rate_slow;
770 sc->sampling_rate_slow = value;
772 if (oldval < 0 && value >= 0) {
775 iichid_setup_callout(sc);
776 }
else if (oldval >= 0 && value < 0) {
778 iichid_teardown_callout(sc);
783 iichid_reset_callout(sc);
787 DPRINTF(sc,
"new sampling_rate value: %d\n", value);
795 struct hid_rdesc_info *rdesc)
802 sc = device_get_softc(
dev);
807 rdesc->rdsize = rdesc->isize;
814 sc->
intr_buf = malloc(rdesc->rdsize, M_DEVBUF, M_WAITOK | M_ZERO);
816#ifdef IICHID_SAMPLING
817 taskqueue_start_threads(&sc->taskqueue, 1, PI_TTY,
818 "%s taskq", device_get_nameunit(sc->
dev));
827 sc = device_get_softc(
dev);
828#ifdef IICHID_SAMPLING
829 taskqueue_drain_all(sc->taskqueue);
839 sc = device_get_softc(
dev);
840 DPRINTF(sc,
"iichid device open\n");
851 sc = device_get_softc(
dev);
852 DPRINTF(sc,
"iichid device close\n");
871 sc = device_get_softc(
dev);
873 if (error == 0 && actual != 0)
886 sc = device_get_softc(
dev);
889 DPRINTF(sc,
"failed to fetch report descriptor: %d\n", error);
903 sc = device_get_softc(
dev);
904 parent = device_get_parent(sc->
dev);
920 sc = device_get_softc(
dev);
926 hid_size_t *actlen, uint8_t type, uint8_t
id)
932 sc = device_get_softc(
dev);
945 sc = device_get_softc(
dev);
981 struct hid_device_info *
hw)
983 ACPI_DEVICE_INFO *device_info;
991 if (ACPI_FAILURE(AcpiGetObjectInfo(handle, &device_info)))
994 if (device_info->Valid & ACPI_VALID_HID)
995 strlcpy(
hw->idPnP, device_info->HardwareId.String,
997 snprintf(
hw->name,
sizeof(
hw->name),
"%s:%02lX %04X:%04X",
998 (device_info->Valid & ACPI_VALID_HID) ?
999 device_info->HardwareId.String :
"Unknown",
1000 (device_info->Valid & ACPI_VALID_UID) ?
1001 strtoul(device_info->UniqueId.String, NULL, 10) : 0UL,
1004 AcpiOsFree(device_info);
1006 strlcpy(
hw->serial,
"",
sizeof(
hw->serial));
1009 hid_add_dynamic_quirk(
hw, HQ_NOWRITE);
1020 uint16_t config_reg;
1023 sc = device_get_softc(
dev);
1031 if (acpi_disabled(
"iichid"))
1034 sc->
addr = iicbus_get_addr(
dev) << 1;
1038 handle = acpi_get_handle(
dev);
1050 config_reg = (uint16_t)reg;
1052 DPRINTF(sc,
" IICbus addr : 0x%02X\n", sc->
addr >> 1);
1053 DPRINTF(sc,
" HID descriptor reg: 0x%02X\n", config_reg);
1057 DPRINTF(sc,
"could not retrieve HID descriptor from the "
1058 "device: %d\n", error);
1064 DPRINTF(sc,
"HID descriptor is broken\n");
1070 DPRINTF(sc,
"error evaluating AcpiGetObjectInfo\n");
1074 if (hid_test_quirk(&sc->
hw, HQ_HID_IGNORE))
1080 snprintf(
buf,
sizeof(
buf),
"%s I2C HID device", sc->
hw.name);
1081 device_set_desc_copy(
dev,
buf);
1093 sc = device_get_softc(
dev);
1096 device_printf(
dev,
"failed to power on: %d\n", error);
1103 pause(
"iichid", (hz + 999) / 1000);
1107 device_printf(
dev,
"failed to reset hardware: %d\n", error);
1115#ifdef IICHID_SAMPLING
1116 TASK_INIT(&sc->event_task, 0, iichid_event_task, sc);
1118 sc->taskqueue = taskqueue_create(
"iichid_tq", M_WAITOK | M_ZERO,
1119 taskqueue_thread_enqueue, &sc->taskqueue);
1120 TIMEOUT_TASK_INIT(sc->taskqueue, &sc->periodic_task, 0,
1121 iichid_event_task, sc);
1123 sc->sampling_rate_slow = -1;
1129 sc->
irq_res = bus_alloc_resource_any(sc->
dev, SYS_RES_IRQ,
1133 DPRINTF(sc,
"allocated irq at %p and rid %d\n",
1138 if (sc->
irq_res == NULL || error != 0) {
1139#ifdef IICHID_SAMPLING
1140 device_printf(sc->
dev,
1141 "Interrupt setup failed. Fallback to sampling\n");
1144 device_printf(sc->
dev,
"Interrupt setup failed\n");
1146 bus_release_resource(
dev, SYS_RES_IRQ, sc->
irq_rid,
1153#ifdef IICHID_SAMPLING
1154 SYSCTL_ADD_PROC(device_get_sysctl_ctx(sc->
dev),
1155 SYSCTL_CHILDREN(device_get_sysctl_tree(sc->
dev)),
1156 OID_AUTO,
"sampling_rate_slow", CTLTYPE_INT | CTLFLAG_RWTUN,
1157 sc, 0, iichid_sysctl_sampling_rate_handler,
"I",
1158 "idle sampling rate in num/second");
1159 SYSCTL_ADD_INT(device_get_sysctl_ctx(sc->
dev),
1160 SYSCTL_CHILDREN(device_get_sysctl_tree(sc->
dev)),
1161 OID_AUTO,
"sampling_rate_fast", CTLFLAG_RWTUN,
1162 &sc->sampling_rate_fast, 0,
1163 "active sampling rate in num/second");
1164 SYSCTL_ADD_INT(device_get_sysctl_ctx(sc->
dev),
1165 SYSCTL_CHILDREN(device_get_sysctl_tree(sc->
dev)),
1166 OID_AUTO,
"sampling_hysteresis", CTLFLAG_RWTUN,
1167 &sc->sampling_hysteresis, 0,
1168 "number of missing samples before enabling of slow mode");
1169 hid_add_dynamic_quirk(&sc->
hw, HQ_IICHID_SAMPLING);
1171 if (sc->sampling_rate_slow >= 0) {
1172 pause(
"iichid", (hz + 999) / 1000);
1177 child = device_add_child(
dev,
"hidbus", -1);
1178 if (child == NULL) {
1179 device_printf(sc->
dev,
"Could not add I2C device\n");
1185 device_set_ivars(child, &sc->
hw);
1186 error = bus_generic_attach(
dev);
1188 device_printf(
dev,
"failed to attach child: error %d\n", error);
1203 sc = device_get_softc(
dev);
1204 error = device_delete_children(
dev);
1209 bus_release_resource(
dev, SYS_RES_IRQ, sc->
irq_rid,
1211#ifdef IICHID_SAMPLING
1212 if (sc->taskqueue != NULL)
1213 taskqueue_free(sc->taskqueue);
1214 sc->taskqueue = NULL;
1233 sc = device_get_softc(
dev);
1234 (void)bus_generic_suspend(
dev);
1241 DPRINTF(sc,
"Suspend called, setting device to power_state 1\n");
1244 DPRINTF(sc,
"Could not set power_state, error: %d\n", error);
1246 DPRINTF(sc,
"Successfully set power_state\n");
1248#ifdef IICHID_SAMPLING
1249 if (sc->sampling_rate_slow < 0)
1257#ifdef IICHID_SAMPLING
1258#define suspend_thread sc->taskqueue
1260#define suspend_thread taskqueue_thread
1275 sc = device_get_softc(
dev);
1276#ifdef IICHID_SAMPLING
1277 if (sc->sampling_rate_slow < 0)
1281 DPRINTF(sc,
"Resume called, setting device to power_state 0\n");
1284 DPRINTF(sc,
"Could not set power_state, error: %d\n", error);
1286 DPRINTF(sc,
"Successfully set power_state\n");
1287 (void)bus_generic_resume(
dev);
SYSCTL_INT(_hw_i2c, OID_AUTO, iicbb_debug, CTLFLAG_RWTUN, &i2c_debug, 0, "Enable i2c bit-banging driver debug")
SYSCTL_NODE(_hw, OID_AUTO, i2c, CTLFLAG_RW, 0, "i2c controls")
static void iichid_intr_setup(device_t dev, hid_intr_t intr, void *context, struct hid_rdesc_info *rdesc)
static device_resume_t iichid_resume
#define IICHID_SAMPLING_HYSTERESIS
static void iichid_intr_poll(device_t dev)
static int iichid_fill_device_info(struct i2c_hid_desc *desc, ACPI_HANDLE handle, struct hid_device_info *hw)
static int iichid_intr_start(device_t dev)
static int iichid_set_power(struct iichid_softc *sc, uint8_t param)
static int iichid_set_report(device_t dev, const void *buf, hid_size_t len, uint8_t type, uint8_t id)
static driver_t iichid_driver
static int iichid_setup_interrupt(struct iichid_softc *sc)
static int iichid_set_power_state(struct iichid_softc *sc, enum iichid_powerstate_how how_open, enum iichid_powerstate_how how_suspend)
MODULE_VERSION(iichid, 1)
struct i2c_hid_desc __packed
static const struct iichid_id iichid_ids[]
static device_attach_t iichid_attach
static int acpi_is_iichid(ACPI_HANDLE handle)
static int iichid_cmd_get_report(struct iichid_softc *sc, void *buf, iichid_size_t maxlen, iichid_size_t *actual_len, uint8_t type, uint8_t id)
static int iichid_write(device_t dev, const void *buf, hid_size_t len)
static int iichid_set_protocol(device_t dev, uint16_t protocol)
static device_probe_t iichid_probe
static device_suspend_t iichid_suspend
static int iichid_cmd_get_hid_desc(struct iichid_softc *sc, uint16_t config_reg, struct i2c_hid_desc *hid_desc)
static void iichid_intr_unsetup(device_t dev)
static int iichid_ioctl(device_t dev, unsigned long cmd, uintptr_t data)
static int iichid_reset(struct iichid_softc *sc)
#define I2C_HID_POWER_OFF
MODULE_DEPEND(iichid, iicbus, IICBUS_MINVER, IICBUS_PREFVER, IICBUS_MAXVER)
DRIVER_MODULE(iichid, iicbus, iichid_driver, iichid_devclass, NULL, 0)
#define IICHID_SAMPLING_RATE_FAST
IICBUS_ACPI_PNP_INFO(iichid_ids)
#define IICHID_SAMPLING_RATE_SLOW
static int iichid_intr_stop(device_t dev)
static int iichid_cmd_read(struct iichid_softc *sc, void *buf, iichid_size_t maxlen, iichid_size_t *actual_len)
static ACPI_STATUS iichid_get_config_reg(ACPI_HANDLE handle, uint16_t *config_reg)
static int iichid_read(device_t dev, void *buf, hid_size_t maxlen, hid_size_t *actlen)
static int iichid_cmd_set_report(struct iichid_softc *sc, const void *buf, iichid_size_t len, uint8_t type, uint8_t id)
static void iichid_teardown_interrupt(struct iichid_softc *sc)
static device_detach_t iichid_detach
static int iichid_cmd_get_report_desc(struct iichid_softc *sc, void *buf, iichid_size_t len)
static void iichid_intr(void *context)
static int iichid_set_idle(device_t dev, uint16_t duration, uint8_t id)
static void iichid_suspend_task(void *, int)
static int iichid_get_report(device_t dev, void *buf, hid_size_t maxlen, hid_size_t *actlen, uint8_t type, uint8_t id)
static device_method_t iichid_methods[]
static int iichid_cmd_write(struct iichid_softc *sc, const void *buf, iichid_size_t len)
static devclass_t iichid_devclass
static int iichid_get_rdesc(device_t dev, void *buf, hid_size_t len)
int iicbus_request_bus(device_t bus, device_t dev, int how)
int iicbus_transfer(device_t bus, struct iic_msg *msgs, uint32_t nmsgs)
int iic2errno(int iic_status)
int iicbus_release_bus(device_t bus, device_t dev)
uint16_t wReportDescRegister
uint16_t wReportDescLength
uint16_t wCommandRegister
uint16_t wMaxOutputLength
struct resource * irq_res
iichid_size_t intr_bufsize
struct hid_device_info hw
hid_intr_t * intr_handler