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> 来提高电流强度,部分外围设备(尤其是摄像头和触摸屏)的功能脚可能会引至板子外部,导致电流强度不够,这时候提高电流强度有奇效。典型的特征就是,该设备时好时坏,有时候能认到,有时候又不工作,大概率是电流强度不够导致的。