linux设备树-pinctrl子系统

----------------------------------------------------------------------------------------------------------------------------
内核版本:linux 5.2.8根文件系统: 1.25.0u-boot:2016.05----------------------------------------------------------------------------------------------------------------------------
一、IO概述 1.1 硬件功能分类
ARM based SoC的中总有一个章节叫做GPIO (或者I/O ports)的章节来描述如何配置、使用SoC的引脚 。虽然GPIO 的硬件描述中充满了大量的寄存器的描述 , 但是这些寄存器的功能大概分成下面三个类别:
(1) 有些硬件逻辑是和IO port本身的功能设定相关的 , 我们称这个HW block为pin。软件通过设定pin 这个硬件单元的寄存器可以实现:
(2)如果一组GPIO被配置成SPI , 那么这些pin脚被连接到了SPI  , 如果配置成GPIO , 那么控制这些引脚的就是GPIO。通过访问GPIO 的寄存器 , 软件可以:
(3)如果一组GPIO有中断控制器的功能 , 虽然控制寄存器在中的I/O ports章节描述 , 但是实际上这些GPIO已经被组织成了一个 的硬件block , 它更像是一个GPIO类型的中断控制器 , 通过访问GPIO中断控制寄存器 , 软件可以:
1.2 抽象硬件差异
传统的GPIO 是负责上面三大类的控制 , 而新的linux 中的GPIO 则用三个软件模块来对应上面三类硬件功能:
总体来说 , pin 和GPIO 都是数字输入/输出控制的IP核 , 但其控制的对象不同 , 前者控制的引脚可用于GPIO功能、I2C功能等;后者只是把引脚配置为输入、输出等简单的功能 。两者的关系是先用把引脚配置为GPIO , 再用GPIO 把引脚配置为输入或输出 。
1.3 外部中断 1.3.1 外部中断资源
一共有24个外部中断 , 分别对应24个GPIO引脚:
1.3.2 外部中断初始化
以GPF7为例 , 如果将该引脚配置为上升沿外部中断:
二、子系统
在许多SoC内部都包含有pin  , 通过pin 的寄存器 , 我们可以配置一个或者一组引脚的功能和特性 。
各个厂商SoC的pin脚在使用中 , 都有许多共同的特性 , 要么配置 , 要么复用pin脚 。所以内核提供了一套代码来管理这些pin , 这就是。主要实现的功能:
2.1 重要概念
涉及到了两个对象:
2.2 设备节点
以arch/arm/boot/dts/-.dtsi为例 , 描述了 pin 的dts结构 , 内容如下:
pinctrl_0: pinctrl@56000000 {compatible = "samsung,s3c2440-pinctrl";reg = <0x56000000 0x1000>;wakeup-interrupt-controller {compatible = "samsung,s3c2410-wakeup-eint";interrupts = <0 0 0 3>,<0 0 1 3>,<0 0 2 3>,<0 0 3 3>,<0 0 4 4>,<0 0 5 4>;};/** Pin banks*/gpa: gpa {gpio-controller;#gpio-cells = <2>;};......gpj: gpj {gpio-controller;#gpio-cells = <2>;};/** Pin groups*/uart0_data: uart0-data {samsung,pins = "gph-2", "gph-3";samsung,pin-function = ;};.....};
如上所示:@内部定义了一些自己的属性 , 比如、reg , 此外还定义了大量的子节点 , 这些子节点我们称之为引脚配置(pin ) 。
定义pin 的目的是为了让 引用 。例如串口设备:
在pinnode中定义的pin 可以分为两大类:pin bank和pin group 。
2.2.1 bank
所谓的pin bank , 个人理解就是一组GPIO端口 , 这一组GPIO端口同属于一个GPIO控制器 。以为例 , 分为了9 个GPIO控制器:
GPIO控制器
GPIO端口名称
GPIO端口数量
【linux设备树-pinctrl子系统】GPIOA