GPIO

Introduction

GPIO, short for General-Purpose Input/Output, is a type of pin that can be dynamically configured and controlled during software execution. All GPIOs are in input mode after power-up, and can be set to pull-up or pull-down through software. They can also be configured as interrupt pins, and their drive strength is programmable. The core of GPIO operation involves populating the methods and parameters of the GPIO bank and registering it with the kernel using gpiochip_add.

GPIO Pin Calculation

The LKD3568 has 5 groups of GPIO banks: GPIO0~GPIO4, each group is further divided with identifiers A0~A7, B0~B7, C0~C7, D0~D7. The following formulas are commonly used to calculate the pins:

GPIO pin calculation formula: pin = bank * 32 + number

GPIO group number calculation formula: number = group * 8 + X

Here is a demonstration of the calculation method for GPIO4_D5 pin: bank = 4;      //GPIO4_D5 => 4, bank ∈ [0,4]

group = 3;      //GPIO4_D5 => 3, group ∈ {(A=0), (B=1), (C=2), (D=3)}

X = 5;       //GPIO4_D5 => 5, X ∈ [0,7]

number = group * 8 + X = 3 * 8 + 5 = 29

pin = bank*32 + number= 4 * 32 + 29 = 157;

GPIO Identifier Pin Identifier Pin Identifier Pin Identifier Pin
GPIO0 A0 0 B0 8 C0 16 D0 24
A1 1 B1 9 C1 17 D1 25
A2 2 B2 10 C2 18 D2 26
A3 3 B3 11 C3 19 D3 27
A4 4 B4 12 C4 20 D4 28
A5 5 B5 13 C5 21 D5 29
A6 6 B6 14 C6 22 D6 30
A7 7 B7 15 C7 23 D7 31
GPIO1 A0 32 B0 40 C0 48 D0 56
A1 33 B1 41 C1 49 D1 57
A2 34 B2 42 C2 50 D2 58
A3 35 B3 43 C3 51 D3 59
A4 36 B4 44 C4 52 D4 60
A5 37 B5 45 C5 53 D5 61
A6 38 B6 46 C6 54 D6 62
A7 39 B7 47 C7 55 D7 63
GPIO2 A0 64 B0 72 C0 80 D0 88
A1 65 B1 73 C1 81 D1 89
A2 66 B2 74 C2 82 D2 90
A3 67 B3 75 C3 83 D3 91
A4 68 B4 76 C4 84 D4 92
A5 69 B5 77 C5 85 D5 93
A6 70 B6 78 C6 86 D6 94
A7 71 B7 79 C7 87 D7 95
GPIO3 A0 96 B0 104 C0 112 D0 120
A1 97 B1 105 C1 113 D1 121
A2 98 B2 106 C2 114 D2 122
A3 99 B3 107 C3 115 D3 123
A4 100 B4 108 C4 116 D4 124
A5 101 B5 109 C5 117 D5 125
A6 102 B6 110 C6 118 D6 126
A7 103 B7 111 C7 119 D7 127
GPIO4 A0 128 B0 136 C0 144 D0 152
A1 129 B1 137 C1 145 D1 153
A2 130 B2 138 C2 146 D2 154
A3 131 B3 139 C3 147 D3 155
A4 132 B4 140 C4 148 D4 156
A5 133 B5 141 C5 149 D5 157
A6 134 B6 142 C6 150 D6 158
A7 135 B7 143 C7 151 D7 159

The device tree property description corresponding to GPIO4_D5 is: <&gpio4 29 IRQ_TYPE_EDGE_RISING>. As defined by the macros in kernel/include/dt-bindings/pinctrl/rockchip.h, GPIO4_D5 can also be described as <&gpio4 RK_PD5 IRQ_TYPE_EDGE_RISING>.

#define RK_PA0		0
#define RK_PA1		1
#define RK_PA2		2
#define RK_PA3		3
#define RK_PA4		4
#define RK_PA5		5
#define RK_PA6		6
#define RK_PA7		7
#define RK_PB0		8
#define RK_PB1		9
#define RK_PB2		10
#define RK_PB3		11
......

GPIO4_D5 may be occupied by other functions; the following is just an example. When the pin is not multiplexed by other peripherals, we can export the pin for use through export.

:/ # ls /sys/class/gpio/
export     gpiochip128  gpiochip32   gpiochip64  unexport
gpiochip0  gpiochip255  gpiochip500  gpiochip96
:/ # echo 157 > /sys/class/gpio/export
:/ # ls /sys/class/gpio/
export   gpiochip0    gpiochip255  gpiochip500  gpiochip96
gpio157  gpiochip128  gpiochip32   gpiochip64   unexport
:/ # ls /sys/class/gpio/gpio157
active_low  device  direction  edge  power  subsystem  uevent  value
:/ # cat /sys/class/gpio/gpio157/direction
in
:/ # cat /sys/class/gpio/gpio157/value
0

FAQs

Q1: How do I switch the MUX value of a PIN to a general GPIO?

A1: When using GPIO request, the MUX value of that PIN will be forcibly switched to GPIO. Therefore, ensure that the PIN is not being used by other modules when using it for GPIO functionality.

Q2: Why do I get a value of 0x00000000 when I read with IO commands?

A2: If you read a GPIO register with IO commands and get an abnormal value, such as 0x00000000 or 0xffffffff, please confirm whether the CLK of that GPIO is turned off. The CLK of GPIO is controlled by CRU. You can check whether the CLK is on by reading the CRU_CLKGATE_CON* registers in the datasheet. If it is not on, you can use the io command to set the corresponding register to turn on the CLK. After turning on the CLK, you should be able to read the correct register value.

Q3: What should I check if the voltage measured at the PIN is incorrect?

A3: If the voltage measured at the PIN is incorrect, excluding external factors, confirm whether the IO voltage source of that PIN is correct and whether the IO-Domain configuration is correct.

Q4: What is the difference between gpio_set_value() and gpio_direction_output()?

A4: If you are not going to dynamically switch between input and output when using the GPIO, it is recommended to set the GPIO output direction at the start. Later, when pulling high or low, use the gpio_set_value() interface instead of gpio_direction_output(). This is because the gpio_direction_output() interface contains a mutex lock, which can cause errors in interrupt context calls. Moreover, compared to gpio_set_value(), gpio_direction_output() does more things, which is wasteful.