Several chip select on SPI

Hi all,

I’m trying to make SPI work on Linux with the spidev driver with this wanted pinout:

  • SPI 1 enabled
  • CS0 enabled on pin 86
  • CS1 enabled on pin 72
  • CS2 enabled on pin 80
  • SPI 2 enabled
  • CS0 enabled on pin 61

I’m using the 2.7b3-20170630 linux version, with the following changes on the device tree source:

--- <imx6dl-colibri-eval-v3.dts>
+++ <imx6dl-colibri-eval-v3-custom.dts>
@@ -101,24 +101,33 @@
 	};
 };
 
+&can1 {
+       status = "okay";
+};
+
 /* Colibri SPI */
 &ecspi4 {
 	status = "okay";
 
-	mcp258x0: mcp258x@1 {
-		compatible = "microchip,mcp2515";
+	spidev0: spidev@1 {
+		compatible = "spidev";
 		reg = <0>;
-		clocks = <&clk16m>;
-		interrupt-parent = <&gpio3>;
-		interrupts = <27 0x2>;
-		spi-max-frequency = <10000000>;
-		status = "okay";
-	};
-	spidev0: spidev@1 {
-		compatible = "toradex,evalspi";
-		reg = <0>;
-		spi-max-frequency = <23000000>;
-		status = "disabled";
+		spi-max-frequency = <23000000>;
+	};
+	spidev1: spidev@1 {
+		compatible = "spidev";
+		reg = <1>;
+		spi-max-frequency = <23000000>;
+	};
+	spidev2: spidev@1 {
+		compatible = "spidev";
+		reg = <2>;
+		spi-max-frequency = <23000000>;
+	};
+	spidev3: spidev@2 {
+		compatible = "spidev";
+		reg = <3>;
+		spi-max-frequency = <23000000>;
 	};
 };
 
@@ -182,7 +191,6 @@
 	             &pinctrl_weim_gpio_5 &pinctrl_weim_gpio_6
 	             &pinctrl_csi_gpio_1
 	             &pinctrl_gpio_1
-	             &pinctrl_gpio_2
 	             &pinctrl_usbh_oc_1 &pinctrl_usbc_id_1>;
 
 	gpio {
@@ -193,10 +201,6 @@
 			>;
 		};
 	};
-};
-
-&lcd {
-	status = "okay";
 };

and:

--- <imx6qdl-colibri.dtsi>
+++ <imx6qdl-colibri-custom.dtsi>
@@ -174,8 +174,8 @@
 
 /* Colibri SPI */
 &ecspi4 {
-	fsl,spi-num-chipselects = <1>;
-	cs-gpios = <&gpio5 2 0>;
+	fsl,spi-num-chipselects = <4>;
+	cs-gpios = <&gpio5 2 0>, <&gpio4 26 0>, <&gpio4 27 0>, <&gpio5 11 0>;
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_ecspi4 &pinctrl_spi_cs1>;
 	status = "disabled";
@@ -562,7 +562,10 @@
 #endif
 		pinctrl_spi_cs1: spi_cs1 {
 			fsl,pins = <
-				MX6QDL_PAD_EIM_A25__GPIO5_IO02		PAD_CTRL_NO	/* SPI cs */
+				MX6QDL_PAD_EIM_A25__GPIO5_IO02		PAD_CTRL_NO	/* SPI cs 1 */
+				MX6QDL_PAD_DISP0_DAT5__GPIO4_IO26	PAD_CTRL_NO	/* SPI cs 2 */
+				MX6QDL_PAD_DISP0_DAT6__GPIO4_IO27	PAD_CTRL_NO	/* SPI cs 3 */
+				MX6QDL_PAD_DISP0_DAT17__GPIO5_IO11	PAD_CTRL_NO	/* SPI cs 4 */
 			>;
 		};
 		pinctrl_touch_int_1: touch_int-1 {

It appears that I never attached the different SPI CS pin to a specific SPI controller.

On my linux distribution, I have:

ls /dev | grep spi
spidev3.0
spidev3.1

But I hoped to have spidev0.0, spidev0.1, spidev0.2, and spidev1.0, or something similar.

How to setup the SPI to work with multiple SPI CD pins?

Regards,

Léo

Did you really meant to use SPI 2? I do not see any changes enabling the same.Assuming you meant to use four CS with ECSPI4 below would be the expected set of changes (Not tested).

diff --git a/arch/arm/boot/dts/imx6dl-colibri-eval-v3.dts b/arch/arm/boot/dts/imx6dl-colibri-eval-v3.dts
index acd9031cf0a7..93b50f528d4e 100644
--- a/arch/arm/boot/dts/imx6dl-colibri-eval-v3.dts
+++ b/arch/arm/boot/dts/imx6dl-colibri-eval-v3.dts
@@ -112,13 +112,31 @@
                interrupt-parent = <&gpio3>;
                interrupts = <27 0x2>;
                spi-max-frequency = <10000000>;
-               status = "okay";
+               status = "disabled";
        };
        spidev0: spidev@1 {
                compatible = "toradex,evalspi";
                reg = <0>;
                spi-max-frequency = <23000000>;
-               status = "disabled";
+               status = "okay";
+       };
+       spidev1: spidev@2 {
+               compatible = "toradex,evalspi";
+               reg = <1>;
+               spi-max-frequency = <23000000>;
+               status = "okay";
+       };
+       spidev2: spidev@3 {
+               compatible = "toradex,evalspi";
+               reg = <2>;
+               spi-max-frequency = <23000000>;
+               status = "okay";
+       };
+       spidev3: spidev@4 {
+               compatible = "toradex,evalspi";
+               reg = <3>;
+               spi-max-frequency = <23000000>;
+               status = "okay";
        };
 };
 
@@ -196,7 +214,7 @@
 };
 
 &lcd {
-       status = "okay";
+       status = "disabled";
 };
 
 &mxcfb1 {
diff --git a/arch/arm/boot/dts/imx6qdl-colibri.dtsi b/arch/arm/boot/dts/imx6qdl-colibri.dtsi
index 5b7d6ca58fee..c4ab114aac95 100644
--- a/arch/arm/boot/dts/imx6qdl-colibri.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-colibri.dtsi
@@ -174,10 +174,10 @@
 
 /* Colibri SPI */
 &ecspi4 {
-       fsl,spi-num-chipselects = <1>;
-       cs-gpios = <&gpio5 2 0>;
+       fsl,spi-num-chipselects = <4>;
+       cs-gpios = <&gpio5 2 0 &gpio4 26 0 &gpio4 27 0 &gpio5 11 0>;
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_ecspi4 &pinctrl_spi_cs1>;
+       pinctrl-0 = <&pinctrl_ecspi4 &pinctrl_spi_cs1 &pinctrl_spi_cs2 &pinctrl_spi_cs3 &pinctrl_spi_cs4>;
        status = "disabled";
 };
 
@@ -565,6 +565,21 @@
                                MX6QDL_PAD_EIM_A25__GPIO5_IO02          PAD_CTRL_NO     /* SPI cs */
                        >;
                };
+               pinctrl_spi_cs2: spi_cs2 {
+                       fsl,pins = <
+                               MX6QDL_PAD_DISP0_DAT5__GPIO4_IO26       PAD_CTRL_NO     /* SPI cs */
+                       >;
+               };
+               pinctrl_spi_cs3: spi_cs3 {
+                       fsl,pins = <
+                               MX6QDL_PAD_DISP0_DAT6__GPIO4_IO27       PAD_CTRL_NO     /* SPI cs */
+                       >;
+               };
+               pinctrl_spi_cs4: spi_cs4 {
+                       fsl,pins = <
+                               MX6QDL_PAD_DISP0_DAT17__GPIO5_IO11      PAD_CTRL_NO     /* SPI cs */
+                       >;
+               };
                pinctrl_touch_int_1: touch_int-1 {
                        fsl,pins = <
                                MX6QDL_PAD_RGMII_TD0__GPIO6_IO20        PAD_CTRL_HYS_PU /* STMPE811 interrupt */

The expected four spidev nodes.

root@colibri-imx6:~# ls /dev | grep spi
spidev3.0
spidev3.1
spidev3.2
spidev3.3

Hello,

Thank you for your answer.

I want to use two SPI controllers (for buffer and multi-threading purposes).

I have done some progress in the implementation of the device tree for this two SPI controllers, and I’m facing a new issue since there is no documentation of how to use the 4 controllers.

Here are the changes :

--- <imx6qdl-colibri.dtsi>
+++ <imx6qdl-colibri-custom.dtsi>
@@ -174,10 +174,17 @@
 
 /* Colibri SPI */
 &ecspi4 {
+	fsl,spi-num-chipselects = <3>;
+	cs-gpios = <&gpio5 2 0>, <&gpio4 26 0>, <&gpio4 27 0>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_ecspi4 &pinctrl_spi_cs1>;
+	status = "disabled";
+};
+&ecspi1 {
 	fsl,spi-num-chipselects = <1>;
-	cs-gpios = <&gpio5 2 0>;
-	pinctrl-names = "default";
-	pinctrl-0 = <&pinctrl_ecspi4 &pinctrl_spi_cs1>;
+	cs-gpios = <&gpio5 11 0>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_ecspi1 &pinctrl_spi_cs2>;
 	status = "disabled";
 };
 
@@ -425,6 +432,16 @@
 		};
 	};
 
+	ecspi1 {
+		pinctrl_ecspi1: ecspi1grp {
+			fsl,pins = <
+				MX6QDL_PAD_NANDF_D3__GPIO2_IO03		0x100b1
+				MX6QDL_PAD_DISP0_DAT16__GPIO5_IO10	0x100b1
+				MX6QDL_PAD_NANDF_D6__GPIO2_IO06 	0x100b1
+			>;
+		};
+	};
+
 	enet {
 
 		pinctrl_enet: enetgrp { /* RMII */
@@ -562,7 +579,14 @@
 #endif
 		pinctrl_spi_cs1: spi_cs1 {
 			fsl,pins = <
-				MX6QDL_PAD_EIM_A25__GPIO5_IO02		PAD_CTRL_NO	/* SPI cs */
+				MX6QDL_PAD_EIM_A25__GPIO5_IO02		PAD_CTRL_NO	/* SPI cs 1 */
+				MX6QDL_PAD_DISP0_DAT5__GPIO4_IO26	PAD_CTRL_NO	/* SPI cs 2 */
+				MX6QDL_PAD_DISP0_DAT6__GPIO4_IO27	PAD_CTRL_NO	/* SPI cs 3 */
+			>;
+		};
+		pinctrl_spi_cs2: spi_cs2 {
+			fsl,pins = <
+				MX6QDL_PAD_DISP0_DAT17__GPIO5_IO11	PAD_CTRL_NO	/* SPI cs 4 */
 			>;
 		};
 		pinctrl_touch_int_1: touch_int-1 {

and :

--- <imx6dl-colibri-eval-v3.dts>
+++ <imx6dl-colibri-eval-v3-custom.dts>
@@ -105,20 +105,29 @@
 &ecspi4 {
 	status = "okay";
 
-	mcp258x0: mcp258x@1 {
-		compatible = "microchip,mcp2515";
+	spidev0: spidev@1 {
+		compatible = "spidev";
 		reg = <0>;
-		clocks = <&clk16m>;
-		interrupt-parent = <&gpio3>;
-		interrupts = <27 0x2>;
-		spi-max-frequency = <10000000>;
-		status = "okay";
-	};
-	spidev0: spidev@1 {
-		compatible = "toradex,evalspi";
+		spi-max-frequency = <23000000>;
+	};
+	spidev1: spidev@2 {
+		compatible = "spidev";
+		reg = <1>;
+		spi-max-frequency = <23000000>;
+	};
+	spidev2: spidev@3 {
+		compatible = "spidev";
+		reg = <2>;
+		spi-max-frequency = <23000000>;
+	};
+};
+&ecspi1 {
+	status = "okay";
+
+	spidev3: spidev@1 {
+		compatible = "spidev";
 		reg = <0>;
 		spi-max-frequency = <23000000>;
-		status = "disabled";
 	};
 };
 
@@ -181,8 +190,6 @@
 	             &pinctrl_weim_gpio_3 &pinctrl_weim_gpio_4
 	             &pinctrl_weim_gpio_5 &pinctrl_weim_gpio_6
 	             &pinctrl_csi_gpio_1
-	             &pinctrl_gpio_1
-	             &pinctrl_gpio_2
 	             &pinctrl_usbh_oc_1 &pinctrl_usbc_id_1>;
 
 	gpio {
@@ -193,10 +200,6 @@
 			>;
 		};
 	};
-};
-
-&lcd {
-	status = "okay";
 };
 
 &mxcfb1 {

It appears that the new SPI device is created as /dev/spidev0.0 perfectly but I don’t have the MOSI, MISO and CLK signals in the correct pin (the CS signal is OK).

I think that the reason is that in the pinctrl_ecspi1 group I have used #define that are not configured for SPI. But as you can see here there is no #define provided.

The pins have been choosen using the Toradex Pinout Designer.

Léo

Hi

The pins you choose do not provide SPI functionality on i.MX 6.

I checked in the Toradex Pinout Designer and for Colibri iMX6 I do not find SPI functionality on these pins.
Did you set a wrong module type when you used the Toradex Pinout Designer?

Note that Linux has a SPI bitbang driver (CONFIG_SPI_GPIO) which would allow SPI on any three GPIO pins.
Of course this would increase the CPU usage and probably limit SPI throughput.

Max

Hi Max,

I just discovered that the Pinout Designer enables all modules by default while loading reference pinout.
I’ll give an other try with a different configuration.

Léo

Hi all,

At the end, it finally worked, with this current device tree changes:

--- <imx6dl-colibri-eval-v3.dts>
+++ <imx6dl-colibri-eval-v3-custom.dts>
@@ -105,20 +105,29 @@
 &ecspi4 {
 	status = "okay";
 
-	mcp258x0: mcp258x@1 {
-		compatible = "microchip,mcp2515";
+	spidev0: spidev@1 {
+		compatible = "spidev";
 		reg = <0>;
-		clocks = <&clk16m>;
-		interrupt-parent = <&gpio3>;
-		interrupts = <27 0x2>;
-		spi-max-frequency = <10000000>;
-		status = "okay";
-	};
-	spidev0: spidev@1 {
-		compatible = "toradex,evalspi";
+		spi-max-frequency = <23000000>;
+	};
+	spidev1: spidev@2 {
+		compatible = "spidev";
+		reg = <1>;
+		spi-max-frequency = <23000000>;
+	};
+	spidev2: spidev@3 {
+		compatible = "spidev";
+		reg = <2>;
+		spi-max-frequency = <23000000>;
+	};
+};
+&ecspi1 {
+	status = "okay";
+
+	spidev3: spidev@1 {
+		compatible = "spidev";
 		reg = <0>;
 		spi-max-frequency = <23000000>;
-		status = "disabled";
 	};
 };
 
@@ -177,12 +186,8 @@
 	 * so they are ready for export to user space
 	 */
 	pinctrl-names = "default";
-	pinctrl-0 = <&pinctrl_weim_gpio_1 &pinctrl_weim_gpio_2
-	             &pinctrl_weim_gpio_3 &pinctrl_weim_gpio_4
+	pinctrl-0 = <&pinctrl_weim_gpio_3 &pinctrl_weim_gpio_4
 	             &pinctrl_weim_gpio_5 &pinctrl_weim_gpio_6
-	             &pinctrl_csi_gpio_1
-	             &pinctrl_gpio_1
-	             &pinctrl_gpio_2
 	             &pinctrl_usbh_oc_1 &pinctrl_usbc_id_1>;
 
 	gpio {
@@ -193,10 +198,6 @@
 			>;
 		};
 	};
-};
-
-&lcd {
-	status = "okay";
 };
 
 &mxcfb1 {

and:

--- <imx6qdl-colibri.dtsi>
+++ <imx6qdl-colibri-custom.dtsi>
@@ -174,10 +174,17 @@
 
 /* Colibri SPI */
 &ecspi4 {
+	fsl,spi-num-chipselects = <3>;
+	cs-gpios = <&gpio5 2 0>, <&gpio3 29 0>, <&gpio3 24 0>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_ecspi4 &pinctrl_spi_cs1>;
+	status = "disabled";
+};
+&ecspi1 {
 	fsl,spi-num-chipselects = <1>;
-	cs-gpios = <&gpio5 2 0>;
-	pinctrl-names = "default";
-	pinctrl-0 = <&pinctrl_ecspi4 &pinctrl_spi_cs1>;
+	cs-gpios = <&gpio5 17 0>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_ecspi1 &pinctrl_spi_cs2>;
 	status = "disabled";
 };
 
@@ -425,6 +432,16 @@
 		};
 	};
 
+	ecspi1 {
+		pinctrl_ecspi1: ecspi1grp {
+			fsl,pins = <
+				MX6QDL_PAD_DISP0_DAT22__ECSPI1_MISO	0x100b1
+				MX6QDL_PAD_DISP0_DAT21__ECSPI1_MOSI	0x100b1
+				MX6QDL_PAD_DISP0_DAT20__ECSPI1_SCLK	0x100b1
+			>;
+		};
+	};
+
 	enet {
 
 		pinctrl_enet: enetgrp { /* RMII */
@@ -562,7 +579,14 @@
 #endif
 		pinctrl_spi_cs1: spi_cs1 {
 			fsl,pins = <
-				MX6QDL_PAD_EIM_A25__GPIO5_IO02		PAD_CTRL_NO	/* SPI cs */
+				MX6QDL_PAD_EIM_A25__ECSPI4_SS1		PAD_CTRL_NO	/* SPI cs 1 */
+				MX6QDL_PAD_EIM_D29__ECSPI4_SS0		PAD_CTRL_NO	/* SPI cs 2 */
+				MX6QDL_PAD_EIM_D24__ECSPI4_SS2		PAD_CTRL_NO	/* SPI cs 3 */
+			>;
+		};
+		pinctrl_spi_cs2: spi_cs2 {
+			fsl,pins = <
+				MX6QDL_PAD_DISP0_DAT23__ECSPI1_SS0	PAD_CTRL_NO	/* SPI cs 4 */
 			>;
 		};
 		pinctrl_touch_int_1: touch_int-1 {
@@ -955,9 +979,8 @@
 /* UART A */
 &uart1 {
 	pinctrl-names = "default";
-	pinctrl-0 = <&pinctrl_uart1_dte &pinctrl_uart1_ctrl>;
+	pinctrl-0 = <&pinctrl_uart1_dte>;
 	fsl,dte-mode;
-	fsl,uart-has-rtscts;
 	status = "disabled";
 };

Once that changed, the devices appeared perfectly:

# ls /dev/spi*
/dev/spidev0.0  /dev/spidev3.0  /dev/spidev3.1  /dev/spidev3.2

Remember to check that the jumpers in the jumper area are not linking SPI pins to other features (such as SODIMM[81] to PCD in the old Col Eval V2.1c)

Léo