The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/usb/misc/cp2112.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    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 */
  115 struct version_request {
  116         uint8_t id;
  117         uint8_t part_num;
  118         uint8_t version;
  119 } __packed;
  120 
  121 /* CP2112_REQ_GPIO_GET */
  122 struct gpio_get_req {
  123         uint8_t id;
  124         uint8_t state;
  125 } __packed;
  126 
  127 /* CP2112_REQ_GPIO_SET */
  128 struct gpio_set_req {
  129         uint8_t id;
  130         uint8_t state;
  131         uint8_t mask;
  132 } __packed;
  133 
  134 /* CP2112_REQ_GPIO_CFG */
  135 struct gpio_config_req {
  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 */
  144 struct i2c_xfer_status_req {
  145         uint8_t id;
  146         uint8_t request;
  147 } __packed;
  148 
  149 /* CP2112_REQ_SMB_XFER_STATUS_RESP */
  150 struct i2c_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 */
  159 struct i2c_data_read_force_send_req {
  160         uint8_t id;
  161         uint16_t len;
  162 } __packed;
  163 
  164 /* CP2112_REQ_SMB_READ_RESPONSE */
  165 struct i2c_data_read_resp {
  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 */
  173 struct i2c_write_read_req {
  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 */
  182 struct i2c_read_req {
  183         uint8_t id;
  184         uint8_t slave;
  185         uint16_t len;
  186 } __packed;
  187 
  188 /* CP2112_REQ_SMB_WRITE_READ */
  189 struct i2c_write_req {
  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 */
  197 struct i2c_cfg_req {
  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 
  208 enum cp2112_out_mode {
  209         OUT_OD,
  210         OUT_PP,
  211         OUT_KEEP
  212 };
  213 
  214 enum {
  215         CP2112_INTR_OUT = 0,
  216         CP2112_INTR_IN,
  217         CP2112_N_TRANSFER,
  218 };
  219 
  220 struct cp2112_softc {
  221         device_t                sc_gpio_dev;
  222         device_t                sc_iic_dev;
  223         struct usb_device       *sc_udev;
  224         uint8_t                 sc_iface_index;
  225         uint8_t                 sc_version;
  226 };
  227 
  228 struct cp2112gpio_softc {
  229         struct sx               gpio_lock;
  230         device_t                busdev;
  231         int                     gpio_caps;
  232         struct gpio_pin         pins[CP2112_GPIO_COUNT];
  233 };
  234 
  235 struct cp2112iic_softc {
  236         device_t        dev;
  237         device_t        iicbus_dev;
  238         struct usb_xfer *xfers[CP2112_N_TRANSFER];
  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;
  254                 }               out;
  255         }               io;
  256 };
  257 
  258 static int cp2112_detach(device_t dev);
  259 static int cp2112gpio_detach(device_t dev);
  260 static int cp2112iic_detach(device_t dev);
  261 
  262 static const STRUCT_USB_HOST_ID cp2112_devs[] = {
  263         { USB_VP(USB_VENDOR_SILABS, USB_PRODUCT_SILABS_CP2112) },
  264         { USB_VP(0x1009, USB_PRODUCT_SILABS_CP2112) }, /* XXX */
  265 };
  266 
  267 static int
  268 cp2112_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,
  275             len, sc->sc_iface_index, UHID_FEATURE_REPORT, id);
  276         return (err);
  277 }
  278 
  279 static int
  280 cp2112_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,
  288             len, sc->sc_iface_index, UHID_FEATURE_REPORT, id);
  289         return (err);
  290 }
  291 
  292 static int
  293 cp2112_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 
  308 static int
  309 cp2112_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 
  319         device_set_usb_desc(dev);
  320 
  321         sc->sc_udev = uaa->device;
  322         sc->sc_iface_index = uaa->info.bIfaceIndex;
  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 
  356 detach:
  357         cp2112_detach(dev);
  358         return (ENXIO);
  359 }
  360 
  361 static int
  362 cp2112_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 
  373 static int
  374 cp2112_gpio_read_pin(device_t dev, uint32_t pin_num, bool *on)
  375 {
  376         struct gpio_get_req data;
  377         struct cp2112gpio_softc *sc __diagused;
  378         int err;
  379 
  380         sc = device_get_softc(dev);
  381         CP2112GPIO_LOCKED(sc);
  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 
  392 static int
  393 cp2112_gpio_write_pin(device_t dev, uint32_t pin_num, bool on)
  394 {
  395         struct gpio_set_req data;
  396         struct cp2112gpio_softc *sc __diagused;
  397         int err;
  398         bool actual;
  399 
  400         sc = device_get_softc(dev);
  401         CP2112GPIO_LOCKED(sc);
  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 
  417 static int
  418 cp2112_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 __diagused;
  423         int err;
  424         uint8_t mask;
  425 
  426         sc = device_get_softc(dev);
  427         CP2112GPIO_LOCKED(sc);
  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 
  483 static device_t
  484 cp2112_gpio_get_bus(device_t dev)
  485 {
  486         struct cp2112gpio_softc *sc;
  487 
  488         sc = device_get_softc(dev);
  489         return (sc->busdev);
  490 }
  491 
  492 static int
  493 cp2112_gpio_pin_max(device_t dev, int *maxpin)
  494 {
  495 
  496         *maxpin = CP2112_GPIO_COUNT - 1;
  497         return (0);
  498 }
  499 
  500 static int
  501 cp2112_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);
  512         CP2112GPIO_UNLOCK(sc);
  513 
  514         return (err);
  515 }
  516 
  517 static int
  518 cp2112_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);
  530         CP2112GPIO_UNLOCK(sc);
  531 
  532         if (err == 0)
  533                 *pin_value = on;
  534         return (err);
  535 }
  536 
  537 static int
  538 cp2112_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);
  552         CP2112GPIO_UNLOCK(sc);
  553 
  554         return (err);
  555 }
  556 
  557 static int
  558 cp2112_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;
  568         CP2112GPIO_UNLOCK(sc);
  569 
  570         return (0);
  571 }
  572 
  573 static int
  574 cp2112_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;
  584         CP2112GPIO_UNLOCK(sc);
  585 
  586         return (0);
  587 }
  588 
  589 static int
  590 cp2112_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);
  600         CP2112GPIO_UNLOCK(sc);
  601 
  602         return (0);
  603 }
  604 
  605 static int
  606 cp2112_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];
  649         err = cp2112_gpio_configure_write_pin(dev, 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         }
  668         CP2112GPIO_UNLOCK(sc);
  669 
  670         return (err);
  671 }
  672 
  673 static int
  674 cp2112gpio_probe(device_t dev)
  675 {
  676         device_set_desc(dev, "CP2112 GPIO interface");
  677         return (BUS_PROBE_SPECIFIC);
  678 }
  679 
  680 static int
  681 cp2112gpio_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 
  697         err = cp2112_get_report(cp2112, CP2112_REQ_GPIO_CFG,
  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 
  734 detach:
  735         cp2112gpio_detach(dev);
  736         return (ENXIO);
  737 }
  738 
  739 static int
  740 cp2112gpio_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 
  751 static void
  752 cp2112iic_intr_write_callback(struct usb_xfer *xfer, usb_error_t error)
  753 {
  754         struct cp2112iic_softc *sc;
  755         struct usb_page_cache *pc;
  756 
  757         sc = usbd_xfer_softc(xfer);
  758 
  759         mtx_assert(&sc->io.lock, MA_OWNED);
  760 
  761         switch (USB_GET_STATE(xfer)) {
  762         case USB_ST_SETUP:
  763                 pc = usbd_xfer_get_frame(xfer, 0);
  764                 usbd_copy_in(pc, 0, sc->io.out.data, sc->io.out.len);
  765                 usbd_xfer_set_frame_len(xfer, 0, sc->io.out.len);
  766                 usbd_xfer_set_frames(xfer, 1);
  767                 usbd_transfer_submit(xfer);
  768                 break;
  769         case USB_ST_TRANSFERRED:
  770                 sc->io.out.error = 0;
  771                 sc->io.out.done = 1;
  772                 cv_signal(&sc->io.cv);
  773                 break;
  774         default:                        /* Error */
  775                 device_printf(sc->dev, "write intr state %d error %d\n",
  776                     USB_GET_STATE(xfer), error);
  777                 sc->io.out.error = IIC_EBUSERR;
  778                 cv_signal(&sc->io.cv);
  779                 if (error != USB_ERR_CANCELLED) {
  780                         /* try to clear stall first */
  781                         usbd_xfer_set_stall(xfer);
  782                 }
  783                 break;
  784         }
  785 }
  786 
  787 static void
  788 cp2112iic_intr_read_callback(struct usb_xfer *xfer, usb_error_t error)
  789 {
  790         struct cp2112iic_softc *sc = usbd_xfer_softc(xfer);
  791         struct usb_page_cache *pc;
  792         int act_len, len;
  793 
  794         mtx_assert(&sc->io.lock, MA_OWNED);
  795         usbd_xfer_status(xfer, &act_len, NULL, NULL, NULL);
  796 
  797         switch (USB_GET_STATE(xfer)) {
  798         case USB_ST_TRANSFERRED:
  799                 if (sc->io.in.done) {
  800                         device_printf(sc->dev,
  801                             "interrupt while previous is pending, ignored\n");
  802                 } else if (sc->io.in.len == 0) {
  803                         uint8_t buf[8];
  804 
  805                         /*
  806                          * There is a spurious Transfer Status Response and
  807                          * zero-length Read Response during hardware
  808                          * configuration.  Possibly they carry some information
  809                          * about the initial bus state.
  810                          */
  811                         if (device_is_attached(sc->dev)) {
  812                                 device_printf(sc->dev,
  813                                     "unsolicited interrupt, ignored\n");
  814                                 if (bootverbose) {
  815                                         pc = usbd_xfer_get_frame(xfer, 0);
  816                                         len = MIN(sizeof(buf), act_len);
  817                                         usbd_copy_out(pc, 0, buf, len);
  818                                         device_printf(sc->dev, "data: %*D\n",
  819                                             len, buf, " ");
  820                                 }
  821                         } else {
  822                                 pc = usbd_xfer_get_frame(xfer, 0);
  823                                 len = MIN(sizeof(buf), act_len);
  824                                 usbd_copy_out(pc, 0, buf, len);
  825                                 if (buf[0] == CP2112_REQ_SMB_XFER_STATUS_RESP) {
  826                                         device_printf(sc->dev,
  827                                             "initial bus status0 = 0x%02x, "
  828                                             "status1 = 0x%02x\n",
  829                                             buf[1], buf[2]);
  830                                 }
  831                         }
  832                 } else if (act_len == CP2112_REPORT_SIZE) {
  833                         pc = usbd_xfer_get_frame(xfer, 0);
  834                         usbd_copy_out(pc, 0, sc->io.in.data, sc->io.in.len);
  835                         sc->io.in.error = 0;
  836                         sc->io.in.done = 1;
  837                 } else {
  838                         device_printf(sc->dev,
  839                             "unexpected input report length %u\n", act_len);
  840                         sc->io.in.error = IIC_EBUSERR;
  841                         sc->io.in.done = 1;
  842                 }
  843                 cv_signal(&sc->io.cv);
  844         case USB_ST_SETUP:
  845 tr_setup:
  846                 usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer));
  847                 usbd_transfer_submit(xfer);
  848                 break;
  849 
  850         default:                        /* Error */
  851                 device_printf(sc->dev, "read intr state %d error %d\n",
  852                     USB_GET_STATE(xfer), error);
  853 
  854                 sc->io.in.error = IIC_EBUSERR;
  855                 sc->io.in.done = 1;
  856                 cv_signal(&sc->io.cv);
  857                 if (error != USB_ERR_CANCELLED) {
  858                         /* try to clear stall first */
  859                         usbd_xfer_set_stall(xfer);
  860                         goto tr_setup;
  861                 }
  862                 break;
  863         }
  864 }
  865 
  866 static const struct usb_config cp2112iic_config[CP2112_N_TRANSFER] = {
  867         [CP2112_INTR_OUT] = {
  868                 .type = UE_INTERRUPT,
  869                 .endpoint = UE_ADDR_ANY,
  870                 .direction = UE_DIR_OUT,
  871                 .flags = { .pipe_bof = 1, .no_pipe_ok = 1, },
  872                 .bufsize = 0,   /* use wMaxPacketSize */
  873                 .callback = &cp2112iic_intr_write_callback,
  874         },
  875         [CP2112_INTR_IN] = {
  876                 .type = UE_INTERRUPT,
  877                 .endpoint = UE_ADDR_ANY,
  878                 .direction = UE_DIR_IN,
  879                 .flags = { .pipe_bof = 1, .short_xfer_ok = 1, },
  880                 .bufsize = 0,   /* use wMaxPacketSize */
  881                 .callback = &cp2112iic_intr_read_callback,
  882         },
  883 };
  884 
  885 static int
  886 cp2112iic_send_req(struct cp2112iic_softc *sc, const void *data,
  887     uint16_t len)
  888 {
  889         int err;
  890 
  891         mtx_assert(&sc->io.lock, MA_OWNED);
  892         KASSERT(sc->io.out.done == 0, ("%s: conflicting request", __func__));
  893 
  894         sc->io.out.data = data;
  895         sc->io.out.len = len;
  896 
  897         DTRACE_PROBE1(send__req, uint8_t, *(const uint8_t *)data);
  898 
  899         usbd_transfer_start(sc->xfers[CP2112_INTR_OUT]);
  900 
  901         while (!sc->io.out.done)
  902                 cv_wait(&sc->io.cv, &sc->io.lock);
  903 
  904         usbd_transfer_stop(sc->xfers[CP2112_INTR_OUT]);
  905 
  906         sc->io.out.done = 0;
  907         sc->io.out.data = NULL;
  908         sc->io.out.len = 0;
  909         err = sc->io.out.error;
  910         if (err != 0) {
  911                 device_printf(sc->dev, "output report 0x%02x failed: %d\n",
  912                     *(const uint8_t*)data, err);
  913         }
  914         return (err);
  915 }
  916 
  917 static int
  918 cp2112iic_req_resp(struct cp2112iic_softc *sc, const void *req_data,
  919     uint16_t req_len, void *resp_data, uint16_t resp_len)
  920 {
  921         int err;
  922 
  923         mtx_assert(&sc->io.lock, MA_OWNED);
  924 
  925         /*
  926          * Prepare to receive a response interrupt even before the
  927          * request transfer is confirmed (USB_ST_TRANSFERED).
  928          */
  929         KASSERT(sc->io.in.done == 0, ("%s: conflicting request", __func__));
  930         sc->io.in.len = resp_len;
  931         sc->io.in.data = resp_data;
  932 
  933         err = cp2112iic_send_req(sc, req_data, req_len);
  934         if (err != 0) {
  935                 sc->io.in.len = 0;
  936                 sc->io.in.data = NULL;
  937                 return (err);
  938         }
  939 
  940         while (!sc->io.in.done)
  941                 cv_wait(&sc->io.cv, &sc->io.lock);
  942 
  943         err = sc->io.in.error;
  944         sc->io.in.done = 0;
  945         sc->io.in.error = 0;
  946         sc->io.in.len = 0;
  947         sc->io.in.data = NULL;
  948         return (err);
  949 }
  950 
  951 static int
  952 cp2112iic_check_req_status(struct cp2112iic_softc *sc)
  953 {
  954         struct i2c_xfer_status_req xfer_status_req;
  955         struct i2c_xfer_status_resp xfer_status_resp;
  956         int err;
  957 
  958         mtx_assert(&sc->io.lock, MA_OWNED);
  959 
  960         do {
  961                 xfer_status_req.id = CP2112_REQ_SMB_XFER_STATUS_REQ;
  962                 xfer_status_req.request = 1;
  963                 err = cp2112iic_req_resp(sc,
  964                     &xfer_status_req, sizeof(xfer_status_req),
  965                     &xfer_status_resp, sizeof(xfer_status_resp));
  966 
  967                 if (xfer_status_resp.id != CP2112_REQ_SMB_XFER_STATUS_RESP) {
  968                         device_printf(sc->dev,
  969                             "unexpected response 0x%02x to status request\n",
  970                             xfer_status_resp.id);
  971                         err = IIC_EBUSERR;
  972                         goto out;
  973                 }
  974 
  975                 DTRACE_PROBE4(xfer__status, uint8_t, xfer_status_resp.status0,
  976                     uint8_t, xfer_status_resp.status1,
  977                     uint16_t, be16toh(xfer_status_resp.status2),
  978                     uint16_t, be16toh(xfer_status_resp.status3));
  979 
  980                 switch (xfer_status_resp.status0) {
  981                 case CP2112_IIC_STATUS0_IDLE:
  982                         err = IIC_ESTATUS;
  983                         break;
  984                 case CP2112_IIC_STATUS0_BUSY:
  985                         err = ERESTART; /* non-I2C, special handling */
  986                         break;
  987                 case CP2112_IIC_STATUS0_CMP:
  988                         err = IIC_NOERR;
  989                         break;
  990                 case CP2112_IIC_STATUS0_ERROR:
  991                         switch (xfer_status_resp.status1) {
  992                         case CP2112_IIC_STATUS1_TIMEOUT_NACK:
  993                                 err = IIC_ENOACK;
  994                                 break;
  995                         case CP2112_IIC_STATUS1_TIMEOUT_BUS:
  996                                 err = IIC_ETIMEOUT;
  997                                 break;
  998                         case CP2112_IIC_STATUS1_ARB_LOST:
  999                                 err = IIC_EBUSBSY;
 1000                                 break;
 1001                         default:
 1002                                 device_printf(sc->dev,
 1003                                     "i2c error, status = 0x%02x\n",
 1004                                     xfer_status_resp.status1);
 1005                                 err = IIC_ESTATUS;
 1006                                 break;
 1007                         }
 1008                         break;
 1009                 default:
 1010                         device_printf(sc->dev,
 1011                             "unknown i2c xfer status0 0x%02x\n",
 1012                             xfer_status_resp.status0);
 1013                         err = IIC_EBUSERR;
 1014                         break;
 1015                 }
 1016 
 1017         } while (err == ERESTART);
 1018 out:
 1019         return (err);
 1020 }
 1021 
 1022 static int
 1023 cp2112iic_read_data(struct cp2112iic_softc *sc, void *data, uint16_t in_len,
 1024     uint16_t *out_len)
 1025 {
 1026         struct i2c_data_read_force_send_req data_read_force_send;
 1027         struct i2c_data_read_resp data_read_resp;
 1028         int err;
 1029 
 1030         mtx_assert(&sc->io.lock, MA_OWNED);
 1031 
 1032         /*
 1033          * Prepare to receive a response interrupt even before the request
 1034          * transfer is confirmed (USB_ST_TRANSFERED).
 1035          */
 1036 
 1037         if (in_len > sizeof(data_read_resp.data))
 1038                 in_len = sizeof(data_read_resp.data);
 1039         data_read_force_send.id = CP2112_REQ_SMB_READ_FORCE_SEND;
 1040         data_read_force_send.len = htobe16(in_len);
 1041         err = cp2112iic_req_resp(sc,
 1042             &data_read_force_send, sizeof(data_read_force_send),
 1043             &data_read_resp, sizeof(data_read_resp));
 1044         if (err != 0)
 1045                 goto out;
 1046 
 1047         if (data_read_resp.id != CP2112_REQ_SMB_READ_RESPONSE) {
 1048                 device_printf(sc->dev,
 1049                     "unexpected response 0x%02x to data read request\n",
 1050                     data_read_resp.id);
 1051                 err = IIC_EBUSERR;
 1052                 goto out;
 1053         }
 1054 
 1055         DTRACE_PROBE2(read__response, uint8_t, data_read_resp.status,
 1056             uint8_t, data_read_resp.len);
 1057 
 1058         /*
 1059          * We expect either the request completed status or, more typical for
 1060          * this driver, the bus idle status because of the preceding
 1061          * Force Read Status command (which is not an I2C request).
 1062          */
 1063         if (data_read_resp.status != CP2112_IIC_STATUS0_CMP &&
 1064             data_read_resp.status != CP2112_IIC_STATUS0_IDLE) {
 1065                 err = IIC_EBUSERR;
 1066                 goto out;
 1067         }
 1068         if (data_read_resp.len > in_len) {
 1069                 device_printf(sc->dev, "device returns more data than asked\n");
 1070                 err = IIC_EOVERFLOW;
 1071                 goto out;
 1072         }
 1073 
 1074         *out_len = data_read_resp.len;
 1075         if (*out_len > 0)
 1076                 memcpy(data, data_read_resp.data, *out_len);
 1077 out:
 1078         return (err);
 1079 }
 1080 
 1081 static int
 1082 cp2112iic_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs)
 1083 {
 1084         struct cp2112iic_softc *sc = device_get_softc(dev);
 1085         struct cp2112_softc *psc = device_get_softc(device_get_parent(dev));
 1086         const char *reason = NULL;
 1087         uint32_t i;
 1088         uint16_t read_off, to_read;
 1089         int err;
 1090 
 1091         /*
 1092          * The hardware interface imposes limits on allowed I2C messages.
 1093          * It is not possible to explicitly send a start or stop.
 1094          * It is not possible to do a zero length transfer.
 1095          * For this reason it's impossible to send a message with no data
 1096          * at all (like an SMBus quick message).
 1097          * Each read or write transfer beginning with the start condition
 1098          * and ends with the stop condition.  The only exception is that
 1099          * it is possible to have a write transfer followed by a read
 1100          * transfer to the same slave with the repeated start condition
 1101          * between them.
 1102          */
 1103         for (i = 0; i < nmsgs; i++) {
 1104                 if (i == 0 && (msgs[i].flags & IIC_M_NOSTART) != 0) {
 1105                         reason = "first message without start";
 1106                         break;
 1107                 }
 1108                 if (i == nmsgs - 1 && (msgs[i].flags & IIC_M_NOSTOP) != 0) {
 1109                         reason = "last message without stop";
 1110                         break;
 1111                 }
 1112                 if (msgs[i].len == 0) {
 1113                         reason = "message with no data";
 1114                         break;
 1115                 }
 1116                 if ((msgs[i].flags & IIC_M_RD) != 0 &&
 1117                     msgs[i].len > CP2112_IIC_MAX_READ_LEN) {
 1118                         reason = "too long read";
 1119                         break;
 1120                 }
 1121                 if ((msgs[i].flags & IIC_M_RD) == 0 &&
 1122                     msgs[i].len > SIZEOF_FIELD(i2c_write_req, data)) {
 1123                         reason = "too long write";
 1124                         break;
 1125                 }
 1126                 if ((msgs[i].flags & IIC_M_NOSTART) != 0) {
 1127                         reason = "message without start or repeated start";
 1128                         break;
 1129                 }
 1130                 if ((msgs[i].flags & IIC_M_NOSTOP) != 0 &&
 1131                     (msgs[i].flags & IIC_M_RD) != 0) {
 1132                         reason = "read without stop";
 1133                         break;
 1134                 }
 1135                 if ((msgs[i].flags & IIC_M_NOSTOP) != 0 &&
 1136                     psc->sc_version < CP2112_IIC_REPSTART_VER) {
 1137                         reason = "write without stop";
 1138                         break;
 1139                 }
 1140                 if ((msgs[i].flags & IIC_M_NOSTOP) != 0 &&
 1141                     msgs[i].len > SIZEOF_FIELD(i2c_write_read_req, wdata)) {
 1142                         reason = "too long write without stop";
 1143                         break;
 1144                 }
 1145                 if (i > 0) {
 1146                         if ((msgs[i - 1].flags & IIC_M_NOSTOP) != 0 &&
 1147                             msgs[i].slave != msgs[i - 1].slave) {
 1148                                 reason = "change of slave without stop";
 1149                                 break;
 1150                         }
 1151                         if ((msgs[i - 1].flags & IIC_M_NOSTOP) != 0 &&
 1152                             (msgs[i].flags & IIC_M_RD) == 0) {
 1153                                 reason = "write after repeated start";
 1154                                 break;
 1155                         }
 1156                 }
 1157         }
 1158         if (reason != NULL) {
 1159                 if (bootverbose)
 1160                         device_printf(dev, "unsupported i2c message: %s\n",
 1161                             reason);
 1162                 return (IIC_ENOTSUPP);
 1163         }
 1164 
 1165         mtx_lock(&sc->io.lock);
 1166 
 1167         for (i = 0; i < nmsgs; i++) {
 1168                 if (i + 1 < nmsgs && (msgs[i].flags & IIC_M_NOSTOP) != 0) {
 1169                         /*
 1170                          * Combine <write><repeated start><read> into a single
 1171                          * CP2112 operation.
 1172                          */
 1173                         struct i2c_write_read_req req;
 1174 
 1175                         KASSERT((msgs[i].flags & IIC_M_RD) == 0,
 1176                             ("read without stop"));
 1177                         KASSERT((msgs[i + 1].flags & IIC_M_RD) != 0,
 1178                             ("write after write without stop"));
 1179                         req.id = CP2112_REQ_SMB_WRITE_READ;
 1180                         req.slave = msgs[i].slave & ~LSB;
 1181                         to_read = msgs[i + 1].len;
 1182                         req.rlen = htobe16(to_read);
 1183                         req.wlen = msgs[i].len;
 1184                         memcpy(req.wdata, msgs[i].buf, msgs[i].len);
 1185                         err = cp2112iic_send_req(sc, &req, msgs[i].len + 5);
 1186 
 1187                         /*
 1188                          * The next message is already handled.
 1189                          * Also needed for read data to go into the right msg.
 1190                          */
 1191                         i++;
 1192                 } else if ((msgs[i].flags & IIC_M_RD) != 0) {
 1193                         struct i2c_read_req req;
 1194 
 1195                         req.id = CP2112_REQ_SMB_READ;
 1196                         req.slave = msgs[i].slave & ~LSB;
 1197                         to_read = msgs[i].len;
 1198                         req.len = htobe16(to_read);
 1199                         err = cp2112iic_send_req(sc, &req, sizeof(req));
 1200                 } else {
 1201                         struct i2c_write_req req;
 1202 
 1203                         req.id = CP2112_REQ_SMB_WRITE;
 1204                         req.slave = msgs[i].slave & ~LSB;
 1205                         req.len = msgs[i].len;
 1206                         memcpy(req.data, msgs[i].buf, msgs[i].len);
 1207                         to_read = 0;
 1208                         err = cp2112iic_send_req(sc, &req, msgs[i].len + 3);
 1209                 }
 1210                 if (err != 0)
 1211                         break;
 1212 
 1213                 err = cp2112iic_check_req_status(sc);
 1214                 if (err != 0)
 1215                         break;
 1216 
 1217                 read_off = 0;
 1218                 while (to_read > 0) {
 1219                         uint16_t act_read;
 1220 
 1221                         err = cp2112iic_read_data(sc, msgs[i].buf + read_off,
 1222                             to_read, &act_read);
 1223                         if (err != 0)
 1224                                 break;
 1225                         KASSERT(act_read <= to_read, ("cp2112iic_read_data "
 1226                             "returned more data than asked"));
 1227                         read_off += act_read;
 1228                         to_read -= act_read;
 1229                 }
 1230                 if (err != 0)
 1231                         break;
 1232         }
 1233 
 1234         mtx_unlock(&sc->io.lock);
 1235         return (err);
 1236 }
 1237 
 1238 static int
 1239 cp2112iic_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr)
 1240 {
 1241         struct i2c_cfg_req i2c_cfg;
 1242         struct cp2112iic_softc *sc;
 1243         device_t cp2112;
 1244         u_int busfreq;
 1245         int err;
 1246 
 1247         sc = device_get_softc(dev);
 1248         cp2112 = device_get_parent(dev);
 1249         if (sc->iicbus_dev == NULL)
 1250                 busfreq = 100000;
 1251         else
 1252                 busfreq = IICBUS_GET_FREQUENCY(sc->iicbus_dev, speed);
 1253 
 1254         err = cp2112_get_report(cp2112, CP2112_REQ_SMB_CFG,
 1255             &i2c_cfg, sizeof(i2c_cfg));
 1256         if (err != 0) {
 1257                 device_printf(dev, "failed to get CP2112_REQ_SMB_CFG report\n");
 1258                 return (err);
 1259         }
 1260 
 1261         if (oldaddr != NULL)
 1262                 *oldaddr = i2c_cfg.slave_addr;
 1263         /*
 1264          * For simplicity we do not enable Auto Send Read
 1265          * because of erratum CP2112_E101 (fixed in version 3).
 1266          *
 1267          * TODO: set I2C parameters based on configuration preferences:
 1268          * - read and write timeouts (no timeout by default),
 1269          * - SCL low timeout (disabled by default),
 1270          * etc.
 1271          *
 1272          * TODO: should the device reset request (0x01) be sent?
 1273          * If the device disconnects as a result, then no.
 1274          */
 1275         i2c_cfg.speed = htobe32(busfreq);
 1276         if (addr != 0)
 1277                 i2c_cfg.slave_addr = addr;
 1278         i2c_cfg.auto_send_read = 0;
 1279         i2c_cfg.retry_count = htobe16(1);
 1280         i2c_cfg.scl_low_timeout = 0;
 1281         if (bootverbose) {
 1282                 device_printf(dev, "speed %d Hz\n", be32toh(i2c_cfg.speed));
 1283                 device_printf(dev, "slave addr 0x%02x\n", i2c_cfg.slave_addr);
 1284                 device_printf(dev, "auto send read %s\n",
 1285                     i2c_cfg.auto_send_read ? "on" : "off");
 1286                 device_printf(dev, "write timeout %d ms (0 - disabled)\n",
 1287                     be16toh(i2c_cfg.write_timeout));
 1288                 device_printf(dev, "read timeout %d ms (0 - disabled)\n",
 1289                     be16toh(i2c_cfg.read_timeout));
 1290                 device_printf(dev, "scl low timeout %s\n",
 1291                     i2c_cfg.scl_low_timeout ? "on" : "off");
 1292                 device_printf(dev, "retry count %d (0 - no limit)\n",
 1293                     be16toh(i2c_cfg.retry_count));
 1294         }
 1295         err = cp2112_set_report(cp2112, CP2112_REQ_SMB_CFG,
 1296             &i2c_cfg, sizeof(i2c_cfg));
 1297         if (err != 0) {
 1298                 device_printf(dev, "failed to set CP2112_REQ_SMB_CFG report\n");
 1299                 return (err);
 1300         }
 1301         return (0);
 1302 }
 1303 
 1304 static int
 1305 cp2112iic_probe(device_t dev)
 1306 {
 1307         device_set_desc(dev, "CP2112 I2C interface");
 1308         return (BUS_PROBE_SPECIFIC);
 1309 }
 1310 
 1311 static int
 1312 cp2112iic_attach(device_t dev)
 1313 {
 1314         struct cp2112iic_softc *sc;
 1315         struct cp2112_softc *psc;
 1316         device_t cp2112;
 1317         int err;
 1318 
 1319         sc = device_get_softc(dev);
 1320         sc->dev = dev;
 1321         cp2112 = device_get_parent(dev);
 1322         psc = device_get_softc(cp2112);
 1323 
 1324         mtx_init(&sc->io.lock, "cp2112iic lock", NULL, MTX_DEF | MTX_RECURSE);
 1325         cv_init(&sc->io.cv, "cp2112iic cv");
 1326 
 1327         err = usbd_transfer_setup(psc->sc_udev,
 1328             &psc->sc_iface_index, sc->xfers, cp2112iic_config,
 1329             nitems(cp2112iic_config), sc, &sc->io.lock);
 1330         if (err != 0) {
 1331                 device_printf(dev, "usbd_transfer_setup failed %d\n", err);
 1332                 goto detach;
 1333         }
 1334 
 1335         /* Prepare to receive interrupts. */
 1336         mtx_lock(&sc->io.lock);
 1337         usbd_transfer_start(sc->xfers[CP2112_INTR_IN]);
 1338         mtx_unlock(&sc->io.lock);
 1339 
 1340         sc->iicbus_dev = device_add_child(dev, "iicbus", -1);
 1341         if (sc->iicbus_dev == NULL) {
 1342                 device_printf(dev, "iicbus creation failed\n");
 1343                 err = ENXIO;
 1344                 goto detach;
 1345         }
 1346         bus_generic_attach(dev);
 1347         return (0);
 1348 
 1349 detach:
 1350         cp2112iic_detach(dev);
 1351         return (err);
 1352 }
 1353 
 1354 static int
 1355 cp2112iic_detach(device_t dev)
 1356 {
 1357         struct cp2112iic_softc *sc;
 1358         int err;
 1359 
 1360         sc = device_get_softc(dev);
 1361         err = bus_generic_detach(dev);
 1362         if (err != 0)
 1363                 return (err);
 1364         device_delete_children(dev);
 1365 
 1366         mtx_lock(&sc->io.lock);
 1367         usbd_transfer_stop(sc->xfers[CP2112_INTR_IN]);
 1368         mtx_unlock(&sc->io.lock);
 1369         usbd_transfer_unsetup(sc->xfers, nitems(cp2112iic_config));
 1370 
 1371         cv_destroy(&sc->io.cv);
 1372         mtx_destroy(&sc->io.lock);
 1373 
 1374         return (0);
 1375 }
 1376 
 1377 static device_method_t cp2112hid_methods[] = {
 1378         DEVMETHOD(device_probe,         cp2112_probe),
 1379         DEVMETHOD(device_attach,        cp2112_attach),
 1380         DEVMETHOD(device_detach,        cp2112_detach),
 1381 
 1382         DEVMETHOD_END
 1383 };
 1384 
 1385 static driver_t cp2112hid_driver = {
 1386         .name = "cp2112hid",
 1387         .methods = cp2112hid_methods,
 1388         .size = sizeof(struct cp2112_softc),
 1389 };
 1390 
 1391 DRIVER_MODULE(cp2112hid, uhub, cp2112hid_driver, NULL, NULL);
 1392 MODULE_DEPEND(cp2112hid, usb, 1, 1, 1);
 1393 MODULE_VERSION(cp2112hid, 1);
 1394 USB_PNP_HOST_INFO(cp2112_devs);
 1395 
 1396 static device_method_t cp2112gpio_methods[] = {
 1397         /* Device */
 1398         DEVMETHOD(device_probe,         cp2112gpio_probe),
 1399         DEVMETHOD(device_attach,        cp2112gpio_attach),
 1400         DEVMETHOD(device_detach,        cp2112gpio_detach),
 1401 
 1402         /* GPIO */
 1403         DEVMETHOD(gpio_get_bus,         cp2112_gpio_get_bus),
 1404         DEVMETHOD(gpio_pin_max,         cp2112_gpio_pin_max),
 1405         DEVMETHOD(gpio_pin_get,         cp2112_gpio_pin_get),
 1406         DEVMETHOD(gpio_pin_set,         cp2112_gpio_pin_set),
 1407         DEVMETHOD(gpio_pin_toggle,      cp2112_gpio_pin_toggle),
 1408         DEVMETHOD(gpio_pin_getname,     cp2112_gpio_pin_getname),
 1409         DEVMETHOD(gpio_pin_getcaps,     cp2112_gpio_pin_getcaps),
 1410         DEVMETHOD(gpio_pin_getflags,    cp2112_gpio_pin_getflags),
 1411         DEVMETHOD(gpio_pin_setflags,    cp2112_gpio_pin_setflags),
 1412 
 1413         DEVMETHOD_END
 1414 };
 1415 
 1416 static driver_t cp2112gpio_driver = {
 1417         .name = "gpio",
 1418         .methods = cp2112gpio_methods,
 1419         .size = sizeof(struct cp2112gpio_softc),
 1420 };
 1421 
 1422 DRIVER_MODULE(cp2112gpio, cp2112hid, cp2112gpio_driver, NULL, NULL);
 1423 MODULE_DEPEND(cp2112gpio, cp2112hid, 1, 1, 1);
 1424 MODULE_DEPEND(cp2112gpio, gpiobus, 1, 1, 1);
 1425 MODULE_VERSION(cp2112gpio, 1);
 1426 
 1427 static device_method_t cp2112iic_methods[] = {
 1428         /* Device interface */
 1429         DEVMETHOD(device_probe, cp2112iic_probe),
 1430         DEVMETHOD(device_attach, cp2112iic_attach),
 1431         DEVMETHOD(device_detach, cp2112iic_detach),
 1432 
 1433         /* I2C methods */
 1434         DEVMETHOD(iicbus_transfer, cp2112iic_transfer),
 1435         DEVMETHOD(iicbus_reset, cp2112iic_reset),
 1436         DEVMETHOD(iicbus_callback, iicbus_null_callback),
 1437 
 1438         DEVMETHOD_END
 1439 };
 1440 
 1441 static driver_t cp2112iic_driver = {
 1442         "iichb",
 1443         cp2112iic_methods,
 1444         sizeof(struct cp2112iic_softc)
 1445 };
 1446 
 1447 DRIVER_MODULE(cp2112iic, cp2112hid, cp2112iic_driver, NULL, NULL);
 1448 MODULE_DEPEND(cp2112iic, cp2112hid, 1, 1, 1);
 1449 MODULE_DEPEND(cp2112iic, iicbus, IICBUS_MINVER, IICBUS_PREFVER, IICBUS_MAXVER);
 1450 MODULE_VERSION(cp2112iic, 1);

Cache object: 7da6df695eb52ab81e4dcf24a1db0e4a


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.