一、 Pinctrl子系统
1、基本架构
现在的芯片动辄几百个引脚,在使用到GPIO功能时,让你一个引脚一个引脚去找对应的寄存器,说实话很烦。所以,要把引脚的复用、配置抽出来,做成Pinctrl子系统,给GPIO、UART等模块使用。
如上图,GPIO1_A6的功能引脚不单单只可以使用在GPIO上,也可以作为多个外设的功能引脚,如I2S引脚,串口UART的接收发送引脚等
无论是哪种芯片,都有类似下图的结构:
要想让pinA、B用于GPIO,需要设置IOMUX让它们连接到GPIO模块; 要想让pinA、B用于UART,需要设置IOMUX让它们连接到UART模块。
2、Pinctrl
Pinctrl主要涉及2个对象:pin controller、client device。
怎么理解?
比如默认状态下,UART设备是工作的,那么所用的引脚就要复用为UART功能。 在休眠状态下,为了省电,可以把这些引脚复用为GPIO功能;或者直接把它们配置输出高电平。
上图中,pinctrl-names里定义了2种状态:default、sleep。 第0种状态用到的引脚在pinctrl-0中定义,它是uart0_pins_a,位于pincontroller节点中。 第1种状态用到的引脚在pinctrl-1中定义,它是uart0_pins_b,位于pincontroller节点中。 当这个设备处于default状态时,pinctrl子系统会自动根据上述信息把所用引脚复用为uart0功能。 当这这个设备处于sleep状态时,pinctrl子系统会自动根据上述信息把所用引脚配置为gpio_in。
二、GPIO子系统
1、引入
在没有使用GPIO子系统之前,如果我们想点亮一个LED,首先要得到led相关的配置寄存器,再手动地读、改、写这些配置寄存器实现 控制LED的目的。有了GPIO子系统之后这部分工作由GPIO子系统帮我们完成,我们只需要调用GPIO子系统提供的API函数即可完成GPIO的 控制动作。
要操作GPIO引脚,先把所用引脚配置为GPIO功能,这通过Pinctrl子系统来实现。
2、在设备树中指定引脚
几乎所有ARM芯片中,GPIO都分为几组,每组中有若干个引脚。所以在使用GPIO子系统之前,就要先确定:它是哪组的?组里的哪一个?
我以全志平台为例,给大家提一下,在全志的T527平台,有两组GPIO控制器,一组为GPIO,另外一组为S_GPIO。
所以我们在添加设备树时,要先确定是属于pio的还是r_pio,再进行添加
如上图,iqr-gpios和reset-gpios就属于pio控制器的的PI组的13 、14号引脚
如上图,flash0_en就属于r_pio控制器的的PL组的11号引脚