add 07_GPIO/05_GPIO子系统层次与数据结构
101
IMX6ULL/doc_pic/07_GPIO/05_GPIO子系统层次与数据结构.md
Normal file
@@ -0,0 +1,101 @@
|
||||
## GPIO子系统层次与数据结构
|
||||
|
||||
参考资料:
|
||||
|
||||
* Linux 5.x内核文档
|
||||
* Linux-5.4\Documentation\driver-api
|
||||
* Linux-5.4\Documentation\devicetree\bindings\gpio\gpio.txt
|
||||
* Linux-5.4\drivers\gpio\gpio-74x164.c
|
||||
* Linux 4.x内核文档
|
||||
* Linux-4.9.88\Documentation\gpio
|
||||
* Linux-4.9.88\Documentation\devicetree\bindings\gpio\gpio.txt
|
||||
* Linux-4.9.88\drivers\gpio\gpio-74x164.c
|
||||
|
||||
### 1. GPIO子系统的层次
|
||||
|
||||
#### 1.1 层次
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
#### 1.2 GPIOLIB向上提供的接口
|
||||
|
||||
| descriptor-based | legacy | 说明 |
|
||||
| ---------------------- | --------------------- | ---- |
|
||||
| 获得GPIO | | |
|
||||
| gpiod_get | gpio_request | |
|
||||
| gpiod_get_index | | |
|
||||
| gpiod_get_array | gpio_request_array | |
|
||||
| devm_gpiod_get | | |
|
||||
| devm_gpiod_get_index | | |
|
||||
| devm_gpiod_get_array | | |
|
||||
| 设置方向 | | |
|
||||
| gpiod_direction_input | gpio_direction_input | |
|
||||
| gpiod_direction_output | gpio_direction_output | |
|
||||
| 读值、写值 | | |
|
||||
| gpiod_get_value | gpio_get_value | |
|
||||
| gpiod_set_value | gpio_set_value | |
|
||||
| 释放GPIO | | |
|
||||
| gpio_free | gpio_free | |
|
||||
| gpiod_put | gpio_free_array | |
|
||||
| gpiod_put_array | | |
|
||||
| devm_gpiod_put | | |
|
||||
| devm_gpiod_put_array | | |
|
||||
|
||||
#### 1.3 GPIOLIB向下提供的接口
|
||||
|
||||

|
||||
|
||||
### 2. 重要的3个核心数据结构
|
||||
|
||||
记住GPIO Controller的要素,这有助于理解它的驱动程序:
|
||||
|
||||
* 一个GPIO Controller里有多少个引脚?有哪些引脚?
|
||||
* 需要提供函数,设置引脚方向、读取/设置数值
|
||||
* 需要提供函数,把引脚转换为中断
|
||||
|
||||
以Linux面向对象编程的思想,一个GPIO Controller必定会使用一个结构体来表示,这个结构体必定含有这些信息:
|
||||
|
||||
* GPIO引脚信息
|
||||
* 控制引脚的函数
|
||||
* 中断相关的函数
|
||||
|
||||
#### 2.1 gpio_device
|
||||
|
||||
每个GPIO Controller用一个gpio_device来表示:
|
||||
|
||||
* 里面每一个gpio引脚用一个gpio_desc来表示
|
||||
* gpio引脚的函数(引脚控制、中断相关),都放在gpio_chip里
|
||||
|
||||

|
||||
|
||||
#### 2.2 gpio_chip
|
||||
|
||||
我们并不需要自己穿件gpio_device,编写驱动时要创建的是gpio_chip,里面提供了:
|
||||
|
||||
* 控制引脚的函数
|
||||
* 中断相关的函数
|
||||
* 引脚信息:支持多少个引脚?各个引脚的名字?
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
#### 2.3 gpio_desc
|
||||
|
||||
我们去使用GPIO子系统时,首先是获得某个引脚对应的gpio_desc。
|
||||
|
||||
gpio_device表示一个GPIO Controller,里面支持多个GPIO。
|
||||
|
||||
在gpio_device中有一个gpio_desc数组,每一引脚有一项gpio_desc。
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
### 3. 怎么编写GPIO Controller驱动程序
|
||||
|
||||
分配、设置、注册gpioc_chip结构体,示例:`drivers\gpio\gpio-74x164.c`
|
||||
|
||||

|
||||
BIN
IMX6ULL/doc_pic/07_GPIO/05_GPIO子系统层次与数据结构.tif
Normal file
96
IMX6ULL/doc_pic/07_GPIO/06_IMX6ULL的GPIO驱动源码分析.md
Normal file
@@ -0,0 +1,96 @@
|
||||
## IMX6ULL的GPIO驱动源码分析
|
||||
|
||||
参考资料:
|
||||
|
||||
* Linux 4.x内核文档
|
||||
* Linux-4.9.88\Documentation\gpio
|
||||
* Linux-4.9.88\Documentation\devicetree\bindings\gpio\gpio.txt
|
||||
* Linux-4.9.88\drivers\gpio\gpio-mxc.c
|
||||
* Linux-4.9.88\arch\arm\boot\dts\imx6ull.dtsi
|
||||
|
||||
### 1. 设备树
|
||||
|
||||
Linux-4.9.88\arch\arm\boot\dts\imx6ull.dtsi:
|
||||
|
||||
```shell
|
||||
aliases {
|
||||
can0 = &flexcan1;
|
||||
can1 = &flexcan2;
|
||||
ethernet0 = &fec1;
|
||||
ethernet1 = &fec2;
|
||||
gpio0 = &gpio1;
|
||||
};
|
||||
|
||||
gpio1: gpio@0209c000 {
|
||||
compatible = "fsl,imx6ul-gpio", "fsl,imx35-gpio";
|
||||
reg = <0x0209c000 0x4000>;
|
||||
interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
|
||||
GPIO控制器的设备树中,有两项是必须的:
|
||||
|
||||
* gpio-controller : 表明这是一个GPIO控制器
|
||||
* gpio-cells : 指定使用多少个cell(就是整数)来描述一个引脚
|
||||
|
||||
|
||||
|
||||
当解析设备节点中的GPIO信息时,需要用到上面的属性。
|
||||
|
||||
比如下面的`led-gpios`,在`#gpio-cells = <2>`的情况下,它表示的引脚数量是1。
|
||||
|
||||
```shell
|
||||
myled {
|
||||
compatible = "100ask,leddrv";
|
||||
led-gpios = <&gpio1 10 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### 2. 驱动程序
|
||||
|
||||
Linux-4.9.88\drivers\gpio\gpio-mxc.c
|
||||
|
||||
#### 2.1 分配gpio_chip
|
||||
|
||||
```c
|
||||
static int mxc_gpio_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
struct mxc_gpio_port *port;
|
||||
struct resource *iores;
|
||||
int irq_base = 0;
|
||||
int err;
|
||||
|
||||
mxc_gpio_get_hw(pdev);
|
||||
|
||||
port = devm_kzalloc(&pdev->dev, sizeof(*port), GFP_KERNEL);
|
||||
if (!port)
|
||||
return -ENOMEM;
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
#### 2.2 设置gpio_chip
|
||||
|
||||

|
||||
|
||||
#### 2.3 注册gpio_chip
|
||||
|
||||
```c
|
||||
err = devm_gpiochip_add_data(&pdev->dev, &port->gc, port);
|
||||
if (err)
|
||||
goto out_bgio;
|
||||
```
|
||||
|
||||
BIN
IMX6ULL/doc_pic/07_GPIO/pic/07_GPIO/03_gpio_system_level.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
IMX6ULL/doc_pic/07_GPIO/pic/07_GPIO/04_gpio_device.png
Normal file
|
After Width: | Height: | Size: 173 KiB |
BIN
IMX6ULL/doc_pic/07_GPIO/pic/07_GPIO/05_gpio_chip.png
Normal file
|
After Width: | Height: | Size: 75 KiB |
|
After Width: | Height: | Size: 64 KiB |
BIN
IMX6ULL/doc_pic/07_GPIO/pic/07_GPIO/07_gpiochip_add_data.png
Normal file
|
After Width: | Height: | Size: 33 KiB |
BIN
IMX6ULL/doc_pic/07_GPIO/pic/07_GPIO/08_gpio_desc.png
Normal file
|
After Width: | Height: | Size: 68 KiB |
BIN
IMX6ULL/doc_pic/07_GPIO/pic/07_GPIO/09_imx6ull_gpio_chip_set.png
Normal file
|
After Width: | Height: | Size: 57 KiB |
@@ -229,6 +229,12 @@ git clone https://e.coding.net/weidongshan/linux/doc_and_source_for_drivers.git
|
||||
04_在100ASK_STM32MP157上机实验
|
||||
```
|
||||
|
||||
* 2021.05.27 发布"GPIO子系统":
|
||||
|
||||
```shell
|
||||
05_GPIO子系统层次与数据结构
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
101
STM32MP157/doc_pic/07_GPIO/05_GPIO子系统层次与数据结构.md
Normal file
@@ -0,0 +1,101 @@
|
||||
## GPIO子系统层次与数据结构
|
||||
|
||||
参考资料:
|
||||
|
||||
* Linux 5.x内核文档
|
||||
* Linux-5.4\Documentation\driver-api
|
||||
* Linux-5.4\Documentation\devicetree\bindings\gpio\gpio.txt
|
||||
* Linux-5.4\drivers\gpio\gpio-74x164.c
|
||||
* Linux 4.x内核文档
|
||||
* Linux-4.9.88\Documentation\gpio
|
||||
* Linux-4.9.88\Documentation\devicetree\bindings\gpio\gpio.txt
|
||||
* Linux-4.9.88\drivers\gpio\gpio-74x164.c
|
||||
|
||||
### 1. GPIO子系统的层次
|
||||
|
||||
#### 1.1 层次
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
#### 1.2 GPIOLIB向上提供的接口
|
||||
|
||||
| descriptor-based | legacy | 说明 |
|
||||
| ---------------------- | --------------------- | ---- |
|
||||
| 获得GPIO | | |
|
||||
| gpiod_get | gpio_request | |
|
||||
| gpiod_get_index | | |
|
||||
| gpiod_get_array | gpio_request_array | |
|
||||
| devm_gpiod_get | | |
|
||||
| devm_gpiod_get_index | | |
|
||||
| devm_gpiod_get_array | | |
|
||||
| 设置方向 | | |
|
||||
| gpiod_direction_input | gpio_direction_input | |
|
||||
| gpiod_direction_output | gpio_direction_output | |
|
||||
| 读值、写值 | | |
|
||||
| gpiod_get_value | gpio_get_value | |
|
||||
| gpiod_set_value | gpio_set_value | |
|
||||
| 释放GPIO | | |
|
||||
| gpio_free | gpio_free | |
|
||||
| gpiod_put | gpio_free_array | |
|
||||
| gpiod_put_array | | |
|
||||
| devm_gpiod_put | | |
|
||||
| devm_gpiod_put_array | | |
|
||||
|
||||
#### 1.3 GPIOLIB向下提供的接口
|
||||
|
||||

|
||||
|
||||
### 2. 重要的3个核心数据结构
|
||||
|
||||
记住GPIO Controller的要素,这有助于理解它的驱动程序:
|
||||
|
||||
* 一个GPIO Controller里有多少个引脚?有哪些引脚?
|
||||
* 需要提供函数,设置引脚方向、读取/设置数值
|
||||
* 需要提供函数,把引脚转换为中断
|
||||
|
||||
以Linux面向对象编程的思想,一个GPIO Controller必定会使用一个结构体来表示,这个结构体必定含有这些信息:
|
||||
|
||||
* GPIO引脚信息
|
||||
* 控制引脚的函数
|
||||
* 中断相关的函数
|
||||
|
||||
#### 2.1 gpio_device
|
||||
|
||||
每个GPIO Controller用一个gpio_device来表示:
|
||||
|
||||
* 里面每一个gpio引脚用一个gpio_desc来表示
|
||||
* gpio引脚的函数(引脚控制、中断相关),都放在gpio_chip里
|
||||
|
||||

|
||||
|
||||
#### 2.2 gpio_chip
|
||||
|
||||
我们并不需要自己穿件gpio_device,编写驱动时要创建的是gpio_chip,里面提供了:
|
||||
|
||||
* 控制引脚的函数
|
||||
* 中断相关的函数
|
||||
* 引脚信息:支持多少个引脚?各个引脚的名字?
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
#### 2.3 gpio_desc
|
||||
|
||||
我们去使用GPIO子系统时,首先是获得某个引脚对应的gpio_desc。
|
||||
|
||||
gpio_device表示一个GPIO Controller,里面支持多个GPIO。
|
||||
|
||||
在gpio_device中有一个gpio_desc数组,每一引脚有一项gpio_desc。
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
### 3. 怎么编写GPIO Controller驱动程序
|
||||
|
||||
分配、设置、注册gpioc_chip结构体,示例:`drivers\gpio\gpio-74x164.c`
|
||||
|
||||

|
||||
BIN
STM32MP157/doc_pic/07_GPIO/05_GPIO子系统层次与数据结构.tif
Normal file
BIN
STM32MP157/doc_pic/07_GPIO/pic/07_GPIO/03_gpio_system_level.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
STM32MP157/doc_pic/07_GPIO/pic/07_GPIO/04_gpio_device.png
Normal file
|
After Width: | Height: | Size: 173 KiB |
BIN
STM32MP157/doc_pic/07_GPIO/pic/07_GPIO/05_gpio_chip.png
Normal file
|
After Width: | Height: | Size: 75 KiB |
|
After Width: | Height: | Size: 64 KiB |
BIN
STM32MP157/doc_pic/07_GPIO/pic/07_GPIO/07_gpiochip_add_data.png
Normal file
|
After Width: | Height: | Size: 33 KiB |
BIN
STM32MP157/doc_pic/07_GPIO/pic/07_GPIO/08_gpio_desc.png
Normal file
|
After Width: | Height: | Size: 68 KiB |