dts pinctrl初始gpio0方法

文章详细介绍了如何在Linux内核的pinctrl-rockchip.c文件中添加头文件并进行GPIO初始化配置。通过解析设备树(DTS)节点,驱动程序获取并设置GPIO的行为,包括GPIO的高低电平状态和初始化配置。在rockchip_pinctrl_probe函数中,代码分配资源,处理注册,并根据不同的SoC类型进行特殊处理。of_get_gpio_init_config函数用于从设备树中提取GPIO初始化信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、在pinctrl-rockchip.c文件中添加头文件

#include <linux/of_gpio.h>

如下

 2、  在如下函数添加红色代码

static int rockchip_pinctrl_probe(struct platform_device *pdev)
{
    struct rockchip_pinctrl *info;
    struct device *dev = &pdev->dev;
    struct rockchip_pin_ctrl *ctrl;
    struct device_node *np = pdev->dev.of_node, *node;
    struct resource *res;
    void __iomem *base;
    int ret;
    int i = 0;

    if (!dev->of_node) {
        dev_err(dev, "device tree node not found\n");
        return -ENODEV;
    }

    info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL);
    if (!info)
        return -ENOMEM;

    info->dev = dev;

    ctrl = rockchip_pinctrl_get_soc_data(info, pdev);
    if (!ctrl) {
        dev_err(dev, "driver data not available\n");
        return -EINVAL;
    }
    info->ctrl = ctrl;

    node = of_parse_phandle(np, "rockchip,grf", 0);
    if (node) {
        info->regmap_base = syscon_node_to_regmap(node);
        if (IS_ERR(info->regmap_base))
            return PTR_ERR(info->regmap_base);
    } else {
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        base = devm_ioremap_resource(&pdev->dev, res);
        if (IS_ERR(base))
            return PTR_ERR(base);

        rockchip_regmap_config.max_register = resource_size(res) - 4;
        rockchip_regmap_config.name = "rockchip,pinctrl";
        info->regmap_base = devm_regmap_init_mmio(&pdev->dev, base,
                            &rockchip_regmap_config);

        /* to check for the old dt-bindings */
        info->reg_size = resource_size(res);

        /* Honor the old binding, with pull registers as 2nd resource */
        if (ctrl->type == RK3188 && info->reg_size < 0x200) {
            res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
            base = devm_ioremap_resource(&pdev->dev, res);
            if (IS_ERR(base))
                return PTR_ERR(base);

            rockchip_regmap_config.max_register =
                            resource_size(res) - 4;
            rockchip_regmap_config.name = "rockchip,pinctrl-pull";
            info->regmap_pull = devm_regmap_init_mmio(&pdev->dev,
                            base,
                            &rockchip_regmap_config);
        }
    }

    /* try to find the optional reference to the pmu syscon */
    node = of_parse_phandle(np, "rockchip,pmu", 0);
    if (node) {
        info->regmap_pmu = syscon_node_to_regmap(node);
        if (IS_ERR(info->regmap_pmu))
            return PTR_ERR(info->regmap_pmu);
    }

    /* Special handle for some Socs */
    if (ctrl->soc_data_init) {
        ret = ctrl->soc_data_init(info);
        if (ret)
            return ret;
    }

    ret = rockchip_pinctrl_register(pdev, info);
    if (ret)
        return ret;

    platform_set_drvdata(pdev, info);

    ret = of_platform_populate(np, rockchip_bank_match, NULL, NULL);
    if (ret) {
        dev_err(&pdev->dev, "failed to register gpio device\n");
        return ret;
    }
    dev_info(dev, "probed %s\n", dev_name(dev));
    
   
    np = dev->of_node;

    if (of_find_property(np, "init-gpios", NULL))
    {
        //printk("of_find_property init-gpios ok!\n");
        info->config = of_get_gpio_init_config(&pdev->dev, np);
        if (IS_ERR(info->config))
        return PTR_ERR(info->config);
        //printk("of_find_property init-gpios ok-1!\n");

        ret = gpio_request_array(info->config->gpios, info->config->nr_gpios);
        if (ret) {
            dev_err(&pdev->dev, "Could not obtain init GPIOs: %d\n", ret);
            //return ret;
        }
        //printk("of_find_property init-gpios ok-2!\n");

        for(i=0; i<info->config->nr_gpios; i++)
        {
            if(info->config->gpios[i].gpio<0)
                break;
            gpio_direction_output(info->config->gpios[i].gpio, info->config->gpios[i].flags);
        }
    }

    return 0;
}
 

3、函数of_get_gpio_init_config定义如下


 static struct gpio_init_config *
 of_get_gpio_init_config(struct device *dev, struct device_node *np)
 {
     struct gpio_init_config *config;
     int gpio, i;    
     enum of_gpio_flags flags;
 
     config = devm_kzalloc(dev,
             sizeof(struct gpio_init_config),
             GFP_KERNEL);
     if (!config)
         return ERR_PTR(-ENOMEM);
 
     /* Fetch GPIOs. */
     config->nr_gpios = of_gpio_named_count(np, "init-gpios");
 printk("==== nr_gpios:%d ====\n",config->nr_gpios);
     config->gpios = devm_kzalloc(dev,
                 sizeof(struct gpio) * config->nr_gpios,
                 GFP_KERNEL);
     if (!config->gpios)
         return ERR_PTR(-ENOMEM);
 
     for (i = 0; i < config->nr_gpios; i++) {
         gpio = of_get_named_gpio_flags(np, "init-gpios", i, &flags);
         if (gpio < 0)
             break;
         config->gpios[i].gpio = gpio;   
         config->gpios[i].flags = (flags == OF_GPIO_ACTIVE_LOW) ? 0 : 1;
 
         
       printk("--%s:gpio[%d] = %d, value = %lu\n",__func__, i, gpio, config->gpios[i].flags);     
     }
 
     return config;
 }

 

4、DTS 配置

&pinctrl {
    init-gpios = <&gpio0 RK_PD3 GPIO_ACTIVE_HIGH    //RK1808_0 RESET
    &gpio0 RK_PD4 GPIO_ACTIVE_HIGH                                //PCIE POWER ENABLE
    &gpio0 RK_PD6 GPIO_ACTIVE_HIGH                                //rk1808_1 RESET
    &gpio0 RK_PB5 GPIO_ACTIVE_HIGH                                //SATA 1 POWER ENABLE
    &gpio0 RK_PC4 GPIO_ACTIVE_HIGH                                //SATA 2 POWER ENABLE
    &gpio2 RK_PC6 GPIO_ACTIVE_HIGH                                //PSE 3V3 ENABLE
    &gpio2 RK_PD1 GPIO_ACTIVE_LOW                                 //WAN LED
    &gpio2 RK_PD4 GPIO_ACTIVE_LOW                                 //3G LED
    &gpio2 RK_PD5 GPIO_ACTIVE_LOW                                 //HDD LED
    &gpio2 RK_PD6 GPIO_ACTIVE_LOW                                 //ERROR LED
    //&gpio3 RK_PB7 GPIO_ACTIVE_HIGH                             //WIFI PWREN ENABLE
    //&gpio4 RK_PD2 GPIO_ACTIVE_HIGH                             //SATAPM RESET  
    >;
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值