diff options
author | Andrey Smirnov <andrew.smirnov@gmail.com> | 2016-11-09 08:13:54 -0800 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2016-11-14 08:57:57 +0100 |
commit | a4e1f15b6be34b3d8b79dee9d47581c975df5fa3 (patch) | |
tree | 6bfcd8916a1ecbab46e8c7c6adfb063babad2b78 /drivers/pinctrl | |
parent | d8162dd6f18eeb51d1a3176e5edf40d150b11e32 (diff) | |
download | barebox-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.c | 45 |
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; |