gpio 配置注释,不同的厂商会有细微的区别
gpio0: gpio@fd8a0000 {
compatible = "rockchip,gpio-bank"; # 兼容性信息 ----------------- 相当这一个节点存在于设备树中的key,其它的子项是value,代码中就是通过这个key找到其它子项的
reg = <0x0 0xfd8a0000 0x0 0x100>; # 寄存器地址和大小
第一个元素(0x0)表示该寄存器在系统中的偏移地址。
第二个元素(0xfd8a0000)表示该寄存器的物理地址,即该寄存器在CPU外围设备中的实际地址。
第三个元素(0x0)通常不使用,可以忽略。
第四个元素(0x100)表示该寄存器所占用的字节数。
interrupts = <GIC_SPI 277 IRQ_TYPE_LEVEL_HIGH>; # 中断类型和编号
clocks = <&cru PCLK_GPIO0>, <&cru DBCLK_GPIO0>; # 时钟配置
gpio-controller; # GPIO控制器声明
gpio-cells = <2>; # GPIO单元格定义
interrupt-controller; # 中断控制器声明
interrupt-cells = <2>; # 中断单元格定义
};
有一组gpio需要处理,一部分需要输入上拉,一部分需要输出16ma
首先需要确保硬件上是支持的,然后可以做如下处理:(高通)
pinctrl部分的定义
yk_w1_input_active{
qcom,pins = <&gp 12>, <&gp 13>, <&gp 14>, <&gp 15>, <&gp 18>, <&gp 19>, <&gp 20>, <&gp 21>;
qcom,num-grp-pins = <8>;
label = "yk_w1_input_active";
w1_input_active: w1_input_active {
drive-strength = <2>;
bias-pull-up; // 输入上拉
};
};
yk_w1_output_active{
qcom,pins = <&gp 0>, <&gp 1>, <&gp 2>, <&gp 3>, <&gp 8>, <&gp 9>, <&gp 10>, <&gp 11>;
qcom,num-grp-pins = <8>;
label = "yk_w1_output_active";
w1_output_active: w1_output_active {
drive-strength = <16>; // 输出16ma
bias-disable; /* No PULL */
output-high;
};
};
dtsi中配置
test_gpio{
compatible = "test_gpio";
gpios = <&msm_gpio 0 0>,
<&msm_gpio 1 0>,
<&msm_gpio 2 0>,
<&msm_gpio 3 0>,
<&msm_gpio 8 0>,
<&msm_gpio 9 0>,
<&msm_gpio 10 0>,
<&msm_gpio 11 0>,
<&msm_gpio 12 0>,
<&msm_gpio 13 0>,
<&msm_gpio 14 0>,
<&msm_gpio 15 0>,
<&msm_gpio 18 0>,
<&msm_gpio 19 0>,
<&msm_gpio 20 0>,
<&msm_gpio 21 0>;
qcom,num-grp-pins = <16>;
qcom,pin-func = <0>;
pintctrl-names = "yk_w1_inout_active";
pinctrl-0 = <&w1_input_active &w1_output_active>; // 同时设置两种不同的状态
};
内核中的处理
static int w1_gpio_pinctrl_configure(struct pinctrl * p, struct device *dev, const char *name)
{
struct pinctrl_state *set_state;
int retval;
set_state =
pinctrl_lookup_state(p, name);
if (IS_ERR(set_state)) {
dev_err(dev,
"cannot get w1 pinctrl active state\n");
return PTR_ERR(set_state);
}
retval = pinctrl_select_state(p, set_state);
if (retval) {
dev_err(dev,
"cannot set w1 pinctrl active state\n");
return retval;
}
return 0;
}
static int test_gpio_probe(struct platform_device *pdev)
{
int ret = 0;
int i=0;
struct device_node *of_node = pdev->dev.of_node;
struct device *dev = &pdev->dev;
pr_err("enter test_gpio_probe, begin \n");
w1_gpio_pinctrl = devm_pinctrl_get(dev);
if (IS_ERR(w1_gpio_pinctrl)) {
if (PTR_ERR(w1_gpio_pinctrl) == -EPROBE_DEFER)
return -EPROBE_DEFER;
pr_debug("W1 Target does not use pinctrl\n");
w1_gpio_pinctrl = NULL;
}
w1_gpio_pinctrl_configure(w1_gpio_pinctrl, dev, "yk_w1_inout_active");
...