Hello,
this message was originally sent to k-d mailing list in the summer,
but unfortunately did not find its way to the list members. The patch is
already commited, so I'm not attaching it, but if there are any
objections/improvement ideas, please let me know. The code itself is
quite generic and might be used by other ports than h5000 (for which it
was originally designed).
Milan
-------- Forwarded Message --------
From: Milan Plzik <milan.plzik_at_gmail.com>
To: kernel-discuss_at_handhelds.org
Cc: pmiscml_at_gmail.com, cbou_at_mail.ru
Subject: [PATCH] gpiodev-keys2
Date: Sun, 12 Aug 2007 16:13:50 +0200
Hello again:),
attached patch and files contain reimplementation of gpiodev-keys
driver, named gpiodev-keys2. This driver implements superset of features
the original gpiodev-keys driver has, most importantly, it supports:
- multiple GPIOs triggering one button,
- button priorities,
- blocking out certaion GPIO combinations,
- (more-or-less:) per-button debounce timeouts,
which are big help with more exotic hardware designs, like h5000
diagonal joypad or side volume/record button. I tried to describe its
function below (it's long, be warned:), at every point first mentioning
motivation and then actual implementation.
Milan
Attached files:
- gpiodev_keys2.h goes to include/linux,
- gpiodev_keys2.c goes to drivers/input/keyboard,
- the patch file modifies neccessary kbuild files,
(sorry, I still could not convince CVS to produce reasonable patch)
1. H5000 joypad
In the following text I will make big use of h5000 diagonal joypad as
example of infinite cruelness of engineers:) and also reason to write
this driver, so I'll first describe it:
The joypad is 5-directional (4 side directions, one direction for
pressing the joypad). "Diagonal" in this case means that the GPIOs are
not connected the usual way (one GPIO for "north" direction, one for
"west", ...) , but trigger diagonal directions -- so we have GPIO for
northeast direction, for southwest, etc. Moreover, pressing joypad in
every direction also triggers the "action" GPIO (5th direction).
2. Gpiodev-keys2 design
2.1. GPIOs and buttons
gpiodev-keys2 divides keyboard configuration into two layers. First
(lower) layer contains GPIOs which are connected to the keys and assigns
them string names.
Second layer maps physical GPIOs to buttons. This is different from
implementation of gpiodev-keys, which allowed only n:1 mapping between
GPIOs and buttons (one GPIO can trigger one or more keys). In this
layer, one button may require more GPIOs to be triggered, and
alternatively, one GPIO can trigger more keys. This is required for e.g.
h5000 diagonal joypad support -- two diagonal GPIOs trigger one arrow
key.
2.2. Button priorities
There is also one other problem -- some buttons can be triggered by
GPIOs, which are subset of other button. Again, great example is h5000
diagonal joypad, e.g. triggering two GPIOs for north direction and one
for northwest. But with only design mentioned above, north direction
would have to assert also west and east direction, as the asserted GPIOs
are NE and NW.
Proposed solution is to assign priorities to the buttons. This way, if
button with higher priority is pressed, it blocks all buttons sharing
some GPIOs with this one and having lower priority (NOTE: buttons with
equal priority can share GPIOs). So, if the north direction of joypad
has priority '2' and diagonal keys have priority '1', asserting NE and
NW GPIOs blocks out buttons handling press of some diagonal direction.
2.3. Blocking out certain GPIO combinations
Some time ago there was a discussion whether it is good idea to have
joypad to generate also 'diagonal' (e.g. northwest, pressing up and left
keys at once) events. Some joypads are quite sensitive and this behavior
may be not welcome. Just not mentioning buttons in gpiodev-keys2 data
won't help much -- h5000 joypad everytime triggers also action key, so
pressing joypad in diagonal direction would result in 'action' event
(enter keypress, in this case).
This problem can be solved by 'blocking out' certain GPIO
combinations. The idea behind this is that we have almost valid buttons
in the diagonal directions (so when pressing them will block the GPIOs,
and in this case also action key), but will not generate any keypess
event.
2.4. Per button device timeouts
This feature might come quite handy in some cases. Again, our example
is h5000, but now the three-functional sidebutton. It allows one to
regulate the volume, but pressing both VolUp and VolDown keys at once
should generate keypress of 'Record' button. Due to very interesting
design, it is also impossible to press the keys really at once, it
usually takes even something close to 100ms for the buttons to settle
down.
Under these conditions, every press of the record button also, as a
side effect, triggers one of the volume keys, which can be quite
annoying. We can use priorities to block out VolUp/VolDown button
presses when Record is pressed, but not before. We can also use
traditional debouncing of keys, but having all keys delayed for almost
100ms is also not good.
gpiodev-keys2 attempts to solve this by using per-button delays. These
should more-or-less assure, that the debouncing will not take too long,
if not neccessary. So, while e.g. joypad buttons are serviced almost
immediately, when asserting one of the 'record' GPIOs, driver will wait
longer.
3. Implementation notes
Actual gpiodev-keys2 implementation is no the ideal one. While it is
working, it can be improved in several ways. List of them is below:
* Currently, not depending on what irq was received, driver scans
through all the buttons and refreshes state of whole keyboard.
* The data structures used by gpiodev-keys2 driver are quite
complicated, maybe there is some way to implement them in more readable
manner.
* Debouncing period is currently taken as "the smallest time
neccessary". If two buttons are pressed, one with 10ms debounce time and
another one with 100ms, it will take 100ms for both keys to report. This
is also connected to the first point, because currently state of whole
defined keyboard is refreshed, so refreshing sooner than 100ms could
cause incorrectly read value of second button (its debounce period is
not yet finished).
Received on Thu Jan 24 2008 - 04:37:55 EST
This archive was generated by hypermail 2.2.0 : Thu Jan 24 2008 - 04:38:22 EST