RK3568系列6——Pinctrl与GPIO的理解

  Pinctrl的配置是几乎所有外围组件的关键部分,刚开始始终分不清Pinctrl与GPIO的关系,云里雾里的,在这里就用白话文来概括一下。

  RK3568的每一个脚都有预定义好的几种功能,可以使用,这个定义跟芯片硬件有关,是无法修改的,你可以选择其中的某一种功能使用,或者将其作为单纯的GPIO功能脚。以RK3568的GPIO2 B1为例,他可以配置成SDMMC1_PWREN/I2C4_SDA_m1/UART8_RTSn_M0/CAN2_RX_m14种预设的功能,若你不需要SDMMC1;且不需要I2C4,或者I2C4配置到M0通道;且不需要UART8,或者UART8配置到M1通道;且不需要CAN2,或者CAN2配置到M0通道;那么这个功能脚就可以用于GPIO脚使用。

  在代码里就是这样:其中第1个参数2即代表第2个GPIO芯片,第2个参数RK_PB1即代表B1脚,第3个参数RK_FUNC_GPIO表明该脚作为GPIO脚使用,第4个参数&pcfg_pull_none表明默认状态下该脚应该在芯片内部上拉还是下拉:

1
2
3
4
5
6
7
&pinctrl {
test {
test_rst: test-rst {
rockchip,pins = <2 RK_PB1 RK_FUNC_GPIO &pcfg_pull_none>;
};
};
};

如何使用声明并使用GPIO脚

  关键在于DTS中的pinctrl-namespinctrl-0,若pinctrl-names的名字被设置为default那么该设备的驱动加载后,就会将功能脚按照pinctrl-0的配置设置。这里的配置就是当ES8316的驱动加载后,将GPIO1 A2当功能设置为MCLK时钟信号输出,将GPIO1 B0作为GPIO脚使用,用于控制功放开启,且默认拉低(关闭功放)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
&pinctrl {
audio {
speaker_enable: speaker-enable {
rockchip,pins = <1 RK_PB0 RK_FUNC_GPIO &pcfg_pull_down>;
};
};
};
&i2c4 {
status = "okay";

es8316: es8316@10 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&i2s1m0_mclk &speaker_enable>;
};
};

GPIO脚默认应该拉高还是拉低

  应该按照外围设备厂商提供的技术文档设置,比如触屏GT9271就明确要求中断脚和重置脚都设置为悬空(&pcfg_pull_none)。如果技术文档没有提且没有找到实例配置,按我的习惯是:默认上下拉设置为有效电平相反的值,比如高电平是启用,那默认就配置成下拉(&pcfg_pull_down);如果低电平是重置外围设备,那默认就配置成上拉(&pcfg_pull_up);同理若高电平产生中断信号,那默认就配置成下拉。

  原理图上可以看到GPIO1_A1_uGPIO1_A2_d,其中ud是指引导阶段为进入系统时,该GPIO在内部是上拉的还是下拉的,在硬件设计阶段,软硬件工程师应该考虑外围设备需要的默认状态,接到相关的GPIO脚。

驱动电流强度

  可以通过配置rockchip,pins = <4 RK_PC0 1 &pcfg_pull_none_drv_level_10>来提高电流强度,部分外围设备(尤其是摄像头和触摸屏)的功能脚可能会引至板子外部,导致电流强度不够,这时候提高电流强度有奇效。典型的特征就是,该设备时好时坏,有时候能认到,有时候又不工作,大概率是电流强度不够导致的。