Gpio Settings for RK3288

Source: Internet
Author: User


    • 1 Introduction
    • 2 use
      • 2.1 Input and output
      • 2.2 Re-use
Brief introduction

GPIO, full name general-purpose input/output (Universal input and output), is a general purpose pin that can be dynamically configured and controlled during software operation.

RK3288 has 9 sets of GPIO Bank:gpio0,gpio1, ..., GPIO8. Each group is also A0~a7, B0~b7, C0~c7, D0~d7 as a number distinction (not all banks have all numbers, such as GPIO5 only B0~b7, C0~C3).

In addition to the general input and output functions, each GPIO port may have other multiplexing functions, such as GPIO5_B4, which can be reused as one of the following functions:

    • Spi0_clk
    • Ts0_data4
    • Uart4exp_ctsn

The initial state of the drive current, pull-up and reset of each GPIO port is different, please refer to the "RK3288 function IO description" chapter in the RK3288 specification for details.

The GPIO drivers for RK3288 are implemented in the following Pinctrl files:

Its core is to populate the GPIO bank's methods and parameters, and call Gpiochip_add to register to the kernel.


The Development Board has two power LED lamps that are controlled by GPIO ports, respectively:

From the circuit diagram, the output of the GPIO port is low, the light is on, and the lamp is off at high power.

In addition, several idle GPIO ports are drawn on the expansion slots, respectively:

These GPIO ports can be customized for input and output use.


The following is an example of how to write code in the kernel to control the output of a GPIO port with the driver for the power LED light.

You first need to add a driver resource description in the DTS (Device Tree) file Firefly-rk3288.dts (version 0930) or Firefly-rk3288_beta.dts (version 0809):

  1. firefly-led{
  2. compatible = "firefly,led";
  3. Led-work = <&gpio8 gpio_a2 gpio_active_low>;
  4. Led-power = <&gpio8 gpio_a1 gpio_active_low>;
  5. Status = "Okay";
  6. };

This defines the GPIO settings for the two LEDs:

Led-work  gpio8_a2  gpio_active_low led-power gpio8_a1  

The gpio_active_low indicates that the low level is active (light on), and if it is active, it needs to be replaced with Gpio_active_high.

After the application and control of the GPIO port are added to the driver, you can:

 #ifdef config_of #include <linux/of.h> #include <linux/of_gpio.h> #endif       static int firefly_led_probe (struct platform_device *pdev) {int ret =-1; int GPIO, flag; struct Device_node *led_node = pdev->dev.of_node;   Gpio = Of_get_named_gpio_flags (Led_node, "Led-power", 0, &flag);      if (!gpio_is_valid (Gpio)) {PRINTK ("Invalid led-power: %d\n", gpio); return-1;}         if (Gpio_request (Gpio, "Led_power")) {PRINTK ("gpio %d request failed!\n", Gpio); return ret; } Led_info.power_gpio = Gpio; Led_info.power_enable_value = (flag = = Of_gpio_active_low)? 0:1; Gpio_direction_output (Led_info.power_gpio,!) ( Led_info.power_enable_value)); ... on_error:gpio_free (GPIO); }

Of_get_named_gpio_flags reads the Led-power gpio configuration number and flag from the device tree, Gpio_is_valid determines whether the Gpio number is valid, and gpio_request applies to occupy the Gpio. If the initialization process goes wrong, you need to call Gpio_free to release the previously requested and successful Gpio.

Call Gpio_direction_output to set the output high or low, because it is gpio_active_low, if you want to light, you need to write 0.

In practice, if you want to read the GPIO, you need to set the input mode first and then read the value:

int Val; Gpio_direction_input (Your_gpio); val = Gpio_get_value (Your_gpio);

The following are common GPIO API definitions:

#include <linux/gpio.h> #include <linux/of_gpio.h> enum of_gpio_flags {of_gpio_active_low = 0x1,};   int of_get_named_gpio_flags (struct device_node *np, const char *propname,    int index, enum of_gpio_flags *flags);   int gpio_is_valid (int gpio);   int gpio_request (unsigned gpio, const char *label);   void Gpio_free (unsigned gpio);   int gpio_direction_input (int gpio); int gpio_direction_output (int gpio, int v)

How do you define what features of a GPIO can be reused, and how do I switch functions at run time? Take I2C4 as an example to make a brief introduction.

The specification table shows that the functions of I2C4_SDA and GPIO7C1 are defined as follows:

pad# func0 func1
I2c4_sda/gpio7_c1 Gpio7c1 I2c4tp_sda
I2c4_scl/gpio7_c2 Gpio7c2 I2c4tp_scl

In the/kernel/arch/arm/boot/dts/rk3288.dtsi there are:

I2C4: [email protected] {compatible = "ROCKCHIP,RK30-I2C"; reg = <0xff160000 0x1000>; interrupts = <gic_spi rq_type_level_high>; #address-cells = <1>; #size-cells = <0>; Pinctrl-names = "Default", "Gpio"; pinctrl-0 = <&i2c4_sda &i2c4_scl>; PINCTRL-1 = <&i2c4_gpio>; Gpios = <&gpio7 gpio_c1 gpio_active_low>, <&gpio7 gpio_c2 gpio_active_low>; Clocks = <&clk_gates6 15>; Rockchip,check-idle = <1>; Status = "Disabled"; };

Here, the property associated with the multiplexing control is pinctrl-:

    • Pinctrl-names defines a list of state names: Default (I²c function) and Gpio two states.
    • Pinctrl-0 defines the PINCTRL:I2C4_SDA and I2C4_SCL that need to be set when state 0 (that is, default)
    • PINCTRL-1 defines the pinctrl:i2c4_gpio that need to be set when State 1 (that is, Gpio)

These pinctrl are defined in/kernel/arch/arm/boot/dts/rk3288-pinctrl.dtsi:

/{pinctrl: [email protected] {compatible =" Rockchip,rk3288-pinctrl "; ... gpio7_i2c4 {i2c4_sda:i2c4-sda {rockchip,pins = <I2C4TP_SDA>; Rockchip,pull = <VALUE_PULL_DISABLE>; Rock Chip,drive = <VALUE_DRV_DEFAULT>; Rockchip,tristate = <VALUE_TRI_DEFAULT>; };   I2C4_SCL:I2C4-SCL {rockchip,pins = <I2C4TP_SCL>; Rockchip,pull = <VALUE_PULL_DISABLE>; Rockchip, Drive = <VALUE_DRV_DEFAULT>; Rockchip,tristate = <VALUE_TRI_DEFAULT>; };   I2c4_gpio:i2c4-gpio {rockchip,pins = <func_to_gpio (I2C4TP_SDA), <func_to_gpio (I2C4TP_SCL) >; Rockchip,drive = <VALUE_DRV_DEFAULT>; };         };   ...     } }

I2C4TP_SDA, I2C4TP_SCL is defined in/kernel/arch/arm/boot/dts/include/dt-bindings/pinctrl/rockchip-rk3288.h:

#define GPIO7_C1 0X7C10 #define I2C4TP_SDA 0x7c11 #define GPIO7_C2 0x7c20 #define I2C4TP_SCL 0x7c21

The definition of Fun_to_gpio is in/kernel/arch/arm/boot/dts/include/dt-bindings/pinctrl/rockchip.h:

#define FUNC_TO_GPIO (M) ((m) & 0XFFF0)

That is to say Func_to_gpio (I2C4TP_SDA) = = Gpio7_c1, Func_to_gpio (I2C4TP_SCL) = = Gpio7_c2.

Values such as 0X7C11 have encoding rules:

7 C1 1 | |  

In the case of re-use, if the "default" (that is, the I²c function), the system will apply the I2C4_SDA and I2C4_SCL two Pinctrl, the final gpio7_c1 and gpio7_c2 two pins to switch to the corresponding I²c function, and if the "G Pio ", the system will apply I2c4_gpio this Pinctrl to restore the GPIO7_C1 and gpio7_c2 two pins to the GPIO function.

Let's look at how the I²c driver/kernel/drivers/i2c/busses/i2c-rockchip.c switches the multiplexing feature:

static int rockchip_i2c_probe (struct platform_device *pdev) {struct ROCKCHIP_I2C *i2c = NULL; struct resource *res; struc T Device_node *NP = pdev->dev.of_node; int ret; ... I2c->sda_gpio = Of_get_gpio (NP, 0); if (!gpio_is_valid (I2c->sda_gpio)) {Dev_err (&pdev->dev, "SDA Gpio is invalid\n"); return-einval;} ret = Devm_ Gpio_request (&pdev->dev, I2c->sda_gpio, Dev_name (&i2c->; if (ret) {Dev_err (&pdev->dev, "failed to request SDA gpio\n"); return ret;} I2c->scl_gpio = Of_get_gpio (NP, 1) ; if (!gpio_is_valid (I2c->scl_gpio)) {Dev_err (&pdev->dev, "SCL Gpio is invalid\n"); return-einval;} ret = Devm_ Gpio_request (&pdev->dev, I2c->scl_gpio, Dev_name (&i2c->; if (ret) {Dev_err (&pdev->dev, "failed to request SCL gpio\n"); return ret;} i2c->gpio_state = pinctrl_lookup_s Tate (I2c->dev->pins->p, "Gpio"); if (Is_err (i2c->gpio_state)) {Dev_err (&pdev->dev, "No Gpio pinctrl STATe\n "); Return Ptr_err (i2c->gpio_state); } pinctrl_select_state (I2c->dev->pins->p, i2c->gpio_state); Gpio_direction_input (I2c->sda_gpio); Gpio_direction_input (I2c->scl_gpio); Pinctrl_select_state (I2c->dev->pins->p, i2c->dev->pins->default_state); // ... }

The first is to call Of_get_gpio to take out the gpios of the I2C4 node in the device tree that belongs to the defined two gpio:

The devm_gpio_request is then called to request a gpio, followed by a call to Pinctrl_lookup_state to find the "Gpio" state, while the default state "Defaults" has been saved by the framework to i2c->dev-pins-> In the default_state.

Finally, call Pinctrl_select_state to select whether it is "default" or "Gpio" function.

The following are common reusable API definitions:

#include <linux/pinctrl/consumer.h> struct Device {/... #ifdef config_pinctrl struct dev_pin_info*pins; #endif/   /... }; struct Dev_pin_info {struct Pinctrl *p; struct pinctrl_state *default_state; #ifdef config_pm struct pinctrl_state *sleep _state; struct Pinctrl_state *idle_state;   #endif};   struct pinctrl_state * pinctrl_lookup_state (struct Pinctrl *p, const char *name); int pinctrl_select_state (struct Pinctrl *p, struct pinctrl_state *s);

Gpio Settings for RK3288

Related Article

E-Commerce Solutions

Leverage the same tools powering the Alibaba Ecosystem

Learn more >

Apsara Conference 2019

The Rise of Data Intelligence, September 25th - 27th, Hangzhou, China

Learn more >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: and provide relevant evidence. A staff member will contact you within 5 working days.