GPIO configuration with Torizon on Apalis iMX.8

Dear support community,

is there a guide or example how to configure GPIO pins with Torizon on iMX-8?

It seems only the default GPIO 1 to 6 are available to be configured.
Other GPIOs like LSIO.GPIO4.IO21 or GPIO7 or 8 are not configurable.

Thank you and best regards,
Peter

Greetings @v2c2,

Yes, as you’ve noticed only certain pins are configured and usable as GPIOs by default. In order to have access to more pins as GPIOs you’ll need to make changes in the device tree.

We do provide a tools container that lets you apply a device tree overlay so that you may make minor changes such as this without recompiling and redeploying the entire device tree. Details on this container can be found here: https://developer.toradex.com/knowledge-base/device-tree-overlays

There is also a section at the end of that article that provides a reference overlay that can be used to configure additional GPIOs. One important thing to keep in mind though is that many pins are already used by other hardware interfaces. So when you configure a pin as a GPIO you’ll need to take care as to resolve any conflicts and make sure the pin is not already in use. This may require disabling interfaces that use the pins that you want to use.

You can see what the default pin assignments are by looking at the device tree source file here: http://git.toradex.com/cgit/linux-toradex.git/tree/arch/arm64/boot/dts/freescale/fsl-imx8qm-apalis.dtsi?h=toradex_4.14-2.0.x-imx

For example it seems that GPIO4_IO21 isn’t used by anything so it should be fine to just add this in an overlay without modifying other interfaces.

Let me know if you have any further questions or require additional clarification.

Best Regards,
Jeremias

Thank you very much for the explanation!

Is there a complete (simple?) example how to configure the pinctrl node (&pinctrl_my_gpios) mentioned in the “Device Tree Overlays” article?

I can’t find an example for a .dts file configuring a GPIO pin.

Thank you and best regards,
Peter

We don’t have a documented example but perhaps we should, thank you for the feedback on that.

So to explain, the pinctrl node &pinctrl_my_gpios you see in the example gets created by the overlay itself. Really you can call the node whatever you want just rename &pinctrl_my_gpios in that example.

Using GPIO4_IO21 as an example again here’s an example overlay that should configure it as a GPIO:

/dts-v1/;
/plugin/;
/ {
	compatible = "toradex";
	fragment@0 {
		target = <&iomuxc>;
		__overlay__ {
			pinctrl-names = "default";
			pinctrl-0 = <&pinctrl_my_gpios>;

                        pinctrl_my_gpios: gpiomuxgrp {
                            SC_P_QSPI1A_SCLK_LSIO_GPIO4_IO21 0x41
                        }
		};
	};
};

If you need more GPIOs you can just add them as needed.

Best Regards,
Jeremias

Thank you very much!! That makes it somewhat clear how this should work.
Now I understand the output of the NXP pin tool (pin names and hex values).

But somehow I cannot make it build.
I tried the exact example you provided and tested in the torizon/arm64v8-debian-dev-tools docker container with the following result:

root@5bd024a1f776:/# dtconf build --no-git-repo /tests/gpio_test_forum.dts
Device is apalis imx8(0037)
Mounting /mnt/part
Failed to build device tree.
Error: /panda/gpio_test_forum.dts:12.62-66 syntax error
FATAL ERROR: Unable to parse input tree

test file:

root@5bd024a1f776:/# cat /tests/gpio_test_forum.dts
/dts-v1/;
/plugin/;
/ {
    compatible = "toradex";
    fragment@0 {
        target = <&iomuxc>;
        __overlay__ {
            pinctrl-names = "default";
            pinctrl-0 = <&pinctrl_my_gpios>;

                        pinctrl_my_gpios: gpiomuxgrp {
                            SC_P_QSPI1A_SCLK_LSIO_GPIO4_IO21 0x41
                        }
        };
    };
};

Apologies seems like some of my formatting got lost in the copy-paste, also I forgot one vital part to the overlay.

So here should be the correct overlay, I double-checked by building this on my setup and it built successfully there:

/dts-v1/;
/plugin/;

#include </root/pads-imx8qm.h>

/ {
    compatible = "toradex";
    fragment@0 {
        target = <&iomuxc>;
        __overlay__ {
            pinctrl-names = "default";
            pinctrl-0 = <&pinctrl_my_gpios>;
            pinctrl_my_gpios: gpiomuxgrp {
               fsl,pins = <
                   SC_P_QSPI1A_SCLK_LSIO_GPIO4_IO21 0x41
               >;
            };
        };
    };
};

So the important thing to note now is that there’s an include statement at the top. As you can imagine in the source code SC_P_QSPI1A_SCLK_LSIO_GPIO4_IO21 is just a variable name to define the various pins on the SoC. However we need to include this file in our overlay so that our overlay has the pin definitions when it compiles.

You’ll need to copy the pin definitions file onto the module which can be found here: http://git.toradex.com/cgit/linux-toradex.git/tree/include/dt-bindings/pinctrl/pads-imx8qm.h?h=toradex_4.14-2.0.x-imx

One small note please modify the include statement to have the full path of wherever you store this header file.

Best Regards,
Jeremias

This seems to compile and activate fine!

But now the module does not boot anymore…
I found similar cases in the forums, but not a suitable solution.

Can I deactivate the overlay in u-boot console during boot?

What could I try to make this simple example work (boot)?!

Best regards,
Peter

Hi Peter,

This seems like the case where this pin may have already been in use or configured somewhere in the device tree. In order to disable this overly from the u-boot console you can do the following:

  • ums 0 mmc 0 This command will attach the internal eMMC of the module to your development PC as a USB device. You’ll need the USB OTG attached for this
  • Once attached you’ll need to look in the BOOT partition. There should be an overlays text file you can simply just delete this file.
  • Once the overlays file has been deleted you can just boot as normal and the overlay shouldn’t load.

Back to the issue I looked again in all the device tree files and I did find one place where GPIO4_IO21 is used (http://git.toradex.com/cgit/linux-toradex.git/tree/arch/arm64/boot/dts/freescale/fsl-imx8qm-apalis-v1.1.dtsi?h=toradex_4.14-2.0.x-imx#n655) but this pinctrl node isn’t referenced anywhere else so it seems like this pin isn’t being used by an interface.

I did a quick test on my i.MX8 and I was able to set GPIO4_IO21 as an output and toggle it’s value using the sysfs interface. This is with no modifications to the device tree. Earlier you said this pin was not configurable, how were you accessing GPIOs initially?

Best Regards,
Jeremias

Hi Jeremias,

i used TEZI from SD-card via serial interface to mount the boot partition and delete the file, which worked (custom board without USB OTG).

You are correct - the newest beta3 of Torizon 4.0.0 seems to switch GPIO4_IO21 fine without overlays.
I had problems with an older image from CI server.

The problem persists for Apalis GPIO-8 (GPIO3_IO28), which seems to be used by:

line  28:      unnamed "GPIO fan control" output active-high [used]

Changing the output with gpioset does not work and returns:

# gpioset /dev/gpiochip3 28=0
gpioset: error setting the GPIO line values: Device or resource busy

I used the docker image “torizonextras/arm64v8-gpiod” and “gpioinfo” / “gpioset” tools in the image as described in the article “How to Use GPIO on TorizonCore”.

When activating the overlay for GPIO3_IO28:

SC_P_MLB_DATA_LSIO_GPIO3_IO28               0x00380021

The system does not boot again.

So this specific pin is my new problem :slight_smile:

Best,
Peter

Hi Peter,

As you’ve noticed with GPIO3_IO28, by default it is the GPIO used for the fan control. Now this is a question of whether you require the fan control to be working. If no then it is a simple matter of disabling this interface which should free up this pin. If yes then you’ll need to shuffle around pins and provide a substitute GPIO pin for the fan control to use.

So do you need this gpio-fan interface operational? And if yes do you have a GPIO pin in your system you can give up as a substitute?

Best Regards,
Jeremias

Hi!

I don’t need the fan control - we use a custom board with the fan always on.

How do i turn off an interface (in this case the fan control and ? Is it possible with device tree overlays?
Another pin I’d like to use is already in use (despite being marked as “GPIO” on Apalis modules): GPIO3 pin 26 (aka “Apalis-GPIO7”). It is used as “pcie_switch” output (from “gpioinfo” command).

How can i use both pins as normal GPIOs?

Thank you and best regards,
Peter

Hi Peter,

Ok so just to summarize everything.

First with Apalis GPIO7 this pin gets used by interface Apalis PCIE 1. A simple matter of disabling this interface, if you don’t require it, should do. This can be done easily with an overlay.

Next with Apalis GPIO8 as we’ve already discussed is used by the gpio-fan interface. Unfortunately as far as I can tell there’s no easy way to just “disable” this, meaning if you don’t want it, the simplest way would be to just remove the device tree node from the source and recompile.

Due to the gpio-fan issue it’d probably just be best to recompile the device tree from source with changes rather than use an overlay here.

As such I’ve gone ahead and done just that here’s a compiled device tree binary that should enable GPIO7 & 8 as free GPIOs: https://share.toradex.com/i59lzb33zp0328e

In order to have your device load this device tree you’ll need to replace the default device tree at this location on the device’s filesystem: /boot/ostree/torizon-{some random checksum}/fsl-imx8qm-apalis-eval.dtb. Once you’ve replaced this with the new device tree a simple reboot of the device should load this new configuration.

Finally for reference here’s the full patch of the changes I made: https://share.toradex.com/e2u3i6lskrtwh5p

You can use this patch if you ever need to recompile the device tree with these changes yourself, or simply as a reference of how you could do similar changes. Just as a note as you might notice in the changes I completely removed gpio-fan which you said you didn’t need. But I also disabled Apalis PCIE1 in order to free up GPIO 7. If you need this PCIE you’ll need to substitute another GPIO pin and re-enable the interface.

Best Regards,
Jeremias