aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pinctrl/pinctrl-coh901.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pinctrl/pinctrl-coh901.c')
-rw-r--r--drivers/pinctrl/pinctrl-coh901.c77
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
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);