pinctrl:add gpio init support
authorluowei <lw@rock-chips.com>
Fri, 18 Apr 2014 10:20:05 +0000 (18:20 +0800)
committerluowei <lw@rock-chips.com>
Fri, 18 Apr 2014 10:20:35 +0000 (18:20 +0800)
arch/arm/boot/dts/rk3288-tb.dts [changed mode: 0644->0755]
drivers/pinctrl/pinctrl-rockchip.c

old mode 100644 (file)
new mode 100755 (executable)
index fc891e0..bc471d5
 };
 
 &pinctrl {
+       //used for init some gpio
+       init-gpios = <&gpio0 GPIO_A6 GPIO_ACTIVE_HIGH
+                       /*&gpio0 GPIO_C2 GPIO_ACTIVE_HIGH */
+                       /*&gpio7 GPIO_B7 GPIO_ACTIVE_LOW */>;
+       
        gpio0_gpio {
                        gpio0_c2: gpio0-c2 {
                                rockchip,pins = <GPIO0_C2>;
 
                        //to add
                };
+               
        //could add other pinctrl definition such as gpio
 
 };
index 263f97cb879883c314fe78b56a57cb7285aa1edb..cdbcfcd505b2ef9b85519a697028365b7aafb64f 100755 (executable)
@@ -43,6 +43,8 @@
 #include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/rockchip/grf.h>
+#include <linux/of_gpio.h>
+
 
 #ifdef CONFIG_DEBUG_FS
 #include <linux/debugfs.h>
@@ -186,6 +188,12 @@ struct rockchip_pmx_func {
        u8                      ngroups;
 };
 
+struct gpio_init_config {
+       struct gpio *gpios;
+       int nr_gpios;
+};
+
+
 struct rockchip_pinctrl {
        void __iomem                    *reg_base;
        
@@ -207,6 +215,7 @@ struct rockchip_pinctrl {
 #ifdef CONFIG_DEBUG_FS
        struct dentry *debugfs;
 #endif
+       struct gpio_init_config         *config;
 };
 
 struct iomux_mode{
@@ -2941,13 +2950,55 @@ static void rockchip_pinctrl_resume(void)
 
 #endif
 
+
+static struct gpio_init_config *
+of_get_gpio_init_config(struct device *dev, struct device_node *np)
+{
+       struct gpio_init_config *config;
+       struct property *prop;
+       const char *regtype;
+       int proplen, 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");
+
+       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(np, "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;
+               
+               printk("%s:gpio[%d] = %d, value = %d\n",__func__, i, gpio, config->gpios[i].flags);
+       }
+
+       return config;
+}
+
+
 static int rockchip_pinctrl_probe(struct platform_device *pdev)
 {
        struct rockchip_pinctrl *info;
        struct device *dev = &pdev->dev;
        struct rockchip_pin_ctrl *ctrl;
        struct resource *res;
-       int ret;
+       int ret;        
+       struct device_node *np;
+       int i;
        
        if (!dev->of_node) {
                dev_err(dev, "device tree node not found\n");
@@ -3058,6 +3109,25 @@ static int rockchip_pinctrl_probe(struct platform_device *pdev)
                rockchip_gpiolib_unregister(pdev, info);
                return ret;
        }
+
+       np = dev->of_node;
+       if (of_find_property(np, "init-gpios", NULL))
+       {
+               info->config = of_get_gpio_init_config(&pdev->dev, np);
+               if (IS_ERR(info->config))
+               return PTR_ERR(info->config);
+
+               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;
+               }
+
+               for(i=0; i<info->config->nr_gpios; i++)
+               {
+                       gpio_direction_output(info->config->gpios[i].gpio, info->config->gpios[i].flags);
+               }
+       }
        
        pinctrl_debugfs_init(info);