FreeBSD kernel IICBUS device code
iichid.c
Go to the documentation of this file.
1/*-
2 * Copyright (c) 2018-2019 Marc Priggemeyer <marc.priggemeyer@gmail.com>
3 * Copyright (c) 2019-2020 Vladimir Kondratyev <wulf@FreeBSD.org>
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27/*
28 * I2C HID transport backend.
29 */
30
31#include <sys/cdefs.h>
32__FBSDID("$FreeBSD$");
33
34#include "opt_hid.h"
35
36#include <sys/param.h>
37#include <sys/bus.h>
38#include <sys/callout.h>
39#include <sys/endian.h>
40#include <sys/kernel.h>
41#include <sys/lock.h>
42#include <sys/malloc.h>
43#include <sys/module.h>
44#include <sys/rman.h>
45#include <sys/sysctl.h>
46#include <sys/systm.h>
47#include <sys/taskqueue.h>
48
49#include <machine/resource.h>
50
51#include <contrib/dev/acpica/include/acpi.h>
52#include <contrib/dev/acpica/include/accommon.h>
53#include <dev/acpica/acpivar.h>
54
55#include <dev/evdev/input.h>
56
57#include <dev/hid/hid.h>
58#include <dev/hid/hidquirk.h>
59
60#include <dev/iicbus/iic.h>
61#include <dev/iicbus/iicbus.h>
62#include <dev/iicbus/iiconf.h>
63
64#include "hid_if.h"
65
66#ifdef IICHID_DEBUG
67static int iichid_debug = 0;
68
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");
72
73#define DPRINTFN(sc, n, ...) do { \
74 if (iichid_debug >= (n)) \
75 device_printf((sc)->dev, __VA_ARGS__); \
76} while (0)
77#define DPRINTF(sc, ...) DPRINTFN(sc, 1, __VA_ARGS__)
78#else
79#define DPRINTFN(...) do {} while (0)
80#define DPRINTF(...) do {} while (0)
81#endif
82
83typedef hid_size_t iichid_size_t;
84#define IICHID_SIZE_MAX (UINT16_MAX - 2)
85
86/* 7.2 */
87enum {
97};
98
99#define I2C_HID_POWER_ON 0x0
100#define I2C_HID_POWER_OFF 0x1
101
102/*
103 * Since interrupt resource acquisition is not always possible (in case of GPIO
104 * interrupts) iichid now supports a sampling_mode.
105 * Set dev.iichid.<unit>.sampling_rate_slow to a value greater then 0
106 * to activate sampling. A value of 0 is possible but will not reset the
107 * callout and, thereby, disable further report requests. Do not set the
108 * sampling_rate_fast value too high as it may result in periodical lags of
109 * cursor motion.
110 */
111#define IICHID_SAMPLING_RATE_FAST 60
112#define IICHID_SAMPLING_RATE_SLOW 10
113#define IICHID_SAMPLING_HYSTERESIS 1
114
115/* 5.1.1 - HID Descriptor Format */
118 uint16_t bcdVersion;
127 uint16_t wVendorID;
128 uint16_t wProductID;
129 uint16_t wVersionID;
130 uint32_t reserved;
132
133#define IICHID_REG_NONE -1
134#define IICHID_REG_ACPI (UINT16_MAX + 1)
135#define IICHID_REG_ELAN 0x0001
136
137static const struct iichid_id {
138 char *id;
139 int reg;
140} iichid_ids[] = {
141 { "ELAN0000", IICHID_REG_ELAN },
142 { "PNP0C50", IICHID_REG_ACPI },
143 { "ACPI0C50", IICHID_REG_ACPI },
144 { NULL, 0 },
146
151};
152
153/*
154 * Locking: no internal locks are used. To serialize access to shared members,
155 * external iicbus lock should be taken. That allows to make locking greatly
156 * simple at the cost of running front interrupt handlers with locked bus.
157 */
159 device_t dev;
160
163
164 struct hid_device_info hw;
165 uint16_t addr; /* Shifted left by 1 */
167
168 hid_intr_t *intr_handler;
169 void *intr_ctx;
170 uint8_t *intr_buf;
172
174 struct resource *irq_res;
176
177#ifdef IICHID_SAMPLING
178 int sampling_rate_slow; /* iicbus lock */
179 int sampling_rate_fast;
180 int sampling_hysteresis;
181 int missing_samples; /* iicbus lock */
182 struct timeout_task periodic_task; /* iicbus lock */
183 bool callout_setup; /* iicbus lock */
184 struct taskqueue *taskqueue;
185 struct task event_task;
186#endif
187
188 struct task suspend_task;
189 bool open; /* iicbus lock */
190 bool suspend; /* iicbus lock */
191 bool power_on; /* iicbus lock */
192};
193
194static device_probe_t iichid_probe;
195static device_attach_t iichid_attach;
196static device_detach_t iichid_detach;
197static device_resume_t iichid_resume;
198static device_suspend_t iichid_suspend;
199
200static void iichid_suspend_task(void *, int);
201
202#ifdef IICHID_SAMPLING
203static int iichid_setup_callout(struct iichid_softc *);
204static int iichid_reset_callout(struct iichid_softc *);
205static void iichid_teardown_callout(struct iichid_softc *);
206#endif
207
208static inline int
209acpi_is_iichid(ACPI_HANDLE handle)
210{
211 const struct iichid_id *ids;
212 UINT32 sta;
213 int reg;
214
215 for (ids = iichid_ids; ids->id != NULL; ids++) {
216 if (acpi_MatchHid(handle, ids->id)) {
217 reg = ids->reg;
218 break;
219 }
220 }
221 if (ids->id == NULL)
222 return (IICHID_REG_NONE);
223
224 /*
225 * If no _STA method or if it failed, then assume that
226 * the device is present.
227 */
228 if (ACPI_FAILURE(acpi_GetInteger(handle, "_STA", &sta)) ||
229 ACPI_DEVICE_PRESENT(sta))
230 return (reg);
231
232 return (IICHID_REG_NONE);
233}
234
235static ACPI_STATUS
236iichid_get_config_reg(ACPI_HANDLE handle, uint16_t *config_reg)
237{
238 ACPI_OBJECT *result;
239 ACPI_BUFFER acpi_buf;
240 ACPI_STATUS status;
241
242 /*
243 * function (_DSM) to be evaluated to retrieve the address of
244 * the configuration register of the HID device.
245 */
246 /* 3cdff6f7-4267-4555-ad05-b30a3d8938de */
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,
250 };
251
252 status = acpi_EvaluateDSMTyped(handle, dsm_guid, 1, 1, NULL, &acpi_buf,
253 ACPI_TYPE_INTEGER);
254 if (ACPI_FAILURE(status)) {
255 printf("%s: error evaluating _DSM\n", __func__);
256 return (status);
257 }
258 result = (ACPI_OBJECT *) acpi_buf.Pointer;
259 *config_reg = result->Integer.Value & 0xFFFF;
260
261 AcpiOsFree(result);
262 return (status);
263}
264
265static int
267 iichid_size_t *actual_len)
268{
269 /*
270 * 6.1.3 - Retrieval of Input Reports
271 * DEVICE returns the length (2 Bytes) and the entire Input Report.
272 */
273 uint8_t actbuf[2] = { 0, 0 };
274 /* Read actual input report length. */
275 struct iic_msg msgs[] = {
276 { sc->addr, IIC_M_RD | IIC_M_NOSTOP, sizeof(actbuf), actbuf },
277 };
278 uint16_t actlen;
279 int error;
280
281 error = iicbus_transfer(sc->dev, msgs, nitems(msgs));
282 if (error != 0)
283 return (error);
284
285 actlen = actbuf[0] | actbuf[1] << 8;
286 if (actlen <= 2 || actlen == 0xFFFF || maxlen == 0) {
287 /* Read and discard 1 byte to send I2C STOP condition. */
288 msgs[0] = (struct iic_msg)
289 { sc->addr, IIC_M_RD | IIC_M_NOSTART, 1, actbuf };
290 actlen = 0;
291 } else {
292 actlen -= 2;
293 if (actlen > maxlen) {
294 DPRINTF(sc, "input report too big. requested=%d "
295 "received=%d\n", maxlen, actlen);
296 actlen = maxlen;
297 }
298 /* Read input report itself. */
299 msgs[0] = (struct iic_msg)
300 { sc->addr, IIC_M_RD | IIC_M_NOSTART, actlen, buf };
301 }
302
303 error = iicbus_transfer(sc->dev, msgs, 1);
304 if (error == 0 && actual_len != NULL)
305 *actual_len = actlen;
306
307 DPRINTFN(sc, 5,
308 "%*D - %*D\n", 2, actbuf, " ", msgs[0].len, msgs[0].buf, " ");
309
310 return (error);
311}
312
313static int
315{
316 /* 6.2.3 - Sending Output Reports. */
317 uint8_t *cmdreg = (uint8_t *)&sc->desc.wOutputRegister;
318 uint16_t replen = 2 + len;
319 uint8_t cmd[4] = { cmdreg[0], cmdreg[1], replen & 0xFF, replen >> 8 };
320 struct iic_msg msgs[] = {
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)},
323 };
324
325 if (le16toh(sc->desc.wMaxOutputLength) == 0)
326 return (IIC_ENOTSUPP);
327 if (len < 2)
328 return (IIC_ENOTSUPP);
329
330 DPRINTF(sc, "HID command I2C_HID_CMD_WRITE (len %d): "
331 "%*D\n", len, len, buf, " ");
332
333 return (iicbus_transfer(sc->dev, msgs, nitems(msgs)));
334}
335
336static int
337iichid_cmd_get_hid_desc(struct iichid_softc *sc, uint16_t config_reg,
338 struct i2c_hid_desc *hid_desc)
339{
340 /*
341 * 5.2.2 - HID Descriptor Retrieval
342 * register is passed from the controller.
343 */
344 uint16_t cmd = htole16(config_reg);
345 struct iic_msg msgs[] = {
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 },
348 };
349 int error;
350
351 DPRINTF(sc, "HID command I2C_HID_CMD_DESCR at 0x%x\n", config_reg);
352
353 error = iicbus_transfer(sc->dev, msgs, nitems(msgs));
354 if (error != 0)
355 return (error);
356
357 DPRINTF(sc, "HID descriptor: %*D\n",
358 (int)sizeof(struct i2c_hid_desc), hid_desc, " ");
359
360 return (0);
361}
362
363static int
364iichid_set_power(struct iichid_softc *sc, uint8_t param)
365{
366 uint8_t *cmdreg = (uint8_t *)&sc->desc.wCommandRegister;
367 uint8_t cmd[] = { cmdreg[0], cmdreg[1], param, I2C_HID_CMD_SET_POWER };
368 struct iic_msg msgs[] = {
369 { sc->addr, IIC_M_WR, sizeof(cmd), cmd },
370 };
371
372 DPRINTF(sc, "HID command I2C_HID_CMD_SET_POWER(%d)\n", param);
373
374 return (iicbus_transfer(sc->dev, msgs, nitems(msgs)));
375}
376
377static int
379{
380 uint8_t *cmdreg = (uint8_t *)&sc->desc.wCommandRegister;
381 uint8_t cmd[] = { cmdreg[0], cmdreg[1], 0, I2C_HID_CMD_RESET };
382 struct iic_msg msgs[] = {
383 { sc->addr, IIC_M_WR, sizeof(cmd), cmd },
384 };
385
386 DPRINTF(sc, "HID command I2C_HID_CMD_RESET\n");
387
388 return (iicbus_transfer(sc->dev, msgs, nitems(msgs)));
389}
390
391static int
394{
395 uint16_t cmd = sc->desc.wReportDescRegister;
396 struct iic_msg msgs[] = {
397 { sc->addr, IIC_M_WR | IIC_M_NOSTOP, 2, (uint8_t *)&cmd },
398 { sc->addr, IIC_M_RD, len, buf },
399 };
400 int error;
401
402 DPRINTF(sc, "HID command I2C_HID_REPORT_DESCR at 0x%x with size %d\n",
403 le16toh(cmd), len);
404
405 error = iicbus_transfer(sc->dev, msgs, nitems(msgs));
406 if (error != 0)
407 return (error);
408
409 DPRINTF(sc, "HID report descriptor: %*D\n", len, buf, " ");
410
411 return (0);
412}
413
414static int
416 iichid_size_t *actual_len, uint8_t type, uint8_t id)
417{
418 /*
419 * 7.2.2.4 - "The protocol is optimized for Report < 15. If a
420 * report ID >= 15 is necessary, then the Report ID in the Low Byte
421 * must be set to 1111 and a Third Byte is appended to the protocol.
422 * This Third Byte contains the entire/actual report ID."
423 */
424 uint8_t *dtareg = (uint8_t *)&sc->desc.wDataRegister;
425 uint8_t *cmdreg = (uint8_t *)&sc->desc.wCommandRegister;
426 uint8_t cmd[] = { /*________|______id>=15_____|______id<15______*/
427 cmdreg[0] ,
428 cmdreg[1] ,
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 ),
434 };
435 int cmdlen = (id >= 15 ? 7 : 6 );
436 uint8_t actbuf[2] = { 0, 0 };
437 uint16_t actlen;
438 int d, error;
439 struct iic_msg msgs[] = {
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 },
443 };
444
445 if (maxlen == 0)
446 return (EINVAL);
447
448 DPRINTF(sc, "HID command I2C_HID_CMD_GET_REPORT %d "
449 "(type %d, len %d)\n", id, type, maxlen);
450
451 /*
452 * 7.2.2.2 - Response will be a 2-byte length value, the report
453 * id (1 byte, if defined in Report Descriptor), and then the report.
454 */
455 error = iicbus_transfer(sc->dev, msgs, nitems(msgs));
456 if (error != 0)
457 return (error);
458
459 actlen = actbuf[0] | actbuf[1] << 8;
460 if (actlen != maxlen + 2)
461 DPRINTF(sc, "response size %d != expected length %d\n",
462 actlen, maxlen + 2);
463
464 if (actlen <= 2 || actlen == 0xFFFF)
465 return (ENOMSG);
466
467 d = id != 0 ? *(uint8_t *)buf : 0;
468 if (d != id) {
469 DPRINTF(sc, "response report id %d != %d\n", d, id);
470 return (EBADMSG);
471 }
472
473 actlen -= 2;
474 if (actlen > maxlen)
475 actlen = maxlen;
476 if (actual_len != NULL)
477 *actual_len = actlen;
478
479 DPRINTF(sc, "response: %*D %*D\n", 2, actbuf, " ", actlen, buf, " ");
480
481 return (0);
482}
483
484static int
485iichid_cmd_set_report(struct iichid_softc* sc, const void *buf,
486 iichid_size_t len, uint8_t type, uint8_t id)
487{
488 /*
489 * 7.2.2.4 - "The protocol is optimized for Report < 15. If a
490 * report ID >= 15 is necessary, then the Report ID in the Low Byte
491 * must be set to 1111 and a Third Byte is appended to the protocol.
492 * This Third Byte contains the entire/actual report ID."
493 */
494 uint8_t *dtareg = (uint8_t *)&sc->desc.wDataRegister;
495 uint8_t *cmdreg = (uint8_t *)&sc->desc.wCommandRegister;
496 uint16_t replen = 2 + len;
497 uint8_t cmd[] = { /*________|______id>=15_____|______id<15______*/
498 cmdreg[0] ,
499 cmdreg[1] ,
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 ),
507 };
508 int cmdlen = (id >= 15 ? 9 : 8 );
509 struct iic_msg msgs[] = {
510 {sc->addr, IIC_M_WR | IIC_M_NOSTOP, cmdlen, cmd},
511 {sc->addr, IIC_M_WR | IIC_M_NOSTART, len, __DECONST(void *, buf)},
512 };
513
514 DPRINTF(sc, "HID command I2C_HID_CMD_SET_REPORT %d (type %d, len %d): "
515 "%*D\n", id, type, len, len, buf, " ");
516
517 return (iicbus_transfer(sc->dev, msgs, nitems(msgs)));
518}
519
520#ifdef IICHID_SAMPLING
521static void
522iichid_event_task(void *context, int pending)
523{
524 struct iichid_softc *sc;
525 device_t parent;
526 iichid_size_t actual;
527 bool bus_requested;
528 int error;
529
530 sc = context;
531 parent = device_get_parent(sc->dev);
532
533 bus_requested = false;
534 if (iicbus_request_bus(parent, sc->dev, IIC_WAIT) != 0)
535 goto rearm;
536 bus_requested = true;
537
538 if (!sc->power_on)
539 goto out;
540
541 error = iichid_cmd_read(sc, sc->intr_buf, sc->intr_bufsize, &actual);
542 if (error == 0) {
543 if (actual > 0) {
544 sc->intr_handler(sc->intr_ctx, sc->intr_buf, actual);
545 sc->missing_samples = 0;
546 } else
547 ++sc->missing_samples;
548 } else
549 DPRINTF(sc, "read error occured: %d\n", error);
550
551rearm:
552 if (sc->callout_setup && sc->sampling_rate_slow > 0) {
553 if (sc->missing_samples == sc->sampling_hysteresis)
554 sc->intr_handler(sc->intr_ctx, sc->intr_buf, 0);
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));
558 }
559out:
560 if (bus_requested)
561 iicbus_release_bus(parent, sc->dev);
562}
563#endif /* IICHID_SAMPLING */
564
565static void
566iichid_intr(void *context)
567{
568 struct iichid_softc *sc;
569 device_t parent;
570 iichid_size_t maxlen, actual;
571 int error;
572
573 sc = context;
574 parent = device_get_parent(sc->dev);
575
576 /*
577 * Designware(IG4) driver-specific hack.
578 * Requesting of an I2C bus with IIC_DONTWAIT parameter enables polled
579 * mode in the driver, making possible iicbus_transfer execution from
580 * interrupt handlers and callouts.
581 */
582 if (iicbus_request_bus(parent, sc->dev, IIC_DONTWAIT) != 0)
583 return;
584
585 /*
586 * Reading of input reports of I2C devices residing in SLEEP state is
587 * not allowed and often returns a garbage. If a HOST needs to
588 * communicate with the DEVICE it MUST issue a SET POWER command
589 * (to ON) before any other command. As some hardware requires reads to
590 * acknowledge interrupts we fetch only length header and discard it.
591 */
592 maxlen = sc->power_on ? sc->intr_bufsize : 0;
593 error = iichid_cmd_read(sc, sc->intr_buf, maxlen, &actual);
594 if (error == 0) {
595 if (sc->power_on) {
596 if (actual != 0)
597 sc->intr_handler(sc->intr_ctx, sc->intr_buf,
598 actual);
599 else
600 DPRINTF(sc, "no data received\n");
601 }
602 } else
603 DPRINTF(sc, "read error occured: %d\n", error);
604
605 iicbus_release_bus(parent, sc->dev);
606}
607
608static int
610 enum iichid_powerstate_how how_open,
611 enum iichid_powerstate_how how_suspend)
612{
613 device_t parent;
614 int error;
615 int how_request;
616 bool power_on;
617
618 /*
619 * Request iicbus early as sc->suspend and sc->power_on
620 * are protected by iicbus internal lock.
621 */
622 parent = device_get_parent(sc->dev);
623 /* Allow to interrupt open()/close() handlers by SIGINT */
624 how_request = how_open == IICHID_PS_NULL ? IIC_WAIT : IIC_INTRWAIT;
625 error = iicbus_request_bus(parent, sc->dev, how_request);
626 if (error != 0)
627 return (error);
628
629 switch (how_open) {
630 case IICHID_PS_ON:
631 sc->open = true;
632 break;
633 case IICHID_PS_OFF:
634 sc->open = false;
635 break;
636 case IICHID_PS_NULL:
637 default:
638 break;
639 }
640
641 switch (how_suspend) {
642 case IICHID_PS_ON:
643 sc->suspend = false;
644 break;
645 case IICHID_PS_OFF:
646 sc->suspend = true;
647 break;
648 case IICHID_PS_NULL:
649 default:
650 break;
651 }
652
653 power_on = sc->open & !sc->suspend;
654
655 if (power_on != sc->power_on) {
656 error = iichid_set_power(sc,
658
659 sc->power_on = power_on;
660#ifdef IICHID_SAMPLING
661 if (sc->sampling_rate_slow >= 0 && sc->intr_handler != NULL) {
662 if (power_on) {
663 iichid_setup_callout(sc);
664 iichid_reset_callout(sc);
665 } else
666 iichid_teardown_callout(sc);
667 }
668#endif
669 }
670
671 iicbus_release_bus(parent, sc->dev);
672
673 return (error);
674}
675
676static int
678{
679 sc->irq_cookie = 0;
680
681 int error = bus_setup_intr(sc->dev, sc->irq_res,
682 INTR_TYPE_TTY|INTR_MPSAFE, NULL, iichid_intr, sc, &sc->irq_cookie);
683 if (error != 0)
684 DPRINTF(sc, "Could not setup interrupt handler\n");
685 else
686 DPRINTF(sc, "successfully setup interrupt\n");
687
688 return (error);
689}
690
691static void
693{
694 if (sc->irq_cookie)
695 bus_teardown_intr(sc->dev, sc->irq_res, sc->irq_cookie);
696
697 sc->irq_cookie = 0;
698}
699
700#ifdef IICHID_SAMPLING
701static int
702iichid_setup_callout(struct iichid_softc *sc)
703{
704
705 if (sc->sampling_rate_slow < 0) {
706 DPRINTF(sc, "sampling_rate is below 0, can't setup callout\n");
707 return (EINVAL);
708 }
709
710 sc->callout_setup = true;
711 DPRINTF(sc, "successfully setup callout\n");
712 return (0);
713}
714
715static int
716iichid_reset_callout(struct iichid_softc *sc)
717{
718
719 if (sc->sampling_rate_slow <= 0) {
720 DPRINTF(sc, "sampling_rate is below or equal to 0, "
721 "can't reset callout\n");
722 return (EINVAL);
723 }
724
725 if (!sc->callout_setup)
726 return (EINVAL);
727
728 /* Start with slow sampling. */
729 sc->missing_samples = sc->sampling_hysteresis;
730 taskqueue_enqueue(sc->taskqueue, &sc->event_task);
731
732 return (0);
733}
734
735static void
736iichid_teardown_callout(struct iichid_softc *sc)
737{
738
739 sc->callout_setup = false;
740 taskqueue_cancel_timeout(sc->taskqueue, &sc->periodic_task, NULL);
741 DPRINTF(sc, "tore callout down\n");
742}
743
744static int
745iichid_sysctl_sampling_rate_handler(SYSCTL_HANDLER_ARGS)
746{
747 struct iichid_softc *sc;
748 device_t parent;
749 int error, oldval, value;
750
751 sc = arg1;
752
753 value = sc->sampling_rate_slow;
754 error = sysctl_handle_int(oidp, &value, 0, req);
755
756 if (error != 0 || req->newptr == NULL ||
757 value == sc->sampling_rate_slow)
758 return (error);
759
760 /* Can't switch to interrupt mode if it is not supported. */
761 if (sc->irq_res == NULL && value < 0)
762 return (EINVAL);
763
764 parent = device_get_parent(sc->dev);
765 error = iicbus_request_bus(parent, sc->dev, IIC_WAIT);
766 if (error != 0)
767 return (iic2errno(error));
768
769 oldval = sc->sampling_rate_slow;
770 sc->sampling_rate_slow = value;
771
772 if (oldval < 0 && value >= 0) {
774 if (sc->power_on)
775 iichid_setup_callout(sc);
776 } else if (oldval >= 0 && value < 0) {
777 if (sc->power_on)
778 iichid_teardown_callout(sc);
780 }
781
782 if (sc->power_on && value > 0)
783 iichid_reset_callout(sc);
784
785 iicbus_release_bus(parent, sc->dev);
786
787 DPRINTF(sc, "new sampling_rate value: %d\n", value);
788
789 return (0);
790}
791#endif /* IICHID_SAMPLING */
792
793static void
794iichid_intr_setup(device_t dev, hid_intr_t intr, void *context,
795 struct hid_rdesc_info *rdesc)
796{
797 struct iichid_softc *sc;
798
799 if (intr == NULL)
800 return;
801
802 sc = device_get_softc(dev);
803 /*
804 * Do not rely on wMaxInputLength, as some devices may set it to
805 * a wrong length. Find the longest input report in report descriptor.
806 */
807 rdesc->rdsize = rdesc->isize;
808 /* Write and get/set_report sizes are limited by I2C-HID protocol. */
809 rdesc->grsize = rdesc->srsize = IICHID_SIZE_MAX;
810 rdesc->wrsize = IICHID_SIZE_MAX;
811
812 sc->intr_handler = intr;
813 sc->intr_ctx = context;
814 sc->intr_buf = malloc(rdesc->rdsize, M_DEVBUF, M_WAITOK | M_ZERO);
815 sc->intr_bufsize = rdesc->rdsize;
816#ifdef IICHID_SAMPLING
817 taskqueue_start_threads(&sc->taskqueue, 1, PI_TTY,
818 "%s taskq", device_get_nameunit(sc->dev));
819#endif
820}
821
822static void
824{
825 struct iichid_softc *sc;
826
827 sc = device_get_softc(dev);
828#ifdef IICHID_SAMPLING
829 taskqueue_drain_all(sc->taskqueue);
830#endif
831 free(sc->intr_buf, M_DEVBUF);
832}
833
834static int
836{
837 struct iichid_softc *sc;
838
839 sc = device_get_softc(dev);
840 DPRINTF(sc, "iichid device open\n");
842
843 return (0);
844}
845
846static int
848{
849 struct iichid_softc *sc;
850
851 sc = device_get_softc(dev);
852 DPRINTF(sc, "iichid device close\n");
853 /*
854 * 8.2 - The HOST determines that there are no active applications
855 * that are currently using the specific HID DEVICE. The HOST
856 * is recommended to issue a HIPO command to the DEVICE to force
857 * the DEVICE in to a lower power state.
858 */
860
861 return (0);
862}
863
864static void
866{
867 struct iichid_softc *sc;
868 iichid_size_t actual;
869 int error;
870
871 sc = device_get_softc(dev);
872 error = iichid_cmd_read(sc, sc->intr_buf, sc->intr_bufsize, &actual);
873 if (error == 0 && actual != 0)
874 sc->intr_handler(sc->intr_ctx, sc->intr_buf, actual);
875}
876
877/*
878 * HID interface
879 */
880static int
881iichid_get_rdesc(device_t dev, void *buf, hid_size_t len)
882{
883 struct iichid_softc *sc;
884 int error;
885
886 sc = device_get_softc(dev);
887 error = iichid_cmd_get_report_desc(sc, buf, len);
888 if (error)
889 DPRINTF(sc, "failed to fetch report descriptor: %d\n", error);
890
891 return (iic2errno(error));
892}
893
894static int
895iichid_read(device_t dev, void *buf, hid_size_t maxlen, hid_size_t *actlen)
896{
897 struct iichid_softc *sc;
898 device_t parent;
899 int error;
900
901 if (maxlen > IICHID_SIZE_MAX)
902 return (EMSGSIZE);
903 sc = device_get_softc(dev);
904 parent = device_get_parent(sc->dev);
905 error = iicbus_request_bus(parent, sc->dev, IIC_WAIT);
906 if (error == 0) {
907 error = iichid_cmd_read(sc, buf, maxlen, actlen);
908 iicbus_release_bus(parent, sc->dev);
909 }
910 return (iic2errno(error));
911}
912
913static int
914iichid_write(device_t dev, const void *buf, hid_size_t len)
915{
916 struct iichid_softc *sc;
917
918 if (len > IICHID_SIZE_MAX)
919 return (EMSGSIZE);
920 sc = device_get_softc(dev);
921 return (iic2errno(iichid_cmd_write(sc, buf, len)));
922}
923
924static int
925iichid_get_report(device_t dev, void *buf, hid_size_t maxlen,
926 hid_size_t *actlen, uint8_t type, uint8_t id)
927{
928 struct iichid_softc *sc;
929
930 if (maxlen > IICHID_SIZE_MAX)
931 return (EMSGSIZE);
932 sc = device_get_softc(dev);
933 return (iic2errno(
934 iichid_cmd_get_report(sc, buf, maxlen, actlen, type, id)));
935}
936
937static int
938iichid_set_report(device_t dev, const void *buf, hid_size_t len, uint8_t type,
939 uint8_t id)
940{
941 struct iichid_softc *sc;
942
943 if (len > IICHID_SIZE_MAX)
944 return (EMSGSIZE);
945 sc = device_get_softc(dev);
946 return (iic2errno(iichid_cmd_set_report(sc, buf, len, type, id)));
947}
948
949static int
950iichid_set_idle(device_t dev, uint16_t duration, uint8_t id)
951{
952 return (ENOTSUP);
953}
954
955static int
956iichid_set_protocol(device_t dev, uint16_t protocol)
957{
958 return (ENOTSUP);
959}
960
961static int
962iichid_ioctl(device_t dev, unsigned long cmd, uintptr_t data)
963{
964 int error;
965
966 switch (cmd) {
967 case I2CRDWR:
969 ((struct iic_rdwr_data *)data)->msgs,
970 ((struct iic_rdwr_data *)data)->nmsgs));
971 break;
972 default:
973 error = EINVAL;
974 }
975
976 return (error);
977}
978
979static int
980iichid_fill_device_info(struct i2c_hid_desc *desc, ACPI_HANDLE handle,
981 struct hid_device_info *hw)
982{
983 ACPI_DEVICE_INFO *device_info;
984
985 hw->idBus = BUS_I2C;
986 hw->idVendor = le16toh(desc->wVendorID);
987 hw->idProduct = le16toh(desc->wProductID);
988 hw->idVersion = le16toh(desc->wVersionID);
989
990 /* get ACPI HID. It is a base part of the device name. */
991 if (ACPI_FAILURE(AcpiGetObjectInfo(handle, &device_info)))
992 return (ENXIO);
993
994 if (device_info->Valid & ACPI_VALID_HID)
995 strlcpy(hw->idPnP, device_info->HardwareId.String,
996 HID_PNP_ID_SIZE);
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,
1002 le16toh(desc->wVendorID), le16toh(desc->wProductID));
1003
1004 AcpiOsFree(device_info);
1005
1006 strlcpy(hw->serial, "", sizeof(hw->serial));
1007 hw->rdescsize = le16toh(desc->wReportDescLength);
1008 if (desc->wOutputRegister == 0 || desc->wMaxOutputLength == 0)
1009 hid_add_dynamic_quirk(hw, HQ_NOWRITE);
1010
1011 return (0);
1012}
1013
1014static int
1016{
1017 struct iichid_softc *sc;
1018 ACPI_HANDLE handle;
1019 char buf[80];
1020 uint16_t config_reg;
1021 int error, reg;
1022
1023 sc = device_get_softc(dev);
1024 sc->dev = dev;
1025 if (sc->probe_done)
1026 goto done;
1027
1028 sc->probe_done = true;
1029 sc->probe_result = ENXIO;
1030
1031 if (acpi_disabled("iichid"))
1032 return (ENXIO);
1033
1034 sc->addr = iicbus_get_addr(dev) << 1;
1035 if (sc->addr == 0)
1036 return (ENXIO);
1037
1038 handle = acpi_get_handle(dev);
1039 if (handle == NULL)
1040 return (ENXIO);
1041
1042 reg = acpi_is_iichid(handle);
1043 if (reg == IICHID_REG_NONE)
1044 return (ENXIO);
1045
1046 if (reg == IICHID_REG_ACPI) {
1047 if (ACPI_FAILURE(iichid_get_config_reg(handle, &config_reg)))
1048 return (ENXIO);
1049 } else
1050 config_reg = (uint16_t)reg;
1051
1052 DPRINTF(sc, " IICbus addr : 0x%02X\n", sc->addr >> 1);
1053 DPRINTF(sc, " HID descriptor reg: 0x%02X\n", config_reg);
1054
1055 error = iichid_cmd_get_hid_desc(sc, config_reg, &sc->desc);
1056 if (error) {
1057 DPRINTF(sc, "could not retrieve HID descriptor from the "
1058 "device: %d\n", error);
1059 return (ENXIO);
1060 }
1061
1062 if (le16toh(sc->desc.wHIDDescLength) != 30 ||
1063 le16toh(sc->desc.bcdVersion) != 0x100) {
1064 DPRINTF(sc, "HID descriptor is broken\n");
1065 return (ENXIO);
1066 }
1067
1068 /* Setup hid_device_info so we can figure out quirks for the device. */
1069 if (iichid_fill_device_info(&sc->desc, handle, &sc->hw) != 0) {
1070 DPRINTF(sc, "error evaluating AcpiGetObjectInfo\n");
1071 return (ENXIO);
1072 }
1073
1074 if (hid_test_quirk(&sc->hw, HQ_HID_IGNORE))
1075 return (ENXIO);
1076
1077 sc->probe_result = BUS_PROBE_DEFAULT;
1078done:
1079 if (sc->probe_result <= BUS_PROBE_SPECIFIC) {
1080 snprintf(buf, sizeof(buf), "%s I2C HID device", sc->hw.name);
1081 device_set_desc_copy(dev, buf);
1082 }
1083 return (sc->probe_result);
1084}
1085
1086static int
1088{
1089 struct iichid_softc *sc;
1090 device_t child;
1091 int error;
1092
1093 sc = device_get_softc(dev);
1095 if (error) {
1096 device_printf(dev, "failed to power on: %d\n", error);
1097 return (ENXIO);
1098 }
1099 /*
1100 * Windows driver sleeps for 1ms between the SET_POWER and RESET
1101 * commands. So we too as some devices may depend on this.
1102 */
1103 pause("iichid", (hz + 999) / 1000);
1104
1105 error = iichid_reset(sc);
1106 if (error) {
1107 device_printf(dev, "failed to reset hardware: %d\n", error);
1108 error = ENXIO;
1109 goto done;
1110 }
1111
1112 sc->power_on = true;
1113
1114 TASK_INIT(&sc->suspend_task, 0, iichid_suspend_task, sc);
1115#ifdef IICHID_SAMPLING
1116 TASK_INIT(&sc->event_task, 0, iichid_event_task, sc);
1117 /* taskqueue_create can't fail with M_WAITOK mflag passed. */
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);
1122
1123 sc->sampling_rate_slow = -1;
1124 sc->sampling_rate_fast = IICHID_SAMPLING_RATE_FAST;
1125 sc->sampling_hysteresis = IICHID_SAMPLING_HYSTERESIS;
1126#endif
1127
1128 sc->irq_rid = 0;
1129 sc->irq_res = bus_alloc_resource_any(sc->dev, SYS_RES_IRQ,
1130 &sc->irq_rid, RF_ACTIVE);
1131
1132 if (sc->irq_res != NULL) {
1133 DPRINTF(sc, "allocated irq at %p and rid %d\n",
1134 sc->irq_res, sc->irq_rid);
1135 error = iichid_setup_interrupt(sc);
1136 }
1137
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");
1142 sc->sampling_rate_slow = IICHID_SAMPLING_RATE_SLOW;
1143#else
1144 device_printf(sc->dev, "Interrupt setup failed\n");
1145 if (sc->irq_res != NULL)
1146 bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid,
1147 sc->irq_res);
1148 error = ENXIO;
1149 goto done;
1150#endif
1151 }
1152
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);
1170
1171 if (sc->sampling_rate_slow >= 0) {
1172 pause("iichid", (hz + 999) / 1000);
1173 (void)iichid_cmd_read(sc, NULL, 0, NULL);
1174 }
1175#endif /* IICHID_SAMPLING */
1176
1177 child = device_add_child(dev, "hidbus", -1);
1178 if (child == NULL) {
1179 device_printf(sc->dev, "Could not add I2C device\n");
1181 error = ENOMEM;
1182 goto done;
1183 }
1184
1185 device_set_ivars(child, &sc->hw);
1186 error = bus_generic_attach(dev);
1187 if (error) {
1188 device_printf(dev, "failed to attach child: error %d\n", error);
1190 }
1191done:
1193 sc->power_on = false;
1194 return (error);
1195}
1196
1197static int
1199{
1200 struct iichid_softc *sc;
1201 int error;
1202
1203 sc = device_get_softc(dev);
1204 error = device_delete_children(dev);
1205 if (error)
1206 return (error);
1208 if (sc->irq_res != NULL)
1209 bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid,
1210 sc->irq_res);
1211#ifdef IICHID_SAMPLING
1212 if (sc->taskqueue != NULL)
1213 taskqueue_free(sc->taskqueue);
1214 sc->taskqueue = NULL;
1215#endif
1216 return (0);
1217}
1218
1219static void
1220iichid_suspend_task(void *context, int pending)
1221{
1222 struct iichid_softc *sc = context;
1223
1225}
1226
1227static int
1229{
1230 struct iichid_softc *sc;
1231 int error;
1232
1233 sc = device_get_softc(dev);
1234 (void)bus_generic_suspend(dev);
1235 /*
1236 * 8.2 - The HOST is going into a deep power optimized state and wishes
1237 * to put all the devices into a low power state also. The HOST
1238 * is recommended to issue a HIPO command to the DEVICE to force
1239 * the DEVICE in to a lower power state.
1240 */
1241 DPRINTF(sc, "Suspend called, setting device to power_state 1\n");
1243 if (error != 0)
1244 DPRINTF(sc, "Could not set power_state, error: %d\n", error);
1245 else
1246 DPRINTF(sc, "Successfully set power_state\n");
1247
1248#ifdef IICHID_SAMPLING
1249 if (sc->sampling_rate_slow < 0)
1250#endif
1251 {
1252 /*
1253 * bus_teardown_intr can not be executed right here as it wants
1254 * to run on certain CPU to interacts with LAPIC while suspend
1255 * thread is bound to CPU0. So run it from taskqueue context.
1256 */
1257#ifdef IICHID_SAMPLING
1258#define suspend_thread sc->taskqueue
1259#else
1260#define suspend_thread taskqueue_thread
1261#endif
1262 taskqueue_enqueue(suspend_thread, &sc->suspend_task);
1263 taskqueue_drain(suspend_thread, &sc->suspend_task);
1264 }
1265
1266 return (0);
1267}
1268
1269static int
1271{
1272 struct iichid_softc *sc;
1273 int error;
1274
1275 sc = device_get_softc(dev);
1276#ifdef IICHID_SAMPLING
1277 if (sc->sampling_rate_slow < 0)
1278#endif
1280
1281 DPRINTF(sc, "Resume called, setting device to power_state 0\n");
1283 if (error != 0)
1284 DPRINTF(sc, "Could not set power_state, error: %d\n", error);
1285 else
1286 DPRINTF(sc, "Successfully set power_state\n");
1287 (void)bus_generic_resume(dev);
1288
1289 return (0);
1290}
1291
1292static devclass_t iichid_devclass;
1293
1294static device_method_t iichid_methods[] = {
1295 DEVMETHOD(device_probe, iichid_probe),
1296 DEVMETHOD(device_attach, iichid_attach),
1297 DEVMETHOD(device_detach, iichid_detach),
1298 DEVMETHOD(device_suspend, iichid_suspend),
1299 DEVMETHOD(device_resume, iichid_resume),
1300
1301 DEVMETHOD(hid_intr_setup, iichid_intr_setup),
1302 DEVMETHOD(hid_intr_unsetup, iichid_intr_unsetup),
1303 DEVMETHOD(hid_intr_start, iichid_intr_start),
1304 DEVMETHOD(hid_intr_stop, iichid_intr_stop),
1305 DEVMETHOD(hid_intr_poll, iichid_intr_poll),
1306
1307 /* HID interface */
1308 DEVMETHOD(hid_get_rdesc, iichid_get_rdesc),
1309 DEVMETHOD(hid_read, iichid_read),
1310 DEVMETHOD(hid_write, iichid_write),
1311 DEVMETHOD(hid_get_report, iichid_get_report),
1312 DEVMETHOD(hid_set_report, iichid_set_report),
1313 DEVMETHOD(hid_set_idle, iichid_set_idle),
1314 DEVMETHOD(hid_set_protocol, iichid_set_protocol),
1315 DEVMETHOD(hid_ioctl, iichid_ioctl),
1316
1317 DEVMETHOD_END
1318};
1319
1320static driver_t iichid_driver = {
1321 .name = "iichid",
1322 .methods = iichid_methods,
1323 .size = sizeof(struct iichid_softc),
1324};
1325
1328MODULE_DEPEND(iichid, acpi, 1, 1, 1);
1329MODULE_DEPEND(iichid, hid, 1, 1, 1);
1330MODULE_DEPEND(iichid, hidbus, 1, 1, 1);
#define IIC_M_WR
Definition: ad7418.c:45
#define I2CRDWR
Definition: iic.h:68
#define IIC_M_RD
Definition: iic.h:42
#define IIC_M_NOSTOP
Definition: iic.h:43
#define IIC_M_NOSTART
Definition: iic.h:44
SYSCTL_INT(_hw_i2c, OID_AUTO, iicbb_debug, CTLFLAG_RWTUN, &i2c_debug, 0, "Enable i2c bit-banging driver debug")
caddr_t data
Definition: iicbb_if.m:61
SYSCTL_NODE(_hw, OID_AUTO, i2c, CTLFLAG_RW, 0, "i2c controls")
char * buf
Definition: iicbus_if.m:55
struct iic_msg * msgs
Definition: iicbus_if.m:134
METHOD int intr
Definition: iicbus_if.m:52
uint32_t nmsgs
Definition: iicbus_if.m:135
INTERFACE iicbus
Definition: iicbus_if.m:32
int len
Definition: iicbus_if.m:102
static void iichid_intr_setup(device_t dev, hid_intr_t intr, void *context, struct hid_rdesc_info *rdesc)
Definition: iichid.c:794
static device_resume_t iichid_resume
Definition: iichid.c:197
#define IICHID_SAMPLING_HYSTERESIS
Definition: iichid.c:113
static void iichid_intr_poll(device_t dev)
Definition: iichid.c:865
static int iichid_fill_device_info(struct i2c_hid_desc *desc, ACPI_HANDLE handle, struct hid_device_info *hw)
Definition: iichid.c:980
static int iichid_intr_start(device_t dev)
Definition: iichid.c:835
static int iichid_set_power(struct iichid_softc *sc, uint8_t param)
Definition: iichid.c:364
static int iichid_set_report(device_t dev, const void *buf, hid_size_t len, uint8_t type, uint8_t id)
Definition: iichid.c:938
#define IICHID_SIZE_MAX
Definition: iichid.c:84
#define IICHID_REG_ACPI
Definition: iichid.c:134
static driver_t iichid_driver
Definition: iichid.c:1320
static int iichid_setup_interrupt(struct iichid_softc *sc)
Definition: iichid.c:677
static int iichid_set_power_state(struct iichid_softc *sc, enum iichid_powerstate_how how_open, enum iichid_powerstate_how how_suspend)
Definition: iichid.c:609
MODULE_VERSION(iichid, 1)
hid_size_t iichid_size_t
Definition: iichid.c:83
struct i2c_hid_desc __packed
static const struct iichid_id iichid_ids[]
static device_attach_t iichid_attach
Definition: iichid.c:195
#define suspend_thread
static int acpi_is_iichid(ACPI_HANDLE handle)
Definition: iichid.c:209
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)
Definition: iichid.c:415
static int iichid_write(device_t dev, const void *buf, hid_size_t len)
Definition: iichid.c:914
static int iichid_set_protocol(device_t dev, uint16_t protocol)
Definition: iichid.c:956
static device_probe_t iichid_probe
Definition: iichid.c:194
static device_suspend_t iichid_suspend
Definition: iichid.c:198
static int iichid_cmd_get_hid_desc(struct iichid_softc *sc, uint16_t config_reg, struct i2c_hid_desc *hid_desc)
Definition: iichid.c:337
static void iichid_intr_unsetup(device_t dev)
Definition: iichid.c:823
iichid_powerstate_how
Definition: iichid.c:147
@ IICHID_PS_NULL
Definition: iichid.c:148
@ IICHID_PS_ON
Definition: iichid.c:149
@ IICHID_PS_OFF
Definition: iichid.c:150
static int iichid_ioctl(device_t dev, unsigned long cmd, uintptr_t data)
Definition: iichid.c:962
static int iichid_reset(struct iichid_softc *sc)
Definition: iichid.c:378
#define I2C_HID_POWER_OFF
Definition: iichid.c:100
#define DPRINTFN(...)
Definition: iichid.c:79
MODULE_DEPEND(iichid, iicbus, IICBUS_MINVER, IICBUS_PREFVER, IICBUS_MAXVER)
__FBSDID("$FreeBSD$")
DRIVER_MODULE(iichid, iicbus, iichid_driver, iichid_devclass, NULL, 0)
#define IICHID_REG_NONE
Definition: iichid.c:133
#define IICHID_SAMPLING_RATE_FAST
Definition: iichid.c:111
IICBUS_ACPI_PNP_INFO(iichid_ids)
#define IICHID_SAMPLING_RATE_SLOW
Definition: iichid.c:112
static int iichid_intr_stop(device_t dev)
Definition: iichid.c:847
#define IICHID_REG_ELAN
Definition: iichid.c:135
#define DPRINTF(...)
Definition: iichid.c:80
static int iichid_cmd_read(struct iichid_softc *sc, void *buf, iichid_size_t maxlen, iichid_size_t *actual_len)
Definition: iichid.c:266
static ACPI_STATUS iichid_get_config_reg(ACPI_HANDLE handle, uint16_t *config_reg)
Definition: iichid.c:236
static int iichid_read(device_t dev, void *buf, hid_size_t maxlen, hid_size_t *actlen)
Definition: iichid.c:895
static int iichid_cmd_set_report(struct iichid_softc *sc, const void *buf, iichid_size_t len, uint8_t type, uint8_t id)
Definition: iichid.c:485
static void iichid_teardown_interrupt(struct iichid_softc *sc)
Definition: iichid.c:692
#define I2C_HID_POWER_ON
Definition: iichid.c:99
static device_detach_t iichid_detach
Definition: iichid.c:196
@ I2C_HID_CMD_RESET
Definition: iichid.c:89
@ I2C_HID_CMD_SET_POWER
Definition: iichid.c:96
@ I2C_HID_CMD_GET_REPORT
Definition: iichid.c:90
@ I2C_HID_CMD_SET_REPORT
Definition: iichid.c:91
@ I2C_HID_CMD_GET_IDLE
Definition: iichid.c:92
@ I2C_HID_CMD_GET_PROTO
Definition: iichid.c:94
@ I2C_HID_CMD_SET_PROTO
Definition: iichid.c:95
@ I2C_HID_CMD_DESCR
Definition: iichid.c:88
@ I2C_HID_CMD_SET_IDLE
Definition: iichid.c:93
static int iichid_cmd_get_report_desc(struct iichid_softc *sc, void *buf, iichid_size_t len)
Definition: iichid.c:392
static void iichid_intr(void *context)
Definition: iichid.c:566
static int iichid_set_idle(device_t dev, uint16_t duration, uint8_t id)
Definition: iichid.c:950
static void iichid_suspend_task(void *, int)
Definition: iichid.c:1220
static int iichid_get_report(device_t dev, void *buf, hid_size_t maxlen, hid_size_t *actlen, uint8_t type, uint8_t id)
Definition: iichid.c:925
static device_method_t iichid_methods[]
Definition: iichid.c:1294
static int iichid_cmd_write(struct iichid_softc *sc, const void *buf, iichid_size_t len)
Definition: iichid.c:314
static devclass_t iichid_devclass
Definition: iichid.c:1292
static int iichid_get_rdesc(device_t dev, void *buf, hid_size_t len)
Definition: iichid.c:881
int iicbus_request_bus(device_t bus, device_t dev, int how)
Definition: iiconf.c:138
int iicbus_transfer(device_t bus, struct iic_msg *msgs, uint32_t nmsgs)
Definition: iiconf.c:442
int iic2errno(int iic_status)
Definition: iiconf.c:60
int iicbus_release_bus(device_t bus, device_t dev)
Definition: iiconf.c:206
#define IICBUS_MINVER
Definition: iiconf.h:171
#define IIC_ENOTSUPP
Definition: iiconf.h:115
#define IIC_DONTWAIT
Definition: iiconf.h:44
#define IIC_INTRWAIT
Definition: iiconf.h:48
#define IIC_WAIT
Definition: iiconf.h:46
#define IICBUS_MAXVER
Definition: iiconf.h:172
#define IICBUS_PREFVER
Definition: iiconf.h:173
device_t dev
Definition: ofw_iicbus_if.m:38
uint16_t wReportDescRegister
Definition: iichid.c:120
uint16_t wVendorID
Definition: iichid.c:127
uint16_t wInputRegister
Definition: iichid.c:121
uint16_t wProductID
Definition: iichid.c:128
uint16_t wDataRegister
Definition: iichid.c:126
uint16_t wHIDDescLength
Definition: iichid.c:117
uint16_t bcdVersion
Definition: iichid.c:118
uint16_t wMaxInputLength
Definition: iichid.c:122
uint16_t wOutputRegister
Definition: iichid.c:123
uint16_t wReportDescLength
Definition: iichid.c:119
uint16_t wCommandRegister
Definition: iichid.c:125
uint16_t wMaxOutputLength
Definition: iichid.c:124
uint16_t wVersionID
Definition: iichid.c:129
uint32_t reserved
Definition: iichid.c:130
Definition: iic.h:38
uint8_t * buf
Definition: iic.h:46
char * id
Definition: iichid.c:138
int reg
Definition: iichid.c:139
uint8_t * intr_buf
Definition: iichid.c:170
int probe_result
Definition: iichid.c:162
struct resource * irq_res
Definition: iichid.c:174
bool suspend
Definition: iichid.c:190
iichid_size_t intr_bufsize
Definition: iichid.c:171
bool probe_done
Definition: iichid.c:161
void * intr_ctx
Definition: iichid.c:169
struct hid_device_info hw
Definition: iichid.c:164
struct i2c_hid_desc desc
Definition: iichid.c:166
bool open
Definition: iichid.c:189
struct task suspend_task
Definition: iichid.c:188
int irq_rid
Definition: iichid.c:173
hid_intr_t * intr_handler
Definition: iichid.c:168
uint16_t addr
Definition: iichid.c:165
bool power_on
Definition: iichid.c:191
device_t dev
Definition: iichid.c:159
void * irq_cookie
Definition: iichid.c:175