I have started looking into writing a test program/script to test the functionality of the one of the SPI bus interface (which in the current board called SPI6). I am trying to finish all the legwork before jump into writing the test. I am also waiting for the SPI slave hw to be available from the HW team. In the meantime I have done some searching in the code and in the internet. And I have found out some information regarding this. However, I have a doubt and I would like to request your help in that.
I looked into the kernel (the below is the STM kernel we are using at the moment):
# uname -a
Linux buildroot 5.15.67 #1 SMP PREEMPT Tue Feb 6 16:12:01 GMT 2024 armv7l GNU/Linux
I can see the following:
# ls -la /sys/bus/spi/devices/spi0.
spi0.0/ spi0.1/ spi0.2/ spi0.3/ spi0.4/
# ls -la /sys/class/spi_master/spi
spi0/ spi1/
# ls -la /sys/class/spi_
spi_master/ spi_slave/
# ls -la /sys/class/spi_master/
total 0
drwxr-xr-x 2 root root 0 Feb 7 08:18 .
drwxr-xr-x 58 root root 0 Feb 7 08:18 ..
lrwxrwxrwx 1 root root 0 Feb 7 10:01 spi0 -> ../../devices/platform/soc/44004000.spi/spi_master/spi0
lrwxrwxrwx 1 root root 0 Feb 7 10:01 spi1 -> ../../devices/platform/soc/5c001000.spi/spi_master/spi1
# ls -la /sys/class/spi_slave/
total 0
drwxr-xr-x 2 root root 0 Feb 7 08:18 .
drwxr-xr-x 58 root root 0 Feb 7 08:18 ..
I checked the .config file we are using and the below config options are present:
CONFIG_SPI=y
CONFIG_SPI_DEBUG=y
CONFIG_SPI_STM32=m
CONFIG_SPI_STM32_QSPI=y
CONFIG_SPI_SPIDEV=y
CONFIG_SPI_MASTER=y
I can also see the below module:
# lsmod | grep -i spi
spi_stm32 24576 0
However, I was expecting to see spi nodes under /dev which I cannot:
# ls -la /dev/spi*
ls: /dev/spi*: No such file or directory
I do not have any slave device attached to the bus yet. Can someone please suggest if there is anything I am missing here? Please ask for more information if needed if I have missed to mention anything which may help understand the question.
I am copying the SPI6 (the spi interface I am interested in) entries from the dts file below
&spi6{
pinctrl-names = "default", "sleep";
pinctrl-0 = <&spi6_pins_mx &spi6_pins_z_mx>;
pinctrl-1 = <&spi6_sleep_pins_mx &spi6_sleep_pins_z_mx>;
status = "okay";
/* USER CODE BEGIN spi6 */
/* USER CODE END spi6 */
};
spi6_pins_mx: spi6_mx-0 {
pins {
pinmux = <STM32_PINMUX('G', 14, AF5)>; /* SPI6_MOSI */
bias-disable;
drive-push-pull;
slew-rate = <1>;
};
};
spi6_sleep_pins_mx: spi6_sleep_mx-0 {
pins {
pinmux = <STM32_PINMUX('G', 14, ANALOG)>; /* SPI6_MOSI */
};
};
spi6_pins_z_mx: spi6_mx-0 {
pins {
pinmux = <STM32_PINMUX('Z', 0, AF8)>, /* SPI6_SCK */
<STM32_PINMUX('Z', 1, AF8)>; /* SPI6_MISO */
bias-disable;
drive-push-pull;
slew-rate = <1>;
};
};
spi6_sleep_pins_z_mx: spi6_sleep_mx-0 {
pins {
pinmux = <STM32_PINMUX('Z', 0, ANALOG)>, /* SPI6_SCK */
<STM32_PINMUX('Z', 1, ANALOG)>; /* SPI6_MISO */
};
};
I have now added the following child in the spi6 entry in both the u-boot and the kernel dts fileas as below:
&spi6{
pinctrl-names = "default", "sleep";
pinctrl-0 = <&spi6_pins_mx &spi6_pins_z_mx>;
pinctrl-1 = <&spi6_sleep_pins_mx &spi6_sleep_pins_z_mx>;
status = "okay";
/* USER CODE BEGIN spi6 */
spidev@0{
compatible = "st,stm32h7-spi";
reg = <0>;
spi-max-frequency = <1000000>;
};
/* USER CODE END spi6 */
};
Now I can see the kernel log showing the child has been registered:
Feb 8 14:46:31 buildroot user.debug kernel: [ 4.443136] spi_stm32 5c001000.spi: 8 x 8-bit fifo size
Feb 8 14:46:31 buildroot user.debug kernel: [ 4.443179] spi_stm32 5c001000.spi: 16-bit maximum data frame
Feb 8 14:46:31 buildroot user.debug kernel: [ 4.443921] spi_stm32 5c001000.spi: registered master spi1
Feb 8 14:46:31 buildroot user.debug kernel: [ 4.444284] spi spi1.0: setup mode 0, 8 bits/w, 1000000 Hz max --> 0
Feb 8 14:46:31 buildroot user.debug kernel: [ 4.450214] spi_stm32 5c001000.spi: registered child spi1.0
Feb 8 14:46:31 buildroot user.info kernel: [ 4.450270] spi_stm32 5c001000.spi: driver initialized (master mode)
However, when I check /dev/ the child doesn't show up in the list:
# ls -la /dev/s
shm/ stderr stdin stdout
I am not sure about the below string in the part which I have added in my dts file:
compatible = "st,stm32h7-spi";
I copied it from a grep I did for stm32mpu and found this was used for spi6. Does this have any impact?
Additonal information: CONFIG_SPI_SPIDEV is set in the kernel config:
# cat /proc/config.gz | gunzip | grep CONFIG_SPI_SPIDEV
CONFIG_SPI_SPIDEV=y
Following what @droptop suggested to add a child node under the spi6 dts entry, I could finally manage to get this working using the following entry described in the STM link: https://wiki.st.com/stm32mpu/wiki/How_to_use_SPI_from_Linux_userland_with_spidev
kernel/stm32mp157c-ccb-mx.dts
&spi6{
pinctrl-names = "default", "sleep";
pinctrl-0 = <&spi6_pins_mx &spi6_pins_z_mx>;
pinctrl-1 = <&spi6_sleep_pins_mx &spi6_sleep_pins_z_mx>;
status = "okay";
/* USER CODE BEGIN spi6 */
spidev@0{
compatible = "rohm,dh2228fv";
reg = <0>;
spi-max-frequency = <4000000>;
};
/* USER CODE END spi6 */
};
and also in
CA7/DeviceTree/ccb/u-boot/stm32mp157c-ccb-mx.dts
&spi6{
pinctrl-names = "default", "sleep";
pinctrl-0 = <&spi6_pins_mx &spi6_pins_z_mx>;
pinctrl-1 = <&spi6_sleep_pins_mx &spi6_sleep_pins_z_mx>;
status = "okay";
/* USER CODE BEGIN spi6 */
spidev@0{
compatible = "rohm,dh2228fv";
reg = <0>;
spi-max-frequency = <4000000>;
};
/* USER CODE END spi6 */
};
My kernel configuration was as following:
# cat /proc/config.gz | gunzip | grep -w CONFIG_SPI
CONFIG_SPI=y
# cat /proc/config.gz | gunzip | grep -w CONFIG_SPI_MASTER
CONFIG_SPI_MASTER=y
# cat /proc/config.gz | gunzip | grep -w CONFIG_SPI_STM32
CONFIG_SPI_STM32=m
# cat /proc/config.gz | gunzip | grep -w CONFIG_SPI_SPIDEV
CONFIG_SPI_SPIDEV=y
# cat /proc/config.gz | gunzip | grep -w CONFIG_SPI_DEBUG
CONFIG_SPI_DEBUG=y
After I did this I could see the spi child node under the /dev as follows:
# ls -la /dev/spidev1.0
crw-rw---- 1 root root 153, 0 Feb 8 19:22 /dev/spidev1.0
Just to check if this works I ran spidev_test and I can see this:
# spidev_test -D /dev/spidev1.0 -v
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 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 | ......@....�..................�.
Thanks a lot to @droptop for directing me towards the right direction.