Hey all!
I'm trying to use cs-gpios on a Rock Pi 4B on SPI channel 2, but I have a couple of issues.
Status quo: I'm running an Armbian kernel version 5.10.63, so I assume all required patches should have been applied.
I'm using the following overlay, to both (1) enable SPI 2 and (2) define two GPIOs as CS signals (namely GPIO3_C0 and GPIO4_D6):
/dts-v1/;
/plugin/;
/ {
compatible = "rockchip,rk3399";
fragment@0 {
target-path = "/spi@ff1e0000";
__overlay__ {
#address-cells = <1>;
#size-cells = <0>;
cs-gpios = <&gpio3 16 1>, <&gpio4 30 1>;
status = "okay";
spidev@0 {
compatible = "spidev";
status = "okay";
reg = <0>;
spi-max-frequency = <10000000>;
};
spidev@1 {
compatible = "spidev";
status = "okay";
reg = <1>;
spi-max-frequency = <10000000>;
};
};
};
};
I add the overlay using armbian-add-overlay and I confirmed it is loaded via U-Boot output. I also get corresponding messages in the Kernel log and two SPI devices in Linux:
[ 3.118032] spi:spi_register_controller: rockchip-spi ff1e0000.spi: registered master spi2
[ 3.118265] spi:spi_setup: spi spi2.1: setup mode 0, 8 bits/w, 10000000 Hz max --> 0
[ 3.119331] spi:spi_add_device: rockchip-spi ff1e0000.spi: registered child spi2.1
[ 3.119412] spi:spi_setup: spi spi2.0: setup mode 0, 8 bits/w, 10000000 Hz max --> 0
[ 3.120415] spi:spi_add_device: rockchip-spi ff1e0000.spi: registered child spi2.0
> ls /dev/spi*
/dev/spidev2.0 /dev/spidev2.1
Note, that I enabled additional debug output via dyndbg, so I might have addional messages in my dmesg output that are not "standard".
So far so good.
Next, I tested the configuration using spi_test in loopback mode like so:
sudo ./spidev_test --device /dev/spidev2.0 -S 2 --iter 99999 --speed 10000
sudo ./spidev_test --device /dev/spidev2.1 -S 2 --iter 99999 --speed 10000
And here the problems start:
(1) I noticed, testing spidev2.0, that the hardware CS pin, GPIO2_B4 (aka SPI2_CSn0) toggles inverted to the chip select signal of spidev@0, namely GPIO3_C0, i.e. whenever GPIO3_C0 goes low, GPIO2_B4 goes high and vice-versa. This does not seem to happen if I use spidev@1, aka /dev/spidev2.1. Is this known/intended behaviour? If not, how do I fix it?
(2) I also tried to use the hardware chipselect pin, GPIO2_B4 together with a GPIO pin as chip select, i.e.:
cs-gpios = <0>, <&gpio3 16 1>;
This configuration resulted in spidev2.0 working as expected, but when testing spidev2.1 I got the following error message:
spi mode: 0x4
bits per word: 8
max speed: 10000 Hz (10 kHz)
can't send spi message: Connection timed out
and the following lines were logged to dmesg:
[ 326.295637] spidev spi2.1: SPI transfer timed out
[ 326.296133] spi_master spi2: failed to transfer one message from queue
What is the issue here? Posts by @martinayotte, @Marko Buršič, and @p-i-u.de made me think that this mode of operation was supported. Or am I still missing kernel patches?
I also tried the method of @Marko Buršič adding a spi2_cs1 and then extending pinctrl-0 of spi2 like so:
/dts-v1/;
/plugin/;
/ {
compatible = "rockchip,rk3399";
fragment@0 {
target-path ="/pinctrl/spi2";
__overlay__ {
spi2_cs1: spi2-cs1 {
rockchip,pins = <0x03 0x16 0x02 &pcfg_pull_up>;
};
};
};
fragment@1 {
target-path = "/spi@ff1e0000";
__overlay__ {
#address-cells = <1>;
#size-cells = <0>;
cs-gpios = <0>, <&gpio3 16 1>;
pinctrl-0 = <&spi2_clk &spi2_tx &spi2_rx &spi2_cs0 &spi2_cs1>;
status = "okay";
spidev@0 {
compatible = "spidev";
status = "okay";
reg = <0>;
spi-max-frequency = <10000000>;
};
spidev@1 {
compatible = "spidev";
status = "okay";
reg = <1>;
spi-max-frequency = <10000000>;
};
};
};
};
But that had the same result of spidev2.0 working and spidev2.1 failing with the "Connection timed out" error message.
Does anyone have any suggestion what the issue(s) might be?
Thanks in advance!