From: Yang QU <yang...@stericsson.com>

Set GpioPullUpDownSel register for direction output function as GPIO51
to GPIO54 not share the same register with other GPIOs on AB8540.

Signed-off-by: Lee Jones <lee.jo...@linaro.org>
Signed-off-by: Yang QU <yang...@stericsson.com>
Reviewed-by: Patrick DELAUNAY <patrick.delau...@stericsson.com>
Reviewed-by: Xiao Mei ZHANG <xiaomei.zh...@stericsson.com>
Reviewed-by: Philippe LANGLAIS <philippe.langl...@stericsson.com>
Reviewed-by: Maxime COQUELIN <maxime.coque...@stericsson.com>
Reviewed-by: Jonas ABERG <jonas.ab...@stericsson.com>
Reviewed-by: Mattias WALLIN <mattias.wal...@stericsson.com>
---
 drivers/gpio/gpio-ab8500.c |   33 +++++++++++++++++++++++++--------
 1 file changed, 25 insertions(+), 8 deletions(-)

diff --git a/drivers/gpio/gpio-ab8500.c b/drivers/gpio/gpio-ab8500.c
index edc3037..ed5832e 100644
--- a/drivers/gpio/gpio-ab8500.c
+++ b/drivers/gpio/gpio-ab8500.c
@@ -86,6 +86,8 @@
 #define AB8500_NUM_VIR_GPIO_IRQ        16
 #define AB8540_GPIO_PULL_UPDOWN_MASK   0x03
 #define AB8540_GPIO_VINSEL_MASK        0x03
+#define AB8540_GPIOX_VBAT_START        51
+#define AB8540_GPIOX_VBAT_END  54
 
 enum ab8500_gpio_action {
        NONE,
@@ -222,6 +224,7 @@ static void ab8500_gpio_set(struct gpio_chip *chip, 
unsigned offset, int val)
 static int ab8500_gpio_direction_output(struct gpio_chip *chip, unsigned 
offset,
                                        int val)
 {
+       struct ab8500_gpio *ab8500_gpio = to_ab8500_gpio(chip);
        int ret;
        /* set direction as output */
        ret = ab8500_gpio_set_bits(chip, AB8500_GPIO_DIR1_REG, offset, 1);
@@ -231,6 +234,18 @@ static int ab8500_gpio_direction_output(struct gpio_chip 
*chip, unsigned offset,
        ret = ab8500_gpio_set_bits(chip, AB8500_GPIO_PUD1_REG, offset, 1);
        if (ret < 0)
                return ret;
+       /*
+        * Disable both pull down and pull up for GPIO51 to GPIO54 (GPIO1_VBAT
+        * to GPIO4_VBAT).
+        */
+       if (is_ab8540(ab8500_gpio->parent)) {
+               if (offset >= (AB8540_GPIOX_VBAT_START - 1)
+                       && offset <= (AB8540_GPIOX_VBAT_END - 1))
+                       ret = ab8540_config_pull_updown(ab8500_gpio->dev,
+                               AB8500_PIN_GPIO(offset + 1), 
AB8540_GPIO_PULL_NONE);
+               if (ret < 0)
+                       return ret;
+       }
        /* set the output as 1 or 0 */
        return ab8500_gpio_set_bits(chip, AB8500_GPIO_OUT1_REG, offset, val);
 
@@ -278,10 +293,10 @@ static unsigned int irq_to_rising(unsigned int irq)
        int offset = irq - ab8500_gpio->irq_base;
        int new_irq;
        if (is_ab8540(ab8500_gpio->parent)) {
-               new_irq = offset * 2 +  AB8540_INT_GPIO43R
+               new_irq = offset * 2 + AB8540_INT_GPIO43R
                        + ab8500_gpio->parent->irq_base;
        } else
-               new_irq = offset +  AB8500_INT_GPIO6R
+               new_irq = offset + AB8500_INT_GPIO6R
                        + ab8500_gpio->parent->irq_base;
        return new_irq;
 }
@@ -292,10 +307,10 @@ static unsigned int irq_to_falling(unsigned int irq)
        int offset = irq - ab8500_gpio->irq_base;
        int new_irq;
        if (is_ab8540(ab8500_gpio->parent)) {
-               new_irq = offset * 2 +  AB8540_INT_GPIO43F
+               new_irq = offset * 2 + AB8540_INT_GPIO43F
                        + ab8500_gpio->parent->irq_base;
        } else
-               new_irq = offset +  AB8500_INT_GPIO6F
+               new_irq = offset + AB8500_INT_GPIO6F
                        + ab8500_gpio->parent->irq_base;
        return new_irq;
 
@@ -670,12 +685,13 @@ int ab8540_config_pull_updown(struct device *dev,
        u8 pos;
        int ret;
 
-       if ((gpio < AB8500_PIN_GPIO(51)) || (gpio > AB8500_PIN_GPIO(54))) {
+       if ((gpio < AB8500_PIN_GPIO(AB8540_GPIOX_VBAT_START))
+               || (gpio > AB8500_PIN_GPIO(AB8540_GPIOX_VBAT_END))) {
                ret = -EINVAL;
                goto out;
        }
 
-       pos = (gpio - AB8500_PIN_GPIO(51)) << 1;
+       pos = (gpio - AB8500_PIN_GPIO(AB8540_GPIOX_VBAT_START)) << 1;
 
        ret = abx500_mask_and_set_register_interruptible(dev,
                        AB8500_MISC, AB8540_GPIO_PULL_UPDOWN_REG,
@@ -694,12 +710,13 @@ int ab8540_gpio_config_vinsel(struct device *dev,
        u8 pos;
        int ret;
 
-       if ((gpio < AB8500_PIN_GPIO(51)) || (gpio > AB8500_PIN_GPIO(54))) {
+       if ((gpio < AB8500_PIN_GPIO(AB8540_GPIOX_VBAT_START))
+               || (gpio > AB8500_PIN_GPIO(AB8540_GPIOX_VBAT_END))) {
                ret = -EINVAL;
                goto out;
        }
 
-       pos = (gpio - AB8500_PIN_GPIO(51)) << 1;
+       pos = (gpio - AB8500_PIN_GPIO(AB8540_GPIOX_VBAT_START)) << 1;
 
        ret = abx500_mask_and_set_register_interruptible(dev,
                        AB8500_MISC, AB8540_GPIO_VINSEL_REG,
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to