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
- Understand the Device Tree structure and conventions
- Follow the steps at First Steps with Device Trees
Case Oriented Example: Led Blinking
-
Locate and disable/delete former function definitions: To avoid pin conflicts, disable the PWM nodes using the
statusproperty, 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";
}; -
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_ledthrough thefslproperty 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
GPIO1fromIO01toIO1, andI2C2_SCLtoGPIO5_IO16.noteNot all pinctrls should be referenced in the iomuxc's
pinctrl-0. Some could be directly referenced by other devices' and nodes'pinctrl-<number>. -
Define a new pinctrl property with the GPIO pinmux definitions: Having
pinctrl_my_lednode defined in the previous step, assign it to thepinctrl-0property of theledsnode, which is compatible withgpio-ledsdriver.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";
};
};
};
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
/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.
-
Include the interrupt controller header file
<dt-bindings/interrupt-controller/irq.h>. -
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:
/ 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>;
};
};