SPIdev cannot use CS0 on L4T 21.3 and above

Hi,

This issue has been reported in multiple threads here when discussing SPI and I feel it deserves a seperate discussion. I am trying to make spidev working on L4T21.4 or on the grinch kernel. In both of it I observe the same error in dmesg. In grinch 19.3 this issue does not exist. CS0 is exposed in the expender I/O header.

dmesg | grep spi

[    0.596092] avdd-spi: 3300 mV at 150 mA
[    4.194125] spi-tegra114 spi-tegra114.0: registered master spi0
[    4.194245] spi spi0.0: setup 8 bpw, ~cpol, ~cpha, 12000000Hz
[    4.194303] spi spi0.0: setup mode 0, 8 bits/w, 12000000 Hz max --> 0
[    4.194613] spi-tegra114 spi-tegra114.0: registered child spi0.0
[    4.195009] spi-tegra114 spi-tegra114.0: chipselect 0 already in use
[    4.195017] spi_master spi0: spi_device register error /spi@7000d400/spi0_0
[    4.195422] spi-tegra114 spi-tegra114.3: registered master spi3
[    9.039218] avdd-spi: incomplete constraints, leaving on

I am sure the device tree files are correct.

spi0_0 {
            #address-cells = <0x1>;
            #size-cells = <0x0>;
            compatible = "spidev";
            reg = <0x0>;
            spi-max-frequency = <0x17d7840>;
            spi-cpha;
            nvidia,enable-hw-based-cs;
            nvidia,cs-setup-clk-count = <0x1e>;
            nvidia,cs-hold-clk-count = <0x1e>;
            nvidia,rx-clk-tap-delay = <0x1f>;
            nvidia,tx-clk-tap-delay = <0x0>;
        };

Is there a possibility that there is a spi device somewhere that is grabbing CS0 and initializing it before it reaches the SPIdev? I tried searching for it with no luck. How do I find out who is using CS0? Also which dtb file gets used? /boot and /boot/dtb, which one is used.

Thanks,
Benzun

I haven’t traced it to see where it goes, but I do see a mention of spi0.0 in the dts kernel header files:

arch/arm/boot/dts/tegra124-platforms/tegra124-jetson_tk1-fixed-pm375-0000-c00-00.dtsi
arch/arm/boot/dts/tegra124-platforms/tegra124-jetson_tk1-pmic-pm375-0000-c00-00.dtsi

Content:

tegra124-jetson_tk1-fixed-pm375-0000-c00-00.dtsi: regulator-consumer-device = "spi0.0";
tegra124-jetson_tk1-pmic-pm375-0000-c00-00.dtsi: regulator-consumer-device = "spi0.0";

This is used in “drivers/regulator/of_regulator.c”, so it seems plausible something else is using spi0.0 if this “regulator” code is not associated to spidev (I have not traced anything to know what it is actually used for, I’m just noting references in the kernel source).

What effect will deleting those lines have? Where do these regulator code do? dmesg also states that there is an incomplete description (avdd-spi: incomplete constraints, leaving on) I feel it corresponds to the regulator.

I’m not familiar with the specific regulator, but if this one is associated with clocks or voltage levels internal to the tegra124, the regulator in question would most likely be critical. To be certain you’d have to track down the function of the specific regulator. It might be as simple as something expected to be connected externally through the J3A2 connector, in which case it would easily be disabled without consequence. It’s an area where simply removing something without understanding it first would make me nervous (there could be an actual risk to hardware).

The 12Mhz spi0.0 that is seen initialized from debug message is not from the device tree specification. What other files have access to initializing SPIdev?

The location I saw “spi0.0” at is from the kernel source device tree include files supporting the pm375 board (basically the board components surrounding the Tegra K1 on Jetson). I would guess that this corresponds in the device tree syntax as “spi0_0”, but I have no way of tracing more generally into SPIdev (I have neither SPI hardware nor oscilloscope nor logic analyzer).

I found the source of the spi0.0 its a module named spi:rm_ts_spidev. Is this a touch screen module? If i dont have a touch screen how can i disable it?

In board-ardbeg.c I feel there is a bug which makes the kernel load raydium touch screen spi drivers. I dont know how exactly to fix it. There is a function which is used to identify the touch screen on the board and I dont know where it is defined. The easiest fix for me is to go to board-ardbeg.h and change the spi CS to 1 instead of 0.

Now i can use the CS 0. My fix is a dirty fix. I want to know if there is a clean solution where i can prevent the touch screen spi from being initialized on jetson as there is no touch screen on it.

I am unable to give a complete answer, here is additional information which might be useful for someone with better knowledge. Without anything to test and experiment with, I’m just poking around and guessing and gathering information as to what this SPI might actually be touching (and thus what part of the kernel might be disabled without disabling everything SPI).

As a reference, if you have kernel source on your Jetson, you can extract the actual dtb firmware back into human-readable source via this command from the root of the kernel source tree (output to ~/Documents):

./scripts/dtc/dtc -I dtb -O dts -o /home/ubuntu/Documents/tegra124-pm375-default_extracted_dts.dts /boot/tegra124-jetson_tk1-pm375-000-c00-00.dtb

Looking in this file, spi0.0 is associated with a regulator referred to as “ldo9” (probably a low voltage dropout regulator), set to 3.3V (convert the hex value to decimal and then microvolt to volt). So whatever depends on this runs at 3.3V, and has an abbreviated name in firmware of “avdd-spi”. Under kernel source “drivers/regulator/”, a grep for ldo9 shows these files as referring to the data tree:

<s>as3720-regulator.c</s>
<b>as3722-regulator.c</b>[s]
lp8788-ldo.c
max8907-regulator.c
max8998.c
palmas-regulator.c
tps6586x-regulator.c[/s]

Since the main power management unit on tegra124 is listed on schematics as AS3722, it appears the “as3722-regulator.c” is the smoking gun for what the firmware is applied to, file “drivers/regulator/as3722-regulator.c”. This is used to fill in structs “as3722_register_mapping as3722_reg_lookup” and “of_regulator_match as3722_regulator_matches”.

Going back to the schematic, ldo9 (upper case “LDO9” in the schematic) traces to labels “+3.3V_RUN_TOUCH”, “+3.3V_SYS”, “+3.3V_RUN”, “DP_AUX_N”, “DP_AUX_P” “EN_AVDD_LCD”, “GEN2_I2C_SCL_3.3V”, “GEN2_I2C_SDA_3.3V”, “TS_CLK”, “TS_SPI_CS_L”, “TS_SPI_SCLK”, etc. I suspect this particular regulator shouldn’t be tampered with, but someone else would have to verify that. SPI is certainly a big enough topic someone may have run into spi0.0 before and have more information on it.

I have spi working with CS0 working. The only change i did was in the board-ardbeg.h file where i changed the #define for the raydium touch screen spi chipselect from 0 to 1.

You can also disable the raydium touch screen from the parameters in /boot/extlinux/extlinux.conf
The parameter touch_id=0@0 selects the raydium touch screen. Setting it to 3@3 seems to disable touchscreens, since 3 is defined as VENDOR_NONE in board.h

Then I avoid the “Chipselect 0 already in use” error message.

hi,
I am trying to use SPI for communicating to an FPGA .I am running L4T21.3.Using the neurorobotictech tutorial(http://neurorobotictech.com/Community/Blog/tabid/184/ID/13/Using-the-Jetson-TK1-SPI--Part-3-Configuring-SPI-in-the-device-tree.aspx), I modified the dtb file .But in /dev spidev0.0 was not showing.Then as jkvatne mentioned in the prev post ,I modified the extlinux.conf.Then spidev0.0 is showing.Then i tried moving some data to the dev using echo hello > /dev/spidev0.0. I probed the clock and data of the SPI in the J3A1 jumper. I am not getting any signals.
Can any body help please. Any thing else we need to do for enabling SPI?

hi,
Spi is working fine for me now with minimum clock of 3.2 Mhz.I think there was a problem with the kernel config.I rebuilded the kernel again and followed jkvatne method for disabling raydium .
Thank you

Hi,

I’m using Linux For Tegra R21.5 with grinch-kernel and I had the same issue of not getting the SPI device in /dev/spidev0.0, And when I check the

dmesg | grep "spi"

It shows me the same above mentioned issue

spi-tegra114 spi-tegra114.0: chipselect 0 already in use

I followed the trick mention here[1] and finally was able to get it working
Simply disable the touch controller by editing /boot/extlinux/extlinux.conf and setting “touch_id=3@3”
It seems that touch controller is already using the registry 0x0 hence can’t map it to /dev/spidev0.0

[1]: https://devtalk.nvidia.com/default/topic/883673/jetson-tk1/adding-a-can-bus-with-mcp2515-over-spi/post/4690028/#4690028