Updated: 2025/Dec/31

Please read Privacy Policy. It's for your privacy.


UMCPMIO(4)                   Device Drivers Manual                  UMCPMIO(4)

NAME
     umcpmio - Microchip Technologies MCP2210, MCP2221/MCP2221A multi-io
     bridge

SYNOPSIS
     umcpmio* at uhidev? reportid ?
     gpio* at gpiobus?
     spi* at umcpmio?
     iic* at umcpmio?        # or
     iic* at i2cbus?

DESCRIPTION
     The umcpmio driver provides support for the MCP2210 and MCP2221/MCP2221A
     multi-io bridge chips.  The MCP2210 provides 9 simple gpio pins with
     multiple functions that attach as a gpio(4) device and the ability to do
     SPI via the spi(4) framework.  The pins function as gpio(4) pins or as
     chip select for the spi(4) function.  The MCP2221 provides 4 simple gpio
     pins with multiple functions that attach as a gpio(4) device, an I2C port
     that attaches as an iic(4) device and a UART serial port that attaches
     using umodem(4) as a normal ucom(4) ttyU* device.  The UART is presented
     as one USB function, while the GPIO and I2C pins are presented as a
     second HID USB function.

   GPIO on the MCP2210
     There are 9 basic gpio pins available with the following functions:

     +-----------+-----+-----+-------+--------------+--------+--------+--------------+-------------+-------------+
     |Assignment | GP0 | GP1 | GP2   | GP3          | GP4    | GP5    | GP6          | GP7         | GP8         |
     +===========+=====+=====+=======+==============+========+========+==============+=============+=============+
     |GPIO       | I/O | I/O | I/O   | I/O          | I/O    | I/O    | I/O          | I/O         | I           |
     |ALT0       | CS  | CS  | CS    | CS           | CS     | CS     | CS           | CS          | -           |
     |ALT3       | -   | -   | SSPND | SPI activity | LOWPWR | USBCFG | Falling edge | Release ACK | Release REQ |
     |ALT4       | -   | -   | -     | -            | -      | -      | Rising edge  | -           | -           |
     |ALT5       | -   | -   | -     | -            | -      | -      | Low pulse    | -           | -           |
     |ALT6       | -   | -   | -     | -            | -      | -      | High pulse   | -           | -           |
     +-----------+-----+-----+-------+--------------+--------+--------+--------------+-------------+-------------+
     The IRQ counter on GP6 can be read with a sysctl(8).  The manor in which
     the GP6 IRQ counter detects the event is configured by setting it to ALT3
     to ALT6.  GP8 is only an input pin when configured for gpio purposes.
     The chip select, CS, function will be enabled automatically if a request
     to use the spi(4) framework is performed that requests the use of the
     associated chip select pin.

   SPI
     The MCP2210 supports a basic SPI engine via the spi(4) framework.
     Various SPI delays are configured with umcpmioctl(8).

     The SPI engine on the MCP2210 only functions in full duplex mode.  That
     is, it is not possible to just send bytes without also receiving them.
     The driver will queue up any recived bytes that might have come though on
     a transaction and present them to the upstream layer from the queue when
     asked.  This queue will be cleared out for a particular slave address
     when a configuration call is made against a particular slave device.

     Upon making a configuration call to the umcpmio driver, the driver will
     set the pin associated with the requested slave address to ALT0.  Since
     the spi(4) framework does not support the notion of a session, this pin
     will never be reset by the umcpmio driver.  Further, it is entirely
     possible to use gpioctl(8) to change the pin assignment in such a way
     that SPI no longer works as it is also not possible to know if a pin is
     in use at any moment in time.

   EEPROM
     The MCP2210 has 256 bytes of EEPROM available via the /dev/umcpmio0EEP
     device.  Random reads and writes may be performed against this device,
     but there can only one one opener at a time.

   GPIO on the MCP2221
     There are 4 basic gpio pins available with the following functions:

           +-----------+---------+--------------+--------+--------------+
           |Assignment | GP0     | GP1          | GP2    | GP3          |
           +===========+=========+==============+========+==============+
           |GPIO       | I/O     | I/O          | I/O    | I/O          |
           |ALT0       | UART RX | ADC1         | ADC2   | ADC3         |
           |ALT1       | -       | UART TX      | DAC1   | DAC2         |
           |ALT2       | -       | IRQ          | -      | -            |
           |ALT3       | SSPND   | Clock output | USBCFG | I2C activity |
           +-----------+---------+--------------+--------+--------------+
     ADC1, ADC2 and ADC3 are independent of each other and each 10 bits in
     length.  To utilize one of the ADC pins, an open(2) is performed against
     /dev/umcpmio0GP1, /dev/umcpmio0GP2 or /dev/umcpmio0GP3 with only the
     O_RDONLY flag set.  Reads against the open file descriptor will produce
     uint16_t values.

     There is actually only one DAC present in the chip, but it is mirrored to
     GP2 and GP3 if the pin is set to ALT1.  The DAC is 5 bits in length, and
     to use it, an open(2) is performed against /dev/umcpmio0GP2 or
     /dev/umcpmio0GP3 with only the O_WRONLY flag set.  Writes of uint8_t
     bytes to the file descriptor will result in an analog signal being
     created on the output pin.

     The clock output is derived from the USB clock of 48MHz.  The duty cycle
     and clock divider can be adjusted with sysctl(8) variables.  To utilize
     GP1 as the clock output, the ALT3 function can be set with gpioctl(8)
     command.

   I2C
     The MCP2221/MCP2221A supports a hardware I2C port with a simple scripting
     engine.  When the driver attaches, the I2C speed is set to 100Kb/s.  The
     ability to perform an I2C READ without a STOP is not supported by the
     MCP2221/MCP2221A engine and the driver turns a READ without STOP into a
     READ with STOP.  This behavior is just an attempt to allow a device to
     function, and it may not work for any particular device.  In particular,
     it is known that the ds2482ow(4) device will not work as expected.

     The MCP2221/MCP2221A chip will automatically detect and deal with a
     device that uses I2C clock stretching.

   UART
     The UART on the MCP2221/MCP2221A utilizes the umodem(4) driver.  The UART
     function of the chip only supports 8-N-1 communications.

SYSCTL VARIABLES
     The following sysctl(3) variables are provided:

     hw.umcpmio0.debug
     hw.umcpmio0.dump_buffers
                       If UMCPMIO_DEBUG is defined, additional debugging
                       output can be enabled.

     hw.umcpmio0.response_wait
     hw.umcpmio0.response_errcnt
                       This is how long the driver will wait for a HID
                       response to come back from the chip.  This variable is
                       in microseconds and defaults to 2500.  The driver will
                       only allow response_errcnt number of errors when
                       waiting for a response from a HID report.  This
                       includes timeouts due to exceeding response_wait.

   MCP2210
     hw.umcpmio0.spi.verbose
                       Enable or disable verbose connection reset messages
                       when there are errors.

     hw.umcpmio0.spi.busy_delay
                       When the MCP2210 is busy, use busy_delay number of ms
                       to wait before trying the operation again.  The default
                       is 0 as there usually will not be any reason is wait.

     hw.umcpmio0.spi.retry_busy_chipdrain
     hw.umcpmio0.spi.retry_busy_transfer
                       The number of times to retry either a chipdrain or
                       transfer operation.  A chipdrain is used when the chip
                       has sent back data, but the upstream is not ready for
                       it yet.  A transfer is a normal SPI transfer.

     hw.umcpmio0.gpio.counter
     hw.umcpmio0.gpio.reset_counter
                       When the GP6 pin is set to ALT3 to ALT6, this sysctl
                       reads back the counter.  To reset the counter write 1
                       to the reset_counter sysctl.  The counter will also be
                       reset if any pin changes from a input or output pin to
                       one of the ALT functions or vise versa.  The trigger
                       for this could be the use of gpioctl(8) or if the pin
                       is changed to become a CS from a general I/O pin for
                       the spi(4) infrastructure.

   MCP2221/MCP2221A
     hw.umcpmio0.i2c.reportreadnostop
                       Report on the console if a driver attempts to use an
                       I2C READ without STOP.  A READ without STOP is not
                       supported by the MCP2221/MCP2221A I2C engine and will
                       be turned into a READ with STOP by the driver.

     hw.umcpmio0.i2c.busy_delay
                       The driver checks in a number of cases if the I2C
                       engine is busy and will wait for busy_delay
                       microseconds before checking again.

     hw.umcpmio0.i2c.retry_busy_read
                       The number of times to try to do an I2C READ when the
                       engine is busy.

     hw.umcpmio0.i2c.retry_busy_write
                       The number of times to try to do an I2C WRITE when the
                       engine is busy.

     hw.umcpmio0.gpio.clock_duty_cycle
     hw.umcpmio0.gpio.clock_divider
                       When GP1 is configured to use function ALT3, it will
                       output a clock pulse.  The valid values for
                       clock_duty_cycle are `75%', `50%', `25%', and `0%'.
                       That is, 75% of the time a high and 25% of the time a
                       low will be present on the GP1 pin.  The valid values
                       for clock_divider are `375kHz', `750kHz', `1.5MHz',
                       `3MHz', `6MHz', `12MHz', and `24MHz'.

     hw.umcpmio0.dac.vref
     hw.umcpmio0.adc.vref
                       Sets the VREF value for the DAC or ADC.  The valid
                       values are `4.096V', `2.048V', `1.024V', `OFF', and
                       `VDD'.

FILES
     /dev/umcpmio0ctl                  A control device for the chip instance
                                       that allows for a number of IOCTLs.

     /dev/umcpmio0GP1
     /dev/umcpmio0GP2
     /dev/umcpmio0GP3                  Device files that allow access to the
                                       ADC or DAC functions of the associated
                                       gpio pin on the MCP2221/MCP2221A.

     /dev/umcpmio0EEP                  Device file that interacts with the
                                       EEPROM on the MCP2210.

SEE ALSO
     gpio(4), iic(4), spi(4), sysctl(8), umcpmioctl(8)

HISTORY
     The umcpmio driver first appeared in NetBSD 11.0.  Support for the
     MCP2210 was added in NetBSD 12.0.

AUTHORS
     The umcpmio driver was written by Brad Spencer <brad@anduin.eldar.org>.

BUGS
     The gpio pins on the these two chips are very slow and one should not
     expect to be able to rapidly change their state.  Even if the problem
     mentioned below did not exist, one should not expect to be able to use
     any of the gpio bit banger drivers such as gpioiic(4) or gpioow(4).

     The interrupt function of the MCP2221/MCP2221A on GP1 cannot currently be
     used because it is currently not possible to attach through the driver.
     There may be two possible problems going on:

        The gpio(4) framework runs at IPL_VM with a spin lock and when it
         attempts to establish an interrupt that uses the gpio from umcpmio,
         calls are made into the USB stack that will want to wait in a way
         that is not allowed while holding a spin lock.

        autoconf(9) runs with KERNEL_LOCK and during the attachment, this
         lock is held when calls are made into the USB stack that will cause a
         wait that is not allowed while holding KERNEL_LOCK.

     Either or both of these may be going on, but the end result is that the
     kernel will panic while attempting to perform a USB transfer while
     another driver is attempting to attach through umcpmio.

     Likewise, a `gpioctl gpio1 attach ...' type call will also panic for the
     same reason.

     The end result is that gpioirq(4), gpiopps(4) and gpioow(4) will not work
     with the gpio from umcpmio.

     Please note that the umcpmio driver itself can use the USB stack during
     attachment and there does not appear to be any problems using the GPIO
     pins or setting GPIO pin configurations.  It is only when the driver is a
     target during another driver's attachment that there is a problem.

     The ability to set or change values in most of the chip's FLASH memory is
     not supported.  This includes changing the configuration protection
     password.  Likewise, support for entering the configuration protection
     password does not exist, should a particular chip have password
     protection enabled.

     On the MCP2210, changing any pin from INPUT or OUTPUT to ALTx or vise
     versa has to rewrite some of the setting for all pins.  A consequence of
     doing this is that for a very brief time, the default direction and
     values will be set on all pins.  This has the biggest impact on OUTPUT
     pins which might generate a small pulse.  This behavior really can't be
     avoided as there is no way with the MCP2210 to write the configuration of
     just one pin at a time.  For this same reason, the IRQ event counter will
     be reset if any pin switches from INPUT or OUTPUT to ALTx or vise versa.

     The MCP2210 supports active high or active low CS signals per CS.
     However, the spi(4) framework does not have any way to specify the
     direction of the CS signal, so the only SPI CS signal supported is the
     usual active low signal.

NetBSD 11.99                   November 13, 2025                  NetBSD 11.99