sc16is7xx(4)

NAME
sc16is7xx - Driver for NXP SC16IS7xx family of UART bridges via a I2C or SPI bus

SYNOPSIS
sc16is7xx* at iic? addr 0x48
sc16is7xx* at iic? addr 0x49
sc16is7xx* at iic? addr 0x4a
sc16is7xx* at iic? addr 0x4b
sc16is7xx* at iic? addr 0x4c
sc16is7xx* at iic? addr 0x4d
sc16is7xx* at iic? addr 0x4e
sc16is7xx* at iic? addr 0x4f
sc16is7xx* at iic? addr 0x50
sc16is7xx* at iic? addr 0x51
sc16is7xx* at iic? addr 0x52
sc16is7xx* at iic? addr 0x53
sc16is7xx* at iic? addr 0x54
sc16is7xx* at iic? addr 0x55
sc16is7xx* at iic? addr 0x56
sc16is7xx* at iic? addr 0x57
sc16is7xx* at spi? slave 0
sc16is7xx* at spi? slave 1
options SC16IS7XX_SPI_FREQUENCY=4
com* at sc16is7xx?
gpio* at gpiobus?

DESCRIPTION
The sc16is7xx driver provides one or two UART interfaces and a gpio bus over I2C or SPI. The sc16is7xx addr argument selects the address at the iic(4) bus and the sc16is7xx slave argument selects which chip select will be used on the spi(4) bus. The UART is mostly register compatiable with the 16C450, although it does have aspects of the 16C550 and 16C660. This driver just provides the frontend half and uses com(4) for the backend half. The sc16is7xx is compatiable with COM_16550 and COM_16660. If the COM_ option is left out entirely a 64 byte FIFO, hardware flow control and the automatic use of the prescaler will be enabled.

The prescaler is a additional divide by 4 factor that is mostly used when the baud rate clock has a very high frequency and there is an attempt to use a very low baud rate. In that case, the divider will exceed the number of bits provided by the clock divider registers. The additional prescaler factor will allow for these low baud rates in this case.

The SC16IS7XX_SPI_FREQUENCY can used to set the SPI clock frequency from 1 to 4 or 1 to 15 in Mhz depending on the chip varient.

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

hw.sc16is7xx0.frequency
    This sysctl can be used to set the clock frequency that is being used by the chip to generate the baud rate. There is no standard frequency for this clock, although 14.7456 Mhz is common, but 1.8432 Mhz, 3.072 Mhz and 12.000 Mhz are also known to exist. This value is in Hz and must be set correctly for the baud rate to work as expected. The SC16IS7XX_DEFAULT_FREQUENCY kernel option and the clock-frequency option in a FDT overlay can also be used to set this value.

hw.sc16is7xx0.poll
    The chip supports a interrupt line to a gpio pin that can be used on systems that have FDT support. If the driver can not make use of this interrupt line then it will use a polling kernel thread to check for an interrupt. This sysctl adjusts how often this thread checks. It is in ms and defaults to 50. It is very possible to saturate a I2C bus if the checks are too frequent, but if they are not often enough there will be latency in the processing of incoming and outgoing characters.

Unexpected behavior may result if the frequency is changed while something has the port open.

FDT
On systems that support FDT the following can be used to enable the driver and set parameters:

/dts-v1/;
/plugin/;
/ {
        compatible = "brcm,bcm2835";
        fragment@0 {
                target = <&spi>;
                __overlay__ {
                        status = "okay";
                        pinctrl-names = "default";
                        pinctrl-0 = <&spi0_gpio7>;
                        sc16is750@0 {
                                compatible = "nxp,sc16is750";
                                reg = <0x00>;
                                interrupt-parent = <&gpio>;
                                interrupts = <17 2>;
				gpio-controller;
                        };
                };
        };
};
The above is for a Raspberry PI 3 for enabling the the spi bus itself and the sc16is7xx device on the spi0 bus and allowing it to use gpio pin 17 with a negative edge interrupt. Since "gpio-controller;" was specified a gpiobus will be attached.

/dts-v1/;
/plugin/;
/ {
        compatible = "brcm,bcm2837";
        fragment@0 {
                target= <&i2c1>;
                __overlay__ {
                        sc16is740@48 {
                                compatible = "nxp,sc16is740";
                                reg = <0x48>;
                                clock-frequency = <14745600>;
                                interrupt-parent = <&gpio>;
                                interrupts = <17 2>;
                        };
                };
        };
};
The above is also for a Raspberry PI 3 that configures a SC16IS740 for an I2C bus. Since "gpio-controller;" was not specified, no gpiobus will be attached.

GPIO
There are a number of family members for this chip. All of them except the SC16IS740 and SC16IS741 have gpio(4) pins. These pins are simple input and output pins and in many cases share a ALT0 function that allows them to be modem control lines.

Pin | SC16IS750 / SC16IS760 | ALT0 | SC16IS752 / SC16IS762 | ALT0 | Bank
GP0 | GP0 | - | GP0 | DSRB | B
GP1 | GP1 | - | GP1 | DTRB | B
GP2 | GP2 | - | GP2 | CDB | B
GP3 | GP3 | - | GP3 | RIB | B
GP4 | GP4 | DSR | GP4 | DSRA | A
GP5 | GP5 | DTR | GP5 | DTRA | A
GP6 | GP6 | CD | GP6 | CDA | A
GP7 | GP7 | RI | GP7 | RIA | A

If any of the pins are configured as modem control lines, the entire bank of 4 pins will be modem control lines. Likewise, if any of the pins in a bank are configured for input or output, the entire bank of pins will be input or output and the modem control will be removed.

It is not possible to tell the difference between a SC16IS74x varient from a SC16IS750 or SC16IS760, so gpio(4) will be present on both variants. If FDT can be used, a the "gpio-controller;" directive can be used to tell more specifically if the GPIO pins are present. In the FDT case, if "gpio-controller;" is left out and the chip has GPIO pins, then they will be turned into their respective modem control pins.

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

HISTORY
The sc16is7xx driver first appeared in NetBSD 12.0.

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

BUGS
The driver does not support all of the aspects of the chip family, in particular, the RS-485 and IrDA modes. The driver is unlikely to work as a console or with KGDB. There are assumptions built into the com(4) backend that assumes that the chip is connected directly to the computer bus and this will not be true for the SC16IS7XX family of devices.

A kernel panic will happen if an attempt is made to attach another driver to the gpio pins of the SC16IS7XX using gpioctl or by compiling a kernel with such an attachment. The SPI or I2C bus needs to wait while the transfer is in progress and the other driver will attempt to do the attachment with a spin lock held.

The bandwidth of the I2C bus is typically set to 100 kbits/sec. Attempting to use higher baud rates, especially without flow control, may result in excessive silo overlows. An SPI bus may perform better, but silo overflows can still happen.