The aim of this document is to explain how to use GPIO of SP7350 in Linux. SP7350 has 106 general purpose IO (GPIO) pins. This section explains how to modify device-tree source file to set up GPIO pins as digital input or output pins.
Define GPIO in device-tree source file
Every single device has a node in device-tree source (dts) file in Linux. Property pinctrl-0 (or pinctrl-1, pinctrl-2,… if a device has more states) is used to point at pin configuration node within pin controller (node pinctrl@f8800080 in SP7350). Pin configuration nodes (sub-nodes in node pinctrl@f8800080 ) define the actual pins assignment.
Users need to add properties pinctrl-names and pinctrl-0 to a node (device) in device-tree source file to set up GPIOs as digital input or output pins for a device . For example:
uart0: serial@f8801900 { : : pinctrl-names = "default"; pinctrl-0 = <&uart0_pins &uart0_test_pins>; test1-gpios = <&pctl 0 GPIO_ACTIVE_HIGH>; test2-gpios = <&pctl 90 GPIO_ACTIVE_HIGH>; : : };
where property pinctrl-0 sets up pins of serial@f8801900 device for "default" state. It is a handle (an address) to sub-node of pin-controller node. In this case, pinctrl-0 has two handles. uart0_pins defines pins of UART0, and uart0_test_pins defines new-add test GPIO pins.
Property test1-gpios defines a GPIO pin to GPIO0 of pin controller. Property test2-gpios defines a GPIO pin to GPIO90 of pin controller. Linux driver can get GPIO descriptors using the properties. pctl is a handle (an address) to pin controller.
The following device-tree source of SP7350 shows definitions of sub-node pinmux_uart0-test-pins of node pinctrl@f8800080.
uart0_test_pins: pinmux_uart0_test-pins { function = "GPIO"; pins = "GPIO0", GPIO90"; output-enable; };
Manipulate GPIO in Linux kernel (driver)
In above example, property test1-gpios define one GPIO pin to GPIO0 of pin controller and property test2-gpios define one GPIO pin to GPIO90 of pin controller, respectively. Linux driver can use function devm_gpiod_get to get GPIO descriptor with the property. Use gpiod_set_value to set value to GPIO or use gpiod_get_value to get value from GPIO. Refer to the following C example code.
struct gpio_desc *test1_gpio; struct gpio_desc *test2_gpio; : : // Get test1_gpio. test1_gpio = devm_gpiod_get(&pdev->dev, "test1", GPIOD_OUT_HIGH); if (!IS_ERR(test1_gpio)) { printk(KERN_INFO "test1_gpio is at GPIO[%d].\n", desc_to_gpio(test1_gpio)); } // Get test2_gpio. test2_gpio = devm_gpiod_get(&pdev->dev, "test2", GPIOD_OUT_LOW); if (!IS_ERR(test2_gpio)) { printk(KERN_INFO "test2_gpio is at GPIO[%d].\n", desc_to_gpio(test2_gpio)); } : : gpiod_set_value(test1_gpio, 0); gpiod_set_value(test2_gpio, 1); :
Manipulate GPIO in Linux user-space (using sysfs)
Users can setup and access GPIO using sysfs interface. Path of gpio of sysfs is /sys/class/gpio. Enter the folder and use ls command to list contents:
~ # cd /sys/class/gpio /sys/class/gpio # ls export gpiochip0 unexport /sys/class/gpio #
where export and unexport are write-only control interface. gpiochip0 is a GPIO controller.
Example 1: Set up GPIO0 as output pin.
First, use echo command to export GPIO0:
/sys/class/gpio # echo 0 > export /sys/class/gpio # ls GPIO0 export gpiochip0 unexport /sys/class/gpio #
Folder GPIO0 was created and its contents are:
/sys/class/gpio # ls GPIO0 active_low direction subsystem value device power uevent /sys/class/gpio #
where active_low, direction and value are control interface.
Use echo command to setup GPIO0 as output port.
/sys/class/gpio # echo out > GPIO0/direction /sys/class/gpio # cat GPIO0/direction out /sys/class/gpio #
Read-back value of "out" means GPIO0 is set as output port.
Next, use echo command to write values to the port.
/sys/class/gpio # echo 1 > GPIO0/value /sys/class/gpio # cat GPIO0/value 1 /sys/class/gpio # echo 0 > GPIO0/value /sys/class/gpio # cat GPIO0/value 0 /sys/class/gpio #
Example 2:Setup GPIO0 as input port.
/sys/class/gpio # echo 0 > export /sys/class/gpio # ls GPIO0 export gpiochip0 unexport /sys/class/gpio # echo in > GPIO0/direction /sys/class/gpio # cat GPIO0/direction in /sys/class/gpio # cat GPIO0/value 1 /sys/class/gpio #
GPIO0 is set as input port and the read-back value of the input port is 1.
Exported GPIO can be unexported:
/sys/class/gpio # ls GPIO0 export gpiochip0 unexport /sys/class/gpio # echo 0 > unexport /sys/class/gpio # ls export gpiochip0 unexport /sys/class/gpio #