Merge branch 'devel' of master.kernel.org:/home/rmk/linux-2.6-arm
[pandora-kernel.git] / arch / arm / plat-samsung / gpio-config.c
index 44a84e8..3282db3 100644 (file)
@@ -1,7 +1,7 @@
 /* linux/arch/arm/plat-s3c/gpio-config.c
  *
  * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
+ * Copyright 2008-2010 Simtec Electronics
  *     Ben Dooks <ben@simtec.co.uk>
  *     http://armlinux.simtec.co.uk/
  *
@@ -41,6 +41,26 @@ int s3c_gpio_cfgpin(unsigned int pin, unsigned int config)
 }
 EXPORT_SYMBOL(s3c_gpio_cfgpin);
 
+unsigned s3c_gpio_getcfg(unsigned int pin)
+{
+       struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
+       unsigned long flags;
+       unsigned ret = 0;
+       int offset;
+
+       if (chip) {
+               offset = pin - chip->chip.base;
+
+               local_irq_save(flags);
+               ret = s3c_gpio_do_getcfg(chip, offset);
+               local_irq_restore(flags);
+       }
+
+       return ret;
+}
+EXPORT_SYMBOL(s3c_gpio_getcfg);
+
+
 int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull)
 {
        struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
@@ -61,8 +81,8 @@ int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull)
 EXPORT_SYMBOL(s3c_gpio_setpull);
 
 #ifdef CONFIG_S3C_GPIO_CFG_S3C24XX
-int s3c_gpio_setcfg_s3c24xx_banka(struct s3c_gpio_chip *chip,
-                                 unsigned int off, unsigned int cfg)
+int s3c_gpio_setcfg_s3c24xx_a(struct s3c_gpio_chip *chip,
+                             unsigned int off, unsigned int cfg)
 {
        void __iomem *reg = chip->base;
        unsigned int shift = off;
@@ -87,6 +107,19 @@ int s3c_gpio_setcfg_s3c24xx_banka(struct s3c_gpio_chip *chip,
        return 0;
 }
 
+unsigned s3c_gpio_getcfg_s3c24xx_a(struct s3c_gpio_chip *chip,
+                                  unsigned int off)
+{
+       u32 con;
+
+       con = __raw_readl(chip->base);
+       con >>= off;
+       con &= 1;
+       con++;
+
+       return S3C_GPIO_SFN(con);
+}
+
 int s3c_gpio_setcfg_s3c24xx(struct s3c_gpio_chip *chip,
                            unsigned int off, unsigned int cfg)
 {
@@ -109,6 +142,19 @@ int s3c_gpio_setcfg_s3c24xx(struct s3c_gpio_chip *chip,
 
        return 0;
 }
+
+unsigned int s3c_gpio_getcfg_s3c24xx(struct s3c_gpio_chip *chip,
+                                    unsigned int off)
+{
+       u32 con;
+
+       con = __raw_readl(chip->base);
+       con >>= off * 2;
+       con &= 3;
+
+       /* this conversion works for IN and OUT as well as special mode */
+       return S3C_GPIO_SPECIAL(con);
+}
 #endif
 
 #ifdef CONFIG_S3C_GPIO_CFG_S3C64XX
@@ -134,6 +180,25 @@ int s3c_gpio_setcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip,
 
        return 0;
 }
+
+unsigned s3c_gpio_getcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip,
+                                     unsigned int off)
+{
+       void __iomem *reg = chip->base;
+       unsigned int shift = (off & 7) * 4;
+       u32 con;
+
+       if (off < 8 && chip->chip.ngpio > 8)
+               reg -= 4;
+
+       con = __raw_readl(reg);
+       con >>= shift;
+       con &= 0xf;
+
+       /* this conversion works for IN and OUT as well as special mode */
+       return S3C_GPIO_SPECIAL(con);
+}
+
 #endif /* CONFIG_S3C_GPIO_CFG_S3C64XX */
 
 #ifdef CONFIG_S3C_GPIO_PULL_UPDOWN
@@ -164,3 +229,35 @@ s3c_gpio_pull_t s3c_gpio_getpull_updown(struct s3c_gpio_chip *chip,
        return (__force s3c_gpio_pull_t)pup;
 }
 #endif
+
+#ifdef CONFIG_S3C_GPIO_PULL_UP
+int s3c_gpio_setpull_1up(struct s3c_gpio_chip *chip,
+                        unsigned int off, s3c_gpio_pull_t pull)
+{
+       void __iomem *reg = chip->base + 0x08;
+       u32 pup = __raw_readl(reg);
+
+       pup = __raw_readl(reg);
+
+       if (pup == S3C_GPIO_PULL_UP)
+               pup &= ~(1 << off);
+       else if (pup == S3C_GPIO_PULL_NONE)
+               pup |= (1 << off);
+       else
+               return -EINVAL;
+
+       __raw_writel(pup, reg);
+       return 0;
+}
+
+s3c_gpio_pull_t s3c_gpio_getpull_1up(struct s3c_gpio_chip *chip,
+                                    unsigned int off)
+{
+       void __iomem *reg = chip->base + 0x08;
+       u32 pup = __raw_readl(reg);
+
+       pup &= (1 << off);
+       return pup ? S3C_GPIO_PULL_NONE : S3C_GPIO_PULL_UP;
+}
+#endif /* CONFIG_S3C_GPIO_PULL_UP */
+