Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-2.6
[firefly-linux-kernel-4.4.55.git] / drivers / gpio / wm831x-gpio.c
index 1fa449a1a4cb9f5df485ee505bb3263aeaac120c..309644cf4d9b178cd8d91a2d57e348497f7c76c0 100644 (file)
@@ -108,6 +108,37 @@ static int wm831x_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
        return wm831x->irq_base + WM831X_IRQ_GPIO_1 + offset;
 }
 
+static int wm831x_gpio_set_debounce(struct gpio_chip *chip, unsigned offset,
+                                   unsigned debounce)
+{
+       struct wm831x_gpio *wm831x_gpio = to_wm831x_gpio(chip);
+       struct wm831x *wm831x = wm831x_gpio->wm831x;
+       int reg = WM831X_GPIO1_CONTROL + offset;
+       int ret, fn;
+
+       ret = wm831x_reg_read(wm831x, reg);
+       if (ret < 0)
+               return ret;
+
+       switch (ret & WM831X_GPN_FN_MASK) {
+       case 0:
+       case 1:
+               break;
+       default:
+               /* Not in GPIO mode */
+               return -EBUSY;
+       }
+
+       if (debounce >= 32 && debounce <= 64)
+               fn = 0;
+       else if (debounce >= 4000 && debounce <= 8000)
+               fn = 1;
+       else
+               return -EINVAL;
+
+       return wm831x_set_bits(wm831x, reg, WM831X_GPN_FN_MASK, fn);
+}
+
 #ifdef CONFIG_DEBUG_FS
 static void wm831x_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
 {
@@ -208,6 +239,7 @@ static struct gpio_chip template_chip = {
        .direction_output       = wm831x_gpio_direction_out,
        .set                    = wm831x_gpio_set,
        .to_irq                 = wm831x_gpio_to_irq,
+       .set_debounce           = wm831x_gpio_set_debounce,
        .dbg_show               = wm831x_gpio_dbg_show,
        .can_sleep              = 1,
 };