M4 SPI ChipSelect not toggleing

Problem:

I am trying to connect a SPI device on the Banana Pi M4. So far I could add a spidev to the device-tree and send bytes with a test program.

With a logic analyzer I could confirm that the clock signal is generated and MOSI is also working. Also the MISO pin seems to work (MISO connected to GND/3V3 reads back 0x00 or 0xFF as expected).

However, I cannot see any activity on the chip select pin (CS) and therefore the connected device is also not responding.

What could be the reasons that there is no CS signal? Is the Pinout described at the wiki accurate or could it be on anouther pin?

Thanks for any help in advance!


Steps to reproduce:

Base image

I used the rasbian image as a base.

Add SPI kernel driver

Compile the kernel with CONFIG_SPI_RTD139x enabled. Instructions (or use my kernel binary: uImage)

Replace the uImage in /boot/bananapi/bpi-m4/linux/

Enable spi and spidev in device tree

# goto boot dir
cd /boot/bananapi/bpi-m4/linux/
# decompile the device tree
dtc -I dtb -O dts -o rtd-1395-bananapi-m4.dts  rtd-1395-bananapi-m4.dtb

set spi status to “okay” and add spidev@0: {...};

	spi@9801BD00 {
		compatible = "Realtek,rtk-dw-apb-ssi";
		#address-cells = <0x1>;
		#size-cells = <0x0>;
		interrupt-parent = <0x7>;
		interrupts = <0x0 0x1b>;
		reg = <0x9801bd00 0x100 0x9801b300 0x18>;
		pinctrl-names = "default";
		pinctrl-0 = <0x2c>;
		num-chipselect = <0x1>;
		bus-num = <0x0>;
		clocks = <0x1d 0x3>;
		clock-frequency = <0xf424000>;
		resets = <0x1a 0x2>;
		status = "okay";

		spidev@0 {
			compatible = "spidev";
			status = "okay";
			reg = <0>;
			spi-max-frequency = <1000000>;
		};
	};

Compile device tree and reboot

dtc -I dts -O dtb -o rtd-1395-bananapi-m4.dtb  rtd-1395-bananapi-m4.dts
reboot

Now the SPI device should be available (ls /dev/spidev0.0).

Test program

# wget https://raw.githubusercontent.com/torvalds/linux/master/tools/spi/spidev_test.c
# gcc -o spidev_test spidev_test.c
# ./spidev_test -v -D /dev/spidev0.0
spi mode: 0x0
bits per word: 8
max speed: 500000 Hz (500 KHz)
TX | 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  |......@.........................|
RX | FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF  |................................|

Just tested the chip select pin directly as GPIO.

I can toggle the GPIO as follows:

echo 20 > /sys/class/gpio/export
echo "out" > /sys/class/gpio/gpio20/direction
echo "1" > /sys/class/gpio/gpio20/value
echo "0" > /sys/class/gpio/gpio20/value

This also shows up in the logic analyzer, so the wiring is correct.

The pin number for SPI in device tree also matches gpio_20:

    gspi_pins_0: gspi_pins_0 {
      realtek,pins = "gspi_loc",
      "gpio_18", 
      "gpio_19",                     
      "gpio_20",
      "gpio_31";
      realtek,function = "gspi_loc0";
    }; 

What else can cause the pin not to toggle? Could there be some other function blocking the pin for SPI usage?

One more test to make sure the CS is the real problem here:

If I provide the CS value manually, the communication with the device is also working.

# echo 20 > /sys/class/gpio/export
# echo "out" > /sys/class/gpio/gpio20/direction
# echo "0" > /sys/class/gpio/gpio20/value;./spidev_test -v -s 20000 -D /dev/spidev0.0 -i input.bin;echo "1" > /sys/class/gpio/gpio20/value
spi mode: 0x0
bits per word: 8
max speed: 20000 Hz (20 KHz)
TX | 03 0E 00 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __  |...|
RX | FF FF 80 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __  |...|

Any help to get the the chip select pin working or hint why it is not working would be appreciated.

Looks like somehow the pin is not initialized. For now I added gpio_request(20, "gpio20"); to the spi driver and recompiled the kernel.