The SPI device can not be used

I connected the SPI interface sensor module (MPU9250) to the Expansion Header (SPI1_MOSI(19), SPI1_MISO(21), SPI1_SCK(23) and SP1_CS0(24)), but the SPI device was not recognized.
I tried sudo modprobe spidev command on the assumption that device file (e.g. /dev/spidev.0.0) will be created, but it was not created.
In dmesg, the error spidev: no symbol version for module_layout is output.

How can I use the SPI device?

The SPI device voltage level is 3.3V and I selected 3.3V voltage level by J514 on Xavier.
I used JetPack 4.1.

Thanks.

Did you enable CONFIG_SPI_SPIDEV in configure?

Hello ShaneCCC,
I have use default config.

$ cat /usr/src/linux-headers-4.9.108-tegra/.config | grep SPIDEV
CONFIG_SPI_SPIDEV=m

I think that ‘m’ means the module.

This means the spidev module was built in the wrong module version environment.

See for example this thread for explanation: https://askubuntu.com/questions/14627/no-symbol-version-for-module-layout-when-trying-to-load-usbhid-ko

Did you build the module, or did you get it from Jetpack? If from Jetpack, which version?

I used spidev module from JetPack.
The version is:

cat /etc/nv_tegra_release | head -1
# R31 (release), REVISION: 0.2, GCID: 12860113, BOARD: t186ref, EABI: aarch64, DATE: Sat Sep 29 05:14:38 UTC 2018

I compared the version of the kernel with the module.
The kernel version is:

$ uname -r
4.9.108-tegra

and the module version is:

$ modinfo spidev
filename:       /lib/modules/4.9.108-tegra/kernel/drivers/spi/spidev.ko
alias:          spi:spidev
license:        GPL
description:    User mode SPI device interface
author:         Andrea Paterniani, <a.paterniani@swapp-eng.it>
alias:          of:N*T*Clineartechnology,ltc2488C*
alias:          of:N*T*Clineartechnology,ltc2488
alias:          of:N*T*Crohm,dh2228fvC*
alias:          of:N*T*Crohm,dh2228fv
alias:          of:N*T*CspidevC*
alias:          of:N*T*Cspidev
depends:        
vermagic:       4.9.108-tegra SMP preempt mod_unload modversions aarch64
parm:           bufsiz:data bytes in biggest supported SPI message (uint)

They seem the same version.


I attempted to rebuild the module from the latest source (L4T 31.0.2: https://developer.nvidia.com/embedded/dlc/l4t-sources-31-0-2 ), but the same error occurred when doing insmod.
And I tried modprobe command with f option, I got a different error message.

$ sudo modprobe -f spidev
modprobe: ERROR: could not insert 'spidev': Exec format error

Although this error seems to occur when the version is different, I think that it is the same version in my environment.
What are other possible causes?

I tried this myself, and it does, indeed, seem to not work:

nvidia@xavier:~$ sudo depmod
nvidia@xavier:~$ sudo modprobe -v -f -s spidev
insmod /lib/modules/4.9.108-tegra/kernel/drivers/spi/spidev.ko 
modprobe: ERROR: could not insert 'spidev': Exec format error
nvidia@xavier:~$ file /lib/modules/4.9.108-tegra/kernel/drivers/spi/spidev.ko
/lib/modules/4.9.108-tegra/kernel/drivers/spi/spidev.ko: ELF 64-bit LSB relocatable, ARM aarch64, version 1 (SYSV), BuildID[sha1]=8c99ab33dc53f43d804b41bdeafa456f8489735f, not stripped

So, perhaps the module has some other dependency, that’s not fulfilled?
Kernel module dependency errors are notoriously hard to debug, because the interface back is just “errno” which isn’t particularly rich.
There isn’t any extra output in dmesg or journalctl after using the -s flag, either.

Oh, and then I did:

nvidia@xavier:~$ sudo bash
root@xavier:~# modprobe -s -v spidev
insmod /lib/modules/4.9.108-tegra/kernel/drivers/spi/spidev.ko 
root@xavier:~# lsmod
Module                  Size  Used by
spidev                 12931  0
fuse                  103334  3
bnep                   16619  2
...

So, running from “sudo” doesn’t work, but running from a “su” shell works. Weird.

Thank you for checking.

I built the kernel and drivers from the source and changed the device tree with reference to the information of Jetson TX2, the device file (eg /etc/spidev.0.0) was created.
The changes of the device tree are as follows.

spi@xxxxxx {
    ...
    status = "okay"; // Before change: "disable"
    spidev@0 {
        compatible = "spidev";
        reg = <0>;
        spi-max-frequency=<25000000>;
    };
}

The commands used are as follows.

$ sudo dtc -I fs -O dts -o extracted_proc.dts /proc/device-tree
$ sudo vi extracted_proc.dts # edited device tree.
$ sudo dtc -I dts -O dtb -o tegra194-p2888-0001-p2822-0000-base.dtb extracted_proc.dts
$ sudo dd if=tegra194-p2888-0001-p2822-0000-base.dtb of=/dev/mmcblk0p31
$ ls /dev/ | grep spi
spidev.0.0 spidev.1.0 spidev.2.0 spidev.6.0 spidev.7.0

However, Jetson Xavier can not communicate with the sensor connected to the Expansion Header. It seems that the state of the pin does not change even if the file is opened with spidev.

import spidev
spi = spidev.SpiDev()
spi.open(0, 0) // select device number in 0, 1, 2, 6, 7
spi.xfer2([1, 2])
spi.close()

What are the possible problems?

I think you also need to change the pinmux to set the appropriate pins to SPI function rather than GPIO function.
This is where the large, hard-to-understand, chase-documentation-through-four-separate-documents spreadsheet of pin configurations comes in.
That, and a custom device tree.

I change pinmux setting and confirmed that communication with SPI device is possible.
The changed pinmux settings are as follows.

0x0243d040 = 0x00000400
0x0243d020 = 0x00000458
0x0243d058 = 0x00000400
0x0243d010 = 0x00000400
0x0243d050 = 0x00000400
0x0c302048 = 0x00000400
0x0c302050 = 0x00000450
0x0c302028 = 0x00000400
0x0c302038 = 0x00000400

I used spidev_test (/usr/src/linux-headers-4.9.108-tegra/tools/spi/spidev_test.c) to check spi communication.
device name: /dev/spidev0.0
pin name: SPI1_MOSI(19), SPI1_MISO(21), SPI1_SCLK(23) and SPI1_CS0(24) in Expansion header.

Thank you for giving me good advice!

Hi,SatoshiShimada
Have you made the SPI1 on the Expansion header work?

SPI1 works well on my board.
I connected the IMU sensor module (MPU-9250).

that’s cool!
can you help me with some questions? I want to enable SPI on xavier, L4T 32.1 Jetpac 4.2. I fellow your guide in:
https://devtalk.nvidia.com/default/topic/1044595/jetson-agx-xavier/question-how-do-i-enable-and-address-spi-ports-/

the question is:

  1. Edit device-tree
spi@xxxxxx {
    ...
    status = "okay"; // Before change: "disable"
    spidev@0 {
        compatible = "spidev";
        reg = <0>;
        spi-max-frequency=<25000000>;
    };
}

in the device tree, I want to know SPI1 detail adress, in my system, is spi@c260000, but when I want to change it, I found there is an imx204 exist already, when I add spi@0 block here,the dtc report a duplicate error, so I choice spi@321000,the SPI0 address, but my finally purpose is to enable SPI1.

  1. sudo dd if=tegra194-p2888-0001-p2822-0000-base.dtb of=/dev/mmcblk0p31
    when I use this command, I want to know the meaning of mmcblk0p31, in the TX2SPI official guide, is mmcblk0p1, I first use mmcblk0p31 and the spidev does not work. so I change to mmclbk0p1, my Xavier can’t boot at all, I post a topic at:
    https://devtalk.nvidia.com/default/topic/1055684/jetson-agx-xavier/xavier-boot-fail-after-change-mmcblk0p1-for-spi/

I want to know if the mmcblk0p31 relate to the device(Xavier or tx2) or SPI(SPI0 or SPI1)

  1. pinmux
0x0243d040 = 0x00000400
0x0243d020 = 0x00000458
0x0243d058 = 0x00000400
0x0243d010 = 0x00000400
0x0243d050 = 0x00000400
0x0c302048 = 0x00000400
0x0c302050 = 0x00000450
0x0c302028 = 0x00000400
0x0c302038 = 0x00000400

this change in your guide suit only for SPI1 or all the SPI in xaiver, what are these mean.

looking forward to your answer
thanks a lot!

gaosiy

Hi snarky,
I can find spidev module in the list after useing
sudo modprobe -v -f -s spidev
lsmod

but no SPIDEV at /dev/ dir, is it normal?

Did you build the kernel and a module from source code?

please try rebuilding the kernel and spidev module. Then modify and apply dts.

$ sudo dtc -I fs -O dts -o extracted_proc.dts /proc/device-tree
    $ sudo vi extracted_proc.dts # edited device tree.
    $ sudo dtc -I dts -O dtb -o tegra194-p2888-0001-p2822-0000-base.dtb extracted_proc.dts
    $ sudo dd if=tegra194-p2888-0001-p2822-0000-base.dtb of=/dev/mmcblk0p31

The modified dts are as follows.

spi@c260000 {
	compatible = "nvidia,tegra186-spi";
	clocks = <0x4 0x88 0x4 0x5e 0x4 0x5b>;
	resets = <0x5 0x5c>;
	dma-coherent;
	clock-names = "spi", "pll_p", "osc";
	nvidia,clk-parents = "pll_p", "osc";
	status = "okay";
	#address-cells = <0x1>;
	interrupts = <0x0 0x25 0x4>;
	#size-cells = <0x0>;
	dma-names = "rx", "tx";
	phandle = <0x161>;
	reg = <0x0 0xc260000 0x0 0x10000>;
	iommus = <0x2 0x20>;
	dmas = <0x1e 0x10 0x1e 0x10>;
	reset-names = "spi";
	linux,phandle = <0x161>;
	spi-max-frequency = <0xb71b00>;

	imx204@0 {
		compatible = "nvidia,imx204-spi";
		focus_infinity = "208";
		sensor_model = "imx204";
		physical_w = "4.713";
		focus_max_slew_rate = "180";
		devname = "imx204-spi";
		max_aperture_fnumber = "22000";
		fnumber_map = <0x7d0 0x2 0xaf0 0x22 0xfa0 0x31 0x15e0 0x3b 0x1f40 0x43 0x2af8 0x47 0x3e80 0x4b 0x55f0 0x4e>;
		status = "disabled";
		min_aperture_fnumber = "2000";
		delayed_gain = "true";
		reset-gpios = <0x12 0xc1 0x0>;
		max_aperture = "90";
		phandle = <0x11d>;
		min_aperture = [32 00];
		reg = <0x0>;
		aperture_max_slew_rate = "180";
		linux,phandle = <0x11d>;
		spi-max-frequency = <0xb71b00>;
		physical_h = "3.494";
		focus_macro = "100";

		mode0 {
			line_length = "6667";
			active_w = "5352";
			pixel_t = "bayer_rggb";
			pix_clk_hz = "1320000000";
			dpcm_enable = "false";
			num_lanes = [38 00];
			inherent_gain = [31 00];
			max_gain_val = "22.3";
			min_hdr_ratio = [31 00];
			discontinuous_clk = "no";
			readout_orientation = [30 00];
			min_gain_val = "1.0";
			max_hdr_ratio = [31 00];
			tegra_sinterface = "serial_a";
			min_framerate = "1.5";
			max_framerate = "60";
			phy_mode = "SLVS";
			mclk_khz = "72000";
			cil_settletime = [30 00];
			active_h = "3950";
			max_exp_time = "33333";
			mclk_multiplier = "11";
			min_exp_time = "13";
		};

		ports {
			#address-cells = <0x1>;
			#size-cells = <0x0>;

			port@0 {
				reg = <0x0>;

				endpoint {
					port-index = <0x0>;
					remote-endpoint = <0x29>;
					bus-width = <0x8>;
					phandle = <0x95>;
					linux,phandle = <0x95>;
				};
			};
		};
	};

	spidev@0 {
		compatible = "spidev";
		reg = <0x0>;
		spi-max-frequency = <0x17d7840>;
	};
};

Thanks, Satoshi
I have rebuilt the kernel, and I get spidev.ko and flash it to Xavier, is this enough, what else should I do with the rebuilt kernel?

I will try your method about update device-tree.

by the way, are these commands use on Xavier directly?

$ sudo dtc -I fs -O dts -o extracted_proc.dts /proc/device-tree
    $ sudo vi extracted_proc.dts # edited device tree.
    $ sudo dtc -I dts -O dtb -o tegra194-p2888-0001-p2822-0000-base.dtb extracted_proc.dts
    $ sudo dd if=tegra194-p2888-0001-p2822-0000-base.dtb of=/dev/mmcblk0p31

the last question, why dd command is used for mmcblk0p31, official docs use flash.sh to update the target with mmcblk0p1

Hi

Hi Satoshi,
you say your SPI1 device is spidev0.0
I find my SPI1 show spidev1.0 at /dev/, so I dont know which is right