IRQ0-7 input pins on RZ/G2L

Hello,


On our board using an RZ/G2L, I'm using IRQ0-7 input pins and I'm having 2 problems:
- when the input switches from high to low (or vice versa) I receive 2 events whereas I was expecting only one. Is it normal ?
- how can I know whether my input is in high or low state ?

Thanks,

Bertrand

My Device tree :

	ip_sw {
		compatible = "gpio-keys";
		pinctrl-names = "default";		
		#address-cells = <1>;
        #size-cells = <0>;
		
		pinctrl-0 = <&ip_sw_pins>;
		button@0{
			interrupt-parent = <&intc_ex>;
			interrupts = <0 IRQ_TYPE_EDGE_BOTH>;
			linux,code = <KEY_0>;
			label = "SW_CASE";
			debounce-interval = <50>;
		};	
		button@1{
			interrupt-parent = <&intc_ex>;
			interrupts = <1 IRQ_TYPE_EDGE_BOTH>;
			linux,code = <KEY_1>;
			label = "SW_TAMPER";
			debounce-interval = <50>;
		};	
		button@5{
			interrupt-parent = <&intc_ex>;
			interrupts = <5 IRQ_TYPE_EDGE_BOTH>;
			linux,code = <KEY_5>;
			label = "IRQ5_DEBUG";
			debounce-interval = <50>;
		};	
		button@6{
			interrupt-parent = <&intc_ex>;
			interrupts = <6 IRQ_TYPE_EDGE_BOTH>;
			linux,code = <KEY_6>;
			label = "IRQ6_DEBUG";
			debounce-interval = <50>;
		};	
		button@7{
			interrupt-parent = <&intc_ex>;
			interrupts = <7 IRQ_TYPE_EDGE_BOTH>;
			linux,code = <KEY_7>;
			label = "IRQ7_DEBUG";
			debounce-interval = <50>;
		};	
	};

&intc_ex {
	status = "okay";
};

	ip_sw_pins: ip_sw {
		pinmux = <
			RZG2L_PORT_PINMUX(0, 0, 1)	/* IRQ0 */
			RZG2L_PORT_PINMUX(0, 1, 1)	/* IRQ1 */
			RZG2L_PORT_PINMUX(17, 0, 4)	/* IRQ5 */
			RZG2L_PORT_PINMUX(17, 1, 4)	/* IRQ6 */
			RZG2L_PORT_PINMUX(17, 2, 3)	/* IRQ7 */
		>;
	};	

Evtest :

# evtest /dev/input/event0
Input driver version is 1.0.1
Input device ID: bus 0x19 vendor 0x1 product 0x1 version 0x100
Input device name: "ip_sw"
Supported events:
  Event type 0 (EV_SYN)
  Event type 1 (EV_KEY)
    Event code 2 (KEY_1)
    Event code 6 (KEY_5)
    Event code 7 (KEY_6)
    Event code 8 (KEY_7)
    Event code 11 (KEY_0)
Properties:
Testing ... (interrupt to exit)

// Low to High
Event: time 946685006.290426, type 1 (EV_KEY), code 11 (KEY_0), value 1
Event: time 946685006.290426, -------------- SYN_REPORT ------------
Event: time 946685006.343280, type 1 (EV_KEY), code 11 (KEY_0), value 0
Event: time 946685006.343280, -------------- SYN_REPORT ------------


// High to low
Event: time 946685028.676889, type 1 (EV_KEY), code 11 (KEY_0), value 1
Event: time 946685028.676889, -------------- SYN_REPORT ------------
Event: time 946685028.731532, type 1 (EV_KEY), code 11 (KEY_0), value 0
Event: time 946685028.731532, -------------- SYN_REPORT ------------

  • Hi,

    Try the following.

    Make each of the following three changes to your current device tree, run evtest, and compare each result to the current result.

    • Change the value of the debounce-interval property in your device tree from 50 to e.g., 5.
    • Change the value of the interrupts property in your device tree from IRQ_TYPE_EDGE_BOTH to IRQ_TYPE_LEVEL_LOW.
    • Change the interrupts (and interrupt-parent) property in your device tree to the gpios property.

    Alternatively,

    Find an example description for the gpio-keys keyboard driver under arch/arm64/boot/dts/renesas/ in the kernel source tree and compare it with your description.

    BR

  • Hi egret

    Thank you for your answer.

    You're right, you need to change the interrupts (and interrupt-parent) property in the device tree to the gpios property.

    I had a quick look at the gpio-keys driver and in the case of an interrupt the driver sends an event with value=1 and after a time equal to debounce-interval it sends an event with value=0. This seems strange to me, but there must be a good explanation.

    So I changed my devicetree and now everything is ok :

    button@0{
    			gpios = <&pinctrl RZG2L_GPIO(0, 0) GPIO_ACTIVE_HIGH>;
    			linux,input-type = <EV_KEY>;
    			linux,code = <KEY_0>;
    			label = "SW_CASE";
    			debounce-interval = <50>;
    		};	
    

    Thanks,

    Bertrand

  • This is my guess.

    Roughly speaking,
    The gpio-keys driver cannot read the state of a pin (such as whether a key is pressed or released) without the help of the underlying driver specified by the "gpios" property.

    It seems possible by triggering the interrupt on both edges, as you did, but the gpio-keys driver does not know the initial state (the state of the pin before the first interrupt occurs). In addition, accurate counting may not be possible due to, e.g., interrupt degradation or chattering.

    For that reason, I believe the gpio-keys driver is performing a simple and plausible report.

    1. When an interrupt occurs, "key was pressed".
    2. To prevent chattering, interrupts are masked during the debounce interval.
    3. When the debounce interval has elapsed, "key is released".
      because even if the key is kept pressed, it won't know...

    BR