Changes between Version 14 and Version 15 of linux/devicetree


Ignore:
Timestamp:
09/26/2022 11:18:38 PM (2 years ago)
Author:
Tim Harvey
Comment:

add more dt fragment examples

Legend:

Unmodified
Added
Removed
Modified
  • linux/devicetree

    v14 v15  
    149149 - requires using handles of nodes that are defined in the base devicetree
    150150 - requires compiling with the-@ flag
    151 
    152 To provide a simple example consider adding a simple SPI NOR flash device on an off-board SPI connector. Such a device has a Linux kernel driver and requires using device-tree bindings:
     151 - requires device-tree syntax (so if you are using C defines/includes make sure you run through the C preprocessor before compiling)
     152
     153
     154Examples:
     155 1. add a SPI NOR flash device on an off-board SPI connector. Such a device has a Linux kernel driver and requires using device-tree bindings:
    153156{{{
    154157/dts-v1/;
     
    176179};
    177180}}}
    178  - Note the compatible string specifies the board this is compatible with
    179  - Note the board in question's base dt specifies the ecspi2 handle which we modify here
    180 
    181 To compile this fragment:
     181   - Note the compatible string specifies the board this is compatible with
     182   - Note the board in question's base dt specifies the ecspi2 handle which we modify here
     183   - To compile this fragment:
    182184{{{#!bash
    183185dtc -@ -I dts -O dtb -o imx8mm-gw73xx-0x-spinor.dtbo imx8mm-gw73xx-0x-spinor.dts
    184186}}}
    185 
    186 And to use it on a Venice imx8mm-gw73xx-0x make sure the dtbo exits alongside the kernel in the directory the bootscript resides (ie /boot)
     187   - And to use it on a Venice imx8mm-gw73xx-0x make sure the dtbo exits alongside the kernel in the directory the bootscript resides (ie /boot)
    187188{{{#!bash
    188189setenv fdt_overlays "imx8mm-gw73xx-0x-spinor.dtbo"
    189190saveenv
    190191}}}
     192
     193 2. repurpose the I2C3 and SPI2 pins on a GW730x to GPIO's to be used in userspace via gpiod/sysfs:
     194  - the dts framgment here has C style includes required for the pinmux definitions and the gpio definitions so we use cpp to pre-process it before compiling
     195  - the includes here are from the Linux kernel so you must have the linux kernel source to compile this, place the file in the proper directory per the includes (imx8mm-pinfunc.h is in arch/arm64/boot/dts/freescale so that is where we put the file in our example), and compile from the correct directory such that the includes can be found
     196{{{#!bash
     197# get the kernel source
     198git clone https://github.com/Gateworks/linux-venice.git
     199cd linux-venice
     200cat << EOF > arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-gpio.dts
     201/*
     202 * GW73xx GPIO:
     203 *  - repurpose ecspi2 CLK/MISO/MOSI/CS0 as GPIO
     204 *  - repurpose i2c3 CLK/DATA as GPIO
     205 */
     206
     207#include <dt-bindings/gpio/gpio.h>
     208
     209#include "imx8mm-pinfunc.h"
     210
     211/dts-v1/;
     212/plugin/;
     213
     214&{/} {
     215        compatible = "gw,imx8mm-gw73xx-0x";
     216};
     217
     218&gpio5 {
     219        pinctrl-names = "default";
     220        pinctrl-0 = <&pinctrl_gpio5_hog>;
     221
     222        /* gpio-hog nodes allow you to give gpios a name and a default state:
     223         *   define one of 'input', 'output-low', or 'output-high' properties
     224         */
     225        gpio5_io10 {
     226                gpio-hog;
     227                gpios = <10 GPIO_ACTIVE_HIGH>;
     228                input;
     229                line-name = "gpio5_io10";
     230        };
     231
     232        gpio5_io11 {
     233                gpio-hog;
     234                gpios = <11 GPIO_ACTIVE_HIGH>;
     235                input;
     236                line-name = "gpio5_io11";
     237        };
     238
     239        gpio5_io12 {
     240                gpio-hog;
     241                gpios = <12 GPIO_ACTIVE_HIGH>;
     242                input;
     243                line-name = "gpio5_io12";
     244        };
     245
     246        gpio5_io13 {
     247                gpio-hog;
     248                gpios = <13 GPIO_ACTIVE_HIGH>;
     249                input;
     250                line-name = "gpio5_io13";
     251        };
     252
     253        gpio5_io18 {
     254                gpio-hog;
     255                gpios = <18 GPIO_ACTIVE_HIGH>;
     256                input;
     257                line-name = "gpio5_io18";
     258        };
     259
     260        gpio5_io19 {
     261                gpio-hog;
     262                gpios = <19 GPIO_ACTIVE_HIGH>;
     263                input;
     264                line-name = "gpio5_io19";
     265        };
     266};
     267
     268&i2c3 {
     269        status = "disabled";
     270};
     271
     272&ecspi2 {
     273        status = "disabled";
     274};
     275
     276&iomuxc {
     277        /* pinmux: refer to IMX8M Reference Manuals for the bit configuration
     278         *  - the first definition comes from imx8mm-pinfunc.h and sets the
     279         *    pins NUX_CTL register and input select
     280         *  - the second definition sets the PAD_CTL register that configures
     281         *    things like drive strength, slew rate, pull-up, pull-down, and hysteresis.
     282         *    If you want to be able to read back the pin state you need to set the SION
     283         *    bit by setting bit 30 (as is done below)
     284         */
     285        pinctrl_gpio5_hog: gpio5hoggrp {
     286                fsl,pins = <
     287                        MX8MM_IOMUXC_ECSPI2_SCLK_GPIO5_IO10     0x40000146 /* SION, pull-up, 6x drive str */
     288                        MX8MM_IOMUXC_ECSPI2_MOSI_GPIO5_IO11     0x40000106 /* SION, pull-down, 6x drive str */
     289                        MX8MM_IOMUXC_ECSPI2_MISO_GPIO5_IO12     0x40000006 /* SION, 6x drive-str */
     290                        MX8MM_IOMUXC_ECSPI2_SS0_GPIO5_IO13      0x40000146
     291                        MX8MM_IOMUXC_I2C3_SCL_GPIO5_IO18        0x40000146
     292                        MX8MM_IOMUXC_I2C3_SDA_GPIO5_IO19        0x40000146
     293                >;
     294        };
     295};
     296EOF
     297# run through the C pre-processor to handle the includes/macros/defines
     298cpp -nostdinc -I include -I arch -undef -x assembler-with-cpp \
     299  arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-gpio.dts \
     300  imx8mm-venice-gw73xx-0x-gpio.dts.tmp
     301# compile with Device Tree Compiler
     302dtc -@ -i include/ -I dts -O dtb -o imx8mm-venice-gw73xx-0x-gpio.dtbo \
     303  imx8mm-venice-gw73xx-0x-gpio.dts.tmp
     304}}}
     305   - And to use it on a Venice imx8mm-gw73xx-0x make sure the dtbo exits alongside the kernel in the directory the bootscript resides (ie /boot)
     306{{{#!bash
     307setenv fdt_overlays "imx8mm-venice-gw73xx-0x-gpio.dtbo"
     308saveenv
     309}}}
     310
     311 3. repurpose the I2C3 and SPI2 pins on a GW730x to GPIO's (like above) but bind 4 of them to the gpio-keys driver to use as up/down/right/left buttons and bind 2 of them to the gpio-led driver to use as leds via /sys/class/led
     312  - the dts framgment here has C style includes required for the pinmux definitions and the gpio definitions so we use cpp to pre-process it before compiling
     313  - we use gpio-keys1 and led-controller1 node names so as not to collide with gpio-keys and led-controller nodes already defined in the gw73xx-0x device-tree
     314  - the includes here are from the Linux kernel so you must have the linux kernel source to compile this, place the file in the proper directory per the includes (imx8mm-pinfunc.h is in arch/arm64/boot/dts/freescale so that is where we put the file in our example), and compile from the correct directory such that the includes can be found
     315{{{#!bash
     316# get the kernel source
     317git clone https://github.com/Gateworks/linux-venice.git
     318cd linux-venice
     319cat << EOF > arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-gpio.dts
     320/*
     321 * GW73xx GPIO:
     322 *  - repurpose ecspi2 CLK/MISO/MOSI/CS0 as GPIO buttons tied to linux input events
     323 *  - repurpose i2c3 CLK/DATA as GPIO controlled LED's tied to led class
     324 */
     325
     326#include <dt-bindings/gpio/gpio.h>
     327#include <dt-bindings/input/linux-event-codes.h>
     328#include <dt-bindings/leds/common.h>
     329
     330#include "imx8mm-pinfunc.h"
     331
     332/dts-v1/;
     333/plugin/;
     334
     335&{/} {
     336        compatible = "gw,imx8mm-gw73xx-0x";
     337
     338        gpio-keys1 {
     339                compatible = "gpio-keys";
     340                pinctrl-names = "default";
     341                pinctrl-0 = <&pinctrl_gpio_keys1>;
     342
     343                key-left {
     344                        label = "left";
     345                        gpios = <&gpio5 10 GPIO_ACTIVE_LOW>;
     346                        linux,code = <KEY_LEFT>;
     347                };
     348
     349                key-right {
     350                        label = "right";
     351                        gpios = <&gpio5 11 GPIO_ACTIVE_LOW>;
     352                        linux,code = <KEY_RIGHT>;
     353                };
     354
     355                key-up {
     356                        label = "up";
     357                        gpios = <&gpio5 12 GPIO_ACTIVE_LOW>;
     358                        linux,code = <KEY_UP>;
     359                };
     360
     361                key-down {
     362                        label = "down";
     363                        gpios = <&gpio5 13 GPIO_ACTIVE_LOW>;
     364                        linux,code = <KEY_DOWN>;
     365                };
     366        };
     367
     368        led-controller1 {
     369                compatible = "gpio-leds";
     370                pinctrl-names = "default";
     371                pinctrl-0 = <&pinctrl_gpio_leds1>;
     372
     373                led-0 {
     374                        function = LED_FUNCTION_STATUS;
     375                        color = <LED_COLOR_ID_GREEN>;
     376                        gpios = <&gpio5 18 GPIO_ACTIVE_HIGH>;
     377                        default-state = "on";
     378                        linux,default-trigger = "heartbeat";
     379                };
     380
     381                led-1 {
     382                        function = LED_FUNCTION_STATUS;
     383                        color = <LED_COLOR_ID_RED>;
     384                        gpios = <&gpio5 19 GPIO_ACTIVE_HIGH>;
     385                        default-state = "off";
     386                };
     387        };
     388};
     389
     390&i2c3 {
     391        status = "disabled";
     392};
     393
     394&ecspi2 {
     395        status = "disabled";
     396};
     397
     398&iomuxc {
     399        /* pinmux: refer to IMX8M Reference Manuals for the bit configuration
     400         *  - the first definition comes from imx8mm-pinfunc.h and sets the
     401         *    pins NUX_CTL register and input select
     402         *  - the second definition sets the PAD_CTL register that configures
     403         *    things like drive strength, slew rate, pull-up, pull-down, and hys
     404teresis.
     405         *    If you want to be able to read back the pin state you need to set
     406the SION
     407         *    bit by setting bit 30 (as is done below)
     408         * below the pins are configured with internal pull-up and 6x drive str
     409         */
     410        pinctrl_gpio_keys1: gpiokeys1grp {
     411                fsl,pins = <
     412                        MX8MM_IOMUXC_ECSPI2_SCLK_GPIO5_IO10     0x146
     413                        MX8MM_IOMUXC_ECSPI2_MOSI_GPIO5_IO11     0x146
     414                        MX8MM_IOMUXC_ECSPI2_MISO_GPIO5_IO12     0x146
     415                        MX8MM_IOMUXC_ECSPI2_SS0_GPIO5_IO13      0x146
     416                >;
     417        };
     418
     419        pinctrl_gpio_leds1: gpioleds1grp {
     420                fsl,pins = <
     421                        MX8MM_IOMUXC_I2C3_SCL_GPIO5_IO18        0x146
     422                        MX8MM_IOMUXC_I2C3_SDA_GPIO5_IO19        0x146
     423                >;
     424        };
     425};
     426EOF
     427# run through the C pre-processor to handle the includes/macros/defines
     428cpp -nostdinc -I include -I arch -undef -x assembler-with-cpp \
     429  arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-gpio.dts \
     430  imx8mm-venice-gw73xx-0x-gpio.dts.tmp
     431# compile with Device Tree Compiler
     432dtc -@ -i include/ -I dts -O dtb -o imx8mm-venice-gw73xx-0x-gpio.dtbo \
     433  imx8mm-venice-gw73xx-0x-gpio.dts.tmp
     434}}}
     435   - And to use it on a Venice imx8mm-gw73xx-0x make sure the dtbo exits alongside the kernel in the directory the bootscript resides (ie /boot)
     436{{{#!bash
     437setenv fdt_overlays "imx8mm-venice-gw73xx-0x-gpio.dtbo"
     438saveenv
     439}}}
     440
    191441
    192442Notes:
    193443 * Support for compiling dtbo files appeared in the Linux kernel somewhere between 5.10 and 5.15
    194  * Gateworks uses dtbo's to provide support for adding a RaspberryPi v2.0 camera module and a RaspberryPi DFROBOT touchscreen display to a gw72xx/gw73xx baseboard for example.
     444 * Gateworks uses dtbo's to provide support for adding a !RaspberryPi v2.0 camera module and a RaspberryPi DFROBOT touchscreen display to a gw72xx/gw73xx baseboard for example.
    195445
    196446