Skip to main content

GPIO

GPIO Functionality and Usage Guide.

Overview​

GPIO is the controller for the GPIO module

Functional Description​

The Linux GPIO subsystem driver framework mainly consists of three parts:

  • GPIO Controller Driver: Interacts with the GPIO controller, performing initialization and operations on the controller.
  • GPIO lib Driver: Provides standard APIs for use by other modules, such as setting GPIO direction and reading/writing GPIO level states.
  • GPIO Character Device Driver: Exposes GPIOs to user space as character devices, allowing user space to access GPIOs through standard file interfaces.

Source Code Structure​

The controller driver code is located in the drivers/gpio directory:

|-- gpio-k1x.c

Key Features​

FeatureDescription
Direction Configuration SupportSupports setting GPIO as input or output
High/Low Level Output SupportSupports setting the level of GPIO in output mode
GPIO Interrupt SupportSupports GPIO interrupts triggered by rising and falling edge

Configuration Introduction​

It mainly includes driver CONFIG enablement configuration and DTS configuration.

CONFIG Configuration​

  • CONFIG_GPIOLIB: Provides support for GPIO controllers, with a Ydefault value of
Device Drivers
GPIO Support (GPIOLIB [=y])
  • CONFIG_GPIO_K1X: Provides support for the K1 GPIO controller, with a default value of Y
Device Drivers
GPIO Support (GPIOLIB [=y])
Virtual GPIO drivers
SPACEMIT-K1X GPIO support (GPIO_K1X [=y])

Usage Guide​

Using GPIO involves three steps:

  1. GPIO Description
  2. GPIO Pin Configuration
  3. GPIO Usage

Notes:

  1. Pin numbers are defined in the kernel directory include/dt-bindings/pinctrl/k1-x-pinctrl.h.
  2. Pin configuration is the same when a group of pins is set to the GPIO function, meaning that the mux mode, pull-up/pull-down, edge detection, and drive strength configurations are the same.

GPIO Description​

Define all GPIOs used in the system.

The gpio-ranges property of the Linux GPIO framework is used for definition. If the pin numbers corresponding to a segment of GPIOs are also consecutive, they are defined as a group.

The GPIO controller definition in the solution DTS file for the example above

&gpio{
gpio-ranges = <
&pinctrl 49 GPIO_49 2
&pinctrl 58 GPIO_58 1
&pinctrl 63 GPIO_63 5
&pinctrl 70 PRI_TDI 4
&pinctrl 74 GPIO_74 1
&pinctrl 80 GPIO_80 4
&pinctrl 90 GPIO_90 3
&pinctrl 96 DVL0 2
&pinctrl 110 GPIO_110 1
&pinctrl 114 GPIO_114 3
&pinctrl 123 GPIO_123 5
>;
};

GPIO Pin Configuration​

Set the pins corresponding to the GPIOs used in the solution to the GPIO function and configure them (edge detection/pull-up/pull-down/drive strength).

Use the pinctrl-single,gpio-range property for setting. If there is a continuous range of pin numbers with the same configuration, they are configured as a group.

Refer to Section Pin Configuration Parameters for pin configuration parameters.

For example:

&pinctrl {
pinctrl-single,gpio-range = <
&range GPIO_49 2 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_3V_DS4)
&range GPIO_58 1 (MUX_MODE0 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2)
&range GPIO_63 2 (MUX_MODE0 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2)
&range GPIO_65 1 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_1V8_DS2)
&range GPIO_66 2 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_3V_DS4)
&range PRI_TDI 2 (MUX_MODE1 | EDGE_NONE | PULL_UP | PAD_1V8_DS2)
&range PRI_TCK 1 (MUX_MODE1 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2)
&range PRI_TDO 1 (MUX_MODE1 | EDGE_NONE | PULL_UP | PAD_1V8_DS2)
&range GPIO_74 1 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_1V8_DS2)
&range GPIO_80 1 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_3V_DS4)
&range GPIO_81 3 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_1V8_DS2)
&range GPIO_90 1 (MUX_MODE0 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2)
&range GPIO_91 2 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_1V8_DS2)
&range DVL0 2 (MUX_MODE1 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2)
&range GPIO_110 1 (MUX_MODE0 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2)
&range GPIO_114 1 (MUX_MODE0 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2)
&range GPIO_115 1 (MUX_MODE0 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2)
&range GPIO_116 1 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_1V8_DS2)
&range GPIO_123 1 (MUX_MODE0 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2)
&range GPIO_124 1 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_1V8_DS2)
&range GPIO_125 3 (MUX_MODE0 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2)
>;
};

GPIO Usage​

For example, in the solution, eth0 uses gpio 110 as the PHY Reset signal:

&eth0 {
emac,reset-gpio = <&gpio 110 0>;
};

Interface Introduction​

API​

  • Request a specified GPIO
int gpio_request(unsigned gpio, const char *label);
  • Release a specified GPIO that has been requested
void gpio_free(unsigned gpio);
  • Set a specified GPIO to input mode
int gpio_direction_input(unsigned gpio)
  • Set a specified GPIO to output mode and assign an initial value
int gpio_direction_output(unsigned gpio, int value)
  • Set the output value of a specified GPIO
void gpio_set_value(unsigned gpio, int value)
  • Get the signal value of a specified GPIO
int gpio_get_value(unsigned gpio)
  • Get the interrupt number corresponding to the specified GPIO.
int gpio_to_irq(unsigned gpio)

Debugging​

sysfs​

Accessing and Controlling GPIOs via sysfs.

/sys/class/gpio
|-- export
|-- gpiochip0 -> ../../devices/gpiochip0/gpio/gpiochip0
|-- gpiochip512 -> ../../devices/platform/soc/d401d800.i2c/i2c-8/8-0041/spacemit-pinctrl@spm8821/gpio/gpiochip512
`-- unexport
  • export: Used to inform the system to export the specified GPIO pin number for control
  • unexport: Used to inform the system to unexport (remove) the GPIO pin
  • gpiochipX: Detailed information of GPIO chip X
  • gpioX/direction: Direction setting of GPIO X
  • gpioX/value: Port value of GPIO X

debugfs​

Inspect the system’s GPIO controllers and the GPIO information they manage.

/sys/kernel/debug/gpio
# cat gpio
gpiochip0: GPIOs 0-127, k1x-gpio:
gpio-63 ( |reset ) out lo
gpio-67 ( |pwr ) out hi
gpio-80 ( |cd ) in hi ACTIVE LOW
gpio-96 ( |sys-led ) out lo
gpio-97 ( |vbus ) out hi
gpio-110 ( |mdio-reset ) out hi
gpio-111 ( |reset ) out lo
gpio-113 ( |pwdn ) out lo
gpio-115 ( |mdio-reset ) out hi
gpio-116 ( |regon ) out hi
gpio-123 ( |hub ) out hi
gpio-124 ( |hub ) out hi
gpio-127 ( |? ) out lo

gpiochip1: GPIOs 512-517, parent: platform/spacemit-pinctrl@spm8821, spacemit-pinctrl@spm8821, can sleep:

Testing​

You can use devmem to check register values and determine whether the GPIO configuration has taken effect.

devmem reg_addr

FAQ​