diff options
-rw-r--r-- | drivers/media/dvb/dvb-usb/dib0700.h | 4 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-usb/dib0700_core.c | 4 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-usb/dib0700_devices.c | 58 |
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 { u8 channel_state; u16 mt2060_if1[2]; u8 rc_toggle; + u8 rc_counter; u8 is_dib7000pc; }; @@ -44,12 +45,15 @@ extern int dib0700_set_gpio(struct dvb_usb_device *, enum dib07x0_gpios gpio, u8 extern int dib0700_ctrl_clock(struct dvb_usb_device *d, u32 clk_MHz, u8 clock_out_gp3); extern int dib0700_ctrl_rd(struct dvb_usb_device *d, u8 *tx, u8 txlen, u8 *rx, u8 rxlen); extern int dib0700_download_firmware(struct usb_device *udev, const struct firmware *fw); +extern int dib0700_rc_setup(struct dvb_usb_device *d); extern int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff); extern struct i2c_algorithm dib0700_i2c_algo; extern int dib0700_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props, struct dvb_usb_device_description **desc, int *cold); extern int dib0700_device_count; +extern int dvb_usb_dib0700_ir_proto; extern struct dvb_usb_device_properties dib0700_devices[]; extern struct usb_device_id dib0700_usb_id_table[]; + #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; module_param_named(debug,dvb_usb_dib0700_debug, int, 0644); MODULE_PARM_DESC(debug, "set debugging level (1=info,2=fw,4=fwdata,8=data (or-able))." DVB_USB_DEBUG_STATUS); -static int dvb_usb_dib0700_ir_proto = 1; +int dvb_usb_dib0700_ir_proto = 1; module_param(dvb_usb_dib0700_ir_proto, int, 0644); MODULE_PARM_DESC(dvb_usb_dib0700_ir_proto, "set ir protocol (0=NEC, 1=RC5 (default), 2=RC6)."); @@ -261,7 +261,7 @@ int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) return dib0700_ctrl_wr(adap->dev, b, 4); } -static int dib0700_rc_setup(struct dvb_usb_device *d) +int dib0700_rc_setup(struct dvb_usb_device *d) { u8 rc_setup[3] = {REQUEST_SET_RC, dvb_usb_dib0700_ir_proto, 0}; 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) 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; } |