From: David Brownell <david-b@pacbell.net>
To: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Cc: davinci-linux-open-source@linux.davincidsp.com,
Felipe Balbi <felipebalbi@users.sourceforge.net>,
linux-input@vger.kernel.org
Subject: Re: [patch 2.6.28-rc6-davinci1 5/6] dm355evm input driver
Date: Wed, 14 Jan 2009 11:38:41 -0800 [thread overview]
Message-ID: <200901141138.41623.david-b@pacbell.net> (raw)
In-Reply-To: <20090113213534.ZZRA012@mailhub.coreip.homeip.net>
On Tuesday 13 January 2009, Dmitry Torokhov wrote:
> > > > + /* Report press + release ... we can't tell if
> > > > + * this is an autorepeat, and we need to guess
> > > > + * about the release.
> > > > + */
> > > > + input_report_key(keys->input, keycode, 1);
> > >
> > > input_sync() is also needed here.
> > >
> > > > + input_report_key(keys->input, keycode, 0);
> > > > + }
> > > > + input_sync(keys->input);
> >
> > If so, then the existing input_sync() needs to move up
> > a few lines too ... I had thought that the "sync" was
> > like with a filesystem, where lots of events could be
> > batched, but evidently not.
> >
>
> It is and they can. The idea is that userspace accumulates input events
> until it gets the sync event which signals that as full as possible
> hardware state was transmitted. The problem with keys is that if
> userspace really does accumulate events the 2 down/up in succession will
> cancel each other. There are really 2 separate states - button pressed
> and button released which should be accompanied with its own sync. But
> if you were reposting several buttons at once they could all "share" the
> same sync event. Does it make any sense to you?
Yes. But now I seem to observe a LOT more events. I suppose that's
partly due to the fuzzy semantics of these events: they don't encode
"down" or "up".
> So you will be sending an update, right?
Appended is a patchlet addressing your feedback. What I'll do is
submit this to the DaVinci tree, and send you an all-in-one patch.
- Dave
======= SNIP!
From: David Brownell <dbrownell@users.sourceforge.net>
Address feedback from Dmitry:
- input_sync() per event
- maintain dev->keybit when remapping keys
- since we handle remapping, keycodemax and keycodesize aren't used
- on probe error, don't input_free_device() unless it registered
Also:
- avoid reporting excess events
- more bad-parameter paranoia in the remapping code
The excess event issue is basically that we don't have a way to
distinguish "button press" events from "button release" ones or
autorepeat events, so we should try being a bit smarter about
synthesizing them.
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
---
drivers/input/keyboard/dm355evm_keys.c | 49 ++++++++++++++++++++++++-------
1 file changed, 39 insertions(+), 10 deletions(-)
--- a/drivers/input/keyboard/dm355evm_keys.c
+++ b/drivers/input/keyboard/dm355evm_keys.c
@@ -28,6 +28,8 @@
* using a work_struct. The IRQ is active low, but we use it through
* the GPIO controller so we can trigger on falling edges.
*
+ * Note that physically there can only be one of these devices.
+ *
* This driver was tested with firmware revision A4.
*/
struct dm355evm_keys {
@@ -120,6 +122,8 @@ static void dm355evm_keys_work(struct wo
* Reading INPUT_LOW decrements the count.
*/
for (;;) {
+ static u16 last_event;
+
u16 event;
int keycode;
int i;
@@ -142,6 +146,23 @@ static void dm355evm_keys_work(struct wo
if (event == 0xdead)
break;
+ /* Press and release a button: two events, same code.
+ * Press and hold (autorepeat), then release: N events
+ * (N > 2), same code. For RC5 buttons the toggle bits
+ * distinguish (for example) "1-autorepeat" from "1 1";
+ * but PCB buttons don't support that bit.
+ *
+ * So we must synthesize release events. We do that by
+ * mapping events to a press/release event pair; then
+ * to avoid adding extra events, skip the second event
+ * of each pair.
+ */
+ if (event == last_event) {
+ last_event = 0;
+ continue;
+ }
+ last_event = event;
+
/* ignore the RC5 toggle bit */
event &= ~0x0800;
@@ -157,28 +178,38 @@ static void dm355evm_keys_work(struct wo
"input event 0x%04x--> keycode %d\n",
event, keycode);
- /* Report press + release ... we can't tell if
- * this is an autorepeat, and we need to guess
- * about the release.
- */
+ /* report press + release */
input_report_key(keys->input, keycode, 1);
+ input_sync(keys->input);
input_report_key(keys->input, keycode, 0);
+ input_sync(keys->input);
}
- input_sync(keys->input);
}
static int dm355evm_setkeycode(struct input_dev *dev, int index, int keycode)
{
- if (index >= ARRAY_SIZE(dm355evm_keys))
+ u16 old_keycode;
+ unsigned i;
+
+ if (((unsigned)index) >= ARRAY_SIZE(dm355evm_keys))
return -EINVAL;
+ old_keycode = dm355evm_keys[index].keycode;
dm355evm_keys[index].keycode = keycode;
+ set_bit(keycode, dev->keybit);
+
+ for (i = 0; i < ARRAY_SIZE(dm355evm_keys); i++) {
+ if (dm355evm_keys[index].keycode == old_keycode)
+ goto done;
+ }
+ clear_bit(old_keycode, dev->keybit);
+done:
return 0;
}
static int dm355evm_getkeycode(struct input_dev *dev, int index, int *keycode)
{
- if (index >= ARRAY_SIZE(dm355evm_keys))
+ if (((unsigned)index) >= ARRAY_SIZE(dm355evm_keys))
return -EINVAL;
return dm355evm_keys[index].keycode;
@@ -219,8 +250,6 @@ static int __devinit dm355evm_keys_probe
for (i = 0; i < ARRAY_SIZE(dm355evm_keys); i++)
set_bit(dm355evm_keys[i].keycode, input->keybit);
- input->keycodemax = ARRAY_SIZE(dm355evm_keys);
- input->keycodesize = sizeof(dm355evm_keys[0]);
input->keycode = dm355evm_keys;
input->setkeycode = dm355evm_setkeycode;
input->getkeycode = dm355evm_getkeycode;
@@ -237,7 +266,7 @@ static int __devinit dm355evm_keys_probe
/* register */
status = input_register_device(input);
if (status < 0)
- goto fail1;
+ goto fail0;
/* start reporting events */
status = request_irq(keys->irq, dm355evm_keys_irq,
prev parent reply other threads:[~2009-01-14 19:38 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-12-07 19:59 [patch 2.6.28-rc6-davinci1 5/6] dm355evm input driver David Brownell
2008-12-07 20:21 ` Felipe Balbi
2008-12-07 20:28 ` David Brownell
2008-12-07 20:34 ` Felipe Balbi
2008-12-08 21:41 ` Felipe Balbi
2008-12-08 22:19 ` David Brownell
2008-12-11 4:08 ` David Brownell
2009-01-13 6:13 ` Dmitry Torokhov
2009-01-13 9:42 ` David Brownell
2009-01-14 5:42 ` Dmitry Torokhov
2009-01-14 19:38 ` David Brownell [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=200901141138.41623.david-b@pacbell.net \
--to=david-b@pacbell.net \
--cc=davinci-linux-open-source@linux.davincidsp.com \
--cc=dmitry.torokhov@gmail.com \
--cc=felipebalbi@users.sourceforge.net \
--cc=linux-input@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).