Pinctrl 调试指南
Pinctrl 使用
S100芯片中3个 sys 包含可软件控制的 pin 脚,根据用户的需要,可以对 pin 脚进行功能复用,属性设置和电压域设置。
S600芯片中3个 sys 包含可软件控制的 pin 脚,根据用户的需要,可以对 pin 脚进行功能复用,属性设置和电压域设置。
Pinmux 功能
soc 中的 pin 脚可以被设置为不同的功能,通过 pinmux 设置可以根据用户需要配置为相应的功能,每个引脚有四种复用功能可选。
Pinconf 功能
soc 中的 pin 脚可以被设置为不同的状态,共包含以下几种属性:
- 上下拉设置
- 驱动强度设置
- 电压模式设置
- 输入使能设置
- 施密特设置
- 压摆率选择
io-domain 功能
S100中共存在两种电压域,分别为1.8v 和3.3v,不同的 pin 脚需要工作在合适的电压域中。手册中将 pin 脚划分入 power group 中,在手册中可以看到每个 power group 控制着一组 pin 脚。
S600中共存在两种电压域,分别为1.8v 和3.3v,不同的 pin 脚需要工作在合适的电压域中。手册中将 pin 脚划分入 power group 中,在手册中可以看到每个 power group 控制着一组 pin 脚。
源码说明
pinctrl-hobot.c 文件中包含了 S100/S600共用的 pinctrl 主逻辑代码,向 pinctrl 子系统注册设备,并向下提供 SoC 数据的初始化入口。 pinctrl-hobot-s100.c 文件中包含 S100的 pin、pin group、function 定义和设备匹配信息。
/* 路径 */
hobot-drivers/pinctrl/pinctrl-hobot.c # pinctrl 公共主逻辑
hobot-drivers/pinctrl/pinctrl-hobot.h # pinctrl 公共头文件
hobot-drivers/pinctrl/pinctrl-hobot-s100.c # S100 驱动数据代码
hobot-drivers/kernel-dts/drobot-s100-pinctrl.dtsi # S100 pinctrl 设备树
pinctrl-hobot.c 文件中包含 S100/S600共用的 pinctrl 主逻辑代码。
pinctrl-hobot-s600.c 文件中包含 S600的 pin、pin group、function 定义和设备匹配信息(compatible = "drobot,s600-pinctrl")。
/* 路径 */
hobot-drivers/pinctrl/pinctrl-hobot.c # pinctrl 公共主逻辑
hobot-drivers/pinctrl/pinctrl-hobot.h # pinctrl 公共头文件
hobot-drivers/pinctrl/pinctrl-hobot-s600.c # S600 驱动数据代码
hobot-drivers/kernel-dts/drobot-s600-pinctrl.dtsi # S600 pinctrl 设备树
Pinctrl 驱动使用说明
Pinmux 和 pinconf 的设置
pinmux 和 pinconf 一般是在设备 dts 里配置,具体如下:
&pinctrl_peri {
pinctrl_test_default: pinctrl_test_default {
/* pinmux 的设置, 将peri_i2c5_scl和peri_i2c5_sda两个引脚复用为peri_i2c5的功能*/
pinmux {
function = "peri_i2c5";
pins = "peri_i2c5_scl", "peri_i2c5_sda";
};
/* pinconf 的设置, 为peri_i2c5_scl和peri_i2c5_sda两个引脚配置驱动电流,上下拉,输入使能,电压模式,压摆率,输入施密特等电器属性配置*/
pinconf {
/* 两个引脚 */
pins = "peri_i2c5_scl", "peri_i2c5_sda";
/* 驱动电流配置 */
drive-strength = <7>;
/* 配置为下拉 */
bias-pull-down;
/* 禁用输入 */
input-disable;
/* 禁用低电压模式 */
low-power-disable;
/* 压摆率设置为1 */
slew-rate = <1>;
/* 禁用输入施密特 */
input-schmitt-disable;
};
};
pinctrl_test_sleep: pinctrl_test_sleep {
pinmux {
function = "peri_i2c5";
pins = "peri_i2c5_scl", "peri_i2c5_sda";
};
pinconf {
pins = "peri_i2c5_scl", "peri_i2c5_sda";
drive-strength = <1>;
bias-pull-up;
input-enable;
low-power-enable;
slew-rate = <0>;
input-schmitt-enable;
};
};
};
Pinconf 支持设置的属性与设置树中对应关键字
| 关键字 | 属性 |
|---|---|
| bias-pull-up | 上拉设置 |
| bias-pull-down | 下拉设置 |
| bias-disable | 悬空设置 |
| drive-strength | 驱动强度 |
| low-power-disable | 高电压模式(3.3v) |
| low-power-enable | 低电压模式(1.8v) |
| input-disable | 输入不使能 |
| input-enable | 输入使能 |
| input-schmitt-enable | 施密特触发使能 |
| input-schmitt-disable | 施密特触发不使能 |
电压域设置
pin 脚 io-domain 的设置,会直接影响到模块功能的正常运行,甚至电压域的设置错误,造成元器件损坏,使电路板无法工作。
因此结合之前 bringup 支持经验,给出如下硬件电压值和软件 io-domain 设置一致性确认的实践经验:
- 首先各个模块的软硬件负责人进行拉通,确认模块中相关 pin 脚适用的 io-domain 范围,保证需求一致性,并且输出《pin 脚 io-domain 设置手册》中的参考值部分;(文档名仅供参考)
- 然后根据第一步中确认的信息,在设备树中进行相应的 io-domain 设置;
- 在完成第二步操作后,在样板上抓取所有 pin 脚的 io-domain 值,并且将获得的值填入《pin 脚 io-domain 设置手册》中的实际值部分,识别存在的 gap;
- 由于 S100中一个 group power 控制一组 pin 脚,一个 pin 脚的设置可能会影响同组中其它的 pin。因此拉通对齐会议,根据第三步中识别出来的 gap 信息,进行讨论和修复,直到 gap 消除。
Pinctrl 节点参考设置
S100 acore 中 pinctrl 设备树文件路径为:hobot-drivers/kernel-dts/drobot-s100-pinctrl.dtsi。
pinctrl 节点中将一组 pin 组合到一起,每个节点的配置包含多个子节点.
第一个子节点"pinmux"中包括引脚复用的信息,其中"function"表示设备复用引脚的功能,"pins"表示该复用功能下所需要的引脚。
第二个子节点"pinconf"包括了引脚的配置信息(使用默认值的情况下可以不加 pinconf 节点),"pins"表示需要进行配置的引脚,"pinconf_*"即为配置的内容,主要包括了驱动强度,上下拉,电压模式等。
&pinctrl_peri {
pinctrl_test_default: pinctrl_test_default {
pinmux {
function = "peri_i2c5";
pins = "peri_i2c5_scl", "peri_i2c5_sda";
};
pinconf {
pins = "peri_i2c5_scl", "peri_i2c5_sda";
drive-strength = <7>;
bias-pull-down;
input-disable;
low-power-disable;
slew-rate = <1>;
input-schmitt-disable;
};
};
pinctrl_test_sleep: pinctrl_test_sleep {
pinmux {
function = "peri_i2c5";
pins = "peri_i2c5_scl", "peri_i2c5_sda";
};
pinconf {
pins = "peri_i2c5_scl", "peri_i2c5_sda";
drive-strength = <1>;
bias-pull-up;
input-enable;
low-power-enable;
slew-rate = <0>;
input-schmitt-enable;
};
};
};
S600 acore 中 pinctrl 设备树文件路径为:hobot-drivers/kernel-dts/drobot-s600-pinctrl.dtsi。
S600同样通过pinmux和pinconf子节点完成配置,但节点命名和功能命名与 S100不同,通常按hsi/cam/peri域组织。
&pinctrl_hsi {
hsi_spi3_mosi_spi3_mosi: hsi_spi3_mosi_spi3_mosi_func {
pinmux {
function = "hsi_spi3_mosi_spi3_mosi";
pins = "hsi_spi3_mosi";
};
pinconf {
pins = "hsi_spi3_mosi";
drive-strength = <1>;
};
};
};
节点引用
驱动在使用 pinctrl 接口前,需要在 DTS 里配置相应的 pinctrl 节点。驱动 probe 时会将default状态配置到寄存器,其他状态可在代码中显式切换。
pinctrl_test: pinctrl_test {
compatible = "horizon,s100-pinctrl-test";
pinctrl-names = "default", "sleep";
pinctrl-0 = <&pinctrl_test_default>;
pinctrl-1 = <&pinctrl_test_sleep>;
#address-cells = <1>;
#size-cells = <0>;
};
驱动在使用 pinctrl 接口前,需要在 DTS 里配置相应的 pinctrl 节点。驱动 probe 时会将 default 状态配置到寄存器,其他状态可在代码中显式切换。
pinctrl_test: pinctrl_test {
compatible = "horizon,s600-pinctrl-test";
pinctrl-names = "default", "sleep";
pinctrl-0 = <&pinctrl_test_default>;
pinctrl-1 = <&pinctrl_test_sleep>;
#address-cells = <1>;
#size-cells = <0>;
};
显示切换 pinctrl state 需要调用 pinctrl_select_state 接口。
/**
* pinctrl_select_state() - select/activate/program a pinctrl state to HW
* @p: the pinctrl handle for the device that requests configuration
* @state: the state handle to select/activate/program
*/
int pinctrl_select_state(struct pinctrl *p, struct pinctrl_state *state)