Compare 0 Products     empty

In this guide we will describe the procedure to change pad multiplexing at device tree level, configuring a CPU pin as GPIO. We will then show how to monitor and modify the status of this IO pin in userspace.

Download kernel sources

The first step is to fetch kernel sources of a suitable version for your SOM. Engicam stores all the software for its devices in a Git repository constantly updated, from the Kernel and U-Boot sources to the customized Yocto meta-layers. For this example, we will work with kernel 4.1.43  MicroGEA MX6ULL combined with Microdev board. The relative repository on Engicam GitHub is engicam-linux-fslc. If you are working with other SOM, please contact the Engicam support team to know which repository you should clone according to the Linux kernel version you are using.

Next steps:

  • Open your browser
  • Go to
  • Click on the Code button and copy the https address
  • Open a shell and move into the folder you want to place the sources
  • Clone the repo with the command git clone <https-addr> (Es. git clone

Configure pin as GPIO

You will find the device trees for Engicam devices in arch/arm/boot/dts(the path will be arch/arm64/boot/dts for 64bit processors)  together with other device tree source files with Freescale support. The one for the hardware considered in this guide is microgea-mx6ull-microdev.dts.

In order to add a GPIO on the NXP device tree, the relative PAD should be added to the GPIO hog pin control in the iomux node.

In microgea-mx6ull-microdev.dts the node is:

&iomuxc?? {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_hog_1>;
        imx6ul-evk {
                pinctrl_hog_1: hoggrp-1 {
                        fsl,pins = <
                             MX6UL_PAD_GPIO1_IO03__REF_CLK_32K 0x1b090
                             MX6UL_PAD_UART1_RTS_B__GPIO1_IO19 0x17059
                             MX6UL_PAD_SNVS_TAMPER2__GPIO5_IO02 0x1b0b0
                             MX6UL_PAD_ENET2_RX_DATA0__GPIO2_IO08 0x1b0b0
                             MX6UL_PAD_SNVS_TAMPER0__GPIO5_IO00 0x1b0b0
                             MX6UL_PAD_SNVS_TAMPER1__GPIO5_IO01 0x1b0b0
                             MX6UL_PAD_NAND_CE1_B__GPIO4_IO14 0x1b0b0
                             MX6UL_PAD_GPIO1_IO09__GPIO1_IO09 0x1b0b0
                             MX6UL_PAD_GPIO1_IO02__GPIO1_IO02 0x1b0b0
                             MX6UL_PAD_UART3_RX_DATA__GPIO1_IO25 0x1b0b0
                             MX6UL_PAD_SNVS_TAMPER5__GPIO5_IO05 0x1b0b0
                             MX6UL_PAD_CSI_DATA05__GPIO4_IO26 0x1b0b0
                             MX6UL_PAD_ENET2_RX_DATA1__GPIO2_IO09 0x1b0b0
                             MX6UL_PAD_JTAG_TMS__GPIO1_IO11 0x1b0b0






Let's assume that we need to customize the default SOM pin configuration, using pin 35 on connector J2 of MicroGEA MX6ULL as GPIO. The name of the corresponding PAD on the processor (ENET2_RX_EN in this example) can be found in the SOM hardware manual, where all PAD names are reported. The pinctrl list for MX6ULL can be found in the imx6ull-pinfunc.h, included in the .dts file. The possible pin control macros for ENET2_RX_EN are:

#define MX6UL_PAD_ENET2_RX_EN__ENET2_RX_EN            0x00EC 0x0378 0x0000 0x0 0x0
#define MX6UL_PAD_ENET2_RX_EN__UART7_DCE_TX           0x00EC 0x0378 0x0000 0x1 0x0
#define MX6UL_PAD_ENET2_RX_EN__UART7_DTE_RX           0x00EC 0x0378 0x0654 0x1 0x0
#define MX6UL_PAD_ENET2_RX_EN__SIM1_PORT0_RST_B       0x00EC 0x0378 0x0000 0x2 0x0
#define MX6UL_PAD_ENET2_RX_EN__I2C4_SCL               0x00EC 0x0378 0x05BC 0x3 0x1
#define MX6UL_PAD_ENET2_RX_EN__EIM_ADDR26             0x00EC 0x0378 0x0000 0x4 0x0
#define MX6UL_PAD_ENET2_RX_EN__GPIO2_IO10             0x00EC 0x0378 0x0000 0x5 0x0
#define MX6UL_PAD_ENET2_RX_EN__KPP_ROW05              0x00EC 0x0378 0x0000 0x6 0x0
#define MX6UL_PAD_ENET2_RX_EN__ENET1_REF_CLK_25M      0x00EC 0x0378 0x0000 0x8 0x0

The one that set the PAD as GPIO is MX6UL_PAD_ENET2_RX_EN__GPIO2_IO10. Ensure that any other active node has not ENET2_RX_EN in the pin control list, then add it to the hog as follow:

&iomuxc {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_hog_1>;
    imx6ul-evk {
        pinctrl_hog_1: hoggrp-1 {
            fsl,pins = <
                MX6UL_PAD_GPIO1_IO03__REF_CLK_32K   0x1b090
                MX6UL_PAD_UART1_RTS_B__GPIO1_IO19   0x17059
                MX6UL_PAD_SNVS_TAMPER2__GPIO5_IO02  0x1b0b0 
                MX6UL_PAD_ENET2_RX_DATA0__GPIO2_IO08    0x1b0b0 
                MX6UL_PAD_SNVS_TAMPER0__GPIO5_IO00      0x1b0b0 
                MX6UL_PAD_SNVS_TAMPER1__GPIO5_IO01      0x1b0b0 
                MX6UL_PAD_NAND_CE1_B__GPIO4_IO14    0x1b0b0 
                MX6UL_PAD_GPIO1_IO09__GPIO1_IO09    0x1b0b0 
                MX6UL_PAD_GPIO1_IO02__GPIO1_IO02    0x1b0b0  
                MX6UL_PAD_UART3_RX_DATA__GPIO1_IO25 0x1b0b0 
                MX6UL_PAD_SNVS_TAMPER5__GPIO5_IO05  0x1b0b0 
                MX6UL_PAD_CSI_DATA05__GPIO4_IO26    0x1b0b0 
                MX6UL_PAD_ENET2_RX_DATA1__GPIO2_IO09    0x1b0b0 
                MX6UL_PAD_JTAG_TMS__GPIO1_IO11          0x1b0b0
                MX6UL_PAD_ENET2_RX_EN__GPIO2_IO10      0x1b0b0 


Then add the GPIO to  gpio_export in the root node of the same file. This is where all the GPIO listed in the hog can be exported and configured:

gpio_export {
compatible = "gpio-export";
#size-cells = <0>;


    GPIO_ET {
        gpio-export,name = "GPIO_ET";
        gpio-export,output = <0>;
        gpios = <&gpio2 10 0>;

In the example, GPIO2_IO_10 has been exported as an output GPIO named GPIO_ET.

Compiling the device tree

After changing the .dts sources should be compiled to get the .dtb. As the device tree will be used on the SOM, the sources need to be cross-compiled with the proper toolchain. If you are performing these guide steps in the Engicam BSP you can use the toolchain already installed and configured in the virtual machine for this purpose. Otherwise, if you compiled the SOM image with Yocto outside the virtual machine, just perform the SDK compilation with Yocto. Move to the kernel sources root directory:

To configure the dtbs build, run first the toolchain environment setting script:

. /opt/fslc-framebuffer/2.3/gea/environment-setup-armv7at2hf-neon-fslc-linux-gnueabi

set the variable:

export LOADADDR=80008000

Last, run the build:

make dtbs 

Copy the .dtbs in the SDcard Boot partition

The new device tree should be copied in the sdcard boot partition (/dev/mmcblk0p1) already flashed with the Linux image:

cp <path_to_kernel_sources>/arch/arm/boot/dts/microgea-mx6ull-microdev.dtb /media/user/Boot\ microd

Then plug the SDcard in the module and turn on the device.

Exported GPIO in userspace

All the GPIO exported in the device tree can be found in userspace at the path:


To check if the GPIO has been exported:

root@microdev:~# ls /sys/class/gpio/    
DISP0_PWD       ETH_ALIM_EN     GPIO_ET         MCLK_AUDIO      UMTS_ON         UMTS_STOP       gpiochip0       gpiochip32      gpiochip96
DISP_BIT_MODE   GPIO1_IO09_LED  LCD_ALIM_EN     UMTS_EN         UMTS_RESET      export          gpiochip128     gpiochip64      unexport

31 May 2021