2011-08-18 12:40:30     gpio_keys and polarity

Document created by Aaronwu Employee on Aug 27, 2013
Version 1Show Document
  • View in full screen mode

2011-08-18 12:40:30     gpio_keys and polarity

Kolja Waschk (GERMANY)

Message: 103001   

 

Hi,

 

I'm starting to use gpio_keys on a BF537 STAMP derivative, but get inverted values in the input_event structure.

 

The pins that trigger EV_KEY events are PG13 and PG14, configured in the board setup as low active:

 

static struct gpio_keys_button bfin_gpio_keys_table[] = {

    {BTN_0, GPIO_PG13, 1, "gpio-keys: BTN0"},

    {BTN_1, GPIO_PG14, 1, "gpio-keys: BTN1"}

};

 

Somehow, when gpio_keys loads (as a module) and requests GPIOs and interrupts, PORTGIO_POLAR changes from 0x0000 to 0x6000 effectively inverting the pins. However, the "active_low" setting from bfin_gpio_keys_table[] is applied too in gpio_keys_report_event:

 

  int state = (gpio_get_value(button->gpio) ? 1 : 0) ^ button->active_low;

 

The resulting value in the input_event structure then is 0 when I press my active low button and 1 when I release it

 

Is this intended to behave as is?

 

Kernel bf537-2.6.34.7-ADI-2010R1

 

The only gpio-related patch I have in my kernel is an additional set_gpio_data(number, 0) as described in

 

https://mail.gna.org/public/xenomai-help/2011-08/msg00087.html

 

which I hope doesn't interfere with the output value(?)

 

Thanks for any ideas regarding this!

 

Kolja

QuoteReplyEditDelete

 

 

2011-08-18 12:42:03     Re: gpio_keys and polarity

Kolja Waschk (GERMANY)

Message: 103002   

 

Hi,

 

I'm starting to use gpio_keys on a BF537 STAMP derivative, but get inverted values in the input_event structure.

 

The pins that trigger EV_KEY events are PG13 and PG14, configured in the board setup as low active:

 

static struct gpio_keys_button bfin_gpio_keys_table[] = {

    {BTN_0, GPIO_PG13, 1, "gpio-keys: BTN0"},

    {BTN_1, GPIO_PG14, 1, "gpio-keys: BTN1"}

};

 

Somehow, when gpio_keys loads (as a module) and requests GPIOs and interrupts, PORTGIO_POLAR changes from 0x0000 to 0x6000 effectively inverting the pins. However, the "active_low" setting from bfin_gpio_keys_table[] is applied too in gpio_keys_report_event:

 

  int state = (gpio_get_value(button->gpio) ? 1 : 0) ^ button->active_low;

 

The resulting value in the input_event structure then is 0 when I press my active low button and 1 when I release it (according to the input event documentation, a button down event should occur with value 1).

 

Is this intended to behave as is?

 

Kernel bf537-2.6.34.7-ADI-2010R1

 

The only gpio-related patch I have in my kernel is an additional set_gpio_data(number, 0) as described in

 

https://mail.gna.org/public/xenomai-help/2011-08/msg00087.html

 

which I hope doesn't interfere with the output value(?)

 

Thanks for any ideas regarding this!

 

Kolja

 

---

QuoteReplyEditDelete

 

 

2011-08-18 12:43:11     Re: gpio_keys and polarity

Kolja Waschk (GERMANY)

Message: 103003   

 

Sorry for the double post (added only "according to the input event documentation, a button down event should occur with value 1")

QuoteReplyEditDelete

 

 

2011-08-18 13:17:19     Re: gpio_keys and polarity

Kolja Waschk (GERMANY)

Message: 103005   

 

This seems to fix it but I'm not sure about all possible side effects. It avoids the inverted polarity if the interrupt should occur on both edges anyway.

 

--- linux-2.6.x/arch/blackfin/mach-common/ints-priority.c.orig    2011-08-18 19:11:09.626337740 +0200

+++ linux-2.6.x/arch/blackfin/mach-common/ints-priority.c    2011-08-18 19:11:17.726337735 +0200

@@ -636,14 +638,18 @@

 

     if ((type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING))

         == (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING))

+    {

         set_gpio_both(gpionr, 1);

+    }

     else

+    {

         set_gpio_both(gpionr, 0);

 

-    if ((type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_LEVEL_LOW)))

-        set_gpio_polar(gpionr, 1);    /* low or falling edge denoted by one */

-    else

-        set_gpio_polar(gpionr, 0);    /* high or rising edge denoted by zero */

+        if ((type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_LEVEL_LOW)))

+            set_gpio_polar(gpionr, 1);    /* low or falling edge denoted by one */

+        else

+            set_gpio_polar(gpionr, 0);    /* high or rising edge denoted by zero */

+    }

Attachments

    Outcomes