On Tue, Dec 30, 2008 at 5:50 PM, Andy Green <[email protected]> wrote: > -----BEGIN PGP SIGNED MESSAGE----- > Hash: SHA1 > > Somebody in the thread at some point said: > |> + if (irq == keys[n].irq) { > |> + if (machine_is_neo1973_gta01() && > global_inside_suspend > |> + && NEO1973_KEY_AUX == n) { > |> + /* if you stall inside resume then > AUX will > |> + * force a panic, which in turn > forces a dump > |> + * of the pending syslog */ > |> + int *p = NULL; > |> + printk(KERN_ERR "death %d\n", *p); > |> + } > | > | I assumed the following patch was gta01 specific but I am not sure > anymore. > | > | > http://git.openmoko.org/?p=kernel.git;a=commitdiff;h=a1afc307edcd2b46dcd963373d5eef0b21a4617b > | > | It is useful for GTA02 also, right? > > Yes it was made for GTA02 resume troubles actually.
Please use the attached patch that fixes my wrong assumption. N.-
[Resend] Filter key bouncing for more keys From: Nelson Castillo <[email protected]> This patch filters key bouncing. We store the state of the buttons and only change it when we notice that at least AUX_TIMER_CONSECUTIVE_EVENTS consecutive equal GPIO reads occur. This patch removes the function neo1973kbd_aux_irq and now we use the default handler for the AUX button also. Tested with : GTA02. We need to test with GTA01/GTA03. Signed-off-by: Nelson Castillo <[email protected]> --- drivers/input/keyboard/neo1973kbd.c | 131 ++++++++++++++++++----------------- 1 files changed, 69 insertions(+), 62 deletions(-) diff --git a/drivers/input/keyboard/neo1973kbd.c b/drivers/input/keyboard/neo1973kbd.c index 20f0a34..4d29725 100644 --- a/drivers/input/keyboard/neo1973kbd.c +++ b/drivers/input/keyboard/neo1973kbd.c @@ -1,7 +1,7 @@ /* * Keyboard driver for FIC Neo1973 GSM phone * - * (C) 2006-2007 by Openmoko, Inc. + * (C) 2006-2009 by Openmoko, Inc. * Author: Harald Welte <[email protected]> * All rights reserved. * @@ -33,7 +33,6 @@ struct neo1973kbd { struct input_dev *input; struct device *cdev; struct work_struct work; - int aux_state; int work_in_progress; int hp_irq_count_in_work; int hp_irq_count; @@ -55,9 +54,15 @@ struct neo1973kbd_key { irqreturn_t (*isr)(int irq, void *dev_id); int irq; int input_key; + + /* the following are used to filter bouncing */ + int last; + int last_count; + int state; + int noop_counter; + int active; }; -static irqreturn_t neo1973kbd_aux_irq(int irq, void *dev_id); static irqreturn_t neo1973kbd_headphone_irq(int irq, void *dev_id); static irqreturn_t neo1973kbd_default_key_irq(int irq, void *dev_id); @@ -65,7 +70,7 @@ static irqreturn_t neo1973kbd_default_key_irq(int irq, void *dev_id); static struct neo1973kbd_key keys[] = { [NEO1973_KEY_AUX] = { .name = "Neo1973 AUX button", - .isr = neo1973kbd_aux_irq, + .isr = neo1973kbd_default_key_irq, .input_key = KEY_PHONE, }, [NEO1973_KEY_HOLD] = { @@ -89,86 +94,88 @@ static struct neo1973kbd_key keys[] = { }, }; -/* This timer section filters AUX button IRQ bouncing */ +/* This timer section filters button IRQ bouncing */ -static void aux_key_timer_f(unsigned long data); +static void kbd_key_timer_f(unsigned long data); -static struct timer_list aux_key_timer = - TIMER_INITIALIZER(aux_key_timer_f, 0, 0); +static struct timer_list kbd_key_timer = + TIMER_INITIALIZER(kbd_key_timer_f, 0, 0); -#define AUX_TIMER_TIMEOUT (HZ >> 7) -#define AUX_TIMER_ALLOWED_NOOP 2 -#define AUX_TIMER_CONSECUTIVE_EVENTS 5 +#define KBD_TIMER_TIMEOUT (HZ >> 7) +#define KBD_TIMER_ALLOWED_NOOP 2 +#define KBD_TIMER_CONSECUTIVE_EVENTS 5 struct neo1973kbd *timer_kbd; -static void aux_key_timer_f(unsigned long data) +static void kbd_key_timer_f(unsigned long data) { - static int noop_counter; - static int last_key = -1; - static int last_count; - int key_pressed; - - key_pressed = - !gpio_get_value(timer_kbd->pdev->resource[NEO1973_KEY_AUX].start); - if (machine_is_neo1973_gta02()) - key_pressed = !key_pressed; - - if (likely(key_pressed == last_key)) - last_count++; - else { - last_count = 1; - last_key = key_pressed; - } - - if (unlikely(last_count >= AUX_TIMER_CONSECUTIVE_EVENTS)) { - if (timer_kbd->aux_state != last_key) { - input_report_key(timer_kbd->input, KEY_PHONE, last_key); - input_sync(timer_kbd->input); + int n; + int nactive = 0; - timer_kbd->aux_state = last_key; - noop_counter = 0; - } - last_count = 0; - if (unlikely(++noop_counter > AUX_TIMER_ALLOWED_NOOP)) { - noop_counter = 0; - return; - } - } + for (n = 0; n < ARRAY_SIZE(keys); n++) { + int key_pressed; - mod_timer(&aux_key_timer, jiffies + AUX_TIMER_TIMEOUT); -} + if (!keys[n].active) + continue; + nactive++; -static irqreturn_t neo1973kbd_aux_irq(int irq, void *dev) -{ - int *p = NULL; + key_pressed = + gpio_get_value(timer_kbd->pdev->resource[n].start); - /* if you stall inside resume then AUX will force a panic, - which in turn forces a dump of the pending syslog */ + /* the only exception */ + if (machine_is_neo1973_gta01() && n == NEO1973_KEY_AUX) + key_pressed = !key_pressed; - if (global_inside_suspend) - printk(KERN_ERR "death %d\n", *p); + if (likely(key_pressed == keys[n].last)) { + keys[n].last_count++; + } else { + keys[n].last_count = 1; + keys[n].last = key_pressed; + } - mod_timer(&aux_key_timer, jiffies + AUX_TIMER_TIMEOUT); + if (unlikely(keys[n].last_count >= + KBD_TIMER_CONSECUTIVE_EVENTS)) { + if (keys[n].state != keys[n].last) { + input_report_key(timer_kbd->input, + keys[n].input_key, + key_pressed); + input_sync(timer_kbd->input); + keys[n].state = keys[n].last; + keys[n].noop_counter = 0; + } + keys[n].last_count = 0; + if (unlikely(++keys[n].noop_counter > + KBD_TIMER_ALLOWED_NOOP)) { + keys[n].noop_counter = 0; + keys[n].active = 0; + } + } + } - return IRQ_HANDLED; + if (nactive) + mod_timer(&kbd_key_timer, jiffies + KBD_TIMER_TIMEOUT); } static irqreturn_t neo1973kbd_default_key_irq(int irq, void *dev_id) { - struct neo1973kbd *kbd = dev_id; int n; - for (n = 0; n < ARRAY_SIZE(keys); n++) { + if (irq == keys[n].irq) { + if (global_inside_suspend && NEO1973_KEY_AUX == n) { + /* if you stall inside resume then AUX will + * force a panic, which in turn forces a dump + * of the pending syslog. This depends on other + * patches that will be removed before sending + * upstream. FIXME: Remove this code. */ + int *p = NULL; + printk(KERN_ERR "death %d\n", *p); + } - if (irq != keys[n].irq) - continue; - - input_report_key(kbd->input, keys[n].input_key, - gpio_get_value(kbd->pdev->resource[n].start)); - input_sync(kbd->input); + keys[n].active = 1; + mod_timer(&kbd_key_timer, jiffies + KBD_TIMER_TIMEOUT); + break; + } } - return IRQ_HANDLED; }
