I’ve made some edits to the device tree, but most importantly the kernel module. More investigation is needed, but similar issues were found in How to set SPI CS(chip select) timing?, Bug in spi-tegra114.c and other spi related things, https://forums.developer.nvidia.com/t/spi-slave-can-only-receive-the-second-packet-from-nano-dev-kit-spi-master/110132and for some reason, not all of the proposed patches/fixes made it into the current kernel. I’ve done a quick hack to get something working, but this is not at all robust and may not solve all issues. Basically I commented out a check for gpio chip select, changed tegra-spidev to linux,spidev, and disabled prod-settings in the device tree.
Below I included some quite verbose notes on how I did this for anyone and/or myself in the future.
Getting Kernel Sources
Get the sources:
RELEASE=35
VERSION=1.0
KERNEL=5.10
RELEASE_VERSION=r${RELEASE}_release_v${VERSION}
ARCHIVE_NAME=public_sources_${RELEASE_VERSION}
SOURCES_NAME=Linux_for_Tegra_${RELEASE_VERSION}
mkdir -p ${HOME}/src/nvidia/l4t_sources/xavier_nx && cd ${HOME}/src/nvidia/l4t_sources/xavier_nx
wget https://developer.nvidia.com/embedded/l4t/${RELEASE_VERSION}/sources/public_sources.tbz2
mv public_sources.tbz2 ${ARCHIVE_NAME}.tbz2
tar -xvf ${ARCHIVE_NAME}.tbz2 && mv Linux_for_Tegra ${SOURCES_NAME}
cd ${SOURCES_NAME}/source/public
JETSON_XAVIER_NX_KERNEL_SOURCES=$(pwd)
tar -xvf kernel_src.tbz2
Kernel Module Modifications
Copy the driver
# Make a copy of the spi driver
SPI_DIR=kernel/kernel-${KERNEL}/drivers/spi
SPI_DRIVER_DIR=${JETSON_XAVIER_NX_KERNEL_SOURCES}/${SPI_DIR}
mkdir -p ${HOME}/src/spi && cd ${HOME}/src/spi
cp ${SPI_DRIVER_DIR}/spi-tegra114.c ./
Create a Makefile containing the following with nano Makefile:
obj-m += spi-tegra114.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
install:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules_install
Edit the spi kernel driver. We modified it by commenting out checks on gpio chip selects and inactive cycles as follows: nano spi-tegra114.c
// line 1302
if (cdata && cdata->clk_delay_between_packets) {
// if (cdata->cs_inactive_cycles || !cstate->cs_gpio_valid) {
// if (cdata->cs_inactive_cycles) {
// dev_err(&spi->dev,
// "Invalid cs packet delay config\n");
// tegra_spi_cleanup(spi);
// return -EINVAL;
// }
cdata->cs_inactive_cycles = cdata->clk_delay_between_packets;
}
It was rebuilt as spi-tegra114.ko and placed in /lib/modules/$(uname -r)/kernel/drivers/spi/:
make
mv /lib/modules/$(uname -r)/kernel/drivers/spi/spi-tegra114.ko /lib/modules/$(uname -r)/kernel/drivers/spi/spi-tegra114.ko.bak
cp ${HOME}/src/spi/spi-tegra114.ko /lib/modules/$(uname -r)/kernel/drivers/spi/
Device Tree Preparation
The device tree was prepared as:
# Prepare tree and image
echo DEVICE=tegra194-p3668-0001-p3509-0000 >> ${HOME}/.bashrc && . ${HOME}/.bashrc
echo BOOT_LOCATION=/boot >> ${HOME}/.bashrc && . ${HOME}/.bashrc
sudo cp ${BOOT_LOCATION}/dtb/kernel_${DEVICE}.dtb /boot/dtb/kernel_${DEVICE}.dtb.bak
sudo cp ${BOOT_LOCATION}/Image ${BOOT_LOCATION}/Image.bak
# Get the original device tree
mkdir -p ${HOME}/src/device_trees
dtc -I dtb -O dts -o ~/src/device_trees/original_tree.dts ${BOOT_LOCATION}/dtb/kernel_${DEVICE}.dtb.bak
# Prepare the spi overlay
sudo /opt/nvidia/jetson-io/config-by-function.py spi1 -o dtbo
sudo mv ${BOOT_LOCATION}/kernel_${DEVICE}-hdr40-user-custom.dtbo ~/src/device_trees/kernel_${DEVICE}-hdr40-user-custom.dtbo && dtc -I dtb -O dts -o ~/src/device_trees/spi_overlay.dts ~/src/device_trees/kernel_${DEVICE}-hdr40-user-custom.dtbo
Edit the new overlay: nano ${HOME}/src/device_trees/spi_overlay.dts to add in the following fragment:
fragment@1 {
target-path = "/spi@3210000";
__overlay__ {
prod-settings {
status= "disabled";
};
spi@0 {
compatible = "linux,spidev";
controller-data {
nvidia,clk-delay-between-packets = <2>;
};
};
};
};
Apply the new overlay:
dtc -I dts -O dtb -@ -o ${HOME}/src/device_trees/original_tree.dtb ${HOME}/src/device_trees/original_tree.dts && dtc -I dts -O dtb -@ -o ${HOME}/src/device_trees/spi_overlay.dtbo ${HOME}/src/device_trees/spi_overlay.dts && sudo fdtoverlay -i ${HOME}/src/device_trees/original_tree.dtb -o ${BOOT_LOCATION}/dtb/kernel_${DEVICE}.dtb ${HOME}/src/device_trees/spi_overlay.dtbo
Testing
Basic tests were carried out with https://github.com/rm-hull/spidev-test
mkdir -p ${HOME}/src/ && cd ${HOME}/src/
git clone https://github.com/rm-hull/spidev-test
cd spidev-test
gcc spidev_test.c -o spidev_test
The test was run ${HOME}/src/spidev-test/spidev_test and produced:
Which is a good start. Next, exact timing controls will be investigated.
