aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pinctrl
diff options
context:
space:
mode:
authorLinus Walleij <linus.walleij@linaro.org>2011-11-16 15:58:10 -0500
committerLinus Walleij <linus.walleij@linaro.org>2012-03-12 17:49:03 -0400
commitdc0b1aa3e2fefa6372f38d7f6d5d33581567a1b5 (patch)
treecd0f71588255f4b456f4d2e6f1f5b2446a91a51c /drivers/pinctrl
parenta050b3eee61666421df786c8d898ec22c129f4af (diff)
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')
-rw-r--r--drivers/pinctrl/Kconfig1
-rw-r--r--drivers/pinctrl/pinctrl-coh901.c77
-rw-r--r--drivers/pinctrl/pinctrl-coh901.h5
-rw-r--r--drivers/pinctrl/pinctrl-u300.c60
4 files changed, 135 insertions, 8 deletions
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 07f3d8d38580..abfb96408779 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -73,6 +73,7 @@ config PINCTRL_U300
73 bool "U300 pin controller driver" 73 bool "U300 pin controller driver"
74 depends on ARCH_U300 74 depends on ARCH_U300
75 select PINMUX 75 select PINMUX
76 select GENERIC_PINCONF
76 77
77config PINCTRL_COH901 78config PINCTRL_COH901
78 bool "ST-Ericsson U300 COH 901 335/571 GPIO" 79 bool "ST-Ericsson U300 COH 901 335/571 GPIO"
diff --git a/drivers/pinctrl/pinctrl-coh901.c b/drivers/pinctrl/pinctrl-coh901.c
index 724234c9b01b..0797eba3e33a 100644
--- a/drivers/pinctrl/pinctrl-coh901.c
+++ b/drivers/pinctrl/pinctrl-coh901.c
@@ -23,7 +23,9 @@
23#include <linux/list.h> 23#include <linux/list.h>
24#include <linux/slab.h> 24#include <linux/slab.h>
25#include <linux/pinctrl/consumer.h> 25#include <linux/pinctrl/consumer.h>
26#include <linux/pinctrl/pinconf-generic.h>
26#include <mach/gpio-u300.h> 27#include <mach/gpio-u300.h>
28#include "pinctrl-coh901.h"
27 29
28/* 30/*
29 * Register definitions for COH 901 335 variant 31 * Register definitions for COH 901 335 variant
@@ -418,8 +420,68 @@ static int u300_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
418 return retirq; 420 return retirq;
419} 421}
420 422
421static int u300_gpio_config(struct gpio_chip *chip, unsigned offset, 423/* Returning -EINVAL means "supported but not available" */
422 enum pin_config_param param, unsigned long data) 424int u300_gpio_config_get(struct gpio_chip *chip,
425 unsigned offset,
426 unsigned long *config)
427{
428 struct u300_gpio *gpio = to_u300_gpio(chip);
429 enum pin_config_param param = (enum pin_config_param) *config;
430 bool biasmode;
431 u32 drmode;
432
433 /* One bit per pin, clamp to bool range */
434 biasmode = !!(readl(U300_PIN_REG(offset, per)) & U300_PIN_BIT(offset));
435
436 /* Mask out the two bits for this pin and shift to bits 0,1 */
437 drmode = readl(U300_PIN_REG(offset, pcr));
438 drmode &= (U300_GPIO_PXPCR_PIN_MODE_MASK << ((offset & 0x07) << 1));
439 drmode >>= ((offset & 0x07) << 1);
440
441 switch(param) {
442 case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
443 *config = 0;
444 if (biasmode)
445 return 0;
446 else
447 return -EINVAL;
448 break;
449 case PIN_CONFIG_BIAS_PULL_UP:
450 *config = 0;
451 if (!biasmode)
452 return 0;
453 else
454 return -EINVAL;
455 break;
456 case PIN_CONFIG_DRIVE_PUSH_PULL:
457 *config = 0;
458 if (drmode == U300_GPIO_PXPCR_PIN_MODE_OUTPUT_PUSH_PULL)
459 return 0;
460 else
461 return -EINVAL;
462 break;
463 case PIN_CONFIG_DRIVE_OPEN_DRAIN:
464 *config = 0;
465 if (drmode == U300_GPIO_PXPCR_PIN_MODE_OUTPUT_OPEN_DRAIN)
466 return 0;
467 else
468 return -EINVAL;
469 break;
470 case PIN_CONFIG_DRIVE_OPEN_SOURCE:
471 *config = 0;
472 if (drmode == U300_GPIO_PXPCR_PIN_MODE_OUTPUT_OPEN_SOURCE)
473 return 0;
474 else
475 return -EINVAL;
476 break;
477 default:
478 break;
479 }
480 return -ENOTSUPP;
481}
482
483int u300_gpio_config_set(struct gpio_chip *chip, unsigned offset,
484 enum pin_config_param param)
423{ 485{
424 struct u300_gpio *gpio = to_u300_gpio(chip); 486 struct u300_gpio *gpio = to_u300_gpio(chip);
425 unsigned long flags; 487 unsigned long flags;
@@ -620,13 +682,12 @@ static void __init u300_gpio_init_pin(struct u300_gpio *gpio,
620 u300_gpio_direction_output(&gpio->chip, offset, conf->outval); 682 u300_gpio_direction_output(&gpio->chip, offset, conf->outval);
621 683
622 /* Deactivate bias mode for output */ 684 /* Deactivate bias mode for output */
623 u300_gpio_config(&gpio->chip, offset, 685 u300_gpio_config_set(&gpio->chip, offset,
624 PIN_CONFIG_BIAS_HIGH_IMPEDANCE, 686 PIN_CONFIG_BIAS_HIGH_IMPEDANCE);
625 0);
626 687
627 /* Set drive mode for output */ 688 /* Set drive mode for output */
628 u300_gpio_config(&gpio->chip, offset, 689 u300_gpio_config_set(&gpio->chip, offset,
629 PIN_CONFIG_DRIVE_PUSH_PULL, 0); 690 PIN_CONFIG_DRIVE_PUSH_PULL);
630 691
631 dev_dbg(gpio->dev, "set up pin %d as output, value: %d\n", 692 dev_dbg(gpio->dev, "set up pin %d as output, value: %d\n",
632 offset, conf->outval); 693 offset, conf->outval);
@@ -637,7 +698,7 @@ static void __init u300_gpio_init_pin(struct u300_gpio *gpio,
637 u300_gpio_set(&gpio->chip, offset, 0); 698 u300_gpio_set(&gpio->chip, offset, 0);
638 699
639 /* Set bias mode for input */ 700 /* Set bias mode for input */
640 u300_gpio_config(&gpio->chip, offset, conf->bias_mode, 0); 701 u300_gpio_config_set(&gpio->chip, offset, conf->bias_mode);
641 702
642 dev_dbg(gpio->dev, "set up pin %d as input, bias: %04x\n", 703 dev_dbg(gpio->dev, "set up pin %d as input, bias: %04x\n",
643 offset, conf->bias_mode); 704 offset, conf->bias_mode);
diff --git a/drivers/pinctrl/pinctrl-coh901.h b/drivers/pinctrl/pinctrl-coh901.h
new file mode 100644
index 000000000000..87294222583e
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-coh901.h
@@ -0,0 +1,5 @@
1int u300_gpio_config_get(struct gpio_chip *chip,
2 unsigned offset,
3 unsigned long *config);
4int u300_gpio_config_set(struct gpio_chip *chip, unsigned offset,
5 enum pin_config_param param);
diff --git a/drivers/pinctrl/pinctrl-u300.c b/drivers/pinctrl/pinctrl-u300.c
index fc4a281caba5..26eb8ccd72d5 100644
--- a/drivers/pinctrl/pinctrl-u300.c
+++ b/drivers/pinctrl/pinctrl-u300.c
@@ -19,6 +19,9 @@
19#include <linux/err.h> 19#include <linux/err.h>
20#include <linux/pinctrl/pinctrl.h> 20#include <linux/pinctrl/pinctrl.h>
21#include <linux/pinctrl/pinmux.h> 21#include <linux/pinctrl/pinmux.h>
22#include <linux/pinctrl/pinconf.h>
23#include <linux/pinctrl/pinconf-generic.h>
24#include "pinctrl-coh901.h"
22 25
23/* 26/*
24 * Register definitions for the U300 Padmux control registers in the 27 * Register definitions for the U300 Padmux control registers in the
@@ -1044,12 +1047,69 @@ static struct pinctrl_gpio_range u300_gpio_ranges[] = {
1044 U300_GPIO_RANGE(25, 181, 1), 1047 U300_GPIO_RANGE(25, 181, 1),
1045}; 1048};
1046 1049
1050static struct pinctrl_gpio_range *u300_match_gpio_range(unsigned pin)
1051{
1052 int i;
1053
1054 for (i = 0; i < ARRAY_SIZE(u300_gpio_ranges); i++) {
1055 struct pinctrl_gpio_range *range;
1056
1057 range = &u300_gpio_ranges[i];
1058 if (pin >= range->pin_base &&
1059 pin <= (range->pin_base + range->npins - 1))
1060 return range;
1061 }
1062 return NULL;
1063}
1064
1065int u300_pin_config_get(struct pinctrl_dev *pctldev,
1066 unsigned pin,
1067 unsigned long *config)
1068{
1069 struct pinctrl_gpio_range *range = u300_match_gpio_range(pin);
1070
1071 /* We get config for those pins we CAN get it for and that's it */
1072 if (!range)
1073 return -ENOTSUPP;
1074
1075 return u300_gpio_config_get(range->gc,
1076 (pin - range->pin_base + range->base),
1077 config);
1078}
1079
1080int u300_pin_config_set(struct pinctrl_dev *pctldev,
1081 unsigned pin,
1082 unsigned long config)
1083{
1084 struct pinctrl_gpio_range *range = u300_match_gpio_range(pin);
1085 int ret;
1086
1087 if (!range)
1088 return -EINVAL;
1089
1090 /* Note: none of these configurations take any argument */
1091 ret = u300_gpio_config_set(range->gc,
1092 (pin - range->pin_base + range->base),
1093 pinconf_to_config_param(config));
1094 if (ret)
1095 return ret;
1096
1097 return 0;
1098}
1099
1100static struct pinconf_ops u300_pconf_ops = {
1101 .is_generic = true,
1102 .pin_config_get = u300_pin_config_get,
1103 .pin_config_set = u300_pin_config_set,
1104};
1105
1047static struct pinctrl_desc u300_pmx_desc = { 1106static struct pinctrl_desc u300_pmx_desc = {
1048 .name = DRIVER_NAME, 1107 .name = DRIVER_NAME,
1049 .pins = u300_pads, 1108 .pins = u300_pads,
1050 .npins = ARRAY_SIZE(u300_pads), 1109 .npins = ARRAY_SIZE(u300_pads),
1051 .pctlops = &u300_pctrl_ops, 1110 .pctlops = &u300_pctrl_ops,
1052 .pmxops = &u300_pmx_ops, 1111 .pmxops = &u300_pmx_ops,
1112 .confops = &u300_pconf_ops,
1053 .owner = THIS_MODULE, 1113 .owner = THIS_MODULE,
1054}; 1114};
1055 1115