Yocto - Device Tree GPIO Multiplexing not loading

Hello,
I have been trying to multiplex the PWM 1 pin (SODDIM_15) on the Verdin iMX8M Plus Quad 4GB Wi-Fi / Bluetooth IT V1.1B as GPIO active low to interface with a custom break out board for the Mallow carrier board. When I build the device tree and install it on the board gpioinfo returns

gpiochip4 - 32 lines:
        line   0:  "SODIMM_42"       unused   input  active-high
        line   1:  "SODIMM_46"       unused   input  active-high
        line   2: "SODIMM_187"       unused   input  active-high
        line   3:  "SODIMM_20"       unused   input  active-high
        line   4:  "SODIMM_22"       unused   input  active-high
        line   5:  "SODIMM_15"       unused   input  active-high

The following is the device tree source, verdin-mallow-COMPANY.dts

#include "imx8mp-pinfunc.h"
#include <dt-bindings/pwm/pwm.h>
#include <dt-bindings/gpio/gpio.h>
#include "imx8mp-verdin-wifi-mallow.dts"


/ {
    model = "Custom relay board for COMPANY";
	compatible = "toradex,verdin-imx8mp-wifi-mallow",
		     "toradex,verdin-imx8mp-wifi",
		     "toradex,verdin-imx8mp",
		     "fsl,imx8mp";
    newgpios {
		compatible = "gpio";
		pinctrl-names = "default";
		pinctrl-0 =  <&my_gpio>;
		mygpio_sodimm_15 {
			label = "newgpio";
			gpios = <&gpio5 5 GPIO_ACTIVE_LOW>;
			default-state = "on";
		};
	};
};


&pwm1 {
	status = "disabled";
};

&pwm2 {
	status = "disabled";
};

&iomuxc {
    my_gpio: add_gpio_grp {
		fsl,pins = <
			MX8MP_IOMUXC_SPDIF_EXT_CLK__GPIO5_IO05 0x1C0
		>;
	};
};

The device tree gets compiled by the yocto and appears to be loaded by the kernel as the output of cat /proc/device-tree/model is

Custom relay board for COMPANY

But the output of
cat /sys/kernel/debug/pinctrl/pinctrl-handles
does not show my custom group loaded

Requested pin control handlers their pinmux maps:
device: 30330000.pinctrl current state: default
  state: default
    type: MUX_GROUP controller 30330000.pinctrl group: gpio1grp (10) function: pinctrl (0)
    type: CONFIGS_PIN controller 30330000.pinctrl pin MX8MP_IOMUXC_GPIO1_IO00 (5)config 00000184
    type: MUX_GROUP controller 30330000.pinctrl group: gpio2grp (11) function: pinctrl (0)
    type: CONFIGS_PIN controller 30330000.pinctrl pin MX8MP_IOMUXC_GPIO1_IO01 (6)config 000001c4
    type: MUX_GROUP controller 30330000.pinctrl group: gpio3grp (12) function: pinctrl (0)
    type: CONFIGS_PIN controller 30330000.pinctrl pin MX8MP_IOMUXC_GPIO1_IO05 (10)config 00000184
    type: MUX_GROUP controller 30330000.pinctrl group: gpio4grp (13) function: pinctrl (0)
    type: CONFIGS_PIN controller 30330000.pinctrl pin MX8MP_IOMUXC_GPIO1_IO06 (11)config 00000184
    type: MUX_GROUP controller 30330000.pinctrl group: gpio7grp (16) function: pinctrl (0)
    type: CONFIGS_PIN controller 30330000.pinctrl pin MX8MP_IOMUXC_SAI1_RXD1 (85)config 00000184
    type: MUX_GROUP controller 30330000.pinctrl group: gpio8grp (17) function: pinctrl (0)
    type: CONFIGS_PIN controller 30330000.pinctrl pin MX8MP_IOMUXC_SAI1_RXC (83)config 00000184
    type: MUX_GROUP controller 30330000.pinctrl group: gpiohog2grp (21) function: pinctrl (0)
    type: CONFIGS_PIN controller 30330000.pinctrl pin MX8MP_IOMUXC_SAI3_MCLK (116)config 000001c4
    type: MUX_GROUP controller 30330000.pinctrl group: gpiohog3grp (22) function: pinctrl (0)
    type: CONFIGS_PIN controller 30330000.pinctrl pin MX8MP_IOMUXC_GPIO1_IO15 (20)config 000001c4
    type: MUX_GROUP controller 30330000.pinctrl group: gpiohog4grp (23) function: pinctrl (0)
    type: CONFIGS_PIN controller 30330000.pinctrl pin MX8MP_IOMUXC_UART4_RXD (142)config 000001c4
    type: CONFIGS_PIN controller 30330000.pinctrl pin MX8MP_IOMUXC_UART4_TXD (143)config 000001c4
    type: MUX_GROUP controller 30330000.pinctrl group: hdmihoggrp (25) function: pinctrl (0)
    type: CONFIGS_PIN controller 30330000.pinctrl pin MX8MP_IOMUXC_HDMI_CEC (146)config 00000019
    type: CONFIGS_PIN controller 30330000.pinctrl pin MX8MP_IOMUXC_HDMI_DDC_SCL (144)config 000001c3
    type: CONFIGS_PIN controller 30330000.pinctrl pin MX8MP_IOMUXC_HDMI_DDC_SDA (145)config 000001c3
    type: CONFIGS_PIN controller 30330000.pinctrl pin MX8MP_IOMUXC_HDMI_HPD (147)config 00000019

Any advice/insights on how to proceed?

My output of tdx-info is as follows

Software summary
------------------------------------------------------------
Bootloader:               U-Boot
Kernel version:           5.15.148-6.7.0-devel+git.bfdbfb2c85fb #1 SMP PREEMPT T                                          hu Jun 20 15:59:41 UTC 2024
Kernel command line:      root=PARTUUID=c8ef2bc5-02 ro rootwait console=tty1 con                                          sole=ttymxc2,115200 consoleblank=0 earlycon
Distro name:              NAME="COMPANY-OS"
Distro version:           VERSION_ID=6.7.0-devel-20240704110142-build.0
Distro variant:           -
Hostname:                 verdin-imx8mp-15289197
------------------------------------------------------------

Hardware info
------------------------------------------------------------
HW model:                 Custom relay board for COMPANY
Toradex version:          0058 V1.1B
Serial number:            15289197
Processor arch:           aarch64
------------------------------------------------------------

UPDATE:
It seems to be an issue with the label name, as when I changed the label the device tree gets changed as expected.
I would appreciate an explanation on why this is the case

#include "imx8mp-pinfunc.h"
#include <dt-bindings/pwm/pwm.h>
#include <dt-bindings/gpio/gpio.h>
#include "imx8mp-verdin-wifi-mallow.dts"


/ {
    model = "Custom relay board for COMPANY";
	compatible = "toradex,verdin-imx8mp-wifi-mallow",
		     "toradex,verdin-imx8mp-wifi",
		     "toradex,verdin-imx8mp",
		     "fsl,imx8mp";
	};
&{/} 
{ 
	leds {
        compatible = "gpio-leds";
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_my_led>;
		mygpio_sodimm_15 {
			label = "newgpio";
			gpios = <&gpio5 5 GPIO_ACTIVE_LOW>;
			linux,default-trigger = "heartbeat";
			default-state = "on";
		};
	};
};

&pwm1 {
	status = "disabled";
};

&pwm2 {
	status = "disabled";
};

&iomuxc {
    pinctrl_my_led: myledgrp {
		fsl,pins = <
			MX8MP_IOMUXC_SPDIF_EXT_CLK__GPIO5_IO05 0x1C0
		>;
	};
};

Hi, I’m the Toradex AI Assistant. I’m in early beta, and I would appreciate your feedback.
The Toradex Support team will follow up with you shortly!

Did you like my answer?

:+1: :-1:


Handshake,

To address the issue where your custom GPIO group is not being loaded as expected on the Verdin iMX8M Plus, let’s go through a checklist to ensure all necessary steps and configurations are correctly implemented:

  1. Correct Device Tree Blob (DTB) Loading: Verify that the correct DTB file, which includes your modifications, is being loaded by the bootloader. This can be checked in U-Boot by printing the environment variable that specifies the DTB file or by checking the boot log for the DTB file name.

  2. Device Tree Overlay (DTO) Application: If you are using a Device Tree Overlay to apply these changes, ensure that the overlay is correctly applied. This involves checking that the overlay file is correctly compiled and specified in the bootloader configuration to be applied at boot time.

  3. Pin Configuration: The pin configuration for MX8MP_IOMUXC_SPDIF_EXT_CLK__GPIO5_IO05 as 0x1C0 seems correct for a GPIO use case. However, ensure that this configuration does not conflict with any other peripheral that might be claiming the pin, which could prevent the GPIO configuration from being applied.

  4. Device Tree Node Activation: In the device tree snippet provided, you have correctly disabled the PWM1 and PWM2 nodes by setting their status to “disabled”. This is a necessary step to repurpose the pins for GPIO. Ensure that these changes are present in the DTB that the system is loading.

  5. Syntax and Structure: Review the device tree syntax and structure to ensure there are no errors. This includes checking for missing semicolons, incorrect node names, or hierarchy issues. Use tools like dtc (Device Tree Compiler) to check for syntax errors.

  6. Debugging Device Tree Issues: Utilize the Linux kernel’s device tree debugging facilities to gain insights into how the device tree is interpreted by the kernel. The contents of /proc/device-tree/ and /sys/firmware/devicetree/base/ can be inspected to verify that your modifications are present and correctly structured. Additionally, enabling dynamic debug for device tree and pinctrl subsystems can provide more detailed logs that might highlight issues.

  7. Kernel Configuration: Ensure that the kernel configuration (CONFIG_GPIO_SYSFS, CONFIG_PINCTRL_IMX8MP, etc.) supports the features you are trying to use. Missing kernel configurations can lead to certain subsystems or functionalities not being available, which could explain why the pinmux settings are not

Please, also check if these links can help you solve your problem:

How to Customize Device Trees | Toradex Developer Center.

Hey @Mackenzie_Savoy,

The more significant change that you have made is you have changed the driver that is being used via the compatibly property. “gpio” vs “gpio-leds” I was able to find “gpio-leds” via ../source/linux-toradex/drivers/leds/led_gpio.c but not such compatiblity with just “gpio”

-Eric

1 Like

Hey @eric.tx,
Thank you, I think I understand more.
Just to confirm, for creating a new device tree child-node (such as “mygpio_sodimm_15”), the compatibility field sets the drivers that is used? So for example, if instead of led-gpio is used “gpio-imx-rpmsg” it would use the drivers defined in ../drivers/gpio/gpio-imx-rpmsg.c?

Hey @Mackenzie_Savoy,

If you open the driver file, you can search for compatible and it should show you what the correct naming is. There isn’t a guarantee that the name of the file is the name of the compatible property.

The most complete source of info for what the compatible property does is from the source documents, located here.. If you download the pdf, and go to 2.3.1 compatible you will find more complete information. Example from the source below.

i.e:

Example:
compatible = "fsl,mpc8641", "ns16550";
In this example, an operating system would first try to locate a device driver that supported fsl,mpc8641. If a
driver was not found, it would then try to locate a driver that supported the more general ns16550 device type.

-Eric

1 Like

Hey @eric.tx,
Thank you for that information!
Another follow up question, so now because the led-gpio drivers are assigned to the pin by the dts, it get marked as “used” by the libgpio API, and as such returns busy with gpioset. In order to control the pins with libgpio would the child node need to be removed, leaving the dts to be:

#include "imx8mp-pinfunc.h"
#include <dt-bindings/pwm/pwm.h>
#include <dt-bindings/gpio/gpio.h>
#include "imx8mp-verdin-wifi-mallow.dts"


/ {
    model = "Custom relay board for COMPANY";
	compatible = "toradex,verdin-imx8mp-wifi-mallow",
		     "toradex,verdin-imx8mp-wifi",
		     "toradex,verdin-imx8mp",
		     "fsl,imx8mp";
	};

&pwm1 {
	status = "disabled";
};

&pwm2 {
	status = "disabled";
};

&iomuxc {
    pinctrl_gpio_hog5: mygpiogrp {
		fsl,pins = <
			MX8MP_IOMUXC_SPDIF_EXT_CLK__GPIO5_IO05 0x1C0
		>;
	};
};

And this works because the peripheral that it defaults to gets disabled?

Hey @Mackenzie_Savoy,

I believe you are correct. If a driver and pin are specified under a node, that pin is now attached to that driver. This can be over written, such as if you later reference and status = "disabled" said node, or delete it.

When you attach the pinctrl group to the iomuxc node, via pinctrl-0, you are indicated you want the pin available in userspace, such to be able to use as a gpio.

-Eric

1 Like