不能混用,他们对应不同的驱动。
在设备树中:
&iomuxc中存放的是MX6UL_xxxx相关。
&iomuxc_snvs中存放的是MX6ULL_xxxx相关。
eg:MX6UL_PAD_SNVS_TAMPER3__GPIO5_IO03 0x10B0 /* LED0 */
MX6ULL_PAD_SNVS_TAMPER3__GPIO5_IO03 0x000110A0 /* LED0 */
我试了下,在设备树中,这个二个都可以使用。
IO 复用功能选择器(IOMUXC)的寄存器非常多,主要可以分为四组:
① IOMUXC_GPR 寄存器组,用于通用控制设置。
② IOMUXC_SNVS 组,主要用于GPIO5 的控制。
③ IOMUXC_SNVS_GPR 寄存器组,暂时没用到。
④ IOMUXC 组,用于指定IO 的复用功能选择和IO 属性设置。
在IO 设置的时候,实际上我们只用到了②和④,①和③没用到。
任意一个IO,都是由2 个寄存器(SW_MUX_CTL_PAD/ SW_PAD_CTL_PAD)控制的。
无论是哪种芯片,都有类似下图的结构:
要想让pinA、B用于GPIO,需要设置IOMUX让它们连接到GPIO模块;
要想让pinA、B用于I2C,需要设置IOMUX让它们连接到I2C模块。
所以GPIO、I2C应该是并列的关系,它们能够使用之前,需要设置IOMUX。有时候并不仅仅是设置IOMUX,还要配置引脚,比如上拉、下拉、开漏等等。
现在的芯片动辄几百个引脚,在使用到GPIO功能时,让你一个引脚一个引脚去找对应的寄存器,这要疯掉。术业有专攻,这些累活就让芯片厂家做吧──他们是BSP工程师。
BSP工程师把引脚的复用、配置抽出来,做成Pinctrl子系统,给GPIO、I2C等模块使用。
要操作GPIO引脚,先把所用引脚配置为GPIO功能,这通过Pinctrl子系统来实现。
然后就可以根据设置引脚方向(输入还是输出)、读值──获得电平状态,写值──输出高低电平。
以前我们通过寄存器来操作GPIO引脚,即使LED驱动程序,对于不同的板子它的代码也完全不同。
当BSP工程师实现了GPIO子系统后,我们就可以:
a. 在设备树里指定GPIO引脚
b. 在驱动代码中:
使用GPIO子系统的标准函数获得GPIO、设置GPIO方向、读取/设置GPIO值。
这样的驱动代码,将是单板无关的。