SPI slave mode for imx6ULL CoM

I am using Colibri imx6ULL CoM in my project. In that, we have two linux systems one in SPI master and the other in SPI slave mode. I just have some question regarding the slave mode option.

Does spidev driver maintained by toradex support SPI in slave mode? I believe imx6ULL does support slave mode, but I am not sure how to make the mode change or is it supported out-of-the-box. I am new to embedded Linux, so if that’s possible kindly explain the procedure.

Hi @SurriyaLuavan,

Checking here at the kernel modules that are enabled by default, I can see that the master is enabled and the slave is disabled:

root@colibri-imx6ull-06388420:~# zcat /proc/config.gz | grep SLAVE
# CONFIG_I2C_SLAVE is not set
# CONFIG_SPI_SLAVE is not set
root@colibri-imx6ull-06388420:~# zcat /proc/config.gz | grep MASTER

In order to enable the slave mode, you will need to compile a new kernel with the CONFIG_SPI_MASTER disabled and CONFIG_SPI_SLAVE enabled. This should fix your problem.

Let me know if you need anything else.

Best regards,

I couldn’t disable CONFIG_SPI_MASTER. I’ve tried several different techniques to use my own default config with SPI_MASTER=n. But, SPI_MASTER gets overwritten by the build. If I set other configs I can see that it’s getting reflected (CONFIG_SPI_SLAVE, CONFIG_SPI_SLAVE_SYSTEM_CONTROL etc…).

This is my current setting:

└── linux
├── linux-toradex
│ ├── defconfig
│ └── imx6ull-colibri-SASI-v1.dts
└── linux-toradex_%.bbappend

Contents of linux-toradex_%.bbappend:
FILESEXTRAPATHS_prepend := “${THISDIR}/linux-toradex:”


CUSTOM_DEVICETREE = “imx6ull-colibri-SASI-v1.dts”

SRC_URI += "\

do_configure_append() {
# For arm32 bit devices
cp ${WORKDIR}/${CUSTOM_DEVICETREE} ${S}/arch/arm/boot/dts
# For arm64 bit freescale/NXP devices
# cp ${WORKDIR}/${CUSTOM_DEVICETREE} ${S}/arch/arm64/boot/dts/freescale

Other details:

  1. My layer has the highest priority
  2. I could not find SPI_MASTER in menuconfig either.

Hi @SurriyaLuavan,

Using our linux-toradex (linux-toradex.git - Linux kernel for Apalis and Colibri modules), branch toradex_5.4-2.3.x-imx which is our branch for the downstream kernel, I could find these configs in menuconfig. Just search for SPI_MASTER and SPI_SLAVE.

SPI_SLAVE I could easily enable by setting

---> device drivers
        ---> SPI Support
                [*] SPI Slave protocol handlers

However, I couldn’t disable the SPI_MASTER too.
Could you please enable only the SPI Slave protocol handlers and check if this is enough? Unfortunately, I don’t have any hardware with SPI to test this right now.

Your custom meta-layer seems right to me, remember that the folder linux-toradex should be inside the linux folder, here is an example from my side:

├── conf
│   ├── layer.conf
│   └── machine
│       └── colibri-imx6ull-extra.conf
├── recipes-bsp
│   └── u-boot
│       └── u-boot-toradex_%.bbappend
├── recipes-example
│   └── example
│       └── example_0.1.bb
└── recipes-kernel
    └── linux
        ├── linux-toradex
        │   └── imx6ull-colibri-iris-v2-custom.dts
        │   └── defconfig
        └── linux-toradex%.bbappend

Also, I’ve found this good documentation about SPI in the Linux kernel: linux/spi-summary.rst at master · torvalds/linux · GitHub

Best regards,

Hi @hfranco.tx,

Thank you for your quick response. As you have mentioned, I have the linux-toradex inside linux folder and I can see other changes I have made custom config file such as CONFIG_SPI_SLAVE, CONFIG_SPI_DEBUG getting reflected.

I enabled SPI_SLAVE option and tired doing a spidev_test: first I ran the spidev_test from the slave device so that the FIFO will have the data. As soon as the master sends the data, the slave should be able to send the message from it’s end. But the message didn’t go through and hanged at the slave:

root@colibri-imx6ull-06764338:~# spidev_test -D /dev/spidev0.0 -p “SLAVE_HELLO_TO_MASTER” -v
spi mode: 0x0
bits per word: 8
max speed: 500000 Hz (500 KHz)
[ 353.574605] spidev spi0.0: SPI transfer failed: -4
[ 353.579893] spi_slave spi0: failed to transfer one message from queue

root@colibri-imx6ull-06764338:~# spidev_test -D /dev/spidev0.0 -v
spi mode: 0x0
bits per word: 8
max speed: 500000 Hz (500 KHz)

This is my dmesg output for spi:

root@colibri-imx6ull-06764338:~# dmesg | grep spi
[ 1.611538] spi_imx 2008000.spi: can’t get the TX DMA channel, error -517!
[ 2.244455] spi_imx 2008000.spi: can’t get the TX DMA channel, error -517!
[ 2.260039] spi_imx 2008000.spi: can’t get the TX DMA channel, error -517!
[ 2.261089] spi_imx 2008000.spi: can’t get the TX DMA channel, error -517!
[ 11.623166] spi_imx 2008000.spi: can’t get the TX DMA channel, error -517!
[ 11.763420] spi_imx 2008000.spi: registered slave spi0
[ 11.788439] spi_slave spi0: /soc/aips-bus@2000000/spba-bus@2000000/spi@2008000/spidev@0 is not called ‘slave’
[ 11.802239] spi_slave spi0: Failed to create SPI device for /soc/aips-bus@2000000/spba-bus@2000000/spi@2008000/spidev@0
[ 12.055306] spi spi0.0: spi_imx_setup: mode 0, 8 bpw, 0 hz
[ 12.055349] spi spi0.0: setup mode 0, 8 bits/w, 0 Hz max → 0
[ 12.067312] spi_imx 2008000.spi: registered child spi0.0
[ 12.067333] spi_imx 2008000.spi: probed

FYI, this is my device tree definition of spi for the slave device:

&ecspi1 {
	pinctrl-0 = <&pinctrl_ecspi1_cs &pinctrl_ecspi1>;
	status = "okay";
	slave@0 {
		compatible = "toradex,evalspi";
		spi-max-frequency = <20000000>;
		reg = <0>;
		status = "okay";

pinctrl_ecspi1_cs: ecspi1-cs-grp {
			fsl,pins = <
				MX6UL_PAD_LCD_DATA21__ECSPI1_SS0	0x70a0 /* SODIMM 86 */

pinctrl_ecspi1: ecspi1-grp {
			fsl,pins = <
				MX6UL_PAD_LCD_DATA20__ECSPI1_SCLK	0x000a0 /* SODIMM 88 */
				MX6UL_PAD_LCD_DATA23__ECSPI1_MISO	0x100a0 /* SODIMM 90 */
				MX6UL_PAD_LCD_DATA22__ECSPI1_MOSI	0x000a0 /* SODIMM 92 */	

I am not sure if this is because both the the SPI_MASTER and SPI_SLAVE option are set.