Jetson Orin Nano Developer Kit with GPIO header and oscilloscope showing PWM waveform
jetsonoringpiopwmpinmuxdevice treesysfsembedded linux

GPIO and PWM configuration on Jetson Orin — pinmux, sysfs, and device tree

Aaron Angulo ·

GPIO and PWM configuration on Jetson Orin involves three layers: the pinmux spreadsheet that decides pin function, a device tree overlay that applies it, and either sysfs or libgpiod for runtime control. Skipping the pinmux step is the most common cause of “GPIO not working” issues — if the pin mux is set to I2C or UART function, sysfs GPIO writes are silently ignored.

Key Insights

  • Pinmux must be set before GPIO/PWM works — each pin has a hardware mux selecting its function (GPIO, SPI, I2C, UART, PWM); the mux defaults to non-GPIO on most pins
  • Use gpiod tools, not /sys/class/gpio — the legacy sysfs GPIO interface is deprecated in kernel 5.x; gpioget/gpioset/gpiomon are the correct tools
  • 40-pin header pin numbers ≠ Linux GPIO numbers — header pin 7 is not GPIO 7; use the pinmux spreadsheet to find the correct gpiochipX line number
  • PWM period and duty cycle are in nanoseconds in sysfs — a 1kHz signal is period=1000000 (1,000,000 ns = 1ms)
  • The fan PWM is pre-configured on devkits — /sys/class/hwmon/hwmon*/pwm1 controls the fan without any DT changes

Pinmux spreadsheet workflow

  1. Download Jetson Orin Series Pinmux from developer.nvidia.com/jetson-downloads
  2. Open in Excel or LibreOffice
  3. Find your target pin (by module pin number or header position)
  4. Change the “Customer Usage” column to your desired function (GPIO, PWM, etc.)
  5. Set pull (Pull-Up/Pull-Down/None) and drive strength
  6. Run the provided Python script to generate a .dtsi file
  7. Compile to .dtbo and deploy as a device tree overlay

40-pin header GPIO map (Orin NX / Nano devkit)

Header PinModule PinGPIO chipLineDefault function
3191gpiochip10I2C1_SDA
5189gpiochip11I2C1_SCL
7164gpiochip0164SPI1_SCK / GPIO
11136gpiochip0136UART1_RTS / GPIO
12148gpiochip0148I2S0_SCLK / GPIO
13194gpiochip0194SPI1_SCK / GPIO
15106gpiochip0106GPIO
16112gpiochip0112GPIO
18118gpiochip0118GPIO
19140gpiochip0140SPI1_MOSI / GPIO

Check the pinmux spreadsheet for the authoritative mapping for your carrier board.

GPIO control with libgpiod

# Install gpiod tools
apt install gpiod

# List all GPIO chips
gpiodetect
# gpiochip0 [tegra234-gpio] (164 lines)
# gpiochip1 [tegra234-gpio-aon] (32 lines)

# List lines and their current state
gpioinfo gpiochip0

# Set a GPIO high (output)
gpioset --mode=signal gpiochip0 164=1

# Read a GPIO (input)
gpioget gpiochip0 164

# Monitor for edge events
gpiomon --num-events=10 --rising-edge gpiochip0 164

C program using libgpiod

#include <gpiod.h>
#include <stdio.h>

int main(void) {
    struct gpiod_chip *chip;
    struct gpiod_line *line;

    chip = gpiod_chip_open_by_name("gpiochip0");
    if (!chip) {
        perror("gpiod_chip_open_by_name");
        return 1;
    }

    line = gpiod_chip_get_line(chip, 164);

    /* Request as output, initial value = 0 */
    gpiod_line_request_output(line, "my-app", 0);

    /* Set high */
    gpiod_line_set_value(line, 1);

    gpiod_chip_close(chip);
    return 0;
}

Compile:

gcc -o gpio_example gpio_example.c -lgpiod

Device tree overlay for GPIO pinmux

Generated by the pinmux spreadsheet, or written manually:

/dts-v1/;
/plugin/;

/ {
    overlay-name = "GPIO pin 15 as output";
    compatible = "nvidia,p3767";

    fragment@0 {
        target = <&pinmux>;
        __overlay__ {
            /* Header pin 15 = TEGRA_MAIN_GPIO(A, 6) */
            pinctrl-names = "default";
            pinctrl-0 = <&gpio_pin15_config>;

            gpio_pin15_config: gpio-pin-15 {
                nvidia,pins = "soc_gpio41_pq5";
                nvidia,function = "rsvd1";   /* GPIO mode */
                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
            };
        };
    };
};

Load for development:

# Compile
dtc -I dts -O dtb -o gpio-pin15.dtbo gpio-pin15.dts

# Add to /boot/extlinux/extlinux.conf:
# FDT_OVERLAYS gpio-pin15.dtbo

# Reboot

PWM configuration

Jetson Orin has 8 PWM controllers. On the 40-pin header of the devkit:

Header PinPWM chipChannelPeriod range
32pwmchip101µs – 10s
33pwmchip201µs – 10s
# Export PWM channel 0 on pwmchip1
echo 0 > /sys/class/pwm/pwmchip1/export

# Set period to 1ms (1kHz)
echo 1000000 > /sys/class/pwm/pwmchip1/pwm0/period

# Set duty cycle to 50%
echo 500000 > /sys/class/pwm/pwmchip1/pwm0/duty_cycle

# Enable
echo 1 > /sys/class/pwm/pwmchip1/pwm0/enable

# Verify
cat /sys/class/pwm/pwmchip1/pwm0/enable
# 1

# Disable and unexport when done
echo 0 > /sys/class/pwm/pwmchip1/pwm0/enable
echo 0 > /sys/class/pwm/pwmchip1/unexport

The pin must be configured for PWM function in the pinmux overlay before these sysfs nodes appear. Without the pinmux configuration, pwmchipN may be present but the signal will not appear on the physical pin.

Fan PWM (pre-configured on devkits)

The cooling fan on Orin devkits uses a pre-configured PWM and is managed by nvfancontrol:

# Check fan speed and target
cat /sys/class/hwmon/hwmon*/fan1_target
cat /sys/class/hwmon/hwmon*/pwm1

# Manual control (bypasses nvfancontrol)
systemctl stop nvfancontrol
echo 180 > /sys/class/hwmon/hwmon*/pwm1   # 0-255 scale

For carrier board hardware design including GPIO signal routing and the pinmux spreadsheet download location, see Jetson carrier board hardware design mistakes to avoid.

FAQ

How do I control GPIO on Jetson Orin from the command line?

Use gpioset gpiochipX <line>=1 from the gpiod package. Find the correct chip and line number from the pinmux spreadsheet — header pin numbers don’t match Linux GPIO numbers.

How do I use PWM on Jetson Orin?

Configure the pin for PWM function in a pinmux DT overlay, then use /sys/class/pwm/pwmchipN/. Export the channel, set period and duty_cycle in nanoseconds, then set enable=1.

What is the pinmux spreadsheet for Jetson Orin?

An Excel file from NVIDIA that maps module pins to hardware functions and generates a device tree overlay from your selections. Download from the NVIDIA Jetson Downloads page.

Can I change GPIO pin function without reflashing on Jetson Orin?

Yes. Add a compiled pinmux overlay to FDT_OVERLAYS in /boot/extlinux/extlinux.conf and reboot. No reflash needed for development.


NVIDIA Jetson Expert Support

Stuck on a Jetson bring-up?

We've debugged this failure mode before. BSP, device tree, camera pipelines, OTA, most blockers clear in the first session. No long retainers. No guessing.

Frequently Asked Questions

How do I control GPIO on Jetson Orin from the command line?

Use the sysfs GPIO interface or the gpiod userspace tools. First identify the correct GPIO number using the pinmux spreadsheet — the 40-pin header on the Orin devkit does not use sequential Linux GPIO numbers. Then use gpiod: gpioset gpiochip0 <line>=1 to set a pin high. Avoid the legacy /sys/class/gpio interface on kernels 5.x and later — it is deprecated.

How do I use PWM on Jetson Orin?

Jetson Orin has dedicated PWM controllers accessible via the /sys/class/pwm interface. First configure the pin in the pinmux spreadsheet and device tree overlay to PWM function. Then enable the PWM chip via sysfs: echo 0 > /sys/class/pwm/pwmchipN/export, set period and duty_cycle in nanoseconds, then enable=1. The fan control PWM on the devkit is already configured and accessible.

What is the pinmux spreadsheet for Jetson Orin?

The pinmux spreadsheet is an Excel file from NVIDIA (Jetson Orin Series Pinmux) that maps each module pin to its available functions (GPIO, I2C, SPI, UART, PWM, etc.) and lets you configure the mux selection, pull, and drive strength. The spreadsheet generates a device tree overlay that matches your selections. Download it from the NVIDIA Jetson Downloads page.

Can I change GPIO pin function without reflashing on Jetson Orin?

Yes, using a device tree overlay loaded via extlinux.conf. Add your pinmux overlay DTB to FDT_OVERLAYS in /boot/extlinux/extlinux.conf and reboot. This is faster than a full reflash during development. For production, include the overlay in TEGRA_PLUGIN_MANAGER_OVERLAYS to write it to SPI flash.

Aarón Angulo, Co-Founder & CEO at ProventusNova

Written by

Aarón Angulo

Co-Founder & CEO · ProventusNova

Obsessed with client outcomes. Aarón ensures every engagement delivers real results, on time, on scope, no exceptions.

Connect on LinkedIn