@@ -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,