diff options
-rw-r--r-- | drivers/pinctrl/Kconfig | 1 | ||||
-rw-r--r-- | drivers/pinctrl/pinctrl-coh901.c | 77 | ||||
-rw-r--r-- | drivers/pinctrl/pinctrl-coh901.h | 5 | ||||
-rw-r--r-- | drivers/pinctrl/pinctrl-u300.c | 60 |
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 | ||
77 | config PINCTRL_COH901 | 78 | config 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 | ||
421 | static 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) | 424 | int 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 | |||
483 | int 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 @@ | |||
1 | int u300_gpio_config_get(struct gpio_chip *chip, | ||
2 | unsigned offset, | ||
3 | unsigned long *config); | ||
4 | int 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 | ||
1050 | static 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 | |||
1065 | int 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 | |||
1080 | int 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 | |||
1100 | static 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 | |||
1047 | static struct pinctrl_desc u300_pmx_desc = { | 1106 | static 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 | ||