aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio
diff options
context:
space:
mode:
authorWeike Chen <alvin.chen@intel.com>2014-09-17 12:18:41 -0400
committerLinus Walleij <linus.walleij@linaro.org>2014-09-23 11:51:38 -0400
commit5d60d9efe1447b46f33075fb5841fd83247cdbb2 (patch)
treea947ba97594ecc9c521cfd08ab5f29541ba221e2 /drivers/gpio
parent67809b974a07042dc61cb9d06e30df7a5f25446a (diff)
GPIO: gpio-dwapb: Support Debounce
This patch enables 'debounce' for the designware GPIO, and it is based on Josef Ahmad's previous work. Reviewed-by: Hock Leong Kweh <hock.leong.kweh@intel.com> Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Signed-off-by: Weike Chen <alvin.chen@intel.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/gpio')
-rw-r--r--drivers/gpio/gpio-dwapb.c36
1 files changed, 34 insertions, 2 deletions
diff --git a/drivers/gpio/gpio-dwapb.c b/drivers/gpio/gpio-dwapb.c
index 551eaf7208f4..db059bb8edc3 100644
--- a/drivers/gpio/gpio-dwapb.c
+++ b/drivers/gpio/gpio-dwapb.c
@@ -37,6 +37,7 @@
37#define GPIO_INTTYPE_LEVEL 0x38 37#define GPIO_INTTYPE_LEVEL 0x38
38#define GPIO_INT_POLARITY 0x3c 38#define GPIO_INT_POLARITY 0x3c
39#define GPIO_INTSTATUS 0x40 39#define GPIO_INTSTATUS 0x40
40#define GPIO_PORTA_DEBOUNCE 0x48
40#define GPIO_PORTA_EOI 0x4c 41#define GPIO_PORTA_EOI 0x4c
41#define GPIO_EXT_PORTA 0x50 42#define GPIO_EXT_PORTA 0x50
42#define GPIO_EXT_PORTB 0x54 43#define GPIO_EXT_PORTB 0x54
@@ -64,6 +65,12 @@ struct dwapb_gpio {
64 struct irq_domain *domain; 65 struct irq_domain *domain;
65}; 66};
66 67
68static inline struct dwapb_gpio_port *
69to_dwapb_gpio_port(struct bgpio_chip *bgc)
70{
71 return container_of(bgc, struct dwapb_gpio_port, bgc);
72}
73
67static inline u32 dwapb_read(struct dwapb_gpio *gpio, unsigned int offset) 74static inline u32 dwapb_read(struct dwapb_gpio *gpio, unsigned int offset)
68{ 75{
69 struct bgpio_chip *bgc = &gpio->ports[0].bgc; 76 struct bgpio_chip *bgc = &gpio->ports[0].bgc;
@@ -84,8 +91,7 @@ static inline void dwapb_write(struct dwapb_gpio *gpio, unsigned int offset,
84static int dwapb_gpio_to_irq(struct gpio_chip *gc, unsigned offset) 91static int dwapb_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
85{ 92{
86 struct bgpio_chip *bgc = to_bgpio_chip(gc); 93 struct bgpio_chip *bgc = to_bgpio_chip(gc);
87 struct dwapb_gpio_port *port = container_of(bgc, struct 94 struct dwapb_gpio_port *port = to_dwapb_gpio_port(bgc);
88 dwapb_gpio_port, bgc);
89 struct dwapb_gpio *gpio = port->gpio; 95 struct dwapb_gpio *gpio = port->gpio;
90 96
91 return irq_find_mapping(gpio->domain, offset); 97 return irq_find_mapping(gpio->domain, offset);
@@ -235,6 +241,28 @@ static int dwapb_irq_set_type(struct irq_data *d, u32 type)
235 return 0; 241 return 0;
236} 242}
237 243
244static int dwapb_gpio_set_debounce(struct gpio_chip *gc,
245 unsigned offset, unsigned debounce)
246{
247 struct bgpio_chip *bgc = to_bgpio_chip(gc);
248 struct dwapb_gpio_port *port = to_dwapb_gpio_port(bgc);
249 struct dwapb_gpio *gpio = port->gpio;
250 unsigned long flags, val_deb;
251 unsigned long mask = bgc->pin2mask(bgc, offset);
252
253 spin_lock_irqsave(&bgc->lock, flags);
254
255 val_deb = dwapb_read(gpio, GPIO_PORTA_DEBOUNCE);
256 if (debounce)
257 dwapb_write(gpio, GPIO_PORTA_DEBOUNCE, val_deb | mask);
258 else
259 dwapb_write(gpio, GPIO_PORTA_DEBOUNCE, val_deb & ~mask);
260
261 spin_unlock_irqrestore(&bgc->lock, flags);
262
263 return 0;
264}
265
238static irqreturn_t dwapb_irq_handler_mfd(int irq, void *dev_id) 266static irqreturn_t dwapb_irq_handler_mfd(int irq, void *dev_id)
239{ 267{
240 u32 worked; 268 u32 worked;
@@ -373,6 +401,10 @@ static int dwapb_gpio_add_port(struct dwapb_gpio *gpio,
373 port->bgc.gc.ngpio = pp->ngpio; 401 port->bgc.gc.ngpio = pp->ngpio;
374 port->bgc.gc.base = pp->gpio_base; 402 port->bgc.gc.base = pp->gpio_base;
375 403
404 /* Only port A support debounce */
405 if (pp->idx == 0)
406 port->bgc.gc.set_debounce = dwapb_gpio_set_debounce;
407
376 if (pp->irq) 408 if (pp->irq)
377 dwapb_configure_irqs(gpio, port, pp); 409 dwapb_configure_irqs(gpio, port, pp);
378 410