update for gpio
author沈睿汀 <srt@rock-chips.com>
Thu, 29 Apr 2010 09:12:25 +0000 (09:12 +0000)
committer黄涛 <huangtao@rock-chips.com>
Mon, 21 Jun 2010 05:34:48 +0000 (13:34 +0800)
drivers/gpio/gpiolib.c
include/asm-generic/gpio.h

index 50de0f5750d8b4f5e76c853fe590f08fe52c1a22..57f3042cf9d214b84642648ccd5c8427cf2147c1 100644 (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 @@ fail:
 }
 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);
 
index 66d6106a2067fefc1f4154e500d93ea889f94cd6..f68ea6e02b7e6dd57809c06fd04dbc531911d1d9 100644 (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);