diff options
Diffstat (limited to 'drivers/mfd/wm831x-irq.c')
-rw-r--r-- | drivers/mfd/wm831x-irq.c | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/drivers/mfd/wm831x-irq.c b/drivers/mfd/wm831x-irq.c index 301327697117..4c1122ceb443 100644 --- a/drivers/mfd/wm831x-irq.c +++ b/drivers/mfd/wm831x-irq.c @@ -21,6 +21,7 @@ #include <linux/mfd/wm831x/core.h> #include <linux/mfd/wm831x/pdata.h> +#include <linux/mfd/wm831x/gpio.h> #include <linux/mfd/wm831x/irq.h> #include <linux/delay.h> @@ -388,12 +389,41 @@ static void wm831x_irq_mask(unsigned int irq) wm831x->irq_masks_cur[irq_data->reg - 1] |= irq_data->mask; } +static int wm831x_irq_set_type(unsigned int irq, unsigned int type) +{ + struct wm831x *wm831x = get_irq_chip_data(irq); + int val; + + irq = irq - wm831x->irq_base; + + if (irq < WM831X_IRQ_GPIO_1 || irq > WM831X_IRQ_GPIO_11) + return -EINVAL; + + switch (type) { + case IRQ_TYPE_EDGE_BOTH: + val = WM831X_GPN_INT_MODE; + break; + case IRQ_TYPE_EDGE_RISING: + val = WM831X_GPN_POL; + break; + case IRQ_TYPE_EDGE_FALLING: + val = 0; + break; + default: + return -EINVAL; + } + + return wm831x_set_bits(wm831x, WM831X_GPIO1_CONTROL + irq, + WM831X_GPN_INT_MODE | WM831X_GPN_POL, val); +} + static struct irq_chip wm831x_irq_chip = { .name = "wm831x", .bus_lock = wm831x_irq_lock, .bus_sync_unlock = wm831x_irq_sync_unlock, .mask = wm831x_irq_mask, .unmask = wm831x_irq_unmask, + .set_type = wm831x_irq_set_type, }; /* The processing of the primary interrupt occurs in a thread so that |