diff options
author | Patrick Boettcher <pb@linuxtv.org> | 2008-03-29 21:37:01 -0300 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-04-24 14:07:56 -0300 |
commit | 58e6f95e613b37372a58fd504646ae1b1964c2ed (patch) | |
tree | 473c1ecb2fab26607bbd44b60e34e02a7493d104 /drivers/media/dvb/dvb-usb/dib0700_devices.c | |
parent | 6ca8f0b97473dcef3a754bab5239dcfcdd00b244 (diff) | |
download | linux-58e6f95e613b37372a58fd504646ae1b1964c2ed.tar.gz linux-58e6f95e613b37372a58fd504646ae1b1964c2ed.tar.bz2 linux-58e6f95e613b37372a58fd504646ae1b1964c2ed.zip |
V4L/DVB (7474): support key repeat with dib0700 ir receiver
This patch enables support for repeating last event when a key is holded
down with dib0700 devices. It works with rc5 and nec remotes.
It also fixes an annoying bug that floods kernel log with "Unknown key"
messages after each keypress. This happened because the driver was not
resetting infrared register after each poll so it kept polling last key
even if nothing was being pressed. Fixing this, (calling rc_setup after
each poll), permits to implement key repeat.
Signed-off-by: Filippo Argiolas <filippo.argiolas at gmail.com>
Signed-off-by: Patrick Boettcher <pb@linuxtv.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/dvb/dvb-usb/dib0700_devices.c')
-rw-r--r-- | drivers/media/dvb/dvb-usb/dib0700_devices.c | 58 |
1 files changed, 55 insertions, 3 deletions
diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c index 9fd8399e5d8f..fe96f795792b 100644 --- a/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c @@ -445,6 +445,9 @@ static int stk7700ph_tuner_attach(struct dvb_usb_adapter *adap) static u8 rc_request[] = { REQUEST_POLL_RC, 0 }; +/* Number of keypresses to ignore before start repeating */ +#define RC_REPEAT_DELAY 2 + static int dib0700_rc_query(struct dvb_usb_device *d, u32 *event, int *state) { u8 key[4]; @@ -458,18 +461,67 @@ static int dib0700_rc_query(struct dvb_usb_device *d, u32 *event, int *state) err("RC Query Failed"); return -1; } + + /* losing half of KEY_0 events from Philipps rc5 remotes.. */ if (key[0]==0 && key[1]==0 && key[2]==0 && key[3]==0) return 0; - if (key[3-1]!=st->rc_toggle) { + + /* info("%d: %2X %2X %2X %2X",dvb_usb_dib0700_ir_proto,(int)key[3-2],(int)key[3-3],(int)key[3-1],(int)key[3]); */ + + dib0700_rc_setup(d); /* reset ir sensor data to prevent false events */ + + switch (dvb_usb_dib0700_ir_proto) { + case 0: { + /* NEC protocol sends repeat code as 0 0 0 FF */ + if ((key[3-2] == 0x00) && (key[3-3] == 0x00) && + (key[3] == 0xFF)) { + st->rc_counter++; + if (st->rc_counter > RC_REPEAT_DELAY) { + *event = d->last_event; + *state = REMOTE_KEY_PRESSED; + st->rc_counter = RC_REPEAT_DELAY; + } + return 0; + } for (i=0;i<d->props.rc_key_map_size; i++) { if (keymap[i].custom == key[3-2] && keymap[i].data == key[3-3]) { + st->rc_counter = 0; + *event = keymap[i].event; + *state = REMOTE_KEY_PRESSED; + d->last_event = keymap[i].event; + return 0; + } + } + break; + } + default: { + /* RC-5 protocol changes toggle bit on new keypress */ + for (i = 0; i < d->props.rc_key_map_size; i++) { + if (keymap[i].custom == key[3-2] && keymap[i].data == key[3-3]) { + if (d->last_event == keymap[i].event && + key[3-1] == st->rc_toggle) { + st->rc_counter++; + /* prevents unwanted double hits */ + if (st->rc_counter > RC_REPEAT_DELAY) { + *event = d->last_event; + *state = REMOTE_KEY_PRESSED; + st->rc_counter = RC_REPEAT_DELAY; + } + + return 0; + } + st->rc_counter = 0; *event = keymap[i].event; *state = REMOTE_KEY_PRESSED; - st->rc_toggle=key[3-1]; + st->rc_toggle = key[3-1]; + d->last_event = keymap[i].event; return 0; } } - err("Unknown remote controller key : %2X %2X",(int)key[3-2],(int)key[3-3]); + break; + } } + err("Unknown remote controller key: %2X %2X %2X %2X", (int) key[3-2], (int) key[3-3], (int) key[3-1], (int) key[3]); + d->last_event = 0; return 0; } |