Orin Nano GPIO level always LOW after boot @ GPIO-LED framework

Hi,

We have a custom design with Orin Nano and would like to use SPI0_SCK(PZ.03) as output and control by GPIO-LED framework, userspace control GPIO by C code directly.
Default level = HIGH after boot requirement.

  1. Set PZ.03 = output & level HIGH
diff --git a/bootloader/generic/BCT/tegra234-mb1-bct-pinmux-p3767-hdmi-a03.dtsi b/bootloader/generic/BCT/tegra234-mb1-bct-pinmux-p3767-hdmi-a03.dtsi
 index 0e5e3a420..bff1c17b1 100644
 — a/bootloader/generic/BCT/tegra234-mb1-bct-pinmux-p3767-hdmi-a03.dtsi
 +++ b/bootloader/generic/BCT/tegra234-mb1-bct-pinmux-p3767-hdmi-a03.dtsi
 @@ -732,9 +732,9 @@
     spi1_sck_pz3 {
         nvidia,pins = “spi1_sck_pz3”;
         nvidia,function = “rsvd1”;
 -       nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
 -       nvidia,tristate = <TEGRA_PIN_ENABLE>;
 -       nvidia,enable-input = <TEGRA_PIN_ENABLE>;
 +       nvidia,pull = <TEGRA_PIN_PULL_NONE>;
 +       nvidia,tristate = <TEGRA_PIN_DISABLE>;
 +       nvidia,enable-input = <TEGRA_PIN_DISABLE>;
         nvidia,io-high-voltage = <TEGRA_PIN_DISABLE>;
         nvidia,lpdr = <TEGRA_PIN_DISABLE>;
     };
 
 diff --git a/bootloader/tegra234-mb1-bct-gpio-p3767-hdmi-a03.dtsi b/bootloader/tegra234-mb1-bct-gpio-p3767-hdmi-a03.dtsi
 index e876b0157..8e5b9d2a7 100644
 — a/bootloader/tegra234-mb1-bct-gpio-p3767-hdmi-a03.dtsi
 +++ b/bootloader/tegra234-mb1-bct-gpio-p3767-hdmi-a03.dtsi
 @@ -77,9 +77,10 @@
     gpio-output-high = <
         TEGRA234_MAIN_GPIO(Q, 3)
         TEGRA234_MAIN_GPIO(A, 0)
         TEGRA234_MAIN_GPIO(G, 6)
         TEGRA234_MAIN_GPIO(N, 1)
 +       TEGRA234_MAIN_GPIO(Z, 3)
     >;
 };

Result: PZ.03 level = HIGH after boot, correct

  1. Add GPIO-LED framework
    diff --git a/source/hardware/nvidia/t23x/nv-public/nv-platform/tegra234-p3768-0000+p3767-xxxx-nv-common.dtsi b/source/hardware/nvidia/t23x/nv-public/nv-platform/tegra234-p3768-0000+p3767-xxxx-nv-common.dtsi
    index 98780a431..5660be903 100644
    — a/source/hardware/nvidia/t23x/nv-public/nv-platform/tegra234-p3768-0000+p3767-xxxx-nv-common.dtsi
    +++ b/source/hardware/nvidia/t23x/nv-public/nv-platform/tegra234-p3768-0000+p3767-xxxx-nv-common.dtsi
    @@ -454,6 +459,22 @@
        tegra-hsp@b950000 {
            status = "okay";
         };
    
    +     gpio {
    +            compatible = "gpio-leds";
    +             status = "okay";
    +                          uart-mode0 {
    +                                       gpios = <&gpio TEGRA234_MAIN_GPIO(Z, 3) GPIO_ACTIVE_HIGH>;
    +                         };
    +     };
    };
    
    Result: Node /sys/class/leds/uart-mode0/brightness generated and I can echo 1/0 to control GPIO level, but PZ.03 level = LOW after boot, incorrect

I had a workaround is echo 1 > /sys/class/leds/uart-mode0/brightness by systemd at booting time to correct level.
But I wish better solution.
Please provide any suggestions, beyond GPIO-LED framework also
(I considered /sys/class/gpio, but it was marked as DEPRECATED and couldn’t be named the desired name)

Thanks all very much.

*** Please note that this reply is generated by LLM automatically ***

Based on the provided context, I’ll offer a comprehensive answer to the question.

The issue at hand is that the default level of SPI0SCKPZ03 (PZ03) is not being set to HIGH after boot, despite using the GPIOLED framework to control it. The GPIOLED framework is able to generate a node and allow control of the GPIO level, but the default level after boot is not correct.

To address this issue, I’ll provide suggestions beyond the GPIOLED framework.

  1. Using device tree: You can modify the device tree to set the default level of PZ03 to HIGH. This can be done by adding a property to the device tree node that controls PZ03. For example, you can add a default-state property with a value of high to the node.
  2. Using sysfs: Although sysclass/gpio is deprecated, you can still use the sysfs interface to control the GPIO pin. You can write a script that sets the GPIO pin to HIGH during boot. This can be done by creating a systemd service that runs a script that sets the GPIO pin to HIGH.
  3. Using a custom kernel module: You can create a custom kernel module that sets the default level of PZ03 to HIGH during boot. This module can be loaded during boot and will set the GPIO pin to HIGH.
  4. Using a boot script: You can create a boot script that sets the GPIO pin to HIGH during boot. This script can be run during the boot process and will set the GPIO pin to HIGH.

In comparison to the GPIOLED framework, these solutions offer more flexibility and control over the GPIO pin. However, they may require more development and testing effort.

Here’s an example of how you can use the device tree to set the default level of PZ03 to HIGH:

&spi0 {
    status = "okay";
    spi0_sck_pz03 {
        gpio-hog;
        gpios = <&gpio 356 1>; // assuming gpio-356 is the GPIO number for PZ03
        default-state = <high>;
    };
};

This example assumes that the GPIO number for PZ03 is 356, and sets the default state of the GPIO pin to HIGH.

In conclusion, there are several solutions beyond the GPIOLED framework that can be used to set the default level of PZ03 to HIGH. The choice of solution depends on the specific requirements and constraints of the project.

*** Please give the thumbs up if you get answers you like. Or provide feedback to help us improve the answer. ***

1 Like

Hi @carolyuu

Thanks your full support.

I will go with Using device tree solution as follows.

+     gpio {
+            compatible = "gpio-leds";
+             status = "okay";
+                 uart-mode0 {
+                     gpios = <&gpio TEGRA234_MAIN_GPIO(Z, 3) GPIO_ACTIVE_HIGH>;
++                    default-state = "keep";
+                 };
+     };

Use keep for inherit GPIO level settings from tegra234-mb1-bct-gpio-p3767-hdmi-a03.dts, prevent set two files if level changed.

Thanks you very much.