SC16IS7xx Serial expander support Device Tree

Dear Community,

I’m currently trying to integrate the SC16IS752 (SC16IS7xx Datasheet) into one of my Jetson Nano projects.
The chip acts as a UART expander from I2C or SPI to two more Serial ports.
There even is a driver in the kernel (driver).
For testing purposes, I use the Waveshare breakout board (WS breakout). Since this product is originally designed for the Raspberry Pi, some additional steps are necessary for using the IC with the Jetson Nano.
First, I modified the Tegra kernel config such that the driver is built as a module and installed. ( I used the scripts provided by jetson hacks to perform these tasks: scripts)
As a second step, the Device Tree needs to be adapted. Therefore, I extracted the entire tree with the command
dtc -I fs -O dts -o extracted.dts /proc/device-tree
The extracted device tree : extracted.txt (284.1 KB)
I think, that I need to add the DT node for the SC16 in the i2c@7000c400 block. (Line 9258), since this block corresponds to i2c1.
For the entry which I need to add at this place, I had a look at the DT overlay for Raspberry Pi.
I figured the IC source clock (clocks), max frequency, interrupt parent, phandle, reg and clock-frequency as well as the phandle and clock-frequency for clk out. But I have a problem with the interrupts field. I set the last value to IRQ_TYPE_LEVEL_HIGH according to the irq.h. But I do not know, how to get the middle field. For reference, I posted my proposed DT entry below. I hope, someone can help me with the interrupts field.

sc16is752@48 {
    compatible = "nxp,sc16is752";
    clocks = <0x81>; # phandle to the IC source clock
    gpio-controller;
    status = "okay";
    i2c-max-frequency = <0x61a80>; # 400000 Hz
    interrupt-parent = <0x118>; # i2c phandle
    #interrupts = <0x1f1 0x2>;
    interrupts = <0x0 ?? 0x4>;
    phandle = <0x02>; #Process Handle, should be unique
    reg = <0x48>; # IC I2C address
    #gpio-cells = <0x0>;
    clock-frequency = <0xbb8000>; # 12288000 Hz

    sc16is752_clk {
        compatible = "fixed-clock";
        #clock-cells = <0x0>;
        phandle = <0x01>; # Process Handle, should be unique
        clock-frequency = <0xe10000>; # 14745600 Hz
    };
}; 

Please let me know, if you need any further information
Thank you and have a nice day. ;)

hello LeWerner,

please access L4T sources from download center,
you may check kernel documentation for more details.
for example,
$L4T_Sources/r32.4.3/Linux_for_Tegra/source/public/kernel/nvidia/Documentation/devicetree/bindings/mmc/sdhci-tegra.txt

Hello JerryChang,

first of all thank you very much for your fast answer!

I had a closer look at the kernel documentation files.
The interrupts property Should contain the UART interrupt according to the nxp,sc16is7xx.txt. I am certain, that the first value if the interrupts property needs to be 0x0 and the last 0x4, but I have no idea, what for the middle one is, nor how I get this Information.
Sorry for my lack of experience with device trees, but I just don’t know, how to find this information.

Thank you very much for your time.
have a nice day

hello LeWerner,

middle one is the interrupt number, you may check below for more details.
thanks

$L4T_Sources/r32.4.3/Linux_for_Tegra/source/public/kernel/kernel-4.9/include/dt-bindings/interrupt-controller/*

Hi,

to all whom trying to do the same. I figured out, how to get the SC16IS752 working. Here comes the step by step way:

  1. Activate Driver in Kernel Config

  2. Add device Node to DT

  3. Change Pin Config of Interrupt Pin

To 1:
You can easily follow this tutorial until Step 3. After executing
make -C kernel/kernel-4.9/ ARCH=arm64 O=$TEGRA_KERNEL_OUT LOCALVERSION=-tegra CROSS_COMPILE=${TOOLCHAIN_PREFIX} tegra_defconfig
you need to go into the build directory and modify the .config file. just replace # CONFIG_SERIAL_SC16IS7XX is not set with the block:

CONFIG_SERIAL_SC16IS7XX_CORE=y
CONFIG_SERIAL_SC16IS7XX=y
CONFIG_SERIAL_SC16IS7XX_I2C=y
# CONFIG_SERIAL_SC16IS7XX_SPI is not set

and proceed with Step Nr. 2: Add Device Node to DT

To2:
The presented parameters are Valid for the Jetson Nano Developer Kit with the SC16IS752 breakout board linked in my first post.
To add the proper entry in the Device Tree, the file:
.../Linux_for_Tegra/source/public/hardware/nvidia/soc/t210/kernel-dts/tegra210-soc/tegra210-soc-shield.dtsi
needs to be modified.
Here,

i2c@7000c400 {
status = “okay”;
}

can be replaced with the following entry for the SC16IS752 at i2c:

i2c@7000c400 {
status = “okay”;
sc16is752: sc16is752@48 {
compatible = “nxp,sc16is752”;
clocks = <&sc16is752_clk>;
gpio-controller;
status = “okay”;
i2c-max-frequency = <400000>;
interrupt-parent = <&gpio>;
interrupts = <15 2>;
reg = <0x48>; // IC I2C address
#gpio-cells = <0x0>;
clock-frequency = <12288000>;
sc16is752_clk: sc16is752_clk {
compatible = “fixed-clock”;
#clock-cells = <0>;
clock-frequency = <14745600>;
};
};
};

After that, go on with Step 3: Change Pin Config of Interrupt Pin

To 3:
Download the Pinmux Spreadsheet. Pin 18 (spi2_cs0) needs to be modified to GPIO3_PB.07. The Pin Direction must be Input and the Req. Initial State Int PU. The outputted .dtsi files are subject to replace the tegra210-porg-gpio-p3448-0000-a02.dtsi and tegra210-porg-pinmux-p3448-0000-a02.dtsi files in the folder Linux_for_Tegra/source/public/hardware/nvidia/platform/t210/porg/kernel-dts/porg-platforms. Although the official guide for configuring the 40Pin header suggests updating the U-Boot Pinmux, I strongly recommend not to do so, since U-BOOT doesn’t seem to be used by the current version of L4T. Instead CBOOT is used.

After following these steps, you can proceed with the ridgerun tutorial. For updating the CBOOT pin configuration, you need to perform a full flash.

You can find your two extra UART devices at /dev/ttySC0 and /dev/ttySC1
I hoped, I saved you some time tinkering.

Cheers

2 Likes

Nice! Thanks for your sharing to community!