Skip to main content

How to Customize Device Trees

Introduction

This article aims to guide you through the process of writting and customize a pre-existing device tree for it to be suitable for your customized hardware and peripherals.

Prerequisites

Case Oriented Example: Led Blinking

  1. Locate and disable/delete former function definitions: To avoid pin conflicts, disable the PWM nodes using the status property, unassigning the pins. We use the custom device tree created in the previous article.

    imx8mm-verdin-wifi-dev-custom.dts
    &pwm1 {
    status = "disabled";
    };

    &pwm2 {
    status = "disabled";
    };
  2. Add a pinctrl node to the iomuxc group: Define a new pinctrl (pin control) configuration that includes your desired pinmux and pad control definition for the selected pins. In this step, we have a pin multiplexing operation, where we assign a new group of pins in the child node pinctrl_my_led through the fsl property to serve the LEDs.

    imx8mm-verdin-wifi-dev-custom.dts
    &iomuxc {
    pinctrl_my_led: myledgrp {
    fsl,pins =
    <MX8MM_IOMUXC_GPIO1_IO01_GPIO1_IO1 0x104>, // SODIMM 19 // pull-down enabled and drive strength X2
    <MX8MM_IOMUXC_I2C2_SCL_GPIO5_IO16 0x104>; // SODIMM 55 // pull-down enabled and drive strength X2
    };
    };

    Here, it was muxed the GPIO1 from IO01 to IO1, and I2C2_SCL to GPIO5_IO16.

    note

    Not all pinctrls should be referenced in the iomuxc's pinctrl-0. Some could be directly referenced by other devices' and nodes' pinctrl-<number>.

  3. Define a new pinctrl property with the GPIO pinmux definitions: Having pinctrl_my_led node defined in the previous step, assign it to the pinctrl-0 property of the leds node, which is compatible with gpio-leds driver.

    imx8mm-verdin-wifi-dev-custom.dts
    &{/} {
    leds {
    compatible = "gpio-leds";

    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_my_led>;

    myled_sodimm_19 {
    label = "my_led_sodimm_19";
    gpios = <&gpio1 1 GPIO_ACTIVE_HIGH>;
    linux,default-trigger = "heartbeat";
    default-state = "on";
    };

    myled_sodimm_55 {
    label = "my_led_sodimm_55";
    gpios = <&gpio5 16 GPIO_ACTIVE_HIGH>;
    linux,default-trigger = "heartbeat";
    default-state = "on";
    };
    };
    };
note

A pinctrl does not ensure that the selected pins are properly configured, available and active, if it is not set to be active. Each pinctrl is simply an available muxing and pad control configuration for a set of pin(s) that can be enabled once it is referenced by a pinctrl-<number> of some node.

After the previous steps, the imx8mm-verdin-wifi-dev-custom.dts should look simillar to the following:

View custom-overlay.dts
imx8mm-verdin-wifi-dev-custom.dts
/dts-v1/;

#include "imx8mm-verdin.dtsi"
#include "imx8mm-verdin-wifi.dtsi"
#include "imx8mm-verdin-dev.dtsi"

/ {
model = "Toradex Verdin iMX8M Mini WB on Verdin Development Board";
compatible = "toradex,verdin-imx8mm-wifi-dev",
"toradex,verdin-imx8mm-wifi",
"toradex,verdin-imx8mm",
"fsl,imx8mm";
};

&pwm1 {
status = "disabled";
};

&pwm2 {
status = "disabled";
};

&{/} {
leds {
compatible = "gpio-leds";

pinctrl-names = "default";
pinctrl-0 = <&pinctrl_my_led>;

myled_sodimm_19 {
label = "my_led_sodimm_19";
gpios = <&gpio1 1 GPIO_ACTIVE_HIGH>;
linux,default-trigger = "heartbeat";
default-state = "on";
};

myled_sodimm_55 {
label = "my_led_sodimm_55";
gpios = <&gpio5 16 GPIO_ACTIVE_HIGH>;
linux,default-trigger = "heartbeat";
default-state = "on";
};
};
};

&iomuxc {
pinctrl_my_led: myledgrp {
fsl,pins =
<MX8MM_IOMUXC_GPIO1_IO01_GPIO1_IO1 0x104>, // SODIMM 19 // pull-down enabled and drive strength X2
<MX8MM_IOMUXC_I2C2_SCL_GPIO5_IO16 0x104>; // SODIMM 55 // pull-down enabled and drive strength X2
};
};

Case Oriented Example: IMU InvenSense MPU-6050

To add support for the MPU6050, as described in the related documentation, it's required three definitions:

  • compatible: which in this case should be "invensense,mpu6050";
  • reg: which is 0x68, accordingly to the datasheet;
  • interrupts: where you can assign a GPIO pin.
  1. Include the interrupt controller header file <dt-bindings/interrupt-controller/irq.h>.

  2. Configure the accelerometer with reg, interrupts and compatible under and I2C node

    imx8mm-verdin-wifi-dev-custom.dts
    ...
    &i2c1 {
    mpu6050: accelerometer@68 {
    compatible = "invensense,mpu6050";
    reg = <0x68>;
    status="okay"
    interrupt-parent = <&gpio1>;
    interrupts = <21 IRQ_TYPE_LEVEL_HIGH>;
    };
    ...
    };

After the previous steps, the imx8mm-verdin-wifi-dev-custom.dts should look simillar to the following:

imx8mm-verdin-wifi-dev-custom.dts
/ SPDX-License-Identifier: GPL-2.0+ OR MIT
/*
* Copyright 2019-2021 Toradex
*/

/dts-v1/;

#include "imx8mm-verdin.dtsi"
#include "imx8mm-verdin-wifi.dtsi"
#include "imx8mm-verdin-dev.dtsi"
#include <dt-bindings/interrupt-controller/irq.h>

/ {
model = "Toradex Verdin iMX8M Mini WB on Verdin Development Board";
compatible = "toradex,verdin-imx8mm-wifi-dev",
"toradex,verdin-imx8mm-wifi",
"toradex,verdin-imx8mm",
"fsl,imx8mm";
};

&i2c1 {
mpu6050: accelerometer@68 {
compatible = "invensense,mpu6050";
reg = <0x68>;
status="okay"
interrupt-parent = <&gpio1>;
interrupts = <18 IRQ_TYPE_EDGE_RISING>;
};
};


Send Feedback!