本文基于RockPI 4A
單板Linux 4.4
內(nèi)核介紹RK3399 Linux GPIO
功能坡疼。
一概作、GPIO介紹
GPIO(General Purpose Input/Output Port)
:通用輸入輸出端口渊啰。
除作為一般的輸入/輸出功能外憾朴,還可以配置為中斷和模擬PWM倒槐、I2C
等接口功能惕艳。
RK3399 GPIO
屬性如下:
1锈至、一共有5組GPIO(GPIO0~4)
晨缴,每組GPIO
為一個(gè)Bank
,共32個(gè)引腳峡捡。每個(gè)Bank
包括4個(gè)Group (GPIOA(0~7) ~ D(0~7))
击碗。不是所有Bank
都有GPIOA~D
的編號,RK3399
共122個(gè)GPIO
引腳们拙。
2稍途、所有GPIO
都可被配置為CA55或CA53
的中斷功能,且GPIO0
和GPIO1
可用于系統(tǒng)低功耗喚醒模式砚婆。
3械拍、在上電復(fù)位后,所有GPIO
默認(rèn)輸入狀態(tài)装盯。
4坷虑、軟件可配置GPIO
驅(qū)動(dòng)強(qiáng)度。
RK3399
引腳在系統(tǒng)中顯示如下:
root@linaro-alip:/sys/kernel/debug/pinctrl/pinctrl# cat pins
registered pins: 160
## GPIO 0_*包括的GPIO
pin 0 (gpio0-0)
pin 1 (gpio0-1)
pin 2 (gpio0-2)
pin 3 (gpio0-3)
pin 4 (gpio0-4)
pin 5 (gpio0-5)
pin 6 (gpio0-6)
pin 7 (gpio0-7)
pin 8 (gpio0-8)
pin 9 (gpio0-9)
pin 10 (gpio0-10)
...
pin 31 (gpio0-31)
...
## GPIO 2_*包括的GPIO
pin 64 (gpio2-0)
pin 65 (gpio2-1)
pin 66 (gpio2-2)
pin 67 (gpio2-3)
pin 68 (gpio2-4)
pin 69 (gpio2-5)
pin 70 (gpio2-6)
pin 71 (gpio2-7) ## GPIO2_A7
pin 72 (gpio2-8)
pin 73 (gpio2-9)
pin 74 (gpio2-10)
...
pin 95 (gpio2-31)
...
## GPIO 4_*包括的GPIO
pin 128 (gpio4-0)
...
pin 159 (gpio4-31)
RK3399 GPIO
引腳號計(jì)算方式:
pins = 32*bank + 8*group + x
bank: 0 ~ 4埂奈,對應(yīng)GPIO 0~4
group: 0 ~ 3迄损,對應(yīng)GPIO A~D
例:
GPIO2_A7 = 32*2 + 8*0 + 7 = 71
二、GPIO配置
以ROCKPI 4A
單板WIFI
模塊電源(GPIO0_B2
)為例账磺,介紹DTS
中GPIO
配置芹敌。
配置文件:
arch/arm64/boot/dts/rockchip/rockpi-4-linux.dtsi
,內(nèi)容如下:
sdio_pwrseq: sdio-pwrseq {
compatible = "mmc-pwrseq-simple";
clocks = <&rk808 1>;
clock-names = "ext_clock";
## 1垮抗、配置GPIO0_B2_d的pinmux功能
pinctrl-names = "default";
pinctrl-0 = <&wifi_enable_h>;
/*
* On the module itself this is one of these (depending
* on the actual card populated):
* - SDIO_RESET_L_WL_REG_ON
* - PDN (power down when low)
*/
## 2党窜、配置GPIO0_B2_d默認(rèn)輸出低電平
reset-gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
};
## 3、配置GPIO0_B2_d(WIFI_REG_ON_H)為GPIO功能
sdio-pwrseq {
wifi_enable_h: wifi-enable-h {
rockchip,pins =
<0 10 RK_FUNC_GPIO &pcfg_pull_none>;
};
};
在系統(tǒng)啟動(dòng)后借宵,可以查看GPIO
幌衣,命令如下:
root@linaro-alip:/sys/kernel/debug# cat gpio
GPIOs 0-31, platform/pinctrl, gpio0:
gpio-4 ( |bt_default_wake_host) out hi
gpio-9 ( |bt_default_reset ) out hi
gpio-10 ( |reset ) out lo ## 該引腳就是GPIO0_B2_d
GPIOs 32-63, platform/pinctrl, gpio1:
gpio-35 ( |vcc5v0_otg ) out hi
gpio-46 ( |vsel ) out lo
gpio-49 ( |vsel ) out lo
GPIOs 64-95, platform/pinctrl, gpio2:
gpio-83 ( |bt_default_rts ) out lo
gpio-90 ( |vcc3v3_pcie ) out hi
gpio-91 ( |bt_default_wake ) out hi
GPIOs 96-127, platform/pinctrl, gpio3:
gpio-111 ( |mdio-reset ) out hi
gpio-124 ( |? ) out lo
gpio-125 ( |? ) out lo
GPIOs 128-159, platform/pinctrl, gpio4:
gpio-153 ( |vcc5v0_host ) out hi
注:
如果debugfs沒有掛載,使用下面命令掛載
mount -t debugfs none /sys/kernel/debug
三壤玫、GPIO驅(qū)動(dòng)
Linux
內(nèi)核GPIO
主要實(shí)現(xiàn)文件:
drivers/gpio/gpiolib.c ## 新版API豁护,基于描述符(descriptor-based)
drivers/gpio/gpiolib-legacy.c ## 舊API
include/linux/gpio.h
GPIO
子系統(tǒng)有兩套API
:
1、基于描述符(descriptor-based)
前綴為:gpiod_
欲间。
參考:Documentation/gpio/consumer.txt
2楚里、老版本接口(legacy)
前綴為:gpio_
。
參考:Documentation/gpio/gpio-legacy.txt
3猎贴、常用API
功能 | 新版本接口 | 老版本接口 |
---|---|---|
獲取GPIO | gpiod_get() | gpio_request() |
釋放GPIO | gpiod_put() | gpio_free() |
GPIO方向 | 設(shè)置為輸入:gpiod_direction_input()設(shè)置為輸出:gpiod_direction_output()獲取方向:gpiod_get_direction() | 設(shè)置為輸入:gpio_direction_input()設(shè)置為輸出:gpio_direction_output() |
GPIO值 | 獲取輸入值:gpiod_get_value()設(shè)置輸出值:gpiod_set_value() | 獲取輸入值:gpio_get_value()設(shè)置輸出值:gpio_set_value() |
GPIO
還有很多接口班缎,就不一一列舉了蝴光。
RK3399 GPIO
控制器驅(qū)動(dòng)實(shí)現(xiàn)文件:drivers/pinctrl/pinctrl-rockchip.c
,涉及主要函數(shù):
static const struct gpio_chip rockchip_gpiolib_chip = {
.request = gpiochip_generic_request,
.free = gpiochip_generic_free,
.set = rockchip_gpio_set,
.get = rockchip_gpio_get,
.get_direction = rockchip_gpio_get_direction,
.direction_input = rockchip_gpio_direction_input,
.direction_output = rockchip_gpio_direction_output,
.to_irq = rockchip_gpio_to_irq,
.owner = THIS_MODULE,
};
所有GPIO
子系統(tǒng)的API
最終都會(huì)調(diào)到SOC
的GPIO
控制器驅(qū)動(dòng)函數(shù)达址。
四蔑祟、GPIO調(diào)試
ROCKPi 4A
單板有個(gè)40個(gè)引腳的擴(kuò)展口,引用radxa
圖片沉唠,見下圖疆虚。
以
GPIO2_A7
為例,介紹GPIO
的一般調(diào)試方法满葛。
1径簿、進(jìn)入測試目錄
root@linaro-alip:/sys/class/gpio# ls
export gpiochip0 gpiochip128 gpiochip32 gpiochip64 gpiochip96 unexport
2、導(dǎo)出GPIO
在使用GPIO2_A7
前嘀韧,需要導(dǎo)出該引腳篇亭。方法:配置export
后,會(huì)出現(xiàn)gpio71
節(jié)點(diǎn)锄贷。
root@linaro-alip:/sys/class/gpio# echo 71 > export
root@linaro-alip:/sys/class/gpio# ls
export gpiochip0 gpiochip32 gpiochip96
gpio71 gpiochip128 gpiochip64 unexport
測試時(shí)译蒂,注意不要使用在程序中已經(jīng)申請過或配置為其它功能的GPIO
引腳。
3肃叶、配置GPIO方向
設(shè)置GPIO2_A7
的輸入/輸出方向。
root@linaro-alip:/sys/class/gpio# cd gpio71/
root@linaro-alip:/sys/class/gpio/gpio71# ls
active_low device direction edge power subsystem uevent value
root@linaro-alip:/sys/class/gpio/gpio71# cat direction
in
root@linaro-alip:/sys/class/gpio/gpio71# echo out > direction
root@linaro-alip:/sys/class/gpio/gpio71# cat direction
out
in
:表示輸入十嘿。
out
:表示輸出因惭。
active_low
:用于中斷配置中高電平或低電平有效。
edge
:用于中斷配置中上升沿或下降沿有效绩衷。
4蹦魔、配置GPIO輸出值
在GPIO
為輸入時(shí),通過value
查詢GPIO
的輸入電平(高或低電平)咳燕。
在GPIO
為輸出時(shí)勿决,通過value
配置GPIO
的輸出電平(高或低電平)。
root@linaro-alip:/sys/class/gpio/gpio71# cat value
0
root@linaro-alip:/sys/class/gpio/gpio71# echo 1 > value
root@linaro-alip:/sys/class/gpio/gpio71# cat value
1
root@linaro-alip:/sys/class/gpio/gpio71# echo 0 > value
root@linaro-alip:/sys/class/gpio/gpio71# cat value
0
5招盲、查看GPIO
查看已經(jīng)導(dǎo)出的GPIO71
低缩。
root@linaro-alip:/sys/kernel/debug# cat gpio
GPIOs 0-31, platform/pinctrl, gpio0:
gpio-4 ( |bt_default_wake_host) out hi
gpio-9 ( |bt_default_reset ) out hi
gpio-10 ( |reset ) out lo
GPIOs 32-63, platform/pinctrl, gpio1:
gpio-35 ( |vcc5v0_otg ) out hi
gpio-46 ( |vsel ) out lo
gpio-49 ( |vsel ) out lo
GPIOs 64-95, platform/pinctrl, gpio2:
gpio-71 ( |sysfs ) in hi ## GPIO71
gpio-83 ( |bt_default_rts ) out lo
gpio-90 ( |vcc3v3_pcie ) out hi
gpio-91 ( |bt_default_wake ) out hi
GPIOs 96-127, platform/pinctrl, gpio3:
gpio-111 ( |mdio-reset ) out hi
gpio-124 ( |? ) out lo
gpio-125 ( |? ) out lo
GPIOs 128-159, platform/pinctrl, gpio4:
gpio-153 ( |vcc5v0_host ) out hi
6、取消導(dǎo)出
使用完GPIO2_A7
后曹货,需要進(jìn)行釋放咆繁。方法:配置unexport
后,gpio71
節(jié)點(diǎn)會(huì)消失顶籽。
root@linaro-alip:/sys/class/gpio/gpio71# cd ..
root@linaro-alip:/sys/class/gpio# ls
export gpiochip0 gpiochip32 gpiochip96
gpio71 gpiochip128 gpiochip64 unexport
root@linaro-alip:/sys/class/gpio# echo 71 > unexport
root@linaro-alip:/sys/class/gpio# ls
export gpiochip0 gpiochip128 gpiochip32 gpiochip64 gpiochip96 unexport
注:轉(zhuǎn)載請標(biāo)注出處玩般。