GPIO¶
GPIO state¶
The current state of the system's GPIOs can be obtained in user-mode, as shown in the following example:
ON Symphony Board 1.x¶
# cat /sys/kernel/debug/gpio
gpiochip0: GPIOs 0-31, parent: platform/30200000.gpio, 30200000.gpio:
gpio-0 ( |spi0 CS1 ) out hi ACTIVE LOW
gpio-3 ( |pendown ) in hi ACTIVE LOW
gpio-9 ( |PHY reset ) out hi ACTIVE LOW
gpio-10 ( |cd ) in hi ACTIVE LOW
gpio-13 ( |reset ) out hi ACTIVE LOW
gpio-14 ( |spi0 CS0 ) out hi ACTIVE LOW
gpiochip1: GPIOs 32-63, parent: platform/30210000.gpio, 30210000.gpio:
gpio-41 ( |regulator-eth-phy ) out hi
gpio-42 ( |reset ) out hi ACTIVE LOW
gpio-43 ( |enable ) out hi
gpio-44 ( |microchip,rx-int ) in lo ACTIVE LOW
gpio-51 ( |spi0 CS2 ) out hi ACTIVE LOW
gpio-52 ( |reset ) out hi ACTIVE LOW
gpiochip2: GPIOs 64-95, parent: platform/30220000.gpio, 30220000.gpio:
gpiochip3: GPIOs 96-127, parent: platform/30230000.gpio, 30230000.gpio:
gpio-118 ( |regulator-usdhc2 ) out lo
gpiochip4: GPIOs 128-159, parent: platform/30240000.gpio, 30240000.gpio:
gpio-140 ( |powerdown ) out hi
gpio-142 ( |scl ) out lo
gpio-143 ( |sda ) in lo
gpio-144 ( |scl ) out lo
gpio-145 ( |sda ) in lo
gpio-146 ( |scl ) out lo
gpio-147 ( |sda ) in lo
gpio-148 ( |scl ) out lo
gpio-149 ( |sda ) in lo
gpiochip5: GPIOs 512-519, parent: i2c/1-0020, 1-0020, can sleep:
gpio-512 ( |Heartbeat ) out lo
gpio-513 ( |Back ) in hi IRQ ACTIVE LOW
gpio-514 ( |Home ) in hi IRQ ACTIVE LOW
gpio-515 ( |Menu ) in hi IRQ ACTIVE LOW
gpio-516 ( |usb3_sel ) out lo
gpio-517 ( |enet_rst ) out lo
gpio-518 ( |som_vsel ) out lo
gpio-519 ( |enet_sel ) out lo
ON Symphony Board 2.x¶
# cat /sys/kernel/debug/gpio
gpiochip0: GPIOs 0-31, parent: platform/30200000.gpio, 30200000.gpio:
gpio-0 ( |spi0 CS1 ) out hi ACTIVE LOW
gpio-3 ( |pendown ) in hi ACTIVE LOW
gpio-9 ( |PHY reset ) out hi ACTIVE LOW
gpio-10 ( |cd ) in lo ACTIVE LOW
gpio-13 ( |reset ) out hi ACTIVE LOW
gpio-14 ( |spi0 CS0 ) out hi ACTIVE LOW
gpiochip1: GPIOs 32-63, parent: platform/30210000.gpio, 30210000.gpio:
gpio-41 ( |regulator-eth-phy ) out hi
gpio-42 ( |reset ) out hi ACTIVE LOW
gpio-43 ( |enable ) out hi
gpio-44 ( |microchip,rx-int ) in lo ACTIVE LOW
gpio-51 ( |spi0 CS2 ) out hi ACTIVE LOW
gpio-52 ( |reset ) out hi ACTIVE LOW
gpiochip2: GPIOs 64-95, parent: platform/30220000.gpio, 30220000.gpio:
gpiochip3: GPIOs 96-127, parent: platform/30230000.gpio, 30230000.gpio:
gpio-118 ( |regulator-usdhc2 ) out hi
gpiochip4: GPIOs 128-159, parent: platform/30240000.gpio, 30240000.gpio:
gpio-140 ( |powerdown ) out hi
gpio-142 ( |scl ) out lo
gpio-143 ( |sda ) in lo
gpio-144 ( |scl ) out lo
gpio-145 ( |sda ) in lo
gpio-146 ( |scl ) out lo
gpio-147 ( |sda ) in lo
gpio-148 ( |scl ) out lo
gpio-149 ( |sda ) in lo
gpiochip5: GPIOs 512-519, parent: i2c/1-0020, 1-0020, can sleep:
gpio-512 ( |Heartbeat ) out lo
gpio-513 ( |Back ) in hi IRQ ACTIVE LOW
gpio-514 ( |Home ) in hi IRQ ACTIVE LOW
gpio-515 ( |Menu ) in hi IRQ ACTIVE LOW
gpio-516 ( |usb3_sel ) out lo
gpio-517 ( |enet_rst ) out lo
gpio-518 ( |som_vsel ) out lo
gpio-519 ( |enet_sel ) out lo
gpiochip6: GPIOs 520-527, parent: i2c/2-0021, 2-0021, can sleep:
gpio-524 ( |sec_rstn ) out hi
gpio-527 ( |rgb_sel ) out lo
Each GPIO is defined as in or out and the state is shown as lo or hi.
For example pin 44 is the SD card card-detect.
When an SD card is plugged in, the state will be:
When the SD card is removed, the state will be:
Manipulating GPIO using libgpiod¶
The Linux GPIO sysfs interface is being deprecated. Moving forward, user space should use the character device /dev/gpiochip* instead. libgpiod provides bindings and utilities for for manipulating GPIO via user space.
libgpiod via command line¶
libgpiod provides command line utilities for GPIO:
| gpiodetect | List all gpiochips present on the system, their names, labels and number of GPIO lines |
| gpioinfo | List all lines of specified gpiochips, their names, consumers, direction, active state and additional flags |
| gpioget | Read values of specified GPIO lines |
| gpioset | Set values of specified GPIO lines, potentially keep the lines exported and wait until timeout, user input or signal |
| gpiofind | Find the gpiochip name and line offset given the line name |
| gpiomon | Wait for events on GPIO lines, specify which events to watch, how many events to process before exiting or if the events should be reported to the console |
i.MX GPIOs are organized in banks of 32 pins. Each bank corresponds to a character device /dev/gpiochip<bank index>. The gpiodetect utility can be used to inspect the available gpiochip character devices:
The gpioinfo utility can be used to inspect the lines for a given gpiochip:
# gpioinfo -c gpiochip0
gpiochip0 - 32 lines:
line 0: unnamed "spi_imx" output active-high [used]
line 1: unnamed unused input active-high
line 2: unnamed unused input active-high
...
The gpioset and gpioget utilities can be used to manipulate GPIO from the command line.
For example, assuming GPIO4_21 is configured as a GPIO in your device tree:
Set GPIO4_21 high:
Set GPIO4_21 low:
Read GPIO4_21:
Note: To verify the output value of a GPIO pin after using the gpioset command, you can physically connect (jumper) it to a separate GPIO configured as an input. Then, use the gpioget command on the input pin to read the output state.
libgpiod C++ Application¶
libgpiod provides bindings for C++, Python and Rust applications. C++ examples are available in the libgpiod /tree/bindings/cxx/examples directory.
Below is a simple C application demonstrating how to use the bindings with GPIO0_IO05:
Makefile:
LDFLAGS = -lgpiodcxx -lgpiod
# Nome do executável e arquivos fonte
TARGET = main
SRCS = main.cpp
all: $(TARGET)
$(TARGET): $(SRCS)
$(CXX) $(SRCS) $(LDFLAGS) -o $(TARGET)
clean:
rm -f $(TARGET)
main.cpp
// SPDX-License-Identifier: GPL-2.0-or-later
// SPDX-FileCopyrightText: 2023 Kent Gibson <[email protected]>
/* Minimal example of reading a single line. */
#include <cstdlib>
#include <filesystem>
#include <gpiod.hpp>
#include <iostream>
namespace {
/* Example configuration - customize to suit your situation */
const ::std::filesystem::path chip_path("/dev/gpiochip0");
const ::gpiod::line::offset line_offset = 5;
} /* namespace */
int main()
{
auto request = ::gpiod::chip(chip_path)
.prepare_request()
.set_consumer("get-line-value")
.add_line_settings(
line_offset,
::gpiod::line_settings().set_direction(
::gpiod::line::direction::INPUT))
.do_request();
::std::cout << line_offset << "="
<< (request.get_value(line_offset) ==
::gpiod::line::value::ACTIVE ?
"Active" :
"Inactive")
<< ::std::endl;
return EXIT_SUCCESS;
}
libgpiod Python Application¶
libgpiod provides bindings for python applications:
Python examples are available in the libgpiod /tree/bindings/python/examples directory.
Kernel Device Tree GPIO configuration¶
Device Tree GPIO files¶
Pin Func files¶
In the directory arch/arm64/boot/dts/freescale of the Linux kernel source you will find the pin functions definition files.
The relevant file is imx8mn-pinfunc.h.
If you search it for GPIO4_IO22, for example, you will see a group of definitions with same prefix (pad name), "MX8MN_IOMUXC_SAI2_RXC".
#define MX8MN_IOMUXC_SAI2_RXC_SAI2_RX_BCLK 0x01B4 0x041C 0x0000 0x0 0x0
#define MX8MN_IOMUXC_SAI2_RXC_SAI5_TX_BCLK 0x01B4 0x041C 0x04E8 0x1 0x2
#define MX8MN_IOMUXC_SAI2_RXC_UART1_DCE_RX 0x01B4 0x041C 0x04F4 0x4 0x3
#define MX8MN_IOMUXC_SAI2_RXC_UART1_DTE_TX 0x01B4 0x041C 0x0000 0x4 0x0
#define MX8MN_IOMUXC_SAI2_RXC_GPIO4_IO22 0x01B4 0x041C 0x0000 0x5 0x0
#define MX8MN_IOMUXC_SAI2_RXC_PDM_BIT_STREAM1 0x01B4 0x041C 0x0538 0x6 0x8
Adding only the one with the GPIO4_IO22 suffix (function) to your dts file will let you use the pin as GPIO.
Define a pin as GPIO in the kernel Device Tree¶
You need to add the relevant definitions to your device tree, as explained in the Pin Func files section above.
Edit arch/arm64/boot/dts/freescale/imx8mn-var-som-symphony.dts and add the definition for the GPIO you need in the iomuxc node.
&iomuxc {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_hog>;
imx8mn-var-som {
pinctrl_hog: hoggrp {
fsl,pins = <
/* Add your GPIO definitions here */
>;
};
};
…
};
Please consult Variscite's blog post i.MX Device Tree Pinmux Settings Guide for further information.
Device Tree GPIO attribute¶
If you look at the pin control definitions in arch/arm64/boot/dts/freescale/imx8mn-var-som-symphony.dts in the Linux kernel source tree, the number to the right of the pin mux macro can be used for additional attributes like pull-up, slew rate, open drain, drive strength, etc. This value is written to the IOMUXC_SW_PAD_CTRL_ register of the relevant pin.
Please consult the SOC reference manual for details about the relevant register.