From: David Brownell <[email protected]> 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 <[email protected]> --- Merge this and the driver seems ready for mainline submit. I'll have to hope that dm355 hits mainline soon too. :) 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, _______________________________________________ Davinci-linux-open-source mailing list [email protected] http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
