Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 294105
b: refs/heads/master
c: dc0b1aa
h: refs/heads/master
i:
  294103: a5ecb3a
v: v3
  • Loading branch information
Linus Walleij committed Mar 12, 2012
1 parent 4ef20c9 commit 335db4c
Show file tree
Hide file tree
Showing 5 changed files with 136 additions and 9 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: a050b3eee61666421df786c8d898ec22c129f4af
refs/heads/master: dc0b1aa3e2fefa6372f38d7f6d5d33581567a1b5
1 change: 1 addition & 0 deletions trunk/drivers/pinctrl/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ config PINCTRL_U300
bool "U300 pin controller driver"
depends on ARCH_U300
select PINMUX
select GENERIC_PINCONF

config PINCTRL_COH901
bool "ST-Ericsson U300 COH 901 335/571 GPIO"
Expand Down
77 changes: 69 additions & 8 deletions trunk/drivers/pinctrl/pinctrl-coh901.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@
#include <linux/list.h>
#include <linux/slab.h>
#include <linux/pinctrl/consumer.h>
#include <linux/pinctrl/pinconf-generic.h>
#include <mach/gpio-u300.h>
#include "pinctrl-coh901.h"

/*
* Register definitions for COH 901 335 variant
Expand Down Expand Up @@ -418,8 +420,68 @@ static int u300_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
return retirq;
}

static int u300_gpio_config(struct gpio_chip *chip, unsigned offset,
enum pin_config_param param, unsigned long data)
/* Returning -EINVAL means "supported but not available" */
int u300_gpio_config_get(struct gpio_chip *chip,
unsigned offset,
unsigned long *config)
{
struct u300_gpio *gpio = to_u300_gpio(chip);
enum pin_config_param param = (enum pin_config_param) *config;
bool biasmode;
u32 drmode;

/* One bit per pin, clamp to bool range */
biasmode = !!(readl(U300_PIN_REG(offset, per)) & U300_PIN_BIT(offset));

/* Mask out the two bits for this pin and shift to bits 0,1 */
drmode = readl(U300_PIN_REG(offset, pcr));
drmode &= (U300_GPIO_PXPCR_PIN_MODE_MASK << ((offset & 0x07) << 1));
drmode >>= ((offset & 0x07) << 1);

switch(param) {
case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
*config = 0;
if (biasmode)
return 0;
else
return -EINVAL;
break;
case PIN_CONFIG_BIAS_PULL_UP:
*config = 0;
if (!biasmode)
return 0;
else
return -EINVAL;
break;
case PIN_CONFIG_DRIVE_PUSH_PULL:
*config = 0;
if (drmode == U300_GPIO_PXPCR_PIN_MODE_OUTPUT_PUSH_PULL)
return 0;
else
return -EINVAL;
break;
case PIN_CONFIG_DRIVE_OPEN_DRAIN:
*config = 0;
if (drmode == U300_GPIO_PXPCR_PIN_MODE_OUTPUT_OPEN_DRAIN)
return 0;
else
return -EINVAL;
break;
case PIN_CONFIG_DRIVE_OPEN_SOURCE:
*config = 0;
if (drmode == U300_GPIO_PXPCR_PIN_MODE_OUTPUT_OPEN_SOURCE)
return 0;
else
return -EINVAL;
break;
default:
break;
}
return -ENOTSUPP;
}

int u300_gpio_config_set(struct gpio_chip *chip, unsigned offset,
enum pin_config_param param)
{
struct u300_gpio *gpio = to_u300_gpio(chip);
unsigned long flags;
Expand Down Expand Up @@ -620,13 +682,12 @@ static void __init u300_gpio_init_pin(struct u300_gpio *gpio,
u300_gpio_direction_output(&gpio->chip, offset, conf->outval);

/* Deactivate bias mode for output */
u300_gpio_config(&gpio->chip, offset,
PIN_CONFIG_BIAS_HIGH_IMPEDANCE,
0);
u300_gpio_config_set(&gpio->chip, offset,
PIN_CONFIG_BIAS_HIGH_IMPEDANCE);

/* Set drive mode for output */
u300_gpio_config(&gpio->chip, offset,
PIN_CONFIG_DRIVE_PUSH_PULL, 0);
u300_gpio_config_set(&gpio->chip, offset,
PIN_CONFIG_DRIVE_PUSH_PULL);

dev_dbg(gpio->dev, "set up pin %d as output, value: %d\n",
offset, conf->outval);
Expand All @@ -637,7 +698,7 @@ static void __init u300_gpio_init_pin(struct u300_gpio *gpio,
u300_gpio_set(&gpio->chip, offset, 0);

/* Set bias mode for input */
u300_gpio_config(&gpio->chip, offset, conf->bias_mode, 0);
u300_gpio_config_set(&gpio->chip, offset, conf->bias_mode);

dev_dbg(gpio->dev, "set up pin %d as input, bias: %04x\n",
offset, conf->bias_mode);
Expand Down
5 changes: 5 additions & 0 deletions trunk/drivers/pinctrl/pinctrl-coh901.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
int u300_gpio_config_get(struct gpio_chip *chip,
unsigned offset,
unsigned long *config);
int u300_gpio_config_set(struct gpio_chip *chip, unsigned offset,
enum pin_config_param param);
60 changes: 60 additions & 0 deletions trunk/drivers/pinctrl/pinctrl-u300.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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,
};

Expand Down

0 comments on commit 335db4c

Please sign in to comment.