update for gpio

This commit is contained in:
沈睿汀 2010-04-29 09:12:25 +00:00 committed by 黄涛
parent d263011106
commit 65d56d9355
2 changed files with 85 additions and 6 deletions

View File

@ -1204,6 +1204,8 @@ int gpio_direction_output(unsigned gpio, int value)
spin_lock_irqsave(&gpio_lock, flags);
if (value !=0 && value !=1)
goto fail;
if (!gpio_is_valid(gpio))
goto fail;
chip = desc->chip;
@ -1248,6 +1250,70 @@ int gpio_direction_output(unsigned gpio, int value)
}
EXPORT_SYMBOL_GPL(gpio_direction_output);
/*
gpio pull up or pull down
value = 0, normal
value = 1, pull up
value = 2, pull down
*/
int gpio_pull_updown(unsigned gpio, unsigned value)
{
unsigned long flags;
struct gpio_chip *chip;
struct gpio_desc *desc = &gpio_desc[gpio];
int status = -EINVAL;
spin_lock_irqsave(&gpio_lock, flags);
if (value >3)
goto fail;
if (!gpio_is_valid(gpio))
goto fail;
chip = desc->chip;
if (!chip || !chip->get || !chip->pull_updown)
goto fail;
gpio -= chip->base;
if (gpio >= chip->ngpio)
goto fail;
status = gpio_ensure_requested(desc, gpio);
if (status < 0)
goto fail;
/* now we know the gpio is valid and chip won't vanish */
spin_unlock_irqrestore(&gpio_lock, flags);
might_sleep_if(extra_checks && chip->can_sleep);
if (status) {
status = chip->request(chip, gpio);
if (status < 0) {
pr_debug("GPIO-%d: chip request fail, %d\n",
chip->base + gpio, status);
/* and it's not available to anyone else ...
* gpio_request() is the fully clean solution.
*/
goto lose;
}
}
if(chip->pull_updown)
{
status = chip->pull_updown(chip, gpio,value);
if (status == 0)
clear_bit(FLAG_IS_OUT, &desc->flags);
}
lose:
return status;
fail:
spin_unlock_irqrestore(&gpio_lock, flags);
if (status)
pr_debug("%s: gpio-%d status %d\n",
__func__, gpio, status);
return status;
}
EXPORT_SYMBOL_GPL(gpio_pull_updown);
/* I/O calls are only valid after configuration completed; the relevant
* "is this a valid GPIO" error checks should already have been done.
@ -1283,7 +1349,9 @@ EXPORT_SYMBOL_GPL(gpio_direction_output);
int __gpio_get_value(unsigned gpio)
{
struct gpio_chip *chip;
if (!gpio_is_valid(gpio))
return -1;
chip = gpio_to_chip(gpio);
WARN_ON(extra_checks && chip->can_sleep);
return chip->get ? chip->get(chip, gpio - chip->base) : 0;
@ -1303,6 +1371,10 @@ void __gpio_set_value(unsigned gpio, int value)
{
struct gpio_chip *chip;
if(value !=0 && value !=1)
return;
if (!gpio_is_valid(gpio))
return;
chip = gpio_to_chip(gpio);
WARN_ON(extra_checks && chip->can_sleep);
chip->set(chip, gpio - chip->base, value);
@ -1340,9 +1412,13 @@ EXPORT_SYMBOL_GPL(__gpio_cansleep);
int __gpio_to_irq(unsigned gpio)
{
struct gpio_chip *chip;
if (!gpio_is_valid(gpio))
return -1;
chip = gpio_to_chip(gpio);
return chip->to_irq ? chip->to_irq(chip, gpio - chip->base) : -ENXIO;
return chip->to_irq ? chip->to_irq(chip, gpio - chip->base) : -1;
}
EXPORT_SYMBOL_GPL(__gpio_to_irq);

View File

@ -89,14 +89,17 @@ struct gpio_chip {
unsigned offset, int value);
void (*set)(struct gpio_chip *chip,
unsigned offset, int value);
int (*pull_updown)(struct gpio_chip *chip,
unsigned offset, unsigned value);
int (*to_irq)(struct gpio_chip *chip,
unsigned offset);
void (*dbg_show)(struct seq_file *s,
struct gpio_chip *chip);
int base;
u16 ngpio;
int base;// GPIOX_Y其中X=0/1;Y=A/B/C/D的第一个PIN的逻辑位置
u16 ngpio;//GPIOX_Y其中X=0/1;Y=A/B/C/D的PIN总数
char **names;
unsigned can_sleep:1;
unsigned exported:1;
@ -119,7 +122,7 @@ extern void gpio_free(unsigned gpio);
extern int gpio_direction_input(unsigned gpio);
extern int gpio_direction_output(unsigned gpio, int value);
extern int gpio_pull_updown(unsigned gpio, unsigned value);
extern int gpio_get_value_cansleep(unsigned gpio);
extern void gpio_set_value_cansleep(unsigned gpio, int value);