How to change SPI GPIO value on Colibri IMX6ULL

Dear guys,
I activated the SPI on IMX6ULL.
In particular I have 4 different SPI chip select associated to following SODIMM:

         MX6UL_PAD_UART2_CTS_B__GPIO1_IO22    0x70a0 /* SODIMM 32 */
         MX6UL_PAD_UART2_RTS_B__GPIO1_IO23    0x70a0 /* SODIMM 34 */
         MX6UL_PAD_UART2_RX_DATA__GPIO1_IO21      0x70a0    /* SODIMM 38 */
         MX6UL_PAD_UART2_TX_DATA__GPIO1_IO20      0x70a0    /* SODIMM 36 */

For more details see the ticket (How to use SPI on Colibri IMX6ULL).

I need to change the value of SPI output gpio on sometime while the my application is running.
If I use the Toradex GPIO tool the value is changed right, For example I changed the value of gpio-20.

I saw the change value using the command: cat /sys/kernel/debug/gpio and with the oscilloscope.

Before:

           gpiochip0: GPIOs 0-31, parent: platform/209c000.gpio, 209c000.gpio: gpio-2 ( |VCC_USB[1-4] ) out lo
           gpio-11 ( |enable ) out hi
           gpio-20 ( |spi_imx ) out hi
           gpio-21 ( |spi_imx ) out hi
           gpio-22 ( |spi_imx ) out hi
           gpio-23 ( |spi_imx ) out hi

After:

                 gpiochip0: GPIOs 0-31, parent: platform/209c000.gpio, 209c000.gpio: gpio-2 ( |VCC_USB[1-4] ) out lo
                gpio-11 ( |enable ) out hi
                gpio-20 ( |spi_imx ) out hi
                gpio-21 ( |spi_imx ) out lo
                gpio-22 ( |spi_imx ) out hi
                gpio-23 ( |spi_imx ) out hi

I tried to use the following lines:

                  // export GPIO
                  fd = open("/sys/class/gpio/export", O_WRONLY);
                 write(fd, "21", 2);
                 close(fd);

                   // configure as output
                   fd = open("/sys/class/gpio/gpio21/direction", O_WRONLY);
                   write(fd, "out", 3);
                   close(fd);
                  fd = open("/sys/class/gpio/gpio21/value", O_WRONLY | O_SYNC);
                  write(fd, "0", 1);

I used these commands on the VF61 and they run right. Then I tried to export gpio21 on IMX6ULL it’s give me a error message and the folder gpio21 is not created. I tried the following command line: echo 21 > /sys/class/gpio/export

and obtained this error: write error: Device or resource busy

How could I change the status of SPI GPIO output?

Thank you,

Best regards

Matteo

@Matte,

Instead of removing these pinctrl_uart2 lines, you can actually try disabling the uart2 node altogether. Just locate it - &uart2- and then add status = "disabled". It’ll look something like this:

&uart2 {
[...]
    status = "disabled"
};

This should be enough to disable the UART functions from the pins and let it behave properly.

Greetings @Matte!

This looks like some permission issue. Are you also using BSP 2.8b6 on VF61 where it runs right?

Also make sure to remove any other references to the pin you’re trying to use on the device tree (i.e. look for other instances of MX6UL_PAD_UART2_RX_DATA_ that might conflict with your GPIO assignment).

Dear @gustavo.tx,

thank for you replay.

For the VF61 I compiled the branch toradex_vf_4.4.

I disabled the UART2 on the tree,

but I don’t delete the following lines about UART2:

            pinctrl_uart2: uart2grp {
                    fsl,pins = <
                            MX6UL_PAD_UART2_TX_DATA__UART2_DTE_RX   0x1b0b1
                            MX6UL_PAD_UART2_RX_DATA__UART2_DTE_TX   0x1b0b1
                            MX6UL_PAD_UART2_CTS_B__UART2_DTE_RTS    0x1b0b1
                            MX6UL_PAD_UART2_RTS_B__UART2_DTE_CTS    0x1b0b1
                    >;

Do I need to remove these lines ?

Moreover in order to use the SPI I inserted the following lines respect to the default configuration:

&ecspi1 {

 fsl,spi-num-chipselects = <4>;
 cs-gpios =  <&gpio1 20 GPIO_ACTIVE_LOW>,
             <&gpio1 21 GPIO_ACTIVE_LOW>,
             <&gpio1 22 GPIO_ACTIVE_LOW>,
             <&gpio1 23 GPIO_ACTIVE_LOW>;
  pinctrl-names = "default";
  pinctrl-0 = <&pinctrl_ecspi1 &pinctrl_ecspi1_cs>;

};

I attached the tree files. link text

Do you find any errors?

Could you have any other suggestion?

Best regards

Matteo

Dear @gustavo.tx ,

when I opened this ticket I have already disabled the uart2 using exactly your lines:

    &uart2 {
    	status = "disabled";
     };

I don’t understand why it’s not working?

Do you have any other suggestions?

Best regards

Matteo

@Matte,

If those pins are correctly assigned, this should work. Can you please share a log of what you exactly did and what is the output?

Also, do any of the other pins work?

Dear @gustavo.tx,

I show you my changes of the tree, maybe it can explain better the problem:

				diff --git a/arch/arm/boot/dts/imx6ull-colibri-eval-v3.dtsi b/arch/arm/boot/dts/imx6ull-colibri-eval-v3.dtsi
				index 5870638c3a6f..0d27587d28de 100644
				--- a/arch/arm/boot/dts/imx6ull-colibri-eval-v3.dtsi
				+++ b/arch/arm/boot/dts/imx6ull-colibri-eval-v3.dtsi
				@@ -101,15 +101,39 @@
						interrupt-parent = <&gpio2>;
						interrupts = <4 IRQ_TYPE_EDGE_FALLING>;
						spi-max-frequency = <10000000>;
				-		status = "okay";
				-	};
				-
				-	spidev0: spidev@0 {
				-		compatible = "toradex,evalspi";
				-		reg = <0>;
				-		spi-max-frequency = <23000000>;
						status = "disabled";
					};
				+
				+
				+        spidev0: spidev@0 {
				+                compatible = "toradex,evalspi";
				+                reg = <0>;
				+                spi-max-frequency = <1000000>;
				+                status = "okay";
				+        };
				+
				+
				+        spidev1: spidev@1 {
				+                compatible = "toradex,evalspi";
				+                reg = <1>;
				+                spi-max-frequency = <1000000>;
				+                status = "okay";
				+        };
				+
				+
				+         spidev2: spidev@2 {
				+                compatible = "toradex,evalspi";
				+                reg = <2>;
				+                spi-max-frequency = <1000000>;
				+                status = "okay";
				+        };
				+
				+      spidev3: spidev@3 {
				+                compatible = "toradex,evalspi";
				+                reg = <3>;
				+                spi-max-frequency = <1000000>;
				+                status = "okay";
				+        };
				 };
				 
				 #if 0
				@@ -295,7 +319,7 @@
				 
				 /* PWM <B> */
				 &pwm5 {
				-	status = "okay";
				+	status = "disabled";
				 };
				 
				 /* PWM <C> */
				@@ -313,7 +337,7 @@
				 };
				 
				 &uart2 {
				-	status = "okay";
				+	status = "disabled";
				 };
				 
				 &uart5 {
				@@ -359,7 +383,13 @@
				 
				 &iomuxc {
					imx6ull-eval-v3 {
				-		pinctrl_gpiotouch: touchgpios {
				+	
				+           pinctrl_additionalgpio: additionalgpios {
				+               fsl,pins = <
				+                              MX6UL_PAD_NAND_DQS__GPIO4_IO16 0xF81
				+                              >;
				+            };
				+	pinctrl_gpiotouch: touchgpios {
							fsl,pins = <
								MX6UL_PAD_NAND_DQS__GPIO4_IO16		0x74
								MX6UL_PAD_ENET1_TX_EN__GPIO2_IO05	0x14
				diff --git a/arch/arm/boot/dts/imx6ull-colibri.dtsi b/arch/arm/boot/dts/imx6ull-colibri.dtsi
				index f090d967415b..87436a385589 100644
				--- a/arch/arm/boot/dts/imx6ull-colibri.dtsi
				+++ b/arch/arm/boot/dts/imx6ull-colibri.dtsi
				@@ -112,12 +112,17 @@
				 
				 
				 /* Colibri SPI */
				-&ecspi1 {
				-	fsl,spi-num-chipselects = <1>;
				-	cs-gpios = <&gpio3 26 GPIO_ACTIVE_HIGH>;
				-	pinctrl-names = "default";
				-	pinctrl-0 = <&pinctrl_ecspi1 &pinctrl_ecspi1_cs>;
				-};
				+  &ecspi1 {
				+
				+     fsl,spi-num-chipselects = <4>;
				+     cs-gpios =  <&gpio1 20 GPIO_ACTIVE_LOW>,
				+                 <&gpio1 21 GPIO_ACTIVE_LOW>,
				+                 <&gpio1 22 GPIO_ACTIVE_LOW>,
				+                 <&gpio1 23 GPIO_ACTIVE_LOW>;
				+      pinctrl-names = "default";
				+      pinctrl-0 = <&pinctrl_ecspi1 &pinctrl_ecspi1_cs>;
				+  };
				+
				 
				 &fec2 {
					pinctrl-names = "default", "sleep";
				@@ -337,11 +342,16 @@
							>;
						};
				 
				-		pinctrl_ecspi1_cs: ecspi1_cs_grp {
				-			fsl,pins = <
				-				MX6UL_PAD_LCD_DATA21__GPIO3_IO26	0x000a0
				-			>;
				-		};
				+	        pinctrl_ecspi1_cs: ecspi1-cs-grp {
				+		       fsl,pins = <
				+                 MX6UL_PAD_UART2_TX_DATA__GPIO1_IO20  	0x70a0	/* SODIMM 36 */                 
				+                 MX6UL_PAD_UART2_RX_DATA__GPIO1_IO21  	0x70a0	/* SODIMM 38 */
				+                 MX6UL_PAD_UART2_CTS_B__GPIO1_IO22	0x70a0 /* SODIMM 32 */
				+                 MX6UL_PAD_UART2_RTS_B__GPIO1_IO23	0x70a0 /* SODIMM 34 */
				+	        	>;
				+        	};
				+
				+
				 
						pinctrl_ecspi1: ecspi1grp {
							fsl,pins = <
				@@ -358,6 +368,7 @@
							>;
						};
				 
				+
						pinctrl_flexcan2: flexcan2grp {
							fsl,pins = <
								MX6UL_PAD_ENET1_TX_DATA0__FLEXCAN2_RX	0x1b020

and I attached the dmesg log.link text

Do you see any errors?

Moreover I show the errors message when I try to export the gpio:
2445-screenshot-from-2020-12-08-14-11-08.png

Are there any other outputs that I shared with you in order to understand better my problem, or any test that I can do?

Thank you for all your support.

Best regards

Matteo

Dear @gustavo.tx,

thank for you reply.

You can find my changes by the default tree:

			diff --git a/arch/arm/boot/dts/imx6ull-colibri-eval-v3.dtsi b/arch/arm/boot/dts/imx6ull-colibri-eval-v3.dtsi
			index 5870638c3a6f..0d27587d28de 100644
			--- a/arch/arm/boot/dts/imx6ull-colibri-eval-v3.dtsi
			+++ b/arch/arm/boot/dts/imx6ull-colibri-eval-v3.dtsi
			@@ -101,15 +101,39 @@
							interrupt-parent = <&gpio2>;
							interrupts = <4 IRQ_TYPE_EDGE_FALLING>;
							spi-max-frequency = <10000000>;
			-               status = "okay";
			-       };
			-
			-       spidev0: spidev@0 {
			-               compatible = "toradex,evalspi";
			-               reg = <0>;
			-               spi-max-frequency = <23000000>;
							status = "disabled";
					};
			+
			+
			+        spidev0: spidev@0 {
			+                compatible = "toradex,evalspi";
			+                reg = <0>;
			+                spi-max-frequency = <1000000>;
			+                status = "okay";
			+        };
			+
			+
			+        spidev1: spidev@1 {
			+                compatible = "toradex,evalspi";
			+                reg = <1>;
			+                spi-max-frequency = <1000000>;
			+                status = "okay";
			+        };
			+
			+
			+         spidev2: spidev@2 {
			+                compatible = "toradex,evalspi";
			+                reg = <2>;
			+                spi-max-frequency = <1000000>;
			+                status = "okay";
			+        };
			+
			+      spidev3: spidev@3 {
			+                compatible = "toradex,evalspi";
			+                reg = <3>;
			+                spi-max-frequency = <1000000>;
			+                status = "okay";
			+        };
			 };
			 
			 #if 0
			@@ -295,7 +319,7 @@
			 
			 /* PWM <B> */
			 &pwm5 {
			-       status = "okay";
			+       status = "disabled";
			 };
			 
			 /* PWM <C> */
			@@ -313,7 +337,7 @@
			 };
			 
			 &uart2 {
			-       status = "okay";
			+       status = "disabled";
			 };
			 
			 &uart5 {
			@@ -359,7 +383,13 @@
			 
			 &iomuxc {
					imx6ull-eval-v3 {
			-               pinctrl_gpiotouch: touchgpios {
			+       
			+           pinctrl_additionalgpio: additionalgpios {
			+               fsl,pins = <
			+                              MX6UL_PAD_NAND_DQS__GPIO4_IO16 0xF81
			+                              >;
			+            };
			+       pinctrl_gpiotouch: touchgpios {
									fsl,pins = <
											MX6UL_PAD_NAND_DQS__GPIO4_IO16          0x74
											MX6UL_PAD_ENET1_TX_EN__GPIO2_IO05       0x14
			diff --git a/arch/arm/boot/dts/imx6ull-colibri.dtsi b/arch/arm/boot/dts/imx6ull-colibri.dtsi
			index f090d967415b..87436a385589 100644
			--- a/arch/arm/boot/dts/imx6ull-colibri.dtsi
			+++ b/arch/arm/boot/dts/imx6ull-colibri.dtsi
			@@ -112,12 +112,17 @@
			 
			 
			 /* Colibri SPI */
			-&ecspi1 {
			-       fsl,spi-num-chipselects = <1>;
			-       cs-gpios = <&gpio3 26 GPIO_ACTIVE_HIGH>;
			-       pinctrl-names = "default";
			-       pinctrl-0 = <&pinctrl_ecspi1 &pinctrl_ecspi1_cs>;
			-};
			+  &ecspi1 {
			+
			+     fsl,spi-num-chipselects = <4>;
			+     cs-gpios =  <&gpio1 20 GPIO_ACTIVE_LOW>,
			+                 <&gpio1 21 GPIO_ACTIVE_LOW>,
			+                 <&gpio1 22 GPIO_ACTIVE_LOW>,
			+                 <&gpio1 23 GPIO_ACTIVE_LOW>;
			+      pinctrl-names = "default";
			+      pinctrl-0 = <&pinctrl_ecspi1 &pinctrl_ecspi1_cs>;
			+  };
			+
			 
			 &fec2 {
					pinctrl-names = "default", "sleep";
			@@ -337,11 +342,16 @@
									>;
							};
			 
			-               pinctrl_ecspi1_cs: ecspi1_cs_grp {
			-                       fsl,pins = <
			-                               MX6UL_PAD_LCD_DATA21__GPIO3_IO26        0x000a0
			-                       >;
			-               };
			+               pinctrl_ecspi1_cs: ecspi1-cs-grp {
			+                      fsl,pins = <
			+                 MX6UL_PAD_UART2_TX_DATA__GPIO1_IO20   0x70a0  /* SODIMM 36 */                 
			+                 MX6UL_PAD_UART2_RX_DATA__GPIO1_IO21   0x70a0  /* SODIMM 38 */
			+                 MX6UL_PAD_UART2_CTS_B__GPIO1_IO22     0x70a0 /* SODIMM 32 */
			+                 MX6UL_PAD_UART2_RTS_B__GPIO1_IO23     0x70a0 /* SODIMM 34 */
			+                       >;
			+               };
			+
			+
			 
							pinctrl_ecspi1: ecspi1grp {
									fsl,pins = <
			@@ -358,6 +368,7 @@
									>;
							};
			 
			+
							pinctrl_flexcan2: flexcan2grp {
									fsl,pins = <
											MX6UL_PAD_ENET1_TX_DATA0__FLEXCAN2_RX   0x1b020

I attached the dmesg log file link text

and the error when I can try to export the PIN 20:

2445-screenshot-from-2020-12-08-14-11-08.png

Do you see any errors?

I don’t understand what I’m wrong?

Best regards

Matteo

Dear @gustavo.tx ,

So I can not to change the state of these PINS manually?

Why is it possible with VF61?

Moreover on VF61 before to Read and Write a SPI value
I need to Set the GPIO Low and then HIGH.

Best regards

Matteo

@Matte,

I personally didn’t try this, but I think the Vybrids may deal with pins differently.

You can definitely change the state of these pins manually via sysfs just like you were trying to do, but you have to remove those pin assignments from cs-gpios on the ecspi node. They have to be assigned as regular GPIOs so you can control them that way.

@Matte,

Thanks for the info! I think I understand what’s going on there.

You have assigned those pins to the cs-gpios property of the ecspi1 node. This means Linux will give ownership of those pins to the SPI driver and won’t allow you to manipulate them manually via sysfs like you’re doing.

So you can just use Linux’s own SPI subsystem and its tools, the SPI driver will be responsible for manipulating those pins.

Dear @gustavo.tx,

but If I remove those pin assignment from cs-gpios on the ecspi node
I can to you those PINS as SPI drivers?

Because if I’m wrong without this assignment the SPI drivers are not available.

Best regards

Matteo

Hi @Matte,

What @gustavo.tx is saying is that you just need to leave Linux to handle the Chip-Select, once you had assigned the cs-gpios to the driver.

After your system boot, please execute this command for me:

ls /dev/spidev*

And paste here the output.

I hope you’ll see every spidev device created from your device-tree assignment.

Every “spidevX-Y” is X a given SPI port, and Y, its chip-select.

Once you use that given spidevX-Y, Linux will handle the activation of the chip-select and the communication for you.

Best regards,
André Curvello

Dear @gustavo.tx , @andrecurvello.tx,

I’m sorry, for the delay, I missed to respond you.

I used the following configuration and in this way I can to change manually the value of gpio output.

         &ecspi1 {

    fsl,spi-num-chipselects = <4>;
    /*
       cs-gpios =  <&gpio1 20 GPIO_ACTIVE_LOW>,
             <&gpio1 21 GPIO_ACTIVE_LOW>,
             <&gpio1 22 GPIO_ACTIVE_LOW>,
             <&gpio1 23 GPIO_ACTIVE_LOW>;

*/

     pinctrl-names = "default";
     pinctrl-0 = <&pinctrl_ecspi1 &pinctrl_ecspi1_cs>;
      };

Thank you for your support.

Best regards

Matteo

Hi @Matte,

If that is fine for your use-case, we are happy to know that it’s working.

Best regards,
André Curvello