diff options
-rw-r--r-- | drivers/gpio/wm831x-gpio.c | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/drivers/gpio/wm831x-gpio.c b/drivers/gpio/wm831x-gpio.c index 1fa449a1a4cb..309644cf4d9b 100644 --- a/drivers/gpio/wm831x-gpio.c +++ b/drivers/gpio/wm831x-gpio.c @@ -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, }; |