For the love of god....make SPI easy to enable!!!!

Can we please update/append how to do this, such that it reflects the latest L4T 32.1.0 (9/1/2019)?

Yes…I’ve read the following links:
(+ all others in Google search)

It is very frustrating to read multiple outdated sources of information then try to piece it all together for a successful enabling of SPI. I have zero confidence in carrying out what is a trivial task on Raspberry Pi. I think asking people to modify a kernel is quite a bit. I’ve got enough on my plate to learn.

Please, I’m looking for modern support on how to enable SPI!!!

L4T 32.1.0 [ JetPack UNKNOWN ]
Board: t186ref
Ubuntu 18.04.3 LTS
Kernel Version: 4.9.140-tegra
CUDA 10.0.166

DO NOT tell me the first link above is up to date because it says “through R32.1” on the first line. Go down to “Downloading the kernel sources”…it points to an older release and that’s just the first encounter of the link being outdated. I don’t have the knowledge to navigate that level of information.

For r32.x release you can start from “Modifying the Device Tree” due the the default kernel configure already include the “CONFIG_SPI_SPIDEV”

I’m going to give some feedback…

  1. If I'm suppose to start from "Modifying the Device Tree" for r32.x, why doesn't the webpage say that?
  2. Are these commands carried out on the Jetson or on the host?
  3. Under the section "Update The Device-Tree", it says "Use your text editor of choice to update the DTS that we decompiled above: $ sudo gedit myTX2DeviceTreeSource.dts". I'm assuming the file name should be "extracted_proc.dts" as found in the preceding section? Otherwise, I'm not sure where "myTX2DeviceTreeSource.dts" comes from and I don't think its implying we need to create new file.
  4. Under the section "Enabling the New DTB", it says "The r28, r32 release must update the dtb by below command: sudo ./ -r -k kernel-dtb jetson-tx2 mmcblk0p1", but I have no idea where "" is. In fact, I don't know where any of these commands/files are? This step is very unclear.
  5. Under the section "Enabling the New DTB", it says "Do not update the DTB by below for r28. r32 and later release. As in Jetson/TX2 DTB, enable FDT in /boot/extlinux.conf". Can we clean up the english here? I don't know if I should or should not apply the changes that follow.

If Nvidia expects all users, professional or not, to follow these steps simply to enable SPI then the clarity of the webpage needs to be improved. Everything should be explicit and at least give some reasoning or understanding to go along with commands. If I’m just copy-pasting commands, then you might as well write a shell script and title it “”…O wouldn’t that be nice!!!

Please have a review all of this document that could be make it more clear for you.

Previously, I used the Nvidia SDK Manager to flash the Jetson. It was rather straight forward and simple. I read the “Quick start guide” in your latest link. It didn’t offer any help for enabling SPI.

If the link you pointed to earlier is suppose to be the official method, then please help me carry out those instructions. You said to start at “Modifying the Device Tree”. OK, so the first instruction reads:

Decompiling Device Tree

To obtain the device tree source (DTS) that we’ll edit, first we need to decompile the current device tree binary (DTB) back to source:

cd /boot/dtb/ sudo dtc -I fs -O dts -o extracted_proc.dts /proc/device-tree

Is this the “/boot” on the host PC? Is it the “/boot” on the Jetson OS? Is it the “/boot” of the filesystem to be flashed (found in a different directory)? This should be clearly stated. The only place I can find “/boot/dtb” is on the Jetson OS.

When I performed the SDK Manager flash, it created a directory with a bunch of files on my host PC in


I did find “~/nvidia/nvidia_sdk/JetPack_4.2.2_Linux_GA_P3310/Linux_for_Tegra/rootfs/boot” but no “dtb” directory.

Again, the first link you provided is just lacking clarity. For someone who doesn’t modify kernals and flash operation systems on a regular basis, it is easy to get lost. If you were successful in enabling SPI, then please just tell me how you did it. If you followed that webpage, then help clarify my misunderstanding.

OK…I was able to make some progress.

I followed the steps outlined here:

I will repeat with explicit instructions for TX2 for clarity. I should note that I first flashed the Jetson using the SDK Manager This installs a bunch of files in your home directory under ~/nvidia. I then enable SPI as follows

On the host OS, perform the following steps

  1. sudo apt-get install deveice-tree-compiler
  2. ~/nvidia/nvidia_sdk/JetPack_4.2.2_Linux_GA_P3310/Linux_for_Tegra/kernel/dtb
  3. dtc -I dtb -O dts -o extracted.dts ./tegra186-quill-p3310-1000-c03-00-base.dtb
  4. gedit ./extracted.dts

    Search for the string spi@3240000
    Make the following entries

                compatible = "nvidia,tegra186-spi";
                reg = <0x0 0x3240000 0x0 0x10000>;
                phandle = <0x184>;
                spi@0 {
                  compatible = "spidev";
                  reg = <0x0>;
                  spi-max-frequency = <0x1312D00>;
                  nvidia,cs-setup-clk-count = <0x1e>;
                  nvidia,cs-hold-clk-count = <0x1e>;
                  nvidia,rx-clk-tap-delay = <0x1f>;
                  nvidia,tx-clk-tap-delay = <0x0>;
  5. dtc -I dts -O dtb -o tegra186-quill-p3310-1000-c03-00-base.dtb extracted.dts
  6. Start the Jetson board in recovery mode such that it is ready to be flashed from host
  7. Returning to the host, cd ~/nvidia/nvidia_sdk/JetPack_4.2.2_Linux_GA_P3310/Linux_for_Tegra
  8. sudo ./ -r -k kernel-dtb jetson-tx2 mmcblk0p1

The Jetson should then restart after the flash is complete. Login to the Jetson and run the command:

ls /dev/spi*

You should see “/dev/spidev.3.0”

Also, running the command:


which gives a list containing “spidev”.

Based on my research, I’m assuming that I have successfully enabled SPI (at least to this point). According to, I might need to do something with “pinmux settings” then build and run “spidev_test”, which I still need to attempt. I will follow up with any success.


  1. the directory paths in the instructions above may vary with different versions of JetPack and Jetson board. The explicit commands above are copied from my installation.
  2. I'm a complete beginner at this stuff and these instructions only reflect my research and efforts to enable SPI. I have no idea if these procedures are in fact correct and/or stable. Hopefully someone with more experience and expertise can verify and/or correct the procedures.


OK…so here is my final update. I think I got it working.

Just a reminder, I first flashed the Jetson using the SDK Manager This was how I was told to get the Jetson up and running. Only later did I decided I wanted to connect some sensors via SPI, hence my reasoning for taking on this task.

Start by following steps 1-8 above: Technically, you might only have to do steps 1-5 at this point. After editing the pinmux file (see below) you need to flash the system, so maybe you don’t need to do it twice? Not sure…maybe someone can comment on that. Nevertheless, I did steps 1-8 then proceeded…

Once those steps were complete, I needed to update my pinmux, as outlined in the elinux doc ( Thank god for others help on this, because I still don’t have a clue what’s going on here. On top of that, the pin-name mapping stuff is really confusing to keep track of. The file is found on the host OS in the directory created by the SDK Manager:


For the Jetson TX2, the file you want to edit is:


I found this file reading the issue:

Edit the file EXACTLY as outlined in the elinux doc (link above). I will copy paste for convenience

pinmux.0x02430038 = 0x00000401; # gpio_cam4_pn3: spi4, tristate-disable, input-disable
pinmux.0x02430040 = 0x00000455; # gpio_cam5_pn4: spi4, pull-down, tristate-enable, input-enable
pinmux.0x02430048 = 0x00000401; # gpio_cam6_pn5: spi4, tristate-disable, input-disable
pinmux.0x02430050 = 0x00000409; # gpio_cam7_pn6: spi4, pull-up, tristate-disable, input-disable

After editing the file

  1. Start the Jetson board in recovery mode such that it is ready to be flashed from host
  2. Returning to the host, cd ~/nvidia/nvidia_sdk/JetPack_4.2.2_Linux_GA_P3310/Linux_for_Tegra
  3. sudo ./ jetson-tx2 mmcblk0p1

NOTE there is a difference between the last command and that of step 8 (link above). The last command ended up flashing a “fresh new system”, whereas the previous step 8 flash (link above) appears to only update, as opposed to overwrite, the system. This is why I question the need to perform step 8 (link above) prior to editing the pinmux file.

Finally, the elinux doc (link above) states you need (1) obtain and (2) compile spidev_test.c to a binary. The SDK Manager does not provide the source file, so it must be downloaded with the L4T Source files. I have a detailed write up explaining how I performed these steps here:

On the Jetson

After everything above is complete, we should be able to run the spidev_test binary that was copied to the Jetson (see detailed write up in link above). After connecting the jumper wire and running the script, my test output reads:

spi mode: 0x0
bits per word: 8
max speed: 500000 Hz (500 KHz)
RX | FF FF FF FF FF FF 40 00 00 00 00 95 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF F0 0D  | ......@....•..................ð

NOTE: This is not the same exact output as found in the elinux doc (link above). But, if you read the spidev_test.c source code back on the host (see detailed write up in link above), the variable “uint8_t default_tx” does get assigned this transmit sequence which loops back. I don’t know what the trailing gibberish is, but the rest looks like everything works.

Please, follow up with posts to correct my errors as this is my first time performing this. It is highly likely I could have made a mistake.