7.10.2.GPIO子系統概念
也來問4個問題:
1什麼是GPIO子系統?配置GPIO引腳電氣特性的系統;
2如何表現?找到gpio.txt看下,
1) gpios property
需要用"[<name>-]gpios"命名,
gpio1: gpio1 { //名字
gpio-controller
#gpio-cells = <2>;
};
data-gpios = <&gpio1 12 0>,
<&gpio1 13 0>,
通常定義GPIO的標誌位都是用include/dt-bindings/gpio/gpio.h中的宏來定義,看下這個文件:
/*
* This header provides constants for most GPIO bindings.
*
* Most GPIO bindings include a flags cell as part of the GPIO specifier.
* In most cases, the format of the flags cell uses the standard values
* defined in this header.
*/
#ifndef _DT_BINDINGS_GPIO_GPIO_H
#define _DT_BINDINGS_GPIO_GPIO_H
/* Bit 0 express polarity */
#define GPIO_ACTIVE_HIGH 0 //電平?
#define GPIO_ACTIVE_LOW 1
/* Bit 1 express single-endedness */
#define GPIO_PUSH_PULL 0 //上拉?
#define GPIO_SINGLE_ENDED 2
/*
* Open Drain/Collector is the combination of single-ended active low,
* Open Source/Emitter is the combination of single-ended active high.
*/
#define GPIO_OPEN_DRAIN (GPIO_SINGLE_ENDED | GPIO_ACTIVE_LOW) //開漏
#define GPIO_OPEN_SOURCE (GPIO_SINGLE_ENDED | GPIO_ACTIVE_HIGH)
#endif
Example of a node using GPIOs:
node {
enable-gpios = <&qe_pio_e 18 GPIO_ACTIVE_HIGH>; //18是引腳數
};
GPIO_ACTIVE_HIGH is 0, so in this example gpio-specifier is "18 0" and encodes
GPIO pin number, and GPIO flags as accepted by the "qe_pio_e" gpio-controller.
- gpio-controller nodes
Example:
gpio-controller@00000000 {
compatible = "foo";
reg = <0x00000000 0x1000>;
gpio-controller; //必須有
#gpio-cells = <2>; //必須有
ngpios = <18>;
gpio-line-names = "MMC-CD", "MMC-WP", "VDD eth", "RST eth", "LED R",
"LED G", "LED B", "Col A", "Col B", "Col C", "Col D",
"Row A", "Row B", "Row C", "Row D", "NMI button",
"poweroff", "reset";
}
2.1) gpio- and pin-controller interaction
Gpio-和pin controller的關聯:Some or all of the GPIOs provided by a GPIO controller may be routed to pins on the package via a pin controller. This allows muxing those pins between GPIO and other functions.
基本概念已經理清楚了,小結:
3如何使用?分爲設備樹中使用和代碼中使用;
3.1設備樹中使用
//client device
leds {
compatible = "gpio-leds";
pinctrl-names = "default"; //1種狀態,default
pinctrl-0 = <&pinctrl_leds>; //引腳defaul狀態在pinctrl_leds定義
};
************************************************************************
//pin controller
&iomuxc_snvs {
pinctrl-names = "default_snvs";
imx6ul-evk {
pinctrl_leds: ledgrp {
fsl,pins = <
MX6ULL_PAD_SNVS_TAMPER3__GPIO5_IO03 0x000110A0
>; //0x000110A0代表什麼意思???
};
};
};
搜索參考手冊並沒有找到這個變量,MX6ULL_PAD_SNVS_TAMPER3__GPIO5_IO03,google一下找到https://github.com/Xilinx/linux-xlnx/blob/master/arch/arm/boot/dts/imx6ull-pinfunc-snvs.h提到了這個變量的定義在linux-xlnx/arch/arm/boot/dts/imx6ull-pinfunc-snvs.h中,好吧和.dts在一個文件夾中,看下它的具體內容:
#ifndef __DTS_IMX6ULL_PINFUNC_SNVS_H
#define __DTS_IMX6ULL_PINFUNC_SNVS_H
/*
* The pin function ID is a tuple of
* <mux_reg conf_reg input_reg mux_mode input_val>
*/
#define MX6ULL_PAD_SNVS_TAMPER3__GPIO5_IO03 0x0014 0x0058 0x0000 0x5 0x0//後面這一串是什麼意思???
#endif /* __DTS_IMX6ULL_PINFUNC_SNVS_H */
根據ZDYZ的手冊分析下:PAD_SNVS_TAMPER3的複用功能就是GPIO5_IO03,後面5個配置值分別對應<mux_reg conf_reg input_reg mux_mode input_val>,
0x0014:mux_reg寄存器偏移地址,設備樹中的 iomuxc_snvs節點就是 iomuxc_snvs外設對應的節點,根 據 其 reg 屬 性 可 知 iomuxc_snvs外 設 寄 存 器 起 始 地 址 爲 0x02290000。因此0x02290000+0x0014 = 0x02290014,即IOMUXC_SNVS_SW_MUX_CTL_PAD_SNVS_TAMPER3的地址。
iomuxc_snvs: iomuxc-snvs@02290000 {
compatible = "fsl,imx6ull-iomuxc-snvs";
reg = <0x02290000 0x10000>;
};
0x0058:conf_reg 寄存器偏移地址,和 mux_reg 一樣, 0x02290000+0x0058=0x02290058,即IOMUXC_SNVS_SW_PAD_CTL_PAD_SNVS_TAMPER3的地址。
0x0000:input_reg 寄存器偏移地址,有些外設有 input_reg 寄存器,有 input_reg 寄存器的外設需要配置 input_reg 寄存器。沒有的話就不需要設置。
0x5:mux_reg 寄 存 器 值 , 在 這 裏 就 相 當 於 設 置IOMUXC_SNVS_SW_MUX_CTL_PAD_SNVS_TAMPER3 寄存器爲 0x5,也即是設置 PAD_SNVS_TAMPER3這個 PIN 複用爲 GPIO5_IO03。
0x0:input_reg 寄存器值,在這裏無效。
這就是對宏分析,發現並沒有conf_reg寄存器的值, config_reg 寄存器是設置一個PIN 的電氣特性的,這麼重要的寄存器怎麼沒有值呢?回到示例代碼中, 0x000110A0 就是 conf_reg 寄存器值!此值由用戶自行設置,通過此值來設置一個 IO 的上 /下拉、驅動能力和速度等。在這裏就相當於設置寄存器IOMUXC_SNVS_SW_PAD_CTL_PAD_SNVS_TAMPER3的值爲 0x000110A0 ,即0b0001,0001,0000,1010,0000,具體代表什麼意思看下參考手冊。
3.2驅動代碼中使用
也就是 GPIO 子系統的接口函數是什麼?GPIO 子系統有兩套接口: 基於描述符的(descriptor-based)、老的(legacy)。前者的函數都有前綴“gpiod_”,它使用 gpio_desc 結構體來表示一個引腳;後者的函數都有前綴“gpio_”,它使用一個整數來表示一個引腳。要操作一個引腳,首先要 get 引腳,然後設置方向,讀值、寫值。
“在 GPIO 子系統中,每註冊一個 GPIO Controller 時會確定它的“base number”,那麼這個控制器裏的第 n 號引腳的號碼就是: base number + n。但是如果硬件有變化、設備樹有變化,這個 base number 並不能保證是固定的,應該查看 sysfs 來確定 base number。”
3.3sysfs 中的訪問方法
這一塊內容再補充。