imx6ul设备树pinctrl解析

内核使用的是天嵌移植好的linux4.1.15版本的内核,看它的设备树中用到pinctrl的配置不是很理解,理解一番后现在记录下:

1、以led_gpio为例:

leds {
        compatible = "gpio-leds";
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_gpio_leds>;

        led1 {
            label = "LED1";
            gpios = <&gpio5 7 GPIO_ACTIVE_LOW>; //led 使用的引脚,与触发电平
        };
        led2 {
            label = "LED2";
            gpios = <&gpio5 2 GPIO_ACTIVE_LOW>;
        };
    };

pinctrl_gpio_leds: gpio_leds{
            fsl,pins = <
                MX6UL_PAD_SNVS_TAMPER7__GPIO5_IO07  0x70a1      //led1
                MX6UL_PAD_SNVS_TAMPER2__GPIO5_IO02  0x70a1      //led2

            >;
        };

pinctrl的配置信息在上串代码的最后,有两个数据结构;
MX6UL_PAD_SNVS_TAMPER7__GPIO5_IO07的定义在imx6ul-pinfunc.h中:

这里写图片描述

看到头文件上方有对这个五个数据的定义:

imx6ul设备树pinctrl解析_第1张图片

这个五个变量的定义我们 是知道了,但是还有个变量,让我百思不得其解,无奈只能百度然后看源码;
源码在:drivers/pinctrl/freescale/pinctrl-imx.c目录下,imx_pinctrl_parse_groups()函数调用了这些参数,源码如下:

static int imx_pinctrl_parse_groups(struct device_node *np,
                    struct imx_pin_group *grp,
                    struct imx_pinctrl_soc_info *info,
                    u32 index)
{
    int size, pin_size;
    const __be32 *list;
    int i;
    u32 config;

    dev_dbg(info->dev, "group(%d): %s\n", index, np->name);

    if (info->flags & SHARE_MUX_CONF_REG)
        pin_size = SHARE_FSL_PIN_SIZE;
    else
        pin_size = FSL_PIN_SIZE;
    /* Initialise group */
    grp->name = np->name;

    /*
     * the binding format is fsl,pins = <PIN_FUNC_ID CONFIG ...>,
     * do sanity check and calculate pins number
     */
    list = of_get_property(np, "fsl,pins", &size);
    if (!list) {
        dev_err(info->dev, "no fsl,pins property in node %s\n", np->full_name);
        return -EINVAL;
    }

    /* we do not check return since it's safe node passed down */
    if (!size || size % pin_size) {
        dev_err(info->dev, "Invalid fsl,pins property in node %s\n", np->full_name);
        return -EINVAL;
    }

    grp->npins = size / pin_size;
    grp->pins = devm_kzalloc(info->dev, grp->npins * sizeof(struct imx_pin),
                GFP_KERNEL);
    grp->pin_ids = devm_kzalloc(info->dev, grp->npins * sizeof(unsigned int),
                GFP_KERNEL);
    if (!grp->pins || ! grp->pin_ids)
        return -ENOMEM;

    for (i = 0; i < grp->npins; i++) {
        u32 mux_reg = be32_to_cpu(*list++);
        u32 conf_reg;
        unsigned int pin_id;
        struct imx_pin_reg *pin_reg;
        struct imx_pin *pin = &grp->pins[i];

        if (!(info->flags & ZERO_OFFSET_VALID) && !mux_reg)
            mux_reg = -1;

        if (info->flags & SHARE_MUX_CONF_REG) {
            conf_reg = mux_reg;
        } else {
            conf_reg = be32_to_cpu(*list++);
            if (!(info->flags & ZERO_OFFSET_VALID) && !conf_reg)
                conf_reg = -1;
        }

        pin_id = (mux_reg != -1) ? mux_reg / 4 : conf_reg / 4;
        pin_reg = &info->pin_regs[pin_id];
        pin->pin = pin_id;
        grp->pin_ids[i] = pin_id;
        pin_reg->mux_reg = mux_reg;
        pin_reg->conf_reg = conf_reg;
        pin->input_reg = be32_to_cpu(*list++);
        pin->mux_mode = be32_to_cpu(*list++);
        pin->input_val = be32_to_cpu(*list++);

        /* SION bit is in mux register */
        config = be32_to_cpu(*list++);
        if (config & IMX_PAD_SION)
            pin->mux_mode |= IOMUXC_CONFIG_SION;
        pin->config = config & ~IMX_PAD_SION;

        dev_dbg(info->dev, "%s: 0x%x 0x%08lx", info->pins[pin_id].name,
                pin->mux_mode, pin->config);
    }

    return 0;
}

这里能看到,最后一个参数(第六个参数)的配置为config,显而易见是用于配制config_reg寄存器的值。
现在去看看这个配置寄存器做什么什么功能在数据手册得第1598页:
imx6ul设备树pinctrl解析_第2张图片
imx6ul设备树pinctrl解析_第3张图片

从手册可以看出这个寄存器是用来配置io的模式用的,上拉电阻多少,io速度等,pad_ctrl的值就是第六个参数了;

现在参数的意义我们都知道了,但是源代码有点刚看了不是很明白,看下其他设备树对比下,理解如下:

/* SION bit is in mux register */
        config = be32_to_cpu(*list++);
        if (config & IMX_PAD_SION)
            pin->mux_mode |= IOMUXC_CONFIG_SION;
        pin->config = config & ~IMX_PAD_SION;

先判断下是否为输入,如果是输入端口,配置mux_mode模式为输入模式;
imx6ul设备树pinctrl解析_第4张图片
为什么是与上这个值呢,去看下设备树源码就明白了:

pinctrl_i2c2: i2c2grp {
            fsl,pins = <
                MX6UL_PAD_CSI_VSYNC__I2C2_SDA    0x4001b8b0
                MX6UL_PAD_CSI_HSYNC__I2C2_SCL    0x4001b8b0
            >;
};

SION含义:software input on filed

你可能感兴趣的:(linux学习过程)