summaryrefslogtreecommitdiff
path: root/drivers/pinctrl/pinctrl-u300.c
diff options
context:
space:
mode:
authorLinus Walleij <linus.walleij@linaro.org>2011-11-16 21:58:10 +0100
committerLinus Walleij <linus.walleij@linaro.org>2012-03-12 22:49:03 +0100
commitdc0b1aa3e2fefa6372f38d7f6d5d33581567a1b5 (patch)
treecd0f71588255f4b456f4d2e6f1f5b2446a91a51c /drivers/pinctrl/pinctrl-u300.c
parenta050b3eee61666421df786c8d898ec22c129f4af (diff)
downloadlinux-3.10-dc0b1aa3e2fefa6372f38d7f6d5d33581567a1b5.tar.gz
linux-3.10-dc0b1aa3e2fefa6372f38d7f6d5d33581567a1b5.tar.bz2
linux-3.10-dc0b1aa3e2fefa6372f38d7f6d5d33581567a1b5.zip
pinctrl: support pinconfig on the U300
This adds pin configuration support for the U300 driver pair, we can now read out the biasing and drive mode in debugfs and configure it using the new configuration API. ChangeLog v1->v2: - Migrate to pin config and generic pin config changes. ChangeLog v2->v3: - Adjust to generic pin config changes in v7 patch set. Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/pinctrl/pinctrl-u300.c')
-rw-r--r--drivers/pinctrl/pinctrl-u300.c60
1 files changed, 60 insertions, 0 deletions
diff --git a/drivers/pinctrl/pinctrl-u300.c b/drivers/pinctrl/pinctrl-u300.c
index fc4a281caba..26eb8ccd72d 100644
--- a/drivers/pinctrl/pinctrl-u300.c
+++ b/drivers/pinctrl/pinctrl-u300.c
@@ -19,6 +19,9 @@
#include <linux/err.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
+#include <linux/pinctrl/pinconf.h>
+#include <linux/pinctrl/pinconf-generic.h>
+#include "pinctrl-coh901.h"
/*
* Register definitions for the U300 Padmux control registers in the
@@ -1044,12 +1047,69 @@ static struct pinctrl_gpio_range u300_gpio_ranges[] = {
U300_GPIO_RANGE(25, 181, 1),
};
+static struct pinctrl_gpio_range *u300_match_gpio_range(unsigned pin)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(u300_gpio_ranges); i++) {
+ struct pinctrl_gpio_range *range;
+
+ range = &u300_gpio_ranges[i];
+ if (pin >= range->pin_base &&
+ pin <= (range->pin_base + range->npins - 1))
+ return range;
+ }
+ return NULL;
+}
+
+int u300_pin_config_get(struct pinctrl_dev *pctldev,
+ unsigned pin,
+ unsigned long *config)
+{
+ struct pinctrl_gpio_range *range = u300_match_gpio_range(pin);
+
+ /* We get config for those pins we CAN get it for and that's it */
+ if (!range)
+ return -ENOTSUPP;
+
+ return u300_gpio_config_get(range->gc,
+ (pin - range->pin_base + range->base),
+ config);
+}
+
+int u300_pin_config_set(struct pinctrl_dev *pctldev,
+ unsigned pin,
+ unsigned long config)
+{
+ struct pinctrl_gpio_range *range = u300_match_gpio_range(pin);
+ int ret;
+
+ if (!range)
+ return -EINVAL;
+
+ /* Note: none of these configurations take any argument */
+ ret = u300_gpio_config_set(range->gc,
+ (pin - range->pin_base + range->base),
+ pinconf_to_config_param(config));
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static struct pinconf_ops u300_pconf_ops = {
+ .is_generic = true,
+ .pin_config_get = u300_pin_config_get,
+ .pin_config_set = u300_pin_config_set,
+};
+
static struct pinctrl_desc u300_pmx_desc = {
.name = DRIVER_NAME,
.pins = u300_pads,
.npins = ARRAY_SIZE(u300_pads),
.pctlops = &u300_pctrl_ops,
.pmxops = &u300_pmx_ops,
+ .confops = &u300_pconf_ops,
.owner = THIS_MODULE,
};