FreeBSD kernel usb device Code
cp2112.c
Go to the documentation of this file.
1/*-
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright (c) Andriy Gapon
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions, and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
19 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
27 */
28
29/*
30 * Hardware information links:
31 * - CP2112 Datasheet
32 * https://www.silabs.com/documents/public/data-sheets/cp2112-datasheet.pdf
33 * - AN495: CP2112 Interface Specification
34 * https://www.silabs.com/documents/public/application-notes/an495-cp2112-interface-specification.pdf
35 * - CP2112 Errata
36 * https://www.silabs.com/documents/public/errata/cp2112-errata.pdf
37 */
38
39#include <sys/cdefs.h>
40__FBSDID("$FreeBSD$");
41
42#include <sys/param.h>
43#include <sys/systm.h>
44#include <sys/condvar.h>
45#include <sys/bus.h>
46#include <sys/gpio.h>
47#include <sys/kernel.h>
48#include <sys/lock.h>
49#include <sys/module.h>
50#include <sys/mutex.h>
51#include <sys/sdt.h>
52#include <sys/sx.h>
53
54#include <dev/gpio/gpiobusvar.h>
55
56#include <dev/iicbus/iiconf.h>
57#include <dev/iicbus/iicbus.h>
58#include "iicbus_if.h"
59
60#include <dev/usb/usb.h>
61#include <dev/usb/usbdi.h>
62#include <dev/usb/usbdi_util.h>
63#include <dev/usb/usbhid.h>
64#include "usbdevs.h"
65
66#define USB_DEBUG_VAR usb_debug
67#include <dev/usb/usb_debug.h>
68
69#define SIZEOF_FIELD(_s, _f) sizeof(((struct _s *)NULL)->_f)
70
71#define CP2112GPIO_LOCK(sc) sx_xlock(&sc->gpio_lock)
72#define CP2112GPIO_UNLOCK(sc) sx_xunlock(&sc->gpio_lock)
73#define CP2112GPIO_LOCKED(sc) sx_assert(&sc->gpio_lock, SX_XLOCKED)
74
75#define CP2112_PART_NUM 0x0c
76#define CP2112_GPIO_COUNT 8
77#define CP2112_REPORT_SIZE 64
78
79#define CP2112_REQ_RESET 0x1
80#define CP2112_REQ_GPIO_CFG 0x2
81#define CP2112_REQ_GPIO_GET 0x3
82#define CP2112_REQ_GPIO_SET 0x4
83#define CP2112_REQ_VERSION 0x5
84#define CP2112_REQ_SMB_CFG 0x6
85
86#define CP2112_REQ_SMB_READ 0x10
87#define CP2112_REQ_SMB_WRITE_READ 0x11
88#define CP2112_REQ_SMB_READ_FORCE_SEND 0x12
89#define CP2112_REQ_SMB_READ_RESPONSE 0x13
90#define CP2112_REQ_SMB_WRITE 0x14
91#define CP2112_REQ_SMB_XFER_STATUS_REQ 0x15
92#define CP2112_REQ_SMB_XFER_STATUS_RESP 0x16
93#define CP2112_REQ_SMB_CANCEL 0x17
94
95#define CP2112_REQ_LOCK 0x20
96#define CP2112_REQ_USB_CFG 0x21
97
98#define CP2112_IIC_MAX_READ_LEN 512
99#define CP2112_IIC_REPSTART_VER 2 /* Erratum CP2112_E10. */
100
101#define CP2112_GPIO_SPEC_CLK7 1 /* Pin 7 is clock output. */
102#define CP2112_GPIO_SPEC_TX0 2 /* Pin 0 pulses on USB TX. */
103#define CP2112_GPIO_SPEC_RX1 4 /* Pin 1 pulses on USB RX. */
104
105#define CP2112_IIC_STATUS0_IDLE 0
106#define CP2112_IIC_STATUS0_BUSY 1
107#define CP2112_IIC_STATUS0_CMP 2
108#define CP2112_IIC_STATUS0_ERROR 3
109
110#define CP2112_IIC_STATUS1_TIMEOUT_NACK 0
111#define CP2112_IIC_STATUS1_TIMEOUT_BUS 1
112#define CP2112_IIC_STATUS1_ARB_LOST 2
113
114/* CP2112_REQ_VERSION */
116 uint8_t id;
117 uint8_t part_num;
118 uint8_t version;
120
121/* CP2112_REQ_GPIO_GET */
123 uint8_t id;
124 uint8_t state;
125} __packed;
126
127/* CP2112_REQ_GPIO_SET */
129 uint8_t id;
130 uint8_t state;
131 uint8_t mask;
132} __packed;
133
134/* CP2112_REQ_GPIO_CFG */
136 uint8_t id;
137 uint8_t output;
138 uint8_t pushpull;
139 uint8_t special;
140 uint8_t divider;
141} __packed;
142
143/* CP2112_REQ_SMB_XFER_STATUS_REQ */
145 uint8_t id;
146 uint8_t request;
147} __packed;
148
149/* CP2112_REQ_SMB_XFER_STATUS_RESP */
151 uint8_t id;
152 uint8_t status0;
153 uint8_t status1;
154 uint16_t status2;
155 uint16_t status3;
156} __packed;
157
158/* CP2112_REQ_SMB_READ_FORCE_SEND */
160 uint8_t id;
161 uint16_t len;
162} __packed;
163
164/* CP2112_REQ_SMB_READ_RESPONSE */
166 uint8_t id;
167 uint8_t status;
168 uint8_t len;
169 uint8_t data[61];
170} __packed;
171
172/* CP2112_REQ_SMB_READ */
174 uint8_t id;
175 uint8_t slave;
176 uint16_t rlen;
177 uint8_t wlen;
178 uint8_t wdata[16];
179} __packed;
180
181/* CP2112_REQ_SMB_WRITE */
183 uint8_t id;
184 uint8_t slave;
185 uint16_t len;
186} __packed;
187
188/* CP2112_REQ_SMB_WRITE_READ */
190 uint8_t id;
191 uint8_t slave;
192 uint8_t len;
193 uint8_t data[61];
194} __packed;
195
196/* CP2112_REQ_SMB_CFG */
198 uint8_t id;
199 uint32_t speed; /* Hz */
200 uint8_t slave_addr; /* ACK only */
201 uint8_t auto_send_read; /* boolean */
202 uint16_t write_timeout; /* 0-1000 ms, 0 ~ no timeout */
203 uint16_t read_timeout; /* 0-1000 ms, 0 ~ no timeout */
204 uint8_t scl_low_timeout;/* boolean */
205 uint16_t retry_count; /* 1-1000, 0 ~ forever */
206} __packed;
207
213
214enum {
218};
219
221 device_t sc_gpio_dev;
222 device_t sc_iic_dev;
225 uint8_t sc_version;
226};
227
229 struct sx gpio_lock;
230 device_t busdev;
232 struct gpio_pin pins[CP2112_GPIO_COUNT];
233};
234
236 device_t dev;
237 device_t iicbus_dev;
239 u_char own_addr;
240 struct {
241 struct mtx lock;
242 struct cv cv;
243 struct {
244 uint8_t *data;
245 int len;
246 int done;
247 int error;
248 } in;
249 struct {
250 const uint8_t *data;
251 int len;
252 int done;
253 int error;
255 } io;
256};
257
258static int cp2112_detach(device_t dev);
259static int cp2112gpio_detach(device_t dev);
260static int cp2112iic_detach(device_t dev);
261
263 { USB_VP(USB_VENDOR_SILABS, USB_PRODUCT_SILABS_CP2112) },
264 { USB_VP(0x1009, USB_PRODUCT_SILABS_CP2112) }, /* XXX */
265};
266
267static int
268cp2112_get_report(device_t dev, uint8_t id, void *data, uint16_t len)
269{
270 struct cp2112_softc *sc;
271 int err;
272
273 sc = device_get_softc(dev);
274 err = usbd_req_get_report(sc->sc_udev, NULL, data,
276 return (err);
277}
278
279static int
280cp2112_set_report(device_t dev, uint8_t id, void *data, uint16_t len)
281{
282 struct cp2112_softc *sc;
283 int err;
284
285 sc = device_get_softc(dev);
286 *(uint8_t *)data = id;
287 err = usbd_req_set_report(sc->sc_udev, NULL, data,
289 return (err);
290}
291
292static int
293cp2112_probe(device_t dev)
294{
295 struct usb_attach_arg *uaa;
296
297 uaa = device_get_ivars(dev);
298 if (uaa->usb_mode != USB_MODE_HOST)
299 return (ENXIO);
300 if (uaa->info.bInterfaceClass != UICLASS_HID)
301 return (ENXIO);
302
303 if (usbd_lookup_id_by_uaa(cp2112_devs, sizeof(cp2112_devs), uaa) == 0)
304 return (BUS_PROBE_DEFAULT);
305 return (ENXIO);
306}
307
308static int
309cp2112_attach(device_t dev)
310{
311 struct version_request vdata;
312 struct usb_attach_arg *uaa;
313 struct cp2112_softc *sc;
314 int err;
315
316 uaa = device_get_ivars(dev);
317 sc = device_get_softc(dev);
318
320
321 sc->sc_udev = uaa->device;
323
324 err = cp2112_get_report(dev, CP2112_REQ_VERSION, &vdata, sizeof(vdata));
325 if (err != 0)
326 goto detach;
327 device_printf(dev, "part number 0x%02x, version 0x%02x\n",
328 vdata.part_num, vdata.version);
329 if (vdata.part_num != CP2112_PART_NUM) {
330 device_printf(dev, "unsupported part number\n");
331 goto detach;
332 }
333 sc->sc_version = vdata.version;
334 sc->sc_gpio_dev = device_add_child(dev, "gpio", -1);
335 if (sc->sc_gpio_dev != NULL) {
336 err = device_probe_and_attach(sc->sc_gpio_dev);
337 if (err != 0) {
338 device_printf(dev, "failed to attach gpio child\n");
339 }
340 } else {
341 device_printf(dev, "failed to create gpio child\n");
342 }
343
344 sc->sc_iic_dev = device_add_child(dev, "iichb", -1);
345 if (sc->sc_iic_dev != NULL) {
346 err = device_probe_and_attach(sc->sc_iic_dev);
347 if (err != 0) {
348 device_printf(dev, "failed to attach iic child\n");
349 }
350 } else {
351 device_printf(dev, "failed to create iic child\n");
352 }
353
354 return (0);
355
356detach:
358 return (ENXIO);
359}
360
361static int
362cp2112_detach(device_t dev)
363{
364 int err;
365
366 err = bus_generic_detach(dev);
367 if (err != 0)
368 return (err);
369 device_delete_children(dev);
370 return (0);
371}
372
373static int
374cp2112_gpio_read_pin(device_t dev, uint32_t pin_num, bool *on)
375{
376 struct gpio_get_req data;
377 struct cp2112gpio_softc *sc;
378 int err;
379
380 sc = device_get_softc(dev);
382
383 err = cp2112_get_report(device_get_parent(dev),
384 CP2112_REQ_GPIO_GET, &data, sizeof(data));
385 if (err != 0)
386 return (err);
387 *on = (data.state & ((uint8_t)1 << pin_num)) != 0;
388 return (0);
389
390}
391
392static int
393cp2112_gpio_write_pin(device_t dev, uint32_t pin_num, bool on)
394{
395 struct gpio_set_req data;
396 struct cp2112gpio_softc *sc;
397 int err;
398 bool actual;
399
400 sc = device_get_softc(dev);
402
403 data.state = (uint8_t)on << pin_num;
404 data.mask = (uint8_t)1 << pin_num;
405 err = cp2112_set_report(device_get_parent(dev),
406 CP2112_REQ_GPIO_SET, &data, sizeof(data));
407 if (err != 0)
408 return (err);
409 err = cp2112_gpio_read_pin(dev, pin_num, &actual);
410 if (err != 0)
411 return (err);
412 if (actual != on)
413 return (EIO);
414 return (0);
415}
416
417static int
418cp2112_gpio_configure_write_pin(device_t dev, uint32_t pin_num,
419 bool output, enum cp2112_out_mode *mode)
420{
421 struct gpio_config_req data;
422 struct cp2112gpio_softc *sc;
423 int err;
424 uint8_t mask;
425
426 sc = device_get_softc(dev);
428
429 err = cp2112_get_report(device_get_parent(dev),
430 CP2112_REQ_GPIO_CFG, &data, sizeof(data));
431 if (err != 0)
432 return (err);
433
434 mask = (uint8_t)1 << pin_num;
435 if (output) {
436 data.output |= mask;
437 switch (*mode) {
438 case OUT_PP:
439 data.pushpull |= mask;
440 break;
441 case OUT_OD:
442 data.pushpull &= ~mask;
443 break;
444 default:
445 break;
446 }
447 } else {
448 data.output &= ~mask;
449 }
450
451 err = cp2112_set_report(device_get_parent(dev),
452 CP2112_REQ_GPIO_CFG, &data, sizeof(data));
453 if (err != 0)
454 return (err);
455
456 /* Read back and verify. */
457 err = cp2112_get_report(device_get_parent(dev),
458 CP2112_REQ_GPIO_CFG, &data, sizeof(data));
459 if (err != 0)
460 return (err);
461
462 if (((data.output & mask) != 0) != output)
463 return (EIO);
464 if (output) {
465 switch (*mode) {
466 case OUT_PP:
467 if ((data.pushpull & mask) == 0)
468 return (EIO);
469 break;
470 case OUT_OD:
471 if ((data.pushpull & mask) != 0)
472 return (EIO);
473 break;
474 default:
475 *mode = (data.pushpull & mask) != 0 ?
476 OUT_PP : OUT_OD;
477 break;
478 }
479 }
480 return (0);
481}
482
483static device_t
485{
486 struct cp2112gpio_softc *sc;
487
488 sc = device_get_softc(dev);
489 return (sc->busdev);
490}
491
492static int
493cp2112_gpio_pin_max(device_t dev, int *maxpin)
494{
495
496 *maxpin = CP2112_GPIO_COUNT - 1;
497 return (0);
498}
499
500static int
501cp2112_gpio_pin_set(device_t dev, uint32_t pin_num, uint32_t pin_value)
502{
503 struct cp2112gpio_softc *sc;
504 int err;
505
506 if (pin_num >= CP2112_GPIO_COUNT)
507 return (EINVAL);
508
509 sc = device_get_softc(dev);
510 CP2112GPIO_LOCK(sc);
511 err = cp2112_gpio_write_pin(dev, pin_num, pin_value != 0);
513
514 return (err);
515}
516
517static int
518cp2112_gpio_pin_get(device_t dev, uint32_t pin_num, uint32_t *pin_value)
519{
520 struct cp2112gpio_softc *sc;
521 int err;
522 bool on;
523
524 if (pin_num >= CP2112_GPIO_COUNT)
525 return (EINVAL);
526
527 sc = device_get_softc(dev);
528 CP2112GPIO_LOCK(sc);
529 err = cp2112_gpio_read_pin(dev, pin_num, &on);
531
532 if (err == 0)
533 *pin_value = on;
534 return (err);
535}
536
537static int
538cp2112_gpio_pin_toggle(device_t dev, uint32_t pin_num)
539{
540 struct cp2112gpio_softc *sc;
541 int err;
542 bool on;
543
544 if (pin_num >= CP2112_GPIO_COUNT)
545 return (EINVAL);
546
547 sc = device_get_softc(dev);
548 CP2112GPIO_LOCK(sc);
549 err = cp2112_gpio_read_pin(dev, pin_num, &on);
550 if (err == 0)
551 err = cp2112_gpio_write_pin(dev, pin_num, !on);
553
554 return (err);
555}
556
557static int
558cp2112_gpio_pin_getcaps(device_t dev, uint32_t pin_num, uint32_t *caps)
559{
560 struct cp2112gpio_softc *sc;
561
562 if (pin_num >= CP2112_GPIO_COUNT)
563 return (EINVAL);
564
565 sc = device_get_softc(dev);
566 CP2112GPIO_LOCK(sc);
567 *caps = sc->gpio_caps;
569
570 return (0);
571}
572
573static int
574cp2112_gpio_pin_getflags(device_t dev, uint32_t pin_num, uint32_t *flags)
575{
576 struct cp2112gpio_softc *sc;
577
578 if (pin_num >= CP2112_GPIO_COUNT)
579 return (EINVAL);
580
581 sc = device_get_softc(dev);
582 CP2112GPIO_LOCK(sc);
583 *flags = sc->pins[pin_num].gp_flags;
585
586 return (0);
587}
588
589static int
590cp2112_gpio_pin_getname(device_t dev, uint32_t pin_num, char *name)
591{
592 struct cp2112gpio_softc *sc;
593
594 if (pin_num >= CP2112_GPIO_COUNT)
595 return (EINVAL);
596
597 sc = device_get_softc(dev);
598 CP2112GPIO_LOCK(sc);
599 memcpy(name, sc->pins[pin_num].gp_name, GPIOMAXNAME);
601
602 return (0);
603}
604
605static int
606cp2112_gpio_pin_setflags(device_t dev, uint32_t pin_num, uint32_t flags)
607{
608 struct cp2112gpio_softc *sc;
609 struct gpio_pin *pin;
610 enum cp2112_out_mode out_mode;
611 int err;
612
613 if (pin_num >= CP2112_GPIO_COUNT)
614 return (EINVAL);
615
616 sc = device_get_softc(dev);
617 if ((flags & sc->gpio_caps) != flags)
618 return (EINVAL);
619
620 if ((flags & (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT)) == 0)
621 return (EINVAL);
622 if ((flags & (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT)) ==
623 (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT)) {
624 return (EINVAL);
625 }
626 if ((flags & GPIO_PIN_INPUT) != 0) {
627 if ((flags & (GPIO_PIN_OPENDRAIN | GPIO_PIN_PUSHPULL)) != 0)
628 return (EINVAL);
629 } else {
630 if ((flags & (GPIO_PIN_OPENDRAIN | GPIO_PIN_PUSHPULL)) ==
631 (GPIO_PIN_OPENDRAIN | GPIO_PIN_PUSHPULL))
632 return (EINVAL);
633 }
634
635 /*
636 * If neither push-pull or open-drain is explicitly requested, then
637 * preserve the current state.
638 */
639 out_mode = OUT_KEEP;
640 if ((flags & GPIO_PIN_OUTPUT) != 0) {
641 if ((flags & GPIO_PIN_OPENDRAIN) != 0)
642 out_mode = OUT_OD;
643 if ((flags & GPIO_PIN_PUSHPULL) != 0)
644 out_mode = OUT_PP;
645 }
646
647 CP2112GPIO_LOCK(sc);
648 pin = &sc->pins[pin_num];
650 (flags & GPIO_PIN_OUTPUT) != 0, &out_mode);
651 if (err == 0) {
652 /*
653 * If neither open-drain or push-pull was requested, then see
654 * what hardware actually had. Otherwise, it has been
655 * reconfigured as requested.
656 */
657 if ((flags & GPIO_PIN_OUTPUT) != 0 &&
658 (flags & (GPIO_PIN_OPENDRAIN | GPIO_PIN_PUSHPULL)) == 0) {
659 KASSERT(out_mode != OUT_KEEP,
660 ("impossible current output mode"));
661 if (out_mode == OUT_OD)
662 flags |= GPIO_PIN_OPENDRAIN;
663 else
664 flags |= GPIO_PIN_PUSHPULL;
665 }
666 pin->gp_flags = flags;
667 }
669
670 return (err);
671}
672
673static int
674cp2112gpio_probe(device_t dev)
675{
676 device_set_desc(dev, "CP2112 GPIO interface");
677 return (BUS_PROBE_SPECIFIC);
678}
679
680static int
681cp2112gpio_attach(device_t dev)
682{
683 struct gpio_config_req data;
684 struct cp2112gpio_softc *sc;
685 device_t cp2112;
686 int err;
687 int i;
688 uint8_t mask;
689
690 cp2112 = device_get_parent(dev);
691 sc = device_get_softc(dev);
692 sx_init(&sc->gpio_lock, "cp2112 lock");
693
694 sc->gpio_caps = GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | GPIO_PIN_OPENDRAIN |
695 GPIO_PIN_PUSHPULL;
696
698 &data, sizeof(data));
699 if (err != 0)
700 goto detach;
701
702 for (i = 0; i < CP2112_GPIO_COUNT; i++) {
703 struct gpio_pin *pin;
704
705 mask = (uint8_t)1 << i;
706 pin = &sc->pins[i];
707 pin->gp_flags = 0;
708
709 snprintf(pin->gp_name, GPIOMAXNAME, "GPIO%u", i);
710 pin->gp_name[GPIOMAXNAME - 1] = '\0';
711
712 if ((i == 0 && (data.special & CP2112_GPIO_SPEC_TX0) != 0) ||
713 (i == 1 && (data.special & CP2112_GPIO_SPEC_RX1) != 0) ||
714 (i == 7 && (data.special & CP2112_GPIO_SPEC_CLK7) != 0)) {
715 /* Special mode means that a pin is not for GPIO. */
716 } else if ((data.output & mask) != 0) {
717 pin->gp_flags |= GPIO_PIN_OUTPUT;
718 if ((data.pushpull & mask) != 0)
719 pin->gp_flags |= GPIO_PIN_PUSHPULL;
720 else
721 pin->gp_flags |= GPIO_PIN_OPENDRAIN;
722 } else {
723 pin->gp_flags |= GPIO_PIN_INPUT;
724 }
725 }
726
727 sc->busdev = gpiobus_attach_bus(dev);
728 if (sc->busdev == NULL) {
729 device_printf(dev, "gpiobus_attach_bus failed\n");
730 goto detach;
731 }
732 return (0);
733
734detach:
736 return (ENXIO);
737}
738
739static int
740cp2112gpio_detach(device_t dev)
741{
742 struct cp2112gpio_softc *sc;
743
744 sc = device_get_softc(dev);
745 if (sc->busdev != NULL)
746 gpiobus_detach_bus(dev);
747 sx_destroy(&sc->gpio_lock);
748 return (0);
749}
750
751static void
753{
754 struct cp2112iic_softc *sc;
755 struct cp2112_softc *psc;
756 struct usb_page_cache *pc;
757
758 sc = usbd_xfer_softc(xfer);
759 psc = device_get_softc(device_get_parent(sc->dev));
760
761 mtx_assert(&sc->io.lock, MA_OWNED);
762
763 switch (USB_GET_STATE(xfer)) {
764 case USB_ST_SETUP:
765 pc = usbd_xfer_get_frame(xfer, 0);
766 usbd_copy_in(pc, 0, sc->io.out.data, sc->io.out.len);
767 usbd_xfer_set_frame_len(xfer, 0, sc->io.out.len);
768 usbd_xfer_set_frames(xfer, 1);
770 break;
772 sc->io.out.error = 0;
773 sc->io.out.done = 1;
774 cv_signal(&sc->io.cv);
775 break;
776 default: /* Error */
777 device_printf(sc->dev, "write intr state %d error %d\n",
778 USB_GET_STATE(xfer), error);
779 sc->io.out.error = IIC_EBUSERR;
780 cv_signal(&sc->io.cv);
781 if (error != USB_ERR_CANCELLED) {
782 /* try to clear stall first */
784 }
785 break;
786 }
787}
788
789static void
791{
792 struct cp2112iic_softc *sc = usbd_xfer_softc(xfer);
793 struct usb_page_cache *pc;
794 int act_len, len;
795
796 mtx_assert(&sc->io.lock, MA_OWNED);
797 usbd_xfer_status(xfer, &act_len, NULL, NULL, NULL);
798
799 switch (USB_GET_STATE(xfer)) {
801 if (sc->io.in.done) {
802 device_printf(sc->dev,
803 "interrupt while previous is pending, ignored\n");
804 } else if (sc->io.in.len == 0) {
805 uint8_t buf[8];
806
807 /*
808 * There is a spurious Transfer Status Response and
809 * zero-length Read Response during hardware
810 * configuration. Possibly they carry some information
811 * about the initial bus state.
812 */
813 if (device_is_attached(sc->dev)) {
814 device_printf(sc->dev,
815 "unsolicited interrupt, ignored\n");
816 if (bootverbose) {
817 pc = usbd_xfer_get_frame(xfer, 0);
818 len = MIN(sizeof(buf), act_len);
819 usbd_copy_out(pc, 0, buf, len);
820 device_printf(sc->dev, "data: %*D\n",
821 len, buf, " ");
822 }
823 } else {
824 pc = usbd_xfer_get_frame(xfer, 0);
825 len = MIN(sizeof(buf), act_len);
826 usbd_copy_out(pc, 0, buf, len);
827 if (buf[0] == CP2112_REQ_SMB_XFER_STATUS_RESP) {
828 device_printf(sc->dev,
829 "initial bus status0 = 0x%02x, "
830 "status1 = 0x%02x\n",
831 buf[1], buf[2]);
832 }
833 }
834 } else if (act_len == CP2112_REPORT_SIZE) {
835 pc = usbd_xfer_get_frame(xfer, 0);
836 usbd_copy_out(pc, 0, sc->io.in.data, sc->io.in.len);
837 sc->io.in.error = 0;
838 sc->io.in.done = 1;
839 } else {
840 device_printf(sc->dev,
841 "unexpected input report length %u\n", act_len);
842 sc->io.in.error = IIC_EBUSERR;
843 sc->io.in.done = 1;
844 }
845 cv_signal(&sc->io.cv);
846 case USB_ST_SETUP:
847tr_setup:
850 break;
851
852 default: /* Error */
853 device_printf(sc->dev, "read intr state %d error %d\n",
854 USB_GET_STATE(xfer), error);
855
856 sc->io.in.error = IIC_EBUSERR;
857 sc->io.in.done = 1;
858 cv_signal(&sc->io.cv);
859 if (error != USB_ERR_CANCELLED) {
860 /* try to clear stall first */
862 goto tr_setup;
863 }
864 break;
865 }
866}
867
869 [CP2112_INTR_OUT] = {
871 .endpoint = UE_ADDR_ANY,
872 .direction = UE_DIR_OUT,
873 .flags = { .pipe_bof = 1, .no_pipe_ok = 1, },
874 .bufsize = 0, /* use wMaxPacketSize */
876 },
877 [CP2112_INTR_IN] = {
878 .type = UE_INTERRUPT,
879 .endpoint = UE_ADDR_ANY,
880 .direction = UE_DIR_IN,
881 .flags = { .pipe_bof = 1, .short_xfer_ok = 1, },
882 .bufsize = 0, /* use wMaxPacketSize */
883 .callback = &cp2112iic_intr_read_callback,
884 },
885};
886
887static int
888cp2112iic_send_req(struct cp2112iic_softc *sc, const void *data,
889 uint16_t len)
890{
891 int err;
892
893 mtx_assert(&sc->io.lock, MA_OWNED);
894 KASSERT(sc->io.out.done == 0, ("%s: conflicting request", __func__));
895
896 sc->io.out.data = data;
897 sc->io.out.len = len;
898
899 DTRACE_PROBE1(send__req, uint8_t, *(const uint8_t *)data);
900
902
903 while (!sc->io.out.done)
904 cv_wait(&sc->io.cv, &sc->io.lock);
905
907
908 sc->io.out.done = 0;
909 sc->io.out.data = NULL;
910 sc->io.out.len = 0;
911 err = sc->io.out.error;
912 if (err != 0) {
913 device_printf(sc->dev, "output report 0x%02x failed: %d\n",
914 *(const uint8_t*)data, err);
915 }
916 return (err);
917}
918
919static int
920cp2112iic_req_resp(struct cp2112iic_softc *sc, const void *req_data,
921 uint16_t req_len, void *resp_data, uint16_t resp_len)
922{
923 int err;
924
925 mtx_assert(&sc->io.lock, MA_OWNED);
926
927 /*
928 * Prepare to receive a response interrupt even before the
929 * request transfer is confirmed (USB_ST_TRANSFERED).
930 */
931 KASSERT(sc->io.in.done == 0, ("%s: conflicting request", __func__));
932 sc->io.in.len = resp_len;
933 sc->io.in.data = resp_data;
934
935 err = cp2112iic_send_req(sc, req_data, req_len);
936 if (err != 0) {
937 sc->io.in.len = 0;
938 sc->io.in.data = NULL;
939 return (err);
940 }
941
942 while (!sc->io.in.done)
943 cv_wait(&sc->io.cv, &sc->io.lock);
944
945 err = sc->io.in.error;
946 sc->io.in.done = 0;
947 sc->io.in.error = 0;
948 sc->io.in.len = 0;
949 sc->io.in.data = NULL;
950 return (err);
951}
952
953static int
955{
956 struct i2c_xfer_status_req xfer_status_req;
957 struct i2c_xfer_status_resp xfer_status_resp;
958 int err;
959
960 mtx_assert(&sc->io.lock, MA_OWNED);
961
962 do {
963 xfer_status_req.id = CP2112_REQ_SMB_XFER_STATUS_REQ;
964 xfer_status_req.request = 1;
965 err = cp2112iic_req_resp(sc,
966 &xfer_status_req, sizeof(xfer_status_req),
967 &xfer_status_resp, sizeof(xfer_status_resp));
968
969 if (xfer_status_resp.id != CP2112_REQ_SMB_XFER_STATUS_RESP) {
970 device_printf(sc->dev,
971 "unexpected response 0x%02x to status request\n",
972 xfer_status_resp.id);
973 err = IIC_EBUSERR;
974 goto out;
975 }
976
977 DTRACE_PROBE4(xfer__status, uint8_t, xfer_status_resp.status0,
978 uint8_t, xfer_status_resp.status1,
979 uint16_t, be16toh(xfer_status_resp.status2),
980 uint16_t, be16toh(xfer_status_resp.status3));
981
982 switch (xfer_status_resp.status0) {
984 err = IIC_ESTATUS;
985 break;
987 err = ERESTART; /* non-I2C, special handling */
988 break;
990 err = IIC_NOERR;
991 break;
993 switch (xfer_status_resp.status1) {
995 err = IIC_ENOACK;
996 break;
998 err = IIC_ETIMEOUT;
999 break;
1001 err = IIC_EBUSBSY;
1002 break;
1003 default:
1004 device_printf(sc->dev,
1005 "i2c error, status = 0x%02x\n",
1006 xfer_status_resp.status1);
1007 err = IIC_ESTATUS;
1008 break;
1009 }
1010 break;
1011 default:
1012 device_printf(sc->dev,
1013 "unknown i2c xfer status0 0x%02x\n",
1014 xfer_status_resp.status0);
1015 err = IIC_EBUSERR;
1016 break;
1017 }
1018
1019 } while (err == ERESTART);
1020out:
1021 return (err);
1022}
1023
1024static int
1025cp2112iic_read_data(struct cp2112iic_softc *sc, void *data, uint16_t in_len,
1026 uint16_t *out_len)
1027{
1028 struct i2c_data_read_force_send_req data_read_force_send;
1029 struct i2c_data_read_resp data_read_resp;
1030 int err;
1031
1032 mtx_assert(&sc->io.lock, MA_OWNED);
1033
1034 /*
1035 * Prepare to receive a response interrupt even before the request
1036 * transfer is confirmed (USB_ST_TRANSFERED).
1037 */
1038
1039 if (in_len > sizeof(data_read_resp.data))
1040 in_len = sizeof(data_read_resp.data);
1041 data_read_force_send.id = CP2112_REQ_SMB_READ_FORCE_SEND;
1042 data_read_force_send.len = htobe16(in_len);
1043 err = cp2112iic_req_resp(sc,
1044 &data_read_force_send, sizeof(data_read_force_send),
1045 &data_read_resp, sizeof(data_read_resp));
1046 if (err != 0)
1047 goto out;
1048
1049 if (data_read_resp.id != CP2112_REQ_SMB_READ_RESPONSE) {
1050 device_printf(sc->dev,
1051 "unexpected response 0x%02x to data read request\n",
1052 data_read_resp.id);
1053 err = IIC_EBUSERR;
1054 goto out;
1055 }
1056
1057 DTRACE_PROBE2(read__response, uint8_t, data_read_resp.status,
1058 uint8_t, data_read_resp.len);
1059
1060 /*
1061 * We expect either the request completed status or, more typical for
1062 * this driver, the bus idle status because of the preceding
1063 * Force Read Status command (which is not an I2C request).
1064 */
1065 if (data_read_resp.status != CP2112_IIC_STATUS0_CMP &&
1066 data_read_resp.status != CP2112_IIC_STATUS0_IDLE) {
1067 err = IIC_EBUSERR;
1068 goto out;
1069 }
1070 if (data_read_resp.len > in_len) {
1071 device_printf(sc->dev, "device returns more data than asked\n");
1072 err = IIC_EOVERFLOW;
1073 goto out;
1074 }
1075
1076 *out_len = data_read_resp.len;
1077 if (*out_len > 0)
1078 memcpy(data, data_read_resp.data, *out_len);
1079out:
1080 return (err);
1081}
1082
1083static int
1084cp2112iic_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs)
1085{
1086 struct cp2112iic_softc *sc = device_get_softc(dev);
1087 struct cp2112_softc *psc = device_get_softc(device_get_parent(dev));
1088 const char *reason = NULL;
1089 uint32_t i;
1090 uint16_t read_off, to_read;
1091 int err;
1092
1093 /*
1094 * The hardware interface imposes limits on allowed I2C messages.
1095 * It is not possible to explicitly send a start or stop.
1096 * It is not possible to do a zero length transfer.
1097 * For this reason it's impossible to send a message with no data
1098 * at all (like an SMBus quick message).
1099 * Each read or write transfer beginning with the start condition
1100 * and ends with the stop condition. The only exception is that
1101 * it is possible to have a write transfer followed by a read
1102 * transfer to the same slave with the repeated start condition
1103 * between them.
1104 */
1105 for (i = 0; i < nmsgs; i++) {
1106 if (i == 0 && (msgs[i].flags & IIC_M_NOSTART) != 0) {
1107 reason = "first message without start";
1108 break;
1109 }
1110 if (i == nmsgs - 1 && (msgs[i].flags & IIC_M_NOSTOP) != 0) {
1111 reason = "last message without stop";
1112 break;
1113 }
1114 if (msgs[i].len == 0) {
1115 reason = "message with no data";
1116 break;
1117 }
1118 if ((msgs[i].flags & IIC_M_RD) != 0 &&
1119 msgs[i].len > CP2112_IIC_MAX_READ_LEN) {
1120 reason = "too long read";
1121 break;
1122 }
1123 if ((msgs[i].flags & IIC_M_RD) == 0 &&
1124 msgs[i].len > SIZEOF_FIELD(i2c_write_req, data)) {
1125 reason = "too long write";
1126 break;
1127 }
1128 if ((msgs[i].flags & IIC_M_NOSTART) != 0) {
1129 reason = "message without start or repeated start";
1130 break;
1131 }
1132 if ((msgs[i].flags & IIC_M_NOSTOP) != 0 &&
1133 (msgs[i].flags & IIC_M_RD) != 0) {
1134 reason = "read without stop";
1135 break;
1136 }
1137 if ((msgs[i].flags & IIC_M_NOSTOP) != 0 &&
1139 reason = "write without stop";
1140 break;
1141 }
1142 if ((msgs[i].flags & IIC_M_NOSTOP) != 0 &&
1143 msgs[i].len > SIZEOF_FIELD(i2c_write_read_req, wdata)) {
1144 reason = "too long write without stop";
1145 break;
1146 }
1147 if (i > 0) {
1148 if ((msgs[i - 1].flags & IIC_M_NOSTOP) != 0 &&
1149 msgs[i].slave != msgs[i - 1].slave) {
1150 reason = "change of slave without stop";
1151 break;
1152 }
1153 if ((msgs[i - 1].flags & IIC_M_NOSTOP) != 0 &&
1154 (msgs[i].flags & IIC_M_RD) == 0) {
1155 reason = "write after repeated start";
1156 break;
1157 }
1158 }
1159 }
1160 if (reason != NULL) {
1161 if (bootverbose)
1162 device_printf(dev, "unsupported i2c message: %s\n",
1163 reason);
1164 return (IIC_ENOTSUPP);
1165 }
1166
1167 mtx_lock(&sc->io.lock);
1168
1169 for (i = 0; i < nmsgs; i++) {
1170 if (i + 1 < nmsgs && (msgs[i].flags & IIC_M_NOSTOP) != 0) {
1171 /*
1172 * Combine <write><repeated start><read> into a single
1173 * CP2112 operation.
1174 */
1175 struct i2c_write_read_req req;
1176
1177 KASSERT((msgs[i].flags & IIC_M_RD) == 0,
1178 ("read without stop"));
1179 KASSERT((msgs[i + 1].flags & IIC_M_RD) != 0,
1180 ("write after write without stop"));
1182 req.slave = msgs[i].slave & ~LSB;
1183 to_read = msgs[i + 1].len;
1184 req.rlen = htobe16(to_read);
1185 req.wlen = msgs[i].len;
1186 memcpy(req.wdata, msgs[i].buf, msgs[i].len);
1187 err = cp2112iic_send_req(sc, &req, msgs[i].len + 5);
1188
1189 /*
1190 * The next message is already handled.
1191 * Also needed for read data to go into the right msg.
1192 */
1193 i++;
1194 } else if ((msgs[i].flags & IIC_M_RD) != 0) {
1195 struct i2c_read_req req;
1196
1198 req.slave = msgs[i].slave & ~LSB;
1199 to_read = msgs[i].len;
1200 req.len = htobe16(to_read);
1201 err = cp2112iic_send_req(sc, &req, sizeof(req));
1202 } else {
1203 struct i2c_write_req req;
1204
1206 req.slave = msgs[i].slave & ~LSB;
1207 req.len = msgs[i].len;
1208 memcpy(req.data, msgs[i].buf, msgs[i].len);
1209 to_read = 0;
1210 err = cp2112iic_send_req(sc, &req, msgs[i].len + 3);
1211 }
1212 if (err != 0)
1213 break;
1214
1216 if (err != 0)
1217 break;
1218
1219 read_off = 0;
1220 while (to_read > 0) {
1221 uint16_t act_read;
1222
1223 err = cp2112iic_read_data(sc, msgs[i].buf + read_off,
1224 to_read, &act_read);
1225 if (err != 0)
1226 break;
1227 KASSERT(act_read <= to_read, ("cp2112iic_read_data "
1228 "returned more data than asked"));
1229 read_off += act_read;
1230 to_read -= act_read;
1231 }
1232 if (err != 0)
1233 break;
1234 }
1235
1236 mtx_unlock(&sc->io.lock);
1237 return (err);
1238}
1239
1240static int
1241cp2112iic_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr)
1242{
1243 struct i2c_cfg_req i2c_cfg;
1244 struct cp2112iic_softc *sc;
1245 device_t cp2112;
1246 u_int busfreq;
1247 int err;
1248
1249 sc = device_get_softc(dev);
1250 cp2112 = device_get_parent(dev);
1251 if (sc->iicbus_dev == NULL)
1252 busfreq = 100000;
1253 else
1254 busfreq = IICBUS_GET_FREQUENCY(sc->iicbus_dev, speed);
1255
1257 &i2c_cfg, sizeof(i2c_cfg));
1258 if (err != 0) {
1259 device_printf(dev, "failed to get CP2112_REQ_SMB_CFG report\n");
1260 return (err);
1261 }
1262
1263 if (oldaddr != NULL)
1264 *oldaddr = i2c_cfg.slave_addr;
1265 /*
1266 * For simplicity we do not enable Auto Send Read
1267 * because of erratum CP2112_E101 (fixed in version 3).
1268 *
1269 * TODO: set I2C parameters based on configuration preferences:
1270 * - read and write timeouts (no timeout by default),
1271 * - SCL low timeout (disabled by default),
1272 * etc.
1273 *
1274 * TODO: should the device reset request (0x01) be sent?
1275 * If the device disconnects as a result, then no.
1276 */
1277 i2c_cfg.speed = htobe32(busfreq);
1278 if (addr != 0)
1279 i2c_cfg.slave_addr = addr;
1280 i2c_cfg.auto_send_read = 0;
1281 i2c_cfg.retry_count = htobe16(1);
1282 i2c_cfg.scl_low_timeout = 0;
1283 if (bootverbose) {
1284 device_printf(dev, "speed %d Hz\n", be32toh(i2c_cfg.speed));
1285 device_printf(dev, "slave addr 0x%02x\n", i2c_cfg.slave_addr);
1286 device_printf(dev, "auto send read %s\n",
1287 i2c_cfg.auto_send_read ? "on" : "off");
1288 device_printf(dev, "write timeout %d ms (0 - disabled)\n",
1289 be16toh(i2c_cfg.write_timeout));
1290 device_printf(dev, "read timeout %d ms (0 - disabled)\n",
1291 be16toh(i2c_cfg.read_timeout));
1292 device_printf(dev, "scl low timeout %s\n",
1293 i2c_cfg.scl_low_timeout ? "on" : "off");
1294 device_printf(dev, "retry count %d (0 - no limit)\n",
1295 be16toh(i2c_cfg.retry_count));
1296 }
1298 &i2c_cfg, sizeof(i2c_cfg));
1299 if (err != 0) {
1300 device_printf(dev, "failed to set CP2112_REQ_SMB_CFG report\n");
1301 return (err);
1302 }
1303 return (0);
1304}
1305
1306static int
1308{
1309 device_set_desc(dev, "CP2112 I2C interface");
1310 return (BUS_PROBE_SPECIFIC);
1311}
1312
1313static int
1315{
1316 struct cp2112iic_softc *sc;
1317 struct cp2112_softc *psc;
1318 device_t cp2112;
1319 int err;
1320
1321 sc = device_get_softc(dev);
1322 sc->dev = dev;
1323 cp2112 = device_get_parent(dev);
1324 psc = device_get_softc(cp2112);
1325
1326 mtx_init(&sc->io.lock, "cp2112iic lock", NULL, MTX_DEF | MTX_RECURSE);
1327 cv_init(&sc->io.cv, "cp2112iic cv");
1328
1329 err = usbd_transfer_setup(psc->sc_udev,
1331 nitems(cp2112iic_config), sc, &sc->io.lock);
1332 if (err != 0) {
1333 device_printf(dev, "usbd_transfer_setup failed %d\n", err);
1334 goto detach;
1335 }
1336
1337 /* Prepare to receive interrupts. */
1338 mtx_lock(&sc->io.lock);
1340 mtx_unlock(&sc->io.lock);
1341
1342 sc->iicbus_dev = device_add_child(dev, "iicbus", -1);
1343 if (sc->iicbus_dev == NULL) {
1344 device_printf(dev, "iicbus creation failed\n");
1345 err = ENXIO;
1346 goto detach;
1347 }
1348 bus_generic_attach(dev);
1349 return (0);
1350
1351detach:
1353 return (err);
1354}
1355
1356static int
1357cp2112iic_detach(device_t dev)
1358{
1359 struct cp2112iic_softc *sc;
1360 int err;
1361
1362 sc = device_get_softc(dev);
1363 err = bus_generic_detach(dev);
1364 if (err != 0)
1365 return (err);
1366 device_delete_children(dev);
1367
1368 mtx_lock(&sc->io.lock);
1370 mtx_unlock(&sc->io.lock);
1372
1373 cv_destroy(&sc->io.cv);
1374 mtx_destroy(&sc->io.lock);
1375
1376 return (0);
1377}
1378
1379static device_method_t cp2112hid_methods[] = {
1380 DEVMETHOD(device_probe, cp2112_probe),
1381 DEVMETHOD(device_attach, cp2112_attach),
1382 DEVMETHOD(device_detach, cp2112_detach),
1383
1384 DEVMETHOD_END
1385};
1386
1387static driver_t cp2112hid_driver = {
1388 .name = "cp2112hid",
1389 .methods = cp2112hid_methods,
1390 .size = sizeof(struct cp2112_softc),
1391};
1392
1393static devclass_t cp2112hid_devclass;
1395 NULL, NULL);
1396MODULE_DEPEND(cp2112hid, usb, 1, 1, 1);
1397MODULE_VERSION(cp2112hid, 1);
1399
1400static device_method_t cp2112gpio_methods[] = {
1401 /* Device */
1402 DEVMETHOD(device_probe, cp2112gpio_probe),
1403 DEVMETHOD(device_attach, cp2112gpio_attach),
1404 DEVMETHOD(device_detach, cp2112gpio_detach),
1405
1406 /* GPIO */
1407 DEVMETHOD(gpio_get_bus, cp2112_gpio_get_bus),
1408 DEVMETHOD(gpio_pin_max, cp2112_gpio_pin_max),
1409 DEVMETHOD(gpio_pin_get, cp2112_gpio_pin_get),
1410 DEVMETHOD(gpio_pin_set, cp2112_gpio_pin_set),
1411 DEVMETHOD(gpio_pin_toggle, cp2112_gpio_pin_toggle),
1412 DEVMETHOD(gpio_pin_getname, cp2112_gpio_pin_getname),
1413 DEVMETHOD(gpio_pin_getcaps, cp2112_gpio_pin_getcaps),
1414 DEVMETHOD(gpio_pin_getflags, cp2112_gpio_pin_getflags),
1415 DEVMETHOD(gpio_pin_setflags, cp2112_gpio_pin_setflags),
1416
1417 DEVMETHOD_END
1418};
1419
1420static driver_t cp2112gpio_driver = {
1421 .name = "gpio",
1422 .methods = cp2112gpio_methods,
1423 .size = sizeof(struct cp2112gpio_softc),
1424};
1425
1426static devclass_t cp2112gpio_devclass;
1428 NULL, NULL);
1429MODULE_DEPEND(cp2112gpio, cp2112hid, 1, 1, 1);
1430MODULE_DEPEND(cp2112gpio, gpiobus, 1, 1, 1);
1431MODULE_VERSION(cp2112gpio, 1);
1432
1433static device_method_t cp2112iic_methods[] = {
1434 /* Device interface */
1435 DEVMETHOD(device_probe, cp2112iic_probe),
1436 DEVMETHOD(device_attach, cp2112iic_attach),
1437 DEVMETHOD(device_detach, cp2112iic_detach),
1438
1439 /* I2C methods */
1440 DEVMETHOD(iicbus_transfer, cp2112iic_transfer),
1441 DEVMETHOD(iicbus_reset, cp2112iic_reset),
1442 DEVMETHOD(iicbus_callback, iicbus_null_callback),
1443
1444 DEVMETHOD_END
1445};
1446
1447static driver_t cp2112iic_driver = {
1448 "iichb",
1450 sizeof(struct cp2112iic_softc)
1451};
1452
1453static devclass_t cp2112iic_devclass;
1455 NULL, NULL);
1456MODULE_DEPEND(cp2112iic, cp2112hid, 1, 1, 1);
1457MODULE_DEPEND(cp2112iic, iicbus, IICBUS_MINVER, IICBUS_PREFVER, IICBUS_MAXVER);
1458MODULE_VERSION(cp2112iic, 1);
cp2112_out_mode
Definition: cp2112.c:208
@ OUT_PP
Definition: cp2112.c:210
@ OUT_KEEP
Definition: cp2112.c:211
@ OUT_OD
Definition: cp2112.c:209
static device_method_t cp2112hid_methods[]
Definition: cp2112.c:1379
#define CP2112_GPIO_COUNT
Definition: cp2112.c:76
#define CP2112_REQ_SMB_READ_FORCE_SEND
Definition: cp2112.c:88
#define CP2112_IIC_STATUS1_ARB_LOST
Definition: cp2112.c:112
USB_PNP_HOST_INFO(cp2112_devs)
static int cp2112iic_check_req_status(struct cp2112iic_softc *sc)
Definition: cp2112.c:954
#define CP2112GPIO_LOCKED(sc)
Definition: cp2112.c:73
#define CP2112_REQ_SMB_CFG
Definition: cp2112.c:84
#define CP2112_GPIO_SPEC_TX0
Definition: cp2112.c:102
static int cp2112iic_attach(device_t dev)
Definition: cp2112.c:1314
static int cp2112_gpio_pin_getname(device_t dev, uint32_t pin_num, char *name)
Definition: cp2112.c:590
static driver_t cp2112hid_driver
Definition: cp2112.c:1387
static int cp2112_gpio_pin_getcaps(device_t dev, uint32_t pin_num, uint32_t *caps)
Definition: cp2112.c:558
static int cp2112_gpio_configure_write_pin(device_t dev, uint32_t pin_num, bool output, enum cp2112_out_mode *mode)
Definition: cp2112.c:418
static void cp2112iic_intr_read_callback(struct usb_xfer *xfer, usb_error_t error)
Definition: cp2112.c:790
#define CP2112GPIO_UNLOCK(sc)
Definition: cp2112.c:72
static int cp2112_gpio_pin_set(device_t dev, uint32_t pin_num, uint32_t pin_value)
Definition: cp2112.c:501
static driver_t cp2112iic_driver
Definition: cp2112.c:1447
static int cp2112gpio_probe(device_t dev)
Definition: cp2112.c:674
#define CP2112_REQ_SMB_WRITE
Definition: cp2112.c:90
static int cp2112gpio_detach(device_t dev)
Definition: cp2112.c:740
static const STRUCT_USB_HOST_ID cp2112_devs[]
Definition: cp2112.c:262
static int cp2112_attach(device_t dev)
Definition: cp2112.c:309
MODULE_DEPEND(cp2112hid, usb, 1, 1, 1)
DRIVER_MODULE(cp2112hid, uhub, cp2112hid_driver, cp2112hid_devclass, NULL, NULL)
static device_t cp2112_gpio_get_bus(device_t dev)
Definition: cp2112.c:484
static int cp2112iic_send_req(struct cp2112iic_softc *sc, const void *data, uint16_t len)
Definition: cp2112.c:888
#define CP2112_IIC_STATUS0_BUSY
Definition: cp2112.c:106
static int cp2112_gpio_read_pin(device_t dev, uint32_t pin_num, bool *on)
Definition: cp2112.c:374
static int cp2112_gpio_pin_toggle(device_t dev, uint32_t pin_num)
Definition: cp2112.c:538
static int cp2112iic_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr)
Definition: cp2112.c:1241
static int cp2112_gpio_write_pin(device_t dev, uint32_t pin_num, bool on)
Definition: cp2112.c:393
static void cp2112iic_intr_write_callback(struct usb_xfer *xfer, usb_error_t error)
Definition: cp2112.c:752
static int cp2112_set_report(device_t dev, uint8_t id, void *data, uint16_t len)
Definition: cp2112.c:280
#define CP2112_PART_NUM
Definition: cp2112.c:75
static int cp2112_gpio_pin_get(device_t dev, uint32_t pin_num, uint32_t *pin_value)
Definition: cp2112.c:518
#define CP2112_REQ_SMB_READ_RESPONSE
Definition: cp2112.c:89
static int cp2112_gpio_pin_max(device_t dev, int *maxpin)
Definition: cp2112.c:493
MODULE_VERSION(cp2112hid, 1)
static devclass_t cp2112gpio_devclass
Definition: cp2112.c:1426
#define CP2112GPIO_LOCK(sc)
Definition: cp2112.c:71
static devclass_t cp2112iic_devclass
Definition: cp2112.c:1453
__FBSDID("$FreeBSD$")
static device_method_t cp2112iic_methods[]
Definition: cp2112.c:1433
static int cp2112_detach(device_t dev)
Definition: cp2112.c:362
#define CP2112_IIC_MAX_READ_LEN
Definition: cp2112.c:98
static int cp2112_probe(device_t dev)
Definition: cp2112.c:293
static devclass_t cp2112hid_devclass
Definition: cp2112.c:1393
#define SIZEOF_FIELD(_s, _f)
Definition: cp2112.c:69
static const struct usb_config cp2112iic_config[CP2112_N_TRANSFER]
Definition: cp2112.c:868
#define CP2112_IIC_STATUS0_ERROR
Definition: cp2112.c:108
static int cp2112gpio_attach(device_t dev)
Definition: cp2112.c:681
struct version_request __packed
#define CP2112_IIC_STATUS0_CMP
Definition: cp2112.c:107
#define CP2112_REQ_SMB_WRITE_READ
Definition: cp2112.c:87
static int cp2112iic_req_resp(struct cp2112iic_softc *sc, const void *req_data, uint16_t req_len, void *resp_data, uint16_t resp_len)
Definition: cp2112.c:920
static driver_t cp2112gpio_driver
Definition: cp2112.c:1420
#define CP2112_REQ_SMB_XFER_STATUS_REQ
Definition: cp2112.c:91
#define CP2112_REQ_SMB_READ
Definition: cp2112.c:86
static int cp2112iic_probe(device_t dev)
Definition: cp2112.c:1307
static int cp2112iic_read_data(struct cp2112iic_softc *sc, void *data, uint16_t in_len, uint16_t *out_len)
Definition: cp2112.c:1025
static device_method_t cp2112gpio_methods[]
Definition: cp2112.c:1400
#define CP2112_REQ_GPIO_SET
Definition: cp2112.c:82
static int cp2112iic_detach(device_t dev)
Definition: cp2112.c:1357
#define CP2112_IIC_REPSTART_VER
Definition: cp2112.c:99
#define CP2112_IIC_STATUS1_TIMEOUT_BUS
Definition: cp2112.c:111
#define CP2112_REQ_GPIO_GET
Definition: cp2112.c:81
#define CP2112_REQ_VERSION
Definition: cp2112.c:83
#define CP2112_REPORT_SIZE
Definition: cp2112.c:77
#define CP2112_GPIO_SPEC_CLK7
Definition: cp2112.c:101
#define CP2112_GPIO_SPEC_RX1
Definition: cp2112.c:103
#define CP2112_REQ_GPIO_CFG
Definition: cp2112.c:80
#define CP2112_REQ_SMB_XFER_STATUS_RESP
Definition: cp2112.c:92
#define CP2112_IIC_STATUS0_IDLE
Definition: cp2112.c:105
static int cp2112iic_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs)
Definition: cp2112.c:1084
static int cp2112_gpio_pin_getflags(device_t dev, uint32_t pin_num, uint32_t *flags)
Definition: cp2112.c:574
@ CP2112_N_TRANSFER
Definition: cp2112.c:217
@ CP2112_INTR_IN
Definition: cp2112.c:216
@ CP2112_INTR_OUT
Definition: cp2112.c:215
static int cp2112_gpio_pin_setflags(device_t dev, uint32_t pin_num, uint32_t flags)
Definition: cp2112.c:606
#define CP2112_IIC_STATUS1_TIMEOUT_NACK
Definition: cp2112.c:110
static int cp2112_get_report(device_t dev, uint8_t id, void *data, uint16_t len)
Definition: cp2112.c:268
uint16_t len
Definition: ehci.h:41
struct @109 error
uint16_t data
const char * name
device_t dev
uint64_t * addr
int pin
uint8_t sc_version
Definition: cp2112.c:225
uint8_t sc_iface_index
Definition: cp2112.c:224
struct usb_device * sc_udev
Definition: cp2112.c:223
device_t sc_gpio_dev
Definition: cp2112.c:221
device_t sc_iic_dev
Definition: cp2112.c:222
device_t busdev
Definition: cp2112.c:230
struct gpio_pin pins[CP2112_GPIO_COUNT]
Definition: cp2112.c:232
struct sx gpio_lock
Definition: cp2112.c:229
const uint8_t * data
Definition: cp2112.c:250
struct usb_xfer * xfers[CP2112_N_TRANSFER]
Definition: cp2112.c:238
struct cp2112iic_softc::@20 io
struct mtx lock
Definition: cp2112.c:241
struct cp2112iic_softc::@20::@21 in
struct cv cv
Definition: cp2112.c:242
u_char own_addr
Definition: cp2112.c:239
struct cp2112iic_softc::@20::@22 out
uint8_t * data
Definition: cp2112.c:244
device_t iicbus_dev
Definition: cp2112.c:237
device_t dev
Definition: cp2112.c:236
uint8_t id
Definition: cp2112.c:136
uint8_t output
Definition: cp2112.c:137
uint8_t pushpull
Definition: cp2112.c:138
uint8_t special
Definition: cp2112.c:139
uint8_t divider
Definition: cp2112.c:140
uint8_t id
Definition: cp2112.c:123
uint8_t state
Definition: cp2112.c:124
uint8_t mask
Definition: cp2112.c:131
uint8_t id
Definition: cp2112.c:129
uint8_t state
Definition: cp2112.c:130
uint16_t write_timeout
Definition: cp2112.c:202
uint8_t scl_low_timeout
Definition: cp2112.c:204
uint16_t read_timeout
Definition: cp2112.c:203
uint16_t retry_count
Definition: cp2112.c:205
uint8_t id
Definition: cp2112.c:198
uint8_t auto_send_read
Definition: cp2112.c:201
uint32_t speed
Definition: cp2112.c:199
uint8_t slave_addr
Definition: cp2112.c:200
uint8_t data[61]
Definition: cp2112.c:169
uint8_t status
Definition: cp2112.c:167
uint8_t slave
Definition: cp2112.c:184
uint16_t len
Definition: cp2112.c:185
uint8_t id
Definition: cp2112.c:183
uint8_t slave
Definition: cp2112.c:175
uint8_t wdata[16]
Definition: cp2112.c:178
uint16_t rlen
Definition: cp2112.c:176
uint8_t wlen
Definition: cp2112.c:177
uint8_t id
Definition: cp2112.c:190
uint8_t len
Definition: cp2112.c:192
uint8_t data[61]
Definition: cp2112.c:193
uint8_t slave
Definition: cp2112.c:191
uint8_t request
Definition: cp2112.c:146
uint16_t status2
Definition: cp2112.c:154
uint16_t status3
Definition: cp2112.c:155
enum usb_hc_mode usb_mode
Definition: usbdi.h:432
struct usbd_lookup_info info
Definition: usbdi.h:426
struct usb_device * device
Definition: usbdi.h:430
uint8_t type
Definition: usbdi.h:238
uint8_t bIfaceIndex
Definition: usbdi.h:417
uint8_t bInterfaceClass
Definition: usbdi.h:414
uint8_t version
Definition: cp2112.c:118
uint8_t part_num
Definition: cp2112.c:117
uint8_t id
Definition: cp2112.c:116
#define UE_INTERRUPT
Definition: usb.h:544
#define UE_ADDR_ANY
Definition: usb.h:537
#define UE_DIR_IN
Definition: usb.h:531
#define UICLASS_HID
Definition: usb.h:453
#define UE_DIR_OUT
Definition: usb.h:532
@ USB_MODE_HOST
Definition: usb.h:778
void usbd_copy_in(struct usb_page_cache *cache, usb_frlength_t offset, const void *ptr, usb_frlength_t len)
Definition: usb_busdma.c:166
void usbd_copy_out(struct usb_page_cache *cache, usb_frlength_t offset, void *ptr, usb_frlength_t len)
Definition: usb_busdma.c:283
const void * req
Definition: usb_if.m:51
INTERFACE usb
Definition: usb_if.m:35
int usbd_lookup_id_by_uaa(const struct usb_device_id *id, usb_size_t sizeof_id, struct usb_attach_arg *uaa)
Definition: usb_lookup.c:143
usb_error_t usbd_req_set_report(struct usb_device *udev, struct mtx *mtx, void *data, uint16_t len, uint8_t iface_index, uint8_t type, uint8_t id)
Definition: usb_request.c:1806
usb_error_t usbd_req_get_report(struct usb_device *udev, struct mtx *mtx, void *data, uint16_t len, uint8_t iface_index, uint8_t type, uint8_t id)
Definition: usb_request.c:1834
void usbd_transfer_submit(struct usb_xfer *xfer)
void usbd_xfer_set_frames(struct usb_xfer *xfer, usb_frcount_t n)
void usbd_transfer_unsetup(struct usb_xfer **pxfer, uint16_t n_setup)
void usbd_xfer_set_frame_len(struct usb_xfer *xfer, usb_frcount_t frindex, usb_frlength_t len)
struct usb_page_cache * usbd_xfer_get_frame(struct usb_xfer *xfer, usb_frcount_t frindex)
usb_error_t usbd_transfer_setup(struct usb_device *udev, const uint8_t *ifaces, struct usb_xfer **ppxfer, const struct usb_config *setup_start, uint16_t n_setup, void *priv_sc, struct mtx *xfer_mtx)
Definition: usb_transfer.c:987
void usbd_transfer_start(struct usb_xfer *xfer)
void * usbd_xfer_softc(struct usb_xfer *xfer)
void usbd_xfer_set_stall(struct usb_xfer *xfer)
void usbd_transfer_stop(struct usb_xfer *xfer)
void usbd_xfer_status(struct usb_xfer *xfer, int *actlen, int *sumlen, int *aframes, int *nframes)
usb_frlength_t usbd_xfer_max_len(struct usb_xfer *xfer)
void device_set_usb_desc(device_t dev)
Definition: usb_util.c:73
#define USB_ST_SETUP
Definition: usbdi.h:502
#define USB_VP(vend, prod)
Definition: usbdi.h:364
usb_error_t
Definition: usbdi.h:45
@ USB_ERR_CANCELLED
Definition: usbdi.h:51
#define USB_ST_TRANSFERRED
Definition: usbdi.h:503
#define STRUCT_USB_HOST_ID
Definition: usbdi.h:258
#define USB_GET_STATE(xfer)
Definition: usbdi.h:515
#define UHID_FEATURE_REPORT
Definition: usbhid.h:68