The NXP i.MX6 CPU has seven general purpose input/output (GPIO) ports. Each port can generate and control 32 signals.

The Dialog PMIC DA9063 has 16 configurable GPIO pins.

GPIOs on the ConnectCore 6 platforms

  • On the ConnectCore 6 system-on-module:

    • Many of the i.MX6 GPIOs are available at the system-on-module, multiplexed with other functions (labeled GPIOxIOy where _x is the port and y is the GPIO pin). See Hardware reference manuals for information about GPIO pins and their multiplexed functionality.

    • Eight PMIC GPIO pins are available (labeled PMIC_GPIOx where x is the GPIO pin).

  • On the ConnectCore 6 SBC, the expansion connector allows direct access to eight i.MX6 GPIOs.

GPIOs on the SOM and carrier board are used for many purposes, such as:

  • Power enable line for transceivers

  • Reset line for controllers

  • LCD backlight control

  • Interrupt line

  • User LEDs

Kernel configuration

You can manage the GPIO driver support through the kernel configuration option:

  • Dialog Semiconductor DA9063 GPIO (CONFIG_GPIO_DA9063)

This option is enabled as built-in on the ConnectCore 6 SBC kernel configuration file.

Support for i.MX6 GPIOs is automatically provided through the non-visible option CONFIG_GPIO_MXC.

Kernel driver

The i.MX6 GPIO driver is located at drivers/gpio/gpio-mxc.c.

The Dialog DA9063 GPIO driver is located at drivers/gpio/gpio-da9063.c.

Device tree bindings and customization

The i.MX6 GPIO device tree binding is documented at Documentation/devicetree/bindings/gpio/fsl-imx-gpio.yaml.

One GPIO controller is defined for each i.MX6 GPIO port in the common i.MX6 device tree file:

i.MX6 device tree
	gpio1: gpio@0209c000 {
		compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
		reg = <0x0209c000 0x4000>;
		interrupts = <0 66 IRQ_TYPE_LEVEL_HIGH>,
		             <0 67 IRQ_TYPE_LEVEL_HIGH>;
		gpio-controller;
		#gpio-cells = <2>;
		interrupt-controller;
		#interrupt-cells = <2>;
	};

[...]

	gpio7: gpio@020b4000 {
		compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
		reg = <0x020b4000 0x4000>;
		interrupts = <0 78 IRQ_TYPE_LEVEL_HIGH>,
		             <0 79 IRQ_TYPE_LEVEL_HIGH>;
		gpio-controller;
		#gpio-cells = <2>;
		interrupt-controller;
		#interrupt-cells = <2>;
	};

The Dialog DA9063 GPIO device tree binding is documented at Documentation/devicetree/bindings/gpio/gpio-da9063.txt.

The DA9063 PMIC GPIO controller is defined in the ConnectCore 6 device tree file:

ConnectCore 6 device tree
&i2c2 {
	clock-frequency = <100000>;
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_i2c2>;
	status = "okay";
	pmic_dialog: dialog@58 {
		compatible = "dlg,da9063";

		[...]

		gpio_extender: gpio {
			compatible = "dlg,da9063-gpio";
			gpio-controller;
			#gpio-cells = <2>;
		};

		[...]
	};
};

The ConnectCore 6 device tree include file and the ConnectCore 6 SBC device tree files use the i.MX6 and DA9063 PMIC GPIOs.

For example, on the ConnectCore 6 SBC, GPIO1_IO25 is used to reset the PHY of the Ethernet interface:

ConnectCore 6 SBC device tree
&fec {
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_enet>;
	phy-mode = "rgmii";
	phy-reset-gpios = <&gpio1 25 GPIO_ACTIVE_HIGH>;
	phy-reset-duration = <10>;
	phy-reset-wait = <1>;
	phy-supply = <&ldo4>;
	fsl,magic-packet;
};

IOMUX configuration

You must configure the pads that are to be used as i.MX6 GPIOs. See Pin multiplexing (IOMUX).

For GPIOs that are managed by other drivers, you must configure their pad IOMUX inside the driver node specific pinctrl-0 to work according to the specified interface functionalities.

On the ConnectCore 6 SBC example from above, fec node configures pinctrl_enet:

ConnectCore 6 SBC device tree
pinctrl_enet: enet {
	fsl,pins = <
		MX6QDL_PAD_ENET_MDIO__ENET_MDIO       0x1b0b0
		MX6QDL_PAD_ENET_MDC__ENET_MDC         0x1b0b0
		[...]
		MX6QDL_PAD_ENET_TX_EN__GPIO1_IO28     0x1b0b0
		MX6QDL_PAD_ENET_CRS_DV__GPIO1_IO25    0x1b0b0
	>;
};

For GPIOs that are not associated with any interface or that can’t be handled by a driver, see Configure independent pin IOMUX and pad control. The following external pads are configured as GPIOs on the default device tree:

  • On the ConnectCore 6 SBC GPIO connector:

    Pad Signal GPIO

    6

    EXP_GPIO_0

    GPIO2_IO05

    7

    EXP_GPIO_1

    GPIO2_IO06

    8

    EXP_GPIO_2

    GPIO2_IO07

    9

    EXP_GPIO_3

    GPIO2_IO24

    10

    EXP_GPIO_4

    GPIO2_IO28

    11

    EXP_GPIO_5

    GPIO2_IO29

    12

    EXP_GPIO_6

    GPIO7_IO13

    13

    EXP_GPIO_7

    GPIO4_IO05

SION bit

It is not possible to read the real signal level of a GPIO pin that is configured as an output. You can use the software input on (SION) bit to read the value of an output GPIO.

SION bit mode increases the power consumption of the module, so it is disabled by default.

To enable the SION bit, set the bit 30 (special value). For example, to enable the SION bit for EXP_GPIO_0, use the following in the device tree (note that 0x80000000 | (1 << 30) = 0xC0000000 ):

ConnectCore 6 SBC device tree
hog {
	pinctrl_hog: hog {
		fsl,pins = <
			...
			/* EXP_GPIO_0 */
			MX6QDL_PAD_NANDF_D5__GPIO2_IO05 0xC0000000
		};
	};
};

For more information, see the NXP Application Note AN5078.

Using the GPIOs

The package libgpiod (added by packagegroup-dey-core) provides a set of tools (such as gpioget, gpioget, etc.) for controlling the GPIOs from user space.

You can still control the GPIOs from the sysfs, but this ABI is not recommended. See https://www.kernel.org/doc/html/latest/userspace-api/gpio/sysfs.html.

Detect GPIO ports

Use gpiodetect to list the GPIO ports detected by the kernel:

# gpiodetect
gpiochip0 [gpio1] (32 lines)
gpiochip1 [gpio2] (32 lines)
gpiochip2 [gpio3] (32 lines)
gpiochip3 [gpio4] (32 lines)
gpiochip4 [gpio5] (32 lines)
gpiochip5 [gpio6] (32 lines)
gpiochip6 [gpio7] (32 lines)
gpiochip7 [da9063-gpio] (16 lines)

where:

  • Ports gpio0 to gpio6 are the i.MX6 GPIO ports.

  • Port mda9063ca-gpio is the DA9063 PMIC GPIO port.

Information about a GPIO port

Use gpioinfo to list the lines of a given port:

# gpioinfo gpio1
gpiochip0 - 32 lines:
	line   0:      unnamed       unused   input  active-high
	line   1:      unnamed       unused   input  active-high
	line   2:      unnamed       unused   input  active-high
	line   3:      unnamed        "rts"  output  active-high [used]
	line   4:      unnamed "mca-fw-update" output active-high [used]
	line   5:      unnamed       unused   input  active-high
	line   6:      unnamed   "5v_board"  output  active-high [used]
	line   7:      unnamed      "sysfs"  output  active-high [used]
	line   8:      unnamed      "sysfs"  output  active-high [used]
	line   9:      unnamed       unused   input  active-high
	line  10:      unnamed       unused   input  active-high
	line  11:      unnamed       unused   input  active-high
	line  12:      unnamed       unused  output  active-high
	line  13:      unnamed       unused   input  active-high
	line  14:      unnamed       unused   input  active-high
	line  15:      unnamed       unused   input  active-high
	line  16:      unnamed       unused   input  active-high
	line  17:      unnamed       unused   input  active-high
	line  18:      unnamed       unused   input  active-high
	line  19:      unnamed       unused   input  active-high
	line  20:      unnamed       unused   input  active-high
	line  21:      unnamed       unused   input  active-high
	line  22:      unnamed       unused   input  active-high
	line  23:      unnamed       unused   input  active-high
	line  24:      unnamed       unused   input  active-high
	line  25:      unnamed       unused   input  active-high
	line  26:      unnamed       unused   input  active-high
	line  27:      unnamed       unused   input  active-high
	line  28:      unnamed       unused   input  active-high
	line  29:      unnamed       unused   input  active-high
	line  30:      unnamed       unused   input  active-high
	line  31:      unnamed       unused   input  active-high

Set an output high/low

Use gpioset to set a i.MX6 GPIO as output, such as GPIO5_IO27. Use =1 to set it high, or =0 to set it low:

# gpioset gpio5 27=1
# gpioset gpio5 27=0

Read an input

Use gpioget to read the value of a i.MX6 GPIO input, such as GPIO5_IO27:

# gpioget gpio5 27
0

Use a GPIO as interrupt

Use gpiomon to wait for an event on a given GPIO, such as GPIO5_IO27:

# gpiomon --num-events 1 --rising-edge gpio5 27

See the README of libgpiod for more information on the usage of these tools.

See GPIO API for more information about the GPIO APIx.