Can't set GPIO through DTB files?

I’m setting pins on the Orin Nano devkit running on JetPack 5.1.1. I generated the .dtsi files via spreadsheet, placed them in the right folders, set the pinmux/padvoltage environmental variables in the .conf file to point to the generated .dtsi files, and flashed the Orin Nano.
After flashing, I updated the .dtb file and the extlinux.conf file to configure the pins:

	pinmux@2430000 {
		pinctrl-0 = <0x499>;
		pinctrl-names = "default";
		compatible = "nvidia,tegra234-pinmux";
		reg = <0x00 0x2430000 0x00 0x19100 0x00 0xc300000 0x00 0x4000>;
		#gpio-range-cells = <0x03>;
		status = "okay";
		phandle = <0x2b2>;

		exp-header-pinmux {
			phandle = <0x499>;

			hdr40-pin37 {
				nvidia,enable-input = <0x01>;
				nvidia,tristate = <0x00>;
				nvidia,function = "spi3";
				nvidia,pins = "spi3_mosi_py2";
			};

			hdr40-pin22 {
				nvidia,enable-input = <0x01>;
				nvidia,tristate = <0x00>;
				nvidia,function = "spi3";
				nvidia,pins = "spi3_miso_py1";
			};

			hdr40-pin18 {
				nvidia,enable-input = <0x01>;
				nvidia,tristate = <0x00>;
				nvidia,function = "spi3";
				nvidia,pins = "spi3_cs0_py3";
			};

			hdr40-pin16 {
				nvidia,enable-input = <0x01>;
				nvidia,tristate = <0x00>;
				nvidia,function = "spi3";
				nvidia,pins = "spi3_cs1_py4";
			};

			hdr40-pin13 {
				nvidia,enable-input = <0x01>;
				nvidia,tristate = <0x00>;
				nvidia,function = "spi3";
				nvidia,pins = "spi3_sck_py0";
			};

			hdr40-pin36 {
					nvidia,pins = "uart1_cts_pr5";
					nvidia,function = "rsvd1";
					nvidia,tristate = <0x00>;
					nvidia,enable-input = <0x01>;
					nvidia,pull = <0x00>;
					nvidia,lpdr = <0x00>;
			};

		};

And I set pin 36 as a GPIO input (see gpio-default):

        gpio@2200000 {
                compatible = "nvidia,tegra234-gpio";
                reg-names = "security\0gpio";
                reg = <0x00 0x2200000 0x00 0x10000 0x00 0x2210000 0x00 0x10000>;
                interrupts = <0x00 0x120 0x04 0x00 0x121 0x04 0x00 0x122 0x04 0x00 0x123 0x04 0x00 0x124 0x04 0x00 0x125 0x04 0x00 0x126 0x04 0x00 0x127 0x04 0x00 0x128 0x04 0x00 0x129 0x04 0x00 0x12a 0x04 0x00 0x12b 0x04 0x00 0x12c 0x04 0x00 0x12d 0x04 0x00 0x12e 0x04 0x00 0x12f 0x04 0x00 0x130 0x04 0x00 0x131 0x04 0x00 0x132 0x04 0x00 0x133 0x04 0x00 0x134 0x04 0x00 0x135 0x04 0x00 0x136 0x04 0x00 0x137 0x04 0x00 0x138 0x04 0x00 0x139 0x04 0x00 0x13a 0x04 0x00 0x13b 0x04 0x00 0x13c 0x04 0x00 0x13d 0x04 0x00 0x13e 0x04 0x00 0x13f 0x04 0x00 0x140 0x04 0x00 0x141 0x04 0x00 0x142 0x04 0x00 0x143 0x04 0x00 0x144 0x04 0x00 0x145 0x04 0x00 0x146 0x04 0x00 0x147 0x04 0x00 0x148 0x04 0x00 0x149 0x04 0x00 0x14a 0x04 0x00 0x14b 0x04 0x00 0x14c 0x04 0x00 0x14d 0x04 0x00 0x14e 0x04 0x00 0x14f 0x04>;
                gpio-controller;
                #gpio-cells = <0x02>;
                interrupt-controller;
                #interrupt-cells = <0x02>;
                gpio-ranges = <0x2b2 0x00 0x00 0x8a 0x2b2 0x8a 0x92 0x1a>;
                status = "okay";
                phandle = <0x5a>;

                gpio-default {
                        gpio-input = <0x85>;
                };
                camera-control-output-low {
                        gpio-hog;
                        output-low;
                        gpios = <0x3e 0x00 0xa0 0x00>;
                        label = "cam0-pwdn\0cam1-pwdn";
                };
        };

However, only the SPI3 pins are configured, not the GPIO pin when I list the pin states using Jetson-IO config-by-pin.py.

Can you please inform what additional steps need to be taken to configure GPIO on the Jetson using the dtsi/dts/dtb files? I am not interested in using command line tools like SYSFS or busybox for pinmux configuration.

Thanks.

Hi shah2,

These steps should be enough for your use case to configure the default pin state for GPIO.
They would be configured in MB1 during boot up.

You could just use sysfs and devmem to check if the configured pinmux applied correctly.

Hi KevinFFF

I simplified my steps to confirm that the pinmux is applied correctly:

  1. Generate .dtsi files via spreadsheet, place in folders
  2. Update pinmux/padvoltage variables in .conf file to generated .dtsi files
  3. Flash
  4. Read pin states using Jetson-IO config-by-pin.py

On bootup, the SPI, I2C, UART, etc pins are successful so we know .dtsi files are applied, but the SFIO pins aren’t set as GPIO pins even though this was done in the spreadsheet.

I unsuccessfully experimented with the bootup .dtb file by updating gpio@2200000, is more configuration needed here?

What else is needed to configure a SFIO pin as a GPIO? I will use some GPIOs as interrupts for a kernel device later, so command line tools like SYSFS or busybox aren’t options.

Have you confirmed the configuration in gpio.dtsi(which is also generated from the pinmux spreadsheet)?
The gpio.dtsi should also be included by your generated pinmux.dtsi.

Yes, if we look at the gpio.dtsi file pins like PR5 are set as GPIO inputs, but are not configured on bootup.


And I confirmed it is included in the pinmux.dtsi file:

And here is the definition of the PR5 pin in the pinmuxdefault class:
image

The SPI and other SFIO pins have the expected configuration settings in the above files.

I just change the nvidia,function in the generated pinmux.dtsi file from “rsvd1” to “gp”. Now, on bootup that pin has function uarta rather than unused according to jetson-io.
I used sudo cat /sys/kernel/debug/pinctrl/2430000.pinmux/pinconf-groupsto read the pin configuration details:

152 (uart1_cts_pr5): 
	pull=2
	tristate=1
	enable-input=1
	open-drain=0
	io-reset=0
	rcv-sel=0
	io-hv=0
	loopback=0
	schmitt=0
	pull-down-strength=0
	pull-up-strength=0
	drive-type=0
	func=uarta
	pad-power=0

So this pin still has function uarta even though I configured it as “gp” in the pinmux.dtsi file. I also disabled the other UARTA pins, and in the DTB we can under the system map address for UARTA (serial@3110000) its status is “disabled.”

Why is this still happening?

Where did you put the generated Orin-jetson-orin-nano-devkit-gpio-default.dtsi?

Please share your board config file and also pinmux and gpio dtsi as file here for further check.

Do you want to usePR.05 as GPIO input pin?

Please also share the pinmux spreadhseet.

The generated gpio.dtsi file is placed in Linux_for_Tegra/bootloader
I’m trying to configure PR.05 as GPIO input, as well as some other GPIO pins as input/output.

I changed UART1_TXD and UART1_RXD to unused in the spreadsheet and they appear with function rsvd1 on bootup.

The forum doesn’t allow .dtsi or .xlsm extensions and flags my .zip file as malicious so I’ve uploaded them on Github: GitHub - ShaheerRana/orin-nano-pinmux
For your convenience I’ve included .txt versions of the generated .dtsi and .conf files here:

Orin-jetson-orin-nano-devkit-gpio-default.txt (3.6 KB)
Orin-jetson-orin-nano-devkit-padvoltage-default.txt (2.4 KB)
Orin-jetson-orin-nano-devkit-pinmux .txt (65.8 KB)
Orin-jetson-orin-nano-devkit.txt (3.7 KB)

It seems you configuration and pinmux are correct.
PR.05 should be configured as input GPIO by default.

Could you run the following command and share the result?

$ sudo su
# cd /sys/class/gpio/
# echo 461 > export 
# cat PR.05/direction 
# cat PR.05/value 

I think GPIOs are working correctly.
However, I still can’t configure PR.05 as an interrupt. My .dts file:

spi@0 {
    compatible = "ti,tcan4x5x";
    reg = <0>;
    spi-max-frequency = <500000>;
    bosch,mram-cfg = <0x0 0 0 32 0 0 1 1>;
    pinctrl-names = "default";

    #interrupt-cells = <0x02>;
    interrupt-parent = <0x5a>; // 0x5a is the phandle for gpio@2200000
    interrupts = <133  0x02>;  // PR.05 = 16 * 8 + 5 = 133 
    interrupt-names = "tcan4x5x_0_int";
    reset-gpios = <0x5a 64 0x02>; //PI.00 = 8 * 8 + 0 - 64

    address-cells = <1>;
    #size-cells = <1>;
    status= "okay";
    controller-data {
            nvidia,enable-hw-based-cs;
            nvidia,rx-clk-tap-delay = <0x10>;
            nvidia,tx-clk-tap-delay = <0x00>;
    };
};

We know that the GPIO output is configured correctly in my .dts file from the result of sudo gpioinfo gpiochip0:

...
	line  51:      "PI.00"      "reset"  output  active-high [used open-source]
...
	line 113:      "PR.05"       unused   input  active-high 
...

And the driver attempts to allocate an IRQ for the device based on sudo dmesg | grep -i "tcan4x5x"

[  198.255948] tcan4x5x spi2.0: no clock found
[  198.260306] tcan4x5x spi2.0: no CAN clock source defined
[  198.863542] tcan4x5x spi2.0: m_can device registered (irq=299, version=32)
[  198.863555] tcan4x5x spi2.0 can0: TCAN4X5X successfully initialized.

However, I can’t find irq=299 with sudo cat /proc/interrupts as the IRQs stop at 298:

...
295:          0          0          0          0          0          0       MSI 1074266112 Edge      eth0
296:          0          0          0          0          0          0      gpio 131 Level     1-0025
298:      14059          0          0          0          0          0       MSI 134742016 Edge      rtl88x2ce
IPI0:      6935      16000      12094      14729      19329      11649       Rescheduling interrupts
IPI1:      1996       3384       2684       2823        788       1759       Function call interrupts
IPI2:         0          0          0          0          0          0       CPU stop interrupts
IPI3:         0          0          0          0          0          0       CPU stop (for crash dump) interrupts
IPI4:         0          0          0          0          0          0       Timer broadcast interrupts
IPI5:      1164        243        334        254        522        488       IRQ work interrupts
IPI6:         0          0          0          0          0          0       CPU wake-up interrupts

Am I missing something in my .dts file?

So… Is your issue about PR.05 could not be configured as interrupt for tcan4x5x?

Could you share the original device tree from your source rather than the one decompiled from dtb?

Could you use 0x08(IRQ_TYPE_LEVEL_LOW) instead of 0x02(IRQ_TYPE_EDGE_FALLING)?

- interrupts = <133  0x02>;
+ interrupts = <133  0x08>;

Have you also checked these errors in driver?

Is this still an issue to support? Any result can be shared? Thanks

Hi kayccc

It turns out the interrupt isn’t claimed until the tcan4x5x driver is actively used, so I had to test it using something like CAN-Utils. The interrupt is also freed by the kernel after a certain period of time if we stop actively using the driver, so the TCAN4X5X device needs to be reset and reinitialized to be used again.

Aside from this, the device and DTB settings work properly, changing to IRQ_TYPE_LEVEL_LOW also helped. Thank you KevinFFF for your continued support!

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.