aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorPatrick Boettcher <pb@linuxtv.org>2008-03-29 20:37:01 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2008-04-24 13:07:56 -0400
commit58e6f95e613b37372a58fd504646ae1b1964c2ed (patch)
tree473c1ecb2fab26607bbd44b60e34e02a7493d104 /drivers
parent6ca8f0b97473dcef3a754bab5239dcfcdd00b244 (diff)
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')
-rw-r--r--drivers/media/dvb/dvb-usb/dib0700.h4
-rw-r--r--drivers/media/dvb/dvb-usb/dib0700_core.c4
-rw-r--r--drivers/media/dvb/dvb-usb/dib0700_devices.c58
3 files changed, 61 insertions, 5 deletions
diff --git a/drivers/media/dvb/dvb-usb/dib0700.h b/drivers/media/dvb/dvb-usb/dib0700.h
index 4a903ea95896..66d4dc6ba46f 100644
--- a/drivers/media/dvb/dvb-usb/dib0700.h
+++ b/drivers/media/dvb/dvb-usb/dib0700.h
@@ -37,6 +37,7 @@ struct dib0700_state {
37 u8 channel_state; 37 u8 channel_state;
38 u16 mt2060_if1[2]; 38 u16 mt2060_if1[2];
39 u8 rc_toggle; 39 u8 rc_toggle;
40 u8 rc_counter;
40 u8 is_dib7000pc; 41 u8 is_dib7000pc;
41}; 42};
42 43
@@ -44,12 +45,15 @@ extern int dib0700_set_gpio(struct dvb_usb_device *, enum dib07x0_gpios gpio, u8
44extern int dib0700_ctrl_clock(struct dvb_usb_device *d, u32 clk_MHz, u8 clock_out_gp3); 45extern int dib0700_ctrl_clock(struct dvb_usb_device *d, u32 clk_MHz, u8 clock_out_gp3);
45extern int dib0700_ctrl_rd(struct dvb_usb_device *d, u8 *tx, u8 txlen, u8 *rx, u8 rxlen); 46extern int dib0700_ctrl_rd(struct dvb_usb_device *d, u8 *tx, u8 txlen, u8 *rx, u8 rxlen);
46extern int dib0700_download_firmware(struct usb_device *udev, const struct firmware *fw); 47extern int dib0700_download_firmware(struct usb_device *udev, const struct firmware *fw);
48extern int dib0700_rc_setup(struct dvb_usb_device *d);
47extern int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff); 49extern int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff);
48extern struct i2c_algorithm dib0700_i2c_algo; 50extern struct i2c_algorithm dib0700_i2c_algo;
49extern int dib0700_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props, 51extern int dib0700_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props,
50 struct dvb_usb_device_description **desc, int *cold); 52 struct dvb_usb_device_description **desc, int *cold);
51 53
52extern int dib0700_device_count; 54extern int dib0700_device_count;
55extern int dvb_usb_dib0700_ir_proto;
53extern struct dvb_usb_device_properties dib0700_devices[]; 56extern struct dvb_usb_device_properties dib0700_devices[];
54extern struct usb_device_id dib0700_usb_id_table[]; 57extern struct usb_device_id dib0700_usb_id_table[];
58
55#endif 59#endif
diff --git a/drivers/media/dvb/dvb-usb/dib0700_core.c b/drivers/media/dvb/dvb-usb/dib0700_core.c
index c9857d5c6982..4b3836e63be9 100644
--- a/drivers/media/dvb/dvb-usb/dib0700_core.c
+++ b/drivers/media/dvb/dvb-usb/dib0700_core.c
@@ -13,7 +13,7 @@ int dvb_usb_dib0700_debug;
13module_param_named(debug,dvb_usb_dib0700_debug, int, 0644); 13module_param_named(debug,dvb_usb_dib0700_debug, int, 0644);
14MODULE_PARM_DESC(debug, "set debugging level (1=info,2=fw,4=fwdata,8=data (or-able))." DVB_USB_DEBUG_STATUS); 14MODULE_PARM_DESC(debug, "set debugging level (1=info,2=fw,4=fwdata,8=data (or-able))." DVB_USB_DEBUG_STATUS);
15 15
16static int dvb_usb_dib0700_ir_proto = 1; 16int dvb_usb_dib0700_ir_proto = 1;
17module_param(dvb_usb_dib0700_ir_proto, int, 0644); 17module_param(dvb_usb_dib0700_ir_proto, int, 0644);
18MODULE_PARM_DESC(dvb_usb_dib0700_ir_proto, "set ir protocol (0=NEC, 1=RC5 (default), 2=RC6)."); 18MODULE_PARM_DESC(dvb_usb_dib0700_ir_proto, "set ir protocol (0=NEC, 1=RC5 (default), 2=RC6).");
19 19
@@ -261,7 +261,7 @@ int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
261 return dib0700_ctrl_wr(adap->dev, b, 4); 261 return dib0700_ctrl_wr(adap->dev, b, 4);
262} 262}
263 263
264static int dib0700_rc_setup(struct dvb_usb_device *d) 264int dib0700_rc_setup(struct dvb_usb_device *d)
265{ 265{
266 u8 rc_setup[3] = {REQUEST_SET_RC, dvb_usb_dib0700_ir_proto, 0}; 266 u8 rc_setup[3] = {REQUEST_SET_RC, dvb_usb_dib0700_ir_proto, 0};
267 int i = dib0700_ctrl_wr(d, rc_setup, 3); 267 int i = dib0700_ctrl_wr(d, rc_setup, 3);
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)
445 445
446static u8 rc_request[] = { REQUEST_POLL_RC, 0 }; 446static u8 rc_request[] = { REQUEST_POLL_RC, 0 };
447 447
448/* Number of keypresses to ignore before start repeating */
449#define RC_REPEAT_DELAY 2
450
448static int dib0700_rc_query(struct dvb_usb_device *d, u32 *event, int *state) 451static int dib0700_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
449{ 452{
450 u8 key[4]; 453 u8 key[4];
@@ -458,18 +461,67 @@ static int dib0700_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
458 err("RC Query Failed"); 461 err("RC Query Failed");
459 return -1; 462 return -1;
460 } 463 }
464
465 /* losing half of KEY_0 events from Philipps rc5 remotes.. */
461 if (key[0]==0 && key[1]==0 && key[2]==0 && key[3]==0) return 0; 466 if (key[0]==0 && key[1]==0 && key[2]==0 && key[3]==0) return 0;
462 if (key[3-1]!=st->rc_toggle) { 467
468 /* 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]); */
469
470 dib0700_rc_setup(d); /* reset ir sensor data to prevent false events */
471
472 switch (dvb_usb_dib0700_ir_proto) {
473 case 0: {
474 /* NEC protocol sends repeat code as 0 0 0 FF */
475 if ((key[3-2] == 0x00) && (key[3-3] == 0x00) &&
476 (key[3] == 0xFF)) {
477 st->rc_counter++;
478 if (st->rc_counter > RC_REPEAT_DELAY) {
479 *event = d->last_event;
480 *state = REMOTE_KEY_PRESSED;
481 st->rc_counter = RC_REPEAT_DELAY;
482 }
483 return 0;
484 }
463 for (i=0;i<d->props.rc_key_map_size; i++) { 485 for (i=0;i<d->props.rc_key_map_size; i++) {
464 if (keymap[i].custom == key[3-2] && keymap[i].data == key[3-3]) { 486 if (keymap[i].custom == key[3-2] && keymap[i].data == key[3-3]) {
487 st->rc_counter = 0;
488 *event = keymap[i].event;
489 *state = REMOTE_KEY_PRESSED;
490 d->last_event = keymap[i].event;
491 return 0;
492 }
493 }
494 break;
495 }
496 default: {
497 /* RC-5 protocol changes toggle bit on new keypress */
498 for (i = 0; i < d->props.rc_key_map_size; i++) {
499 if (keymap[i].custom == key[3-2] && keymap[i].data == key[3-3]) {
500 if (d->last_event == keymap[i].event &&
501 key[3-1] == st->rc_toggle) {
502 st->rc_counter++;
503 /* prevents unwanted double hits */
504 if (st->rc_counter > RC_REPEAT_DELAY) {
505 *event = d->last_event;
506 *state = REMOTE_KEY_PRESSED;
507 st->rc_counter = RC_REPEAT_DELAY;
508 }
509
510 return 0;
511 }
512 st->rc_counter = 0;
465 *event = keymap[i].event; 513 *event = keymap[i].event;
466 *state = REMOTE_KEY_PRESSED; 514 *state = REMOTE_KEY_PRESSED;
467 st->rc_toggle=key[3-1]; 515 st->rc_toggle = key[3-1];
516 d->last_event = keymap[i].event;
468 return 0; 517 return 0;
469 } 518 }
470 } 519 }
471 err("Unknown remote controller key : %2X %2X",(int)key[3-2],(int)key[3-3]); 520 break;
521 }
472 } 522 }
523 err("Unknown remote controller key: %2X %2X %2X %2X", (int) key[3-2], (int) key[3-3], (int) key[3-1], (int) key[3]);
524 d->last_event = 0;
473 return 0; 525 return 0;
474} 526}
475 527