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 #include "opt_hid.h"
33
34 #include <sys/param.h>
35 #include <sys/bus.h>
36 #include <sys/callout.h>
37 #include <sys/endian.h>
38 #include <sys/kernel.h>
39 #include <sys/lock.h>
40 #include <sys/malloc.h>
41 #include <sys/module.h>
42 #include <sys/rman.h>
43 #include <sys/sysctl.h>
44 #include <sys/systm.h>
45 #include <sys/taskqueue.h>
46
47 #include <machine/resource.h>
48
49 #include <contrib/dev/acpica/include/acpi.h>
50 #include <contrib/dev/acpica/include/accommon.h>
51 #include <dev/acpica/acpivar.h>
52
53 #include <dev/evdev/input.h>
54
55 #include <dev/hid/hid.h>
56 #include <dev/hid/hidquirk.h>
57
58 #include <dev/iicbus/iic.h>
59 #include <dev/iicbus/iicbus.h>
60 #include <dev/iicbus/iiconf.h>
61
62 #include "hid_if.h"
63
64 #ifdef IICHID_DEBUG
65 static int iichid_debug = 0;
66
67 static SYSCTL_NODE(_hw, OID_AUTO, iichid, CTLFLAG_RW, 0, "I2C HID");
68 SYSCTL_INT(_hw_iichid, OID_AUTO, debug, CTLFLAG_RWTUN,
69 &iichid_debug, 1, "Debug level");
70
71 #define DPRINTFN(sc, n, ...) do { \
72 if (iichid_debug >= (n)) \
73 device_printf((sc)->dev, __VA_ARGS__); \
74 } while (0)
75 #define DPRINTF(sc, ...) DPRINTFN(sc, 1, __VA_ARGS__)
76 #else
77 #define DPRINTFN(...) do {} while (0)
78 #define DPRINTF(...) do {} while (0)
79 #endif
80
81 typedef hid_size_t iichid_size_t;
82 #define IICHID_SIZE_MAX (UINT16_MAX - 2)
83
84 /* 7.2 */
85 enum {
86 I2C_HID_CMD_DESCR = 0x0,
87 I2C_HID_CMD_RESET = 0x1,
88 I2C_HID_CMD_GET_REPORT = 0x2,
89 I2C_HID_CMD_SET_REPORT = 0x3,
90 I2C_HID_CMD_GET_IDLE = 0x4,
91 I2C_HID_CMD_SET_IDLE = 0x5,
92 I2C_HID_CMD_GET_PROTO = 0x6,
93 I2C_HID_CMD_SET_PROTO = 0x7,
94 I2C_HID_CMD_SET_POWER = 0x8,
95 };
96
97 #define I2C_HID_POWER_ON 0x0
98 #define I2C_HID_POWER_OFF 0x1
99
100 /*
101 * Since interrupt resource acquisition is not always possible (in case of GPIO
102 * interrupts) iichid now supports a sampling_mode.
103 * Set dev.iichid.<unit>.sampling_rate_slow to a value greater then 0
104 * to activate sampling. A value of 0 is possible but will not reset the
105 * callout and, thereby, disable further report requests. Do not set the
106 * sampling_rate_fast value too high as it may result in periodical lags of
107 * cursor motion.
108 */
109 #define IICHID_SAMPLING_RATE_FAST 80
110 #define IICHID_SAMPLING_RATE_SLOW 10
111 #define IICHID_SAMPLING_HYSTERESIS 16 /* ~ 2x fast / slow */
112
113 /* 5.1.1 - HID Descriptor Format */
114 struct i2c_hid_desc {
115 uint16_t wHIDDescLength;
116 uint16_t bcdVersion;
117 uint16_t wReportDescLength;
118 uint16_t wReportDescRegister;
119 uint16_t wInputRegister;
120 uint16_t wMaxInputLength;
121 uint16_t wOutputRegister;
122 uint16_t wMaxOutputLength;
123 uint16_t wCommandRegister;
124 uint16_t wDataRegister;
125 uint16_t wVendorID;
126 uint16_t wProductID;
127 uint16_t wVersionID;
128 uint32_t reserved;
129 } __packed;
130
131 #define IICHID_REG_NONE -1
132 #define IICHID_REG_ACPI (UINT16_MAX + 1)
133 #define IICHID_REG_ELAN 0x0001
134
135 static const struct iichid_id {
136 char *id;
137 int reg;
138 } iichid_ids[] = {
139 { "ELAN0000", IICHID_REG_ELAN },
140 { "PNP0C50", IICHID_REG_ACPI },
141 { "ACPI0C50", IICHID_REG_ACPI },
142 { NULL, 0 },
143 };
144
145 enum iichid_powerstate_how {
146 IICHID_PS_NULL,
147 IICHID_PS_ON,
148 IICHID_PS_OFF,
149 };
150
151 /*
152 * Locking: no internal locks are used. To serialize access to shared members,
153 * external iicbus lock should be taken. That allows to make locking greatly
154 * simple at the cost of running front interrupt handlers with locked bus.
155 */
156 struct iichid_softc {
157 device_t dev;
158
159 bool probe_done;
160 int probe_result;
161
162 struct hid_device_info hw;
163 uint16_t addr; /* Shifted left by 1 */
164 struct i2c_hid_desc desc;
165
166 hid_intr_t *intr_handler;
167 void *intr_ctx;
168 uint8_t *intr_buf;
169 iichid_size_t intr_bufsize;
170
171 int irq_rid;
172 struct resource *irq_res;
173 void *irq_cookie;
174
175 #ifdef IICHID_SAMPLING
176 int sampling_rate_slow; /* iicbus lock */
177 int sampling_rate_fast;
178 int sampling_hysteresis;
179 int missing_samples; /* iicbus lock */
180 int dup_samples; /* iicbus lock */
181 iichid_size_t dup_size; /* iicbus lock */
182 bool callout_setup; /* iicbus lock */
183 uint8_t *dup_buf;
184 struct taskqueue *taskqueue;
185 struct timeout_task sampling_task; /* iicbus lock */
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
194 static device_probe_t iichid_probe;
195 static device_attach_t iichid_attach;
196 static device_detach_t iichid_detach;
197 static device_resume_t iichid_resume;
198 static device_suspend_t iichid_suspend;
199
200 static void iichid_suspend_task(void *, int);
201
202 #ifdef IICHID_SAMPLING
203 static int iichid_setup_callout(struct iichid_softc *);
204 static int iichid_reset_callout(struct iichid_softc *);
205 static void iichid_teardown_callout(struct iichid_softc *);
206 #endif
207
208 static inline int
acpi_is_iichid(ACPI_HANDLE handle)209 acpi_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
235 static ACPI_STATUS
iichid_get_config_reg(ACPI_HANDLE handle,uint16_t * config_reg)236 iichid_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
265 static int
iichid_cmd_read(struct iichid_softc * sc,void * buf,iichid_size_t maxlen,iichid_size_t * actual_len)266 iichid_cmd_read(struct iichid_softc* sc, void *buf, iichid_size_t maxlen,
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
313 static int
iichid_cmd_write(struct iichid_softc * sc,const void * buf,iichid_size_t len)314 iichid_cmd_write(struct iichid_softc *sc, const void *buf, iichid_size_t len)
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
336 static int
iichid_cmd_get_hid_desc(struct iichid_softc * sc,uint16_t config_reg,struct i2c_hid_desc * hid_desc)337 iichid_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
363 static int
iichid_set_power(struct iichid_softc * sc,uint8_t param)364 iichid_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
377 static int
iichid_reset(struct iichid_softc * sc)378 iichid_reset(struct iichid_softc *sc)
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
391 static int
iichid_cmd_get_report_desc(struct iichid_softc * sc,void * buf,iichid_size_t len)392 iichid_cmd_get_report_desc(struct iichid_softc* sc, void *buf,
393 iichid_size_t len)
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
414 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)415 iichid_cmd_get_report(struct iichid_softc* sc, void *buf, iichid_size_t maxlen,
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)),
430 I2C_HID_CMD_GET_REPORT ,
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
484 static int
iichid_cmd_set_report(struct iichid_softc * sc,const void * buf,iichid_size_t len,uint8_t type,uint8_t id)485 iichid_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)),
501 I2C_HID_CMD_SET_REPORT ,
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
521 static void
iichid_sampling_task(void * context,int pending)522 iichid_sampling_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, rate;
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 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;
551 } else
552 ++sc->dup_samples;
553 } else {
554 if (++sc->missing_samples == 1)
555 sc->intr_handler(sc->intr_ctx, sc->intr_buf, 0);
556 sc->dup_samples = 0;
557 }
558 } else
559 DPRINTF(sc, "read error occurred: %d\n", error);
560
561 rearm:
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;
566 else
567 rate = sc->sampling_rate_fast;
568 taskqueue_enqueue_timeout_sbt(sc->taskqueue, &sc->sampling_task,
569 SBT_1S / MAX(rate, 1), 0, C_PREL(2));
570 }
571 out:
572 if (bus_requested)
573 iicbus_release_bus(parent, sc->dev);
574 }
575 #endif /* IICHID_SAMPLING */
576
577 static void
iichid_intr(void * context)578 iichid_intr(void *context)
579 {
580 struct iichid_softc *sc;
581 device_t parent;
582 iichid_size_t maxlen, actual;
583 int error;
584
585 sc = context;
586 parent = device_get_parent(sc->dev);
587
588 /*
589 * Designware(IG4) driver-specific hack.
590 * Requesting of an I2C bus with IIC_DONTWAIT parameter enables polled
591 * mode in the driver, making possible iicbus_transfer execution from
592 * interrupt handlers and callouts.
593 */
594 if (iicbus_request_bus(parent, sc->dev, IIC_DONTWAIT) != 0)
595 return;
596
597 /*
598 * Reading of input reports of I2C devices residing in SLEEP state is
599 * not allowed and often returns a garbage. If a HOST needs to
600 * communicate with the DEVICE it MUST issue a SET POWER command
601 * (to ON) before any other command. As some hardware requires reads to
602 * acknowledge interrupts we fetch only length header and discard it.
603 */
604 maxlen = sc->power_on ? sc->intr_bufsize : 0;
605 error = iichid_cmd_read(sc, sc->intr_buf, maxlen, &actual);
606 if (error == 0) {
607 if (sc->power_on) {
608 if (actual != 0)
609 sc->intr_handler(sc->intr_ctx, sc->intr_buf,
610 actual);
611 else
612 DPRINTF(sc, "no data received\n");
613 }
614 } else
615 DPRINTF(sc, "read error occurred: %d\n", error);
616
617 iicbus_release_bus(parent, sc->dev);
618 }
619
620 static int
iichid_set_power_state(struct iichid_softc * sc,enum iichid_powerstate_how how_open,enum iichid_powerstate_how how_suspend)621 iichid_set_power_state(struct iichid_softc *sc,
622 enum iichid_powerstate_how how_open,
623 enum iichid_powerstate_how how_suspend)
624 {
625 device_t parent;
626 int error;
627 int how_request;
628 bool power_on;
629
630 /*
631 * Request iicbus early as sc->suspend and sc->power_on
632 * are protected by iicbus internal lock.
633 */
634 parent = device_get_parent(sc->dev);
635 /* Allow to interrupt open()/close() handlers by SIGINT */
636 how_request = how_open == IICHID_PS_NULL ? IIC_WAIT : IIC_INTRWAIT;
637 error = iicbus_request_bus(parent, sc->dev, how_request);
638 if (error != 0)
639 return (error);
640
641 switch (how_open) {
642 case IICHID_PS_ON:
643 sc->open = true;
644 break;
645 case IICHID_PS_OFF:
646 sc->open = false;
647 break;
648 case IICHID_PS_NULL:
649 default:
650 break;
651 }
652
653 switch (how_suspend) {
654 case IICHID_PS_ON:
655 sc->suspend = false;
656 break;
657 case IICHID_PS_OFF:
658 sc->suspend = true;
659 break;
660 case IICHID_PS_NULL:
661 default:
662 break;
663 }
664
665 power_on = sc->open & !sc->suspend;
666
667 if (power_on != sc->power_on) {
668 error = iichid_set_power(sc,
669 power_on ? I2C_HID_POWER_ON : I2C_HID_POWER_OFF);
670
671 sc->power_on = power_on;
672 #ifdef IICHID_SAMPLING
673 if (sc->sampling_rate_slow >= 0 && sc->intr_handler != NULL) {
674 if (power_on) {
675 iichid_setup_callout(sc);
676 iichid_reset_callout(sc);
677 } else
678 iichid_teardown_callout(sc);
679 }
680 #endif
681 }
682
683 iicbus_release_bus(parent, sc->dev);
684
685 return (error);
686 }
687
688 static int
iichid_setup_interrupt(struct iichid_softc * sc)689 iichid_setup_interrupt(struct iichid_softc *sc)
690 {
691 sc->irq_cookie = 0;
692
693 int error = bus_setup_intr(sc->dev, sc->irq_res,
694 INTR_TYPE_TTY|INTR_MPSAFE, NULL, iichid_intr, sc, &sc->irq_cookie);
695 if (error != 0)
696 DPRINTF(sc, "Could not setup interrupt handler\n");
697 else
698 DPRINTF(sc, "successfully setup interrupt\n");
699
700 return (error);
701 }
702
703 static void
iichid_teardown_interrupt(struct iichid_softc * sc)704 iichid_teardown_interrupt(struct iichid_softc *sc)
705 {
706 if (sc->irq_cookie)
707 bus_teardown_intr(sc->dev, sc->irq_res, sc->irq_cookie);
708
709 sc->irq_cookie = 0;
710 }
711
712 #ifdef IICHID_SAMPLING
713 static int
iichid_setup_callout(struct iichid_softc * sc)714 iichid_setup_callout(struct iichid_softc *sc)
715 {
716
717 if (sc->sampling_rate_slow < 0) {
718 DPRINTF(sc, "sampling_rate is below 0, can't setup callout\n");
719 return (EINVAL);
720 }
721
722 sc->callout_setup = true;
723 DPRINTF(sc, "successfully setup callout\n");
724 return (0);
725 }
726
727 static int
iichid_reset_callout(struct iichid_softc * sc)728 iichid_reset_callout(struct iichid_softc *sc)
729 {
730
731 if (sc->sampling_rate_slow <= 0) {
732 DPRINTF(sc, "sampling_rate is below or equal to 0, "
733 "can't reset callout\n");
734 return (EINVAL);
735 }
736
737 if (!sc->callout_setup)
738 return (EINVAL);
739
740 /* Start with slow sampling. */
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);
745
746 return (0);
747 }
748
749 static void
iichid_teardown_callout(struct iichid_softc * sc)750 iichid_teardown_callout(struct iichid_softc *sc)
751 {
752
753 sc->callout_setup = false;
754 taskqueue_cancel_timeout(sc->taskqueue, &sc->sampling_task, NULL);
755 DPRINTF(sc, "tore callout down\n");
756 }
757
758 static int
iichid_sysctl_sampling_rate_handler(SYSCTL_HANDLER_ARGS)759 iichid_sysctl_sampling_rate_handler(SYSCTL_HANDLER_ARGS)
760 {
761 struct iichid_softc *sc;
762 device_t parent;
763 int error, oldval, value;
764
765 sc = arg1;
766
767 value = sc->sampling_rate_slow;
768 error = sysctl_handle_int(oidp, &value, 0, req);
769
770 if (error != 0 || req->newptr == NULL ||
771 value == sc->sampling_rate_slow)
772 return (error);
773
774 /* Can't switch to interrupt mode if it is not supported. */
775 if (sc->irq_res == NULL && value < 0)
776 return (EINVAL);
777
778 parent = device_get_parent(sc->dev);
779 error = iicbus_request_bus(parent, sc->dev, IIC_WAIT);
780 if (error != 0)
781 return (iic2errno(error));
782
783 oldval = sc->sampling_rate_slow;
784 sc->sampling_rate_slow = value;
785
786 if (oldval < 0 && value >= 0) {
787 iichid_teardown_interrupt(sc);
788 if (sc->power_on)
789 iichid_setup_callout(sc);
790 } else if (oldval >= 0 && value < 0) {
791 if (sc->power_on)
792 iichid_teardown_callout(sc);
793 iichid_setup_interrupt(sc);
794 }
795
796 if (sc->power_on && value > 0)
797 iichid_reset_callout(sc);
798
799 iicbus_release_bus(parent, sc->dev);
800
801 DPRINTF(sc, "new sampling_rate value: %d\n", value);
802
803 return (0);
804 }
805 #endif /* IICHID_SAMPLING */
806
807 static void
iichid_intr_setup(device_t dev,device_t child __unused,hid_intr_t intr,void * context,struct hid_rdesc_info * rdesc)808 iichid_intr_setup(device_t dev, device_t child __unused, hid_intr_t intr,
809 void *context, struct hid_rdesc_info *rdesc)
810 {
811 struct iichid_softc *sc;
812
813 if (intr == NULL)
814 return;
815
816 sc = device_get_softc(dev);
817 /*
818 * Do not rely on wMaxInputLength, as some devices may set it to
819 * a wrong length. Find the longest input report in report descriptor.
820 */
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;
825
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;
830 #ifdef IICHID_SAMPLING
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));
834 #endif
835 }
836
837 static void
iichid_intr_unsetup(device_t dev,device_t child __unused)838 iichid_intr_unsetup(device_t dev, device_t child __unused)
839 {
840 struct iichid_softc *sc;
841
842 sc = device_get_softc(dev);
843 #ifdef IICHID_SAMPLING
844 taskqueue_drain_all(sc->taskqueue);
845 free(sc->dup_buf, M_DEVBUF);
846 #endif
847 free(sc->intr_buf, M_DEVBUF);
848 }
849
850 static int
iichid_intr_start(device_t dev,device_t child __unused)851 iichid_intr_start(device_t dev, device_t child __unused)
852 {
853 struct iichid_softc *sc;
854
855 sc = device_get_softc(dev);
856 DPRINTF(sc, "iichid device open\n");
857 iichid_set_power_state(sc, IICHID_PS_ON, IICHID_PS_NULL);
858
859 return (0);
860 }
861
862 static int
iichid_intr_stop(device_t dev,device_t child __unused)863 iichid_intr_stop(device_t dev, device_t child __unused)
864 {
865 struct iichid_softc *sc;
866
867 sc = device_get_softc(dev);
868 DPRINTF(sc, "iichid device close\n");
869 /*
870 * 8.2 - The HOST determines that there are no active applications
871 * that are currently using the specific HID DEVICE. The HOST
872 * is recommended to issue a HIPO command to the DEVICE to force
873 * the DEVICE in to a lower power state.
874 */
875 iichid_set_power_state(sc, IICHID_PS_OFF, IICHID_PS_NULL);
876
877 return (0);
878 }
879
880 static void
iichid_intr_poll(device_t dev,device_t child __unused)881 iichid_intr_poll(device_t dev, device_t child __unused)
882 {
883 struct iichid_softc *sc;
884 iichid_size_t actual;
885 int error;
886
887 sc = device_get_softc(dev);
888 error = iichid_cmd_read(sc, sc->intr_buf, sc->intr_bufsize, &actual);
889 if (error == 0 && actual != 0)
890 sc->intr_handler(sc->intr_ctx, sc->intr_buf, actual);
891 }
892
893 /*
894 * HID interface
895 */
896 static int
iichid_get_rdesc(device_t dev,device_t child __unused,void * buf,hid_size_t len)897 iichid_get_rdesc(device_t dev, device_t child __unused, void *buf,
898 hid_size_t len)
899 {
900 struct iichid_softc *sc;
901 int error;
902
903 sc = device_get_softc(dev);
904 error = iichid_cmd_get_report_desc(sc, buf, len);
905 if (error)
906 DPRINTF(sc, "failed to fetch report descriptor: %d\n", error);
907
908 return (iic2errno(error));
909 }
910
911 static int
iichid_read(device_t dev,device_t child __unused,void * buf,hid_size_t maxlen,hid_size_t * actlen)912 iichid_read(device_t dev, device_t child __unused, void *buf,
913 hid_size_t maxlen, hid_size_t *actlen)
914 {
915 struct iichid_softc *sc;
916 device_t parent;
917 int error;
918
919 if (maxlen > IICHID_SIZE_MAX)
920 return (EMSGSIZE);
921 sc = device_get_softc(dev);
922 parent = device_get_parent(sc->dev);
923 error = iicbus_request_bus(parent, sc->dev, IIC_WAIT);
924 if (error == 0) {
925 error = iichid_cmd_read(sc, buf, maxlen, actlen);
926 iicbus_release_bus(parent, sc->dev);
927 }
928 return (iic2errno(error));
929 }
930
931 static int
iichid_write(device_t dev,device_t child __unused,const void * buf,hid_size_t len)932 iichid_write(device_t dev, device_t child __unused, const void *buf,
933 hid_size_t len)
934 {
935 struct iichid_softc *sc;
936
937 if (len > IICHID_SIZE_MAX)
938 return (EMSGSIZE);
939 sc = device_get_softc(dev);
940 return (iic2errno(iichid_cmd_write(sc, buf, len)));
941 }
942
943 static int
iichid_get_report(device_t dev,device_t child __unused,void * buf,hid_size_t maxlen,hid_size_t * actlen,uint8_t type,uint8_t id)944 iichid_get_report(device_t dev, device_t child __unused, void *buf,
945 hid_size_t maxlen, hid_size_t *actlen, uint8_t type, uint8_t id)
946 {
947 struct iichid_softc *sc;
948
949 if (maxlen > IICHID_SIZE_MAX)
950 return (EMSGSIZE);
951 sc = device_get_softc(dev);
952 return (iic2errno(
953 iichid_cmd_get_report(sc, buf, maxlen, actlen, type, id)));
954 }
955
956 static int
iichid_set_report(device_t dev,device_t child __unused,const void * buf,hid_size_t len,uint8_t type,uint8_t id)957 iichid_set_report(device_t dev, device_t child __unused, const void *buf,
958 hid_size_t len, uint8_t type, uint8_t id)
959 {
960 struct iichid_softc *sc;
961
962 if (len > IICHID_SIZE_MAX)
963 return (EMSGSIZE);
964 sc = device_get_softc(dev);
965 return (iic2errno(iichid_cmd_set_report(sc, buf, len, type, id)));
966 }
967
968 static int
iichid_set_idle(device_t dev,device_t child __unused,uint16_t duration,uint8_t id)969 iichid_set_idle(device_t dev, device_t child __unused,
970 uint16_t duration, uint8_t id)
971 {
972 return (ENOTSUP);
973 }
974
975 static int
iichid_set_protocol(device_t dev,device_t child __unused,uint16_t protocol)976 iichid_set_protocol(device_t dev, device_t child __unused, uint16_t protocol)
977 {
978 return (ENOTSUP);
979 }
980
981 static int
iichid_ioctl(device_t dev,device_t child __unused,unsigned long cmd,uintptr_t data)982 iichid_ioctl(device_t dev, device_t child __unused, unsigned long cmd,
983 uintptr_t data)
984 {
985 int error;
986
987 switch (cmd) {
988 case I2CRDWR:
989 error = iic2errno(iicbus_transfer(dev,
990 ((struct iic_rdwr_data *)data)->msgs,
991 ((struct iic_rdwr_data *)data)->nmsgs));
992 break;
993 default:
994 error = EINVAL;
995 }
996
997 return (error);
998 }
999
1000 static int
iichid_fill_device_info(struct i2c_hid_desc * desc,ACPI_HANDLE handle,struct hid_device_info * hw)1001 iichid_fill_device_info(struct i2c_hid_desc *desc, ACPI_HANDLE handle,
1002 struct hid_device_info *hw)
1003 {
1004 ACPI_DEVICE_INFO *device_info;
1005
1006 hw->idBus = BUS_I2C;
1007 hw->idVendor = le16toh(desc->wVendorID);
1008 hw->idProduct = le16toh(desc->wProductID);
1009 hw->idVersion = le16toh(desc->wVersionID);
1010
1011 /* get ACPI HID. It is a base part of the device name. */
1012 if (ACPI_FAILURE(AcpiGetObjectInfo(handle, &device_info)))
1013 return (ENXIO);
1014
1015 if (device_info->Valid & ACPI_VALID_HID)
1016 strlcpy(hw->idPnP, device_info->HardwareId.String,
1017 HID_PNP_ID_SIZE);
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));
1024
1025 AcpiOsFree(device_info);
1026
1027 strlcpy(hw->serial, "", sizeof(hw->serial));
1028 hw->rdescsize = le16toh(desc->wReportDescLength);
1029 if (desc->wOutputRegister == 0 || desc->wMaxOutputLength == 0)
1030 hid_add_dynamic_quirk(hw, HQ_NOWRITE);
1031
1032 return (0);
1033 }
1034
1035 static int
iichid_probe(device_t dev)1036 iichid_probe(device_t dev)
1037 {
1038 struct iichid_softc *sc;
1039 ACPI_HANDLE handle;
1040 uint16_t config_reg;
1041 int error, reg;
1042
1043 sc = device_get_softc(dev);
1044 sc->dev = dev;
1045 if (sc->probe_done)
1046 goto done;
1047
1048 sc->probe_done = true;
1049 sc->probe_result = ENXIO;
1050
1051 if (acpi_disabled("iichid"))
1052 return (ENXIO);
1053
1054 sc->addr = iicbus_get_addr(dev) << 1;
1055 if (sc->addr == 0)
1056 return (ENXIO);
1057
1058 handle = acpi_get_handle(dev);
1059 if (handle == NULL)
1060 return (ENXIO);
1061
1062 reg = acpi_is_iichid(handle);
1063 if (reg == IICHID_REG_NONE)
1064 return (ENXIO);
1065
1066 if (reg == IICHID_REG_ACPI) {
1067 if (ACPI_FAILURE(iichid_get_config_reg(handle, &config_reg)))
1068 return (ENXIO);
1069 } else
1070 config_reg = (uint16_t)reg;
1071
1072 DPRINTF(sc, " IICbus addr : 0x%02X\n", sc->addr >> 1);
1073 DPRINTF(sc, " HID descriptor reg: 0x%02X\n", config_reg);
1074
1075 error = iichid_cmd_get_hid_desc(sc, config_reg, &sc->desc);
1076 if (error) {
1077 DPRINTF(sc, "could not retrieve HID descriptor from the "
1078 "device: %d\n", error);
1079 return (ENXIO);
1080 }
1081
1082 if (le16toh(sc->desc.wHIDDescLength) != 30 ||
1083 le16toh(sc->desc.bcdVersion) != 0x100) {
1084 DPRINTF(sc, "HID descriptor is broken\n");
1085 return (ENXIO);
1086 }
1087
1088 /* Setup hid_device_info so we can figure out quirks for the device. */
1089 if (iichid_fill_device_info(&sc->desc, handle, &sc->hw) != 0) {
1090 DPRINTF(sc, "error evaluating AcpiGetObjectInfo\n");
1091 return (ENXIO);
1092 }
1093
1094 if (hid_test_quirk(&sc->hw, HQ_HID_IGNORE))
1095 return (ENXIO);
1096
1097 sc->probe_result = BUS_PROBE_DEFAULT;
1098 done:
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);
1102 }
1103
1104 static int
iichid_attach(device_t dev)1105 iichid_attach(device_t dev)
1106 {
1107 struct iichid_softc *sc;
1108 device_t child;
1109 int error;
1110
1111 sc = device_get_softc(dev);
1112 error = iichid_set_power(sc, I2C_HID_POWER_ON);
1113 if (error) {
1114 device_printf(dev, "failed to power on: %d\n", error);
1115 return (ENXIO);
1116 }
1117 /*
1118 * Windows driver sleeps for 1ms between the SET_POWER and RESET
1119 * commands. So we too as some devices may depend on this.
1120 */
1121 pause("iichid", (hz + 999) / 1000);
1122
1123 error = iichid_reset(sc);
1124 if (error) {
1125 device_printf(dev, "failed to reset hardware: %d\n", error);
1126 error = ENXIO;
1127 goto done;
1128 }
1129
1130 sc->power_on = true;
1131
1132 TASK_INIT(&sc->suspend_task, 0, iichid_suspend_task, sc);
1133 #ifdef IICHID_SAMPLING
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,
1137 iichid_sampling_task, sc);
1138
1139 sc->sampling_rate_slow = -1;
1140 sc->sampling_rate_fast = IICHID_SAMPLING_RATE_FAST;
1141 sc->sampling_hysteresis = IICHID_SAMPLING_HYSTERESIS;
1142 #endif
1143
1144 sc->irq_rid = 0;
1145 sc->irq_res = bus_alloc_resource_any(sc->dev, SYS_RES_IRQ,
1146 &sc->irq_rid, RF_ACTIVE);
1147
1148 if (sc->irq_res != NULL) {
1149 DPRINTF(sc, "allocated irq at %p and rid %d\n",
1150 sc->irq_res, sc->irq_rid);
1151 error = iichid_setup_interrupt(sc);
1152 }
1153
1154 if (sc->irq_res == NULL || error != 0) {
1155 #ifdef IICHID_SAMPLING
1156 device_printf(sc->dev,
1157 "Using sampling mode\n");
1158 sc->sampling_rate_slow = IICHID_SAMPLING_RATE_SLOW;
1159 #else
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);
1164 error = ENXIO;
1165 goto done;
1166 #endif
1167 }
1168
1169 #ifdef IICHID_SAMPLING
1170 SYSCTL_ADD_PROC(device_get_sysctl_ctx(sc->dev),
1171 SYSCTL_CHILDREN(device_get_sysctl_tree(sc->dev)),
1172 OID_AUTO, "sampling_rate_slow", CTLTYPE_INT | CTLFLAG_RWTUN,
1173 sc, 0, iichid_sysctl_sampling_rate_handler, "I",
1174 "idle sampling rate in num/second");
1175 SYSCTL_ADD_INT(device_get_sysctl_ctx(sc->dev),
1176 SYSCTL_CHILDREN(device_get_sysctl_tree(sc->dev)),
1177 OID_AUTO, "sampling_rate_fast", CTLFLAG_RWTUN,
1178 &sc->sampling_rate_fast, 0,
1179 "active sampling rate in num/second");
1180 SYSCTL_ADD_INT(device_get_sysctl_ctx(sc->dev),
1181 SYSCTL_CHILDREN(device_get_sysctl_tree(sc->dev)),
1182 OID_AUTO, "sampling_hysteresis", CTLFLAG_RWTUN,
1183 &sc->sampling_hysteresis, 0,
1184 "number of missing samples before enabling of slow mode");
1185 hid_add_dynamic_quirk(&sc->hw, HQ_IICHID_SAMPLING);
1186
1187 if (sc->sampling_rate_slow >= 0) {
1188 pause("iichid", (hz + 999) / 1000);
1189 (void)iichid_cmd_read(sc, NULL, 0, NULL);
1190 }
1191 #endif /* IICHID_SAMPLING */
1192
1193 child = device_add_child(dev, "hidbus", DEVICE_UNIT_ANY);
1194 if (child == NULL) {
1195 device_printf(sc->dev, "Could not add I2C device\n");
1196 iichid_detach(dev);
1197 error = ENOMEM;
1198 goto done;
1199 }
1200
1201 device_set_ivars(child, &sc->hw);
1202 bus_attach_children(dev);
1203 error = 0;
1204 done:
1205 iicbus_request_bus(device_get_parent(dev), dev, IIC_WAIT);
1206 if (!sc->open) {
1207 (void)iichid_set_power(sc, I2C_HID_POWER_OFF);
1208 sc->power_on = false;
1209 }
1210 iicbus_release_bus(device_get_parent(dev), dev);
1211 return (error);
1212 }
1213
1214 static int
iichid_detach(device_t dev)1215 iichid_detach(device_t dev)
1216 {
1217 struct iichid_softc *sc;
1218 int error;
1219
1220 sc = device_get_softc(dev);
1221 error = device_delete_children(dev);
1222 if (error)
1223 return (error);
1224 iichid_teardown_interrupt(sc);
1225 if (sc->irq_res != NULL)
1226 bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid,
1227 sc->irq_res);
1228 #ifdef IICHID_SAMPLING
1229 if (sc->taskqueue != NULL)
1230 taskqueue_free(sc->taskqueue);
1231 sc->taskqueue = NULL;
1232 #endif
1233 return (0);
1234 }
1235
1236 static void
iichid_suspend_task(void * context,int pending)1237 iichid_suspend_task(void *context, int pending)
1238 {
1239 struct iichid_softc *sc = context;
1240
1241 iichid_teardown_interrupt(sc);
1242 }
1243
1244 static int
iichid_suspend(device_t dev)1245 iichid_suspend(device_t dev)
1246 {
1247 struct iichid_softc *sc;
1248 int error;
1249
1250 sc = device_get_softc(dev);
1251 (void)bus_generic_suspend(dev);
1252 /*
1253 * 8.2 - The HOST is going into a deep power optimized state and wishes
1254 * to put all the devices into a low power state also. The HOST
1255 * is recommended to issue a HIPO command to the DEVICE to force
1256 * the DEVICE in to a lower power state.
1257 */
1258 DPRINTF(sc, "Suspend called, setting device to power_state 1\n");
1259 error = iichid_set_power_state(sc, IICHID_PS_NULL, IICHID_PS_OFF);
1260 if (error != 0)
1261 DPRINTF(sc, "Could not set power_state, error: %d\n", error);
1262 else
1263 DPRINTF(sc, "Successfully set power_state\n");
1264
1265 #ifdef IICHID_SAMPLING
1266 if (sc->sampling_rate_slow < 0)
1267 #endif
1268 {
1269 /*
1270 * bus_teardown_intr can not be executed right here as it wants
1271 * to run on certain CPU to interacts with LAPIC while suspend
1272 * thread is bound to CPU0. So run it from taskqueue context.
1273 */
1274 #ifdef IICHID_SAMPLING
1275 #define suspend_thread sc->taskqueue
1276 #else
1277 #define suspend_thread taskqueue_thread
1278 #endif
1279 taskqueue_enqueue(suspend_thread, &sc->suspend_task);
1280 taskqueue_drain(suspend_thread, &sc->suspend_task);
1281 }
1282
1283 return (0);
1284 }
1285
1286 static int
iichid_resume(device_t dev)1287 iichid_resume(device_t dev)
1288 {
1289 struct iichid_softc *sc;
1290 int error;
1291
1292 sc = device_get_softc(dev);
1293 #ifdef IICHID_SAMPLING
1294 if (sc->sampling_rate_slow < 0)
1295 #endif
1296 iichid_setup_interrupt(sc);
1297
1298 DPRINTF(sc, "Resume called, setting device to power_state 0\n");
1299 error = iichid_set_power_state(sc, IICHID_PS_NULL, IICHID_PS_ON);
1300 if (error != 0)
1301 DPRINTF(sc, "Could not set power_state, error: %d\n", error);
1302 else
1303 DPRINTF(sc, "Successfully set power_state\n");
1304 (void)bus_generic_resume(dev);
1305
1306 return (0);
1307 }
1308
1309 static device_method_t iichid_methods[] = {
1310 DEVMETHOD(device_probe, iichid_probe),
1311 DEVMETHOD(device_attach, iichid_attach),
1312 DEVMETHOD(device_detach, iichid_detach),
1313 DEVMETHOD(device_suspend, iichid_suspend),
1314 DEVMETHOD(device_resume, iichid_resume),
1315
1316 DEVMETHOD(hid_intr_setup, iichid_intr_setup),
1317 DEVMETHOD(hid_intr_unsetup, iichid_intr_unsetup),
1318 DEVMETHOD(hid_intr_start, iichid_intr_start),
1319 DEVMETHOD(hid_intr_stop, iichid_intr_stop),
1320 DEVMETHOD(hid_intr_poll, iichid_intr_poll),
1321
1322 /* HID interface */
1323 DEVMETHOD(hid_get_rdesc, iichid_get_rdesc),
1324 DEVMETHOD(hid_read, iichid_read),
1325 DEVMETHOD(hid_write, iichid_write),
1326 DEVMETHOD(hid_get_report, iichid_get_report),
1327 DEVMETHOD(hid_set_report, iichid_set_report),
1328 DEVMETHOD(hid_set_idle, iichid_set_idle),
1329 DEVMETHOD(hid_set_protocol, iichid_set_protocol),
1330 DEVMETHOD(hid_ioctl, iichid_ioctl),
1331
1332 DEVMETHOD_END
1333 };
1334
1335 static driver_t iichid_driver = {
1336 .name = "iichid",
1337 .methods = iichid_methods,
1338 .size = sizeof(struct iichid_softc),
1339 };
1340
1341 DRIVER_MODULE(iichid, iicbus, iichid_driver, NULL, NULL);
1342 MODULE_DEPEND(iichid, iicbus, IICBUS_MINVER, IICBUS_PREFVER, IICBUS_MAXVER);
1343 MODULE_DEPEND(iichid, acpi, 1, 1, 1);
1344 MODULE_DEPEND(iichid, hid, 1, 1, 1);
1345 MODULE_DEPEND(iichid, hidbus, 1, 1, 1);
1346 MODULE_VERSION(iichid, 1);
1347 IICBUS_ACPI_PNP_INFO(iichid_ids);
1348