diff options
Diffstat (limited to 'drivers/pinctrl/pinctrl-coh901.c')
-rw-r--r-- | drivers/pinctrl/pinctrl-coh901.c | 77 |
1 files changed, 69 insertions, 8 deletions
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); |