summaryrefslogtreecommitdiffstats
path: root/drivers/pinctrl
diff options
context:
space:
mode:
authorAndrey Smirnov <andrew.smirnov@gmail.com>2016-11-09 08:13:54 -0800
committerSascha Hauer <s.hauer@pengutronix.de>2016-11-14 08:57:57 +0100
commita4e1f15b6be34b3d8b79dee9d47581c975df5fa3 (patch)
tree6bfcd8916a1ecbab46e8c7c6adfb063babad2b78 /drivers/pinctrl
parentd8162dd6f18eeb51d1a3176e5edf40d150b11e32 (diff)
downloadbarebox-a4e1f15b6be34b3d8b79dee9d47581c975df5fa3.tar.gz
barebox-a4e1f15b6be34b3d8b79dee9d47581c975df5fa3.tar.xz
pinctrl: Add provisions to control GPIO pin direction
Some SoC (of which Vybrid is a one example) relegate GPIO direction control to their pinmux IP block, instead of having that functionality within GPIO IP. Add provisions to control that aspect of pinmux to support such SoCs. Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'drivers/pinctrl')
-rw-r--r--drivers/pinctrl/pinctrl.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/drivers/pinctrl/pinctrl.c b/drivers/pinctrl/pinctrl.c
index e7b08a2bfe..bef4fcdba1 100644
--- a/drivers/pinctrl/pinctrl.c
+++ b/drivers/pinctrl/pinctrl.c
@@ -24,6 +24,51 @@
static LIST_HEAD(pinctrl_list);
+static struct pinctrl_device *pin_to_pinctrl(unsigned int pin)
+{
+ struct pinctrl_device *pinctrl;
+
+ list_for_each_entry(pinctrl, &pinctrl_list, list)
+ if (pin > pinctrl->base &&
+ pin < pinctrl->base + pinctrl->npins)
+ return pinctrl;
+ return NULL;
+}
+
+static int pinctrl_gpio_direction(unsigned pin, bool input)
+{
+ struct pinctrl_device *pinctrl = pin_to_pinctrl(pin);
+
+ if (!pinctrl)
+ return -EINVAL;
+
+ BUG_ON(!pinctrl->ops->set_direction);
+
+ return pinctrl->ops->set_direction(pinctrl, pin, input);
+}
+
+int pinctrl_gpio_direction_input(unsigned int pin)
+{
+ return pinctrl_gpio_direction(pin, true);
+}
+
+int pinctrl_gpio_direction_output(unsigned int pin)
+{
+ return pinctrl_gpio_direction(pin, false);
+}
+
+int pinctrl_gpio_get_direction(unsigned pin)
+{
+ struct pinctrl_device *pinctrl = pin_to_pinctrl(pin);
+
+ if (!pinctrl)
+ return -EINVAL;
+
+ BUG_ON(!pinctrl->ops->get_direction);
+
+ return pinctrl->ops->get_direction(pinctrl, pin);
+}
+
static struct pinctrl_device *find_pinctrl(struct device_node *node)
{
struct pinctrl_device *pdev;