]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
ENGR00269945: pinctrl: support pinctrl setting assertion via gpios
authorShawn Guo <shawn.guo@freescale.com>
Mon, 15 Jul 2013 08:31:53 +0000 (16:31 +0800)
committerLothar Waßmann <LW@KARO-electronics.de>
Wed, 20 Aug 2014 08:06:05 +0000 (10:06 +0200)
It's pretty common that on some reference design or validation boards,
one pin could be used by two devices on board, and the pin route is
controlled by a GPIO.  So to assert the pin for given device, not only
the pinmux controller in SoC needs to be set up properly but also the
GPIO needs to be pulled up/down.

The patch adds support of a device tree property "pinctrl-assert-gpios"
under client device node.  It plays pretty much like a board level pin
multiplexer, and steers the pin route by controlling the GPIOs.  When
client device has the property represent in its node, pinctrl device
tree mapping function will firstly pull up/down the GPIOs to assert the
pins for the device at board level.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt
drivers/pinctrl/devicetree.c

index fa40a177164ce0b68ace98b0adf05855989bc623..70028f6c7138a5af0a91d5f4f59ab0282cac38bc 100644 (file)
@@ -71,6 +71,13 @@ pinctrl-names:       The list of names to assign states. List entry 0 defines the
                name for integer state ID 0, list entry 1 for state ID 1, and
                so on.
 
+pinctrl-assert-gpios:
+               List of phandles, each pointing at a GPIO which is used by some
+               board design to steer pins between two peripherals on the board.
+               It plays like a board level pin multiplexer to choose different
+               functions for given pins by pulling up/down the GPIOs.  See
+               bindings/gpio/gpio.txt for details of how to specify GPIO.
+
 For example:
 
        /* For a client device requiring named states */
index eda13de2e7c0d110f5e105a84b5b19da93cadc36..02b11f7d11db4f1b067bc5bbe9a14e4a3a88c296 100644 (file)
@@ -18,6 +18,7 @@
 
 #include <linux/device.h>
 #include <linux/of.h>
+#include <linux/of_gpio.h>
 #include <linux/pinctrl/pinctrl.h>
 #include <linux/slab.h>
 
@@ -172,6 +173,43 @@ static int dt_remember_dummy_state(struct pinctrl *p, const char *statename)
        return dt_remember_or_free_map(p, statename, NULL, map, 1);
 }
 
+static int dt_gpio_assert_pinctrl(struct pinctrl *p)
+{
+       struct device_node *np = p->dev->of_node;
+       enum of_gpio_flags flags;
+       int gpio;
+       int index = 0;
+       int ret;
+
+       if (!of_find_property(np, "pinctrl-assert-gpios", NULL))
+               return 0; /* Missing the property, so nothing to be done */
+
+       for (;; index++) {
+               gpio = of_get_named_gpio_flags(np, "pinctrl-assert-gpios",
+                                              index, &flags);
+               if (gpio < 0)
+                       break; /* End of the phandle list */
+
+               if (!gpio_is_valid(gpio))
+                       return -EINVAL;
+
+               ret = devm_gpio_request_one(p->dev, gpio, GPIOF_OUT_INIT_LOW,
+                                           NULL);
+               if (ret < 0)
+                       return ret;
+
+               if (flags & OF_GPIO_ACTIVE_LOW)
+                       continue;
+
+               if (gpio_cansleep(gpio))
+                       gpio_set_value_cansleep(gpio, 1);
+               else
+                       gpio_set_value(gpio, 1);
+       }
+
+       return 0;
+}
+
 int pinctrl_dt_to_map(struct pinctrl *p)
 {
        struct device_node *np = p->dev->of_node;
@@ -192,6 +230,12 @@ int pinctrl_dt_to_map(struct pinctrl *p)
                return 0;
        }
 
+       ret = dt_gpio_assert_pinctrl(p);
+       if (ret) {
+               dev_dbg(p->dev, "failed to assert pinctrl setting: %d\n", ret);
+               return ret;
+       }
+
        /* We may store pointers to property names within the node */
        of_node_get(np);