Raspberry GPIO buttons as input keys?

Can I use GPIO buttons as input keys: home, back, enter, arrow keys?
How?

Thank you.

Comments

  • Can someone help please?

  • OK. I made some progress.
    Using multiple lines:
    dtoverlay=gpio-key,<parameters>
    ... I can assign GPIO buttons to linux keycodes.

    After Android boots, gpio_keys.ko must be manually loaded from terminal console. After that, the "keyboard" appears in /proc/bus/input/devices and can be used... almost...
    Letter keys work. Punctuation works. I didn't test them all; I only have 5 buttons connected.

    My problem is this:
    I'm not looking for letters, but special keys like enter, back, home, directional navigation keys. I'm unable to determine which keycodes are these. I couldn't find these keys in linux keycodes list or they don't match android keycodes (keys have different effects than desired).

    Questions:
    How do I automatically load gpio_keys.ko on boot? Is there a kernel commandline option or config file?
    Do I need a key layout file for those keys? If not, what are the linux keycodes for navigating menus in Android (up/down/left/right/enter/back/home)?
    If a keyboard layout is needed, I see several key layout files in /system/usr/keylayout. How do I find out which one is currently in use for my GPIO input device? I would prefer to use it as a reference.
    How do I name a new layout to be loaded with a higher priority than the current layout?

    Thank you!

  • OK, it works! This how I did it:

    1. Activate gpio-key devicetree overlay for each button in config.txt. I have 6 buttons configured. Each line maps a GPIO pin to a kernel keycode. Keycodes list can be found here:
      https://github.com/torvalds/linux/blob/master/include/uapi/linux/input-event-codes.h

    /boot/config.txt
    dtoverlay=gpio-key,gpio=21,active_low=1,gpio_pull=up,label=GPIO_Enter,keycode=28
    dtoverlay=gpio-key,gpio=26,active_low=1,gpio_pull=up,label=GPIO_Up,keycode=103
    dtoverlay=gpio-key,gpio=20,active_low=1,gpio_pull=up,label=GPIO_Down,keycode=108
    dtoverlay=gpio-key,gpio=19,active_low=1,gpio_pull=up,label=GPIO_Left,keycode=105
    dtoverlay=gpio-key,gpio=16,active_low=1,gpio_pull=up,label=GPIO_Right,keycode=106
    dtoverlay=gpio-key,gpio=13,active_low=1,gpio_pull=up,label=GPIO_Back,keycode=158

    1. Create a keyboard layout file to map kernel keycodes to Android keycodes. Information about key layout files can be found here:
      https://source.android.com/devices/input/key-layout-files
      The list of Android keycodes is here:
      https://developer.android.com/reference/android/view/KeyEvent
      The filename must match the device ID (or name, but I don't know what that is, so I use IDs). The IDs I got from inspecting /proc/bus/input/devices.

    /system/usr/keylayout/Vendor_0001_Product_0001_Version_0100.kl
    key 28 KEYCODE_DPAD_CENTER
    key 103 KEYCODE_DPAD_UP
    key 108 KEYCODE_DPAD_DOWN
    key 105 KEYCODE_DPAD_LEFT
    key 106 KEYCODE_DPAD_RIGHT
    key 158 KEYCODE_BACK

    1. Create init file to load gpio_keys kernel module after boot.
      This step is a workaround. If there is a device overlay, the required kernel module should be automatically loaded. But it's not. I don't know why! Maybe it's a bug? Please discuss.

    /system/etc/init/gpio_keys.rc
    on property:sys.boot_completed=1
    insmod /boot/modules/gpio_keys.ko

    Have fun navigating Android with your new hardware buttons! ;-)

  • PS:
    The device overlay, as configured above, is for buttons connected between each listed GPIO pin and ground pin. Use a resistor to be safe!

  • Thank you for your help. i wil try it

  • @M95D said:

    ...
    3. Create init file to load gpio_keys kernel module after boot.
    ...
    /system/etc/init/gpio_keys.rc
    on property:sys.boot_completed=1
    insmod /boot/modules/gpio_keys.ko

    Did you have to rebuild the disk image so that the new .rc file is considered during boot? I am trying to make this .rc file work, but for some (for now) unknown reasons it does not work for me - it is not executed during boot:

    /system/etc/init/powerblock.rc
    on property:sys.boot_completed=1
    exec_background - root root -- /system/bin/powerblockservice.sh

    When I call /system/bin/powerblockservice.sh from the console, the script can be executed and works fine, though.

  • Update: I was thinking too complicated. I just has to move the shell script into the folder /data/init.d/. That's it - the shell script is executed during boot. No rc file is needed.

  • Okay, another update: The boot process is halted until the shell script is finished. That does not happen in my case (as expected) and that is the reason why I need that script to be executed non-blocking in background. Therefore, the exec_background command would be a match I guess.

    I would be grateful for any hint.

  • Didn't rebuild anything. Just remount /system as read-write and create the file.
    Don't know about the exec_background. That's too advanced for me.

  • edited September 19

    Thanks a lot. I have worked around this by coming up with a "kickstarter" bash script, which, in turn, calls the actual service as background task.

    With that I have finished the work on the power button solution for Emteria, https://blog.petrockblock.com/2019/09/19/power-button-emteria/ :smile:

Sign In or Register to comment.