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?
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! ;-)
...
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.
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:
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
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
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:
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.
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/