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
>;
};