diff options
author | Jarod Wilson <jarod@redhat.com> | 2011-07-13 17:26:07 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2011-07-27 16:55:59 -0400 |
commit | c53f9f00e5ddf72046698d6a378384e29fc9795f (patch) | |
tree | 31504404bb1635a9a4d9616e15ac1d0899ccd292 /drivers/media/rc | |
parent | 2c594ffae40306ba1a5a5d59186cd3d49dc3ad6a (diff) |
[media] redrat3: improve compat with lirc userspace decode
This is admittedly a bit of a hack, but if we change our timeout value
to something longer and fudge our synthesized trailing space sample
based on the initial pulse sample, rc-core decode continues to work just
fine with both rc-6 and rc-5, and now lirc userspace decode shows proper
repeats for both of those protocols as well. Also tested NEC
successfully with both decode options.
We do still need a reset timer callback using the hardware's timeout
value to make sure we actually process samples correctly, regardless of
our somewhat hacky timeout and synthesized trailer above.
This also adds a missing del_timer_sync call to the module unload path.
CC: Chris Dodge <chris@redrat.co.uk>
CC: Andrew Vincer <andrew.vincer@redrat.co.uk>
CC: Stephen Cox <scox_nz@yahoo.com>
Signed-off-by: Jarod Wilson <jarod@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/rc')
-rw-r--r-- | drivers/media/rc/redrat3.c | 43 |
1 files changed, 24 insertions, 19 deletions
diff --git a/drivers/media/rc/redrat3.c b/drivers/media/rc/redrat3.c index ea5039b88c50..a16604477917 100644 --- a/drivers/media/rc/redrat3.c +++ b/drivers/media/rc/redrat3.c | |||
@@ -205,6 +205,7 @@ struct redrat3_dev { | |||
205 | 205 | ||
206 | /* rx signal timeout timer */ | 206 | /* rx signal timeout timer */ |
207 | struct timer_list rx_timeout; | 207 | struct timer_list rx_timeout; |
208 | u32 hw_timeout; | ||
208 | 209 | ||
209 | /* Is the device currently receiving? */ | 210 | /* Is the device currently receiving? */ |
210 | bool recv_in_progress; | 211 | bool recv_in_progress; |
@@ -428,7 +429,7 @@ static void redrat3_process_ir_data(struct redrat3_dev *rr3) | |||
428 | DEFINE_IR_RAW_EVENT(rawir); | 429 | DEFINE_IR_RAW_EVENT(rawir); |
429 | struct redrat3_signal_header header; | 430 | struct redrat3_signal_header header; |
430 | struct device *dev; | 431 | struct device *dev; |
431 | int i; | 432 | int i, trailer = 0; |
432 | unsigned long delay; | 433 | unsigned long delay; |
433 | u32 mod_freq, single_len; | 434 | u32 mod_freq, single_len; |
434 | u16 *len_vals; | 435 | u16 *len_vals; |
@@ -454,7 +455,8 @@ static void redrat3_process_ir_data(struct redrat3_dev *rr3) | |||
454 | if (!(header.length >= RR3_HEADER_LENGTH)) | 455 | if (!(header.length >= RR3_HEADER_LENGTH)) |
455 | dev_warn(dev, "read returned less than rr3 header len\n"); | 456 | dev_warn(dev, "read returned less than rr3 header len\n"); |
456 | 457 | ||
457 | delay = usecs_to_jiffies(rr3->rc->timeout / 1000); | 458 | /* Make sure we reset the IR kfifo after a bit of inactivity */ |
459 | delay = usecs_to_jiffies(rr3->hw_timeout); | ||
458 | mod_timer(&rr3->rx_timeout, jiffies + delay); | 460 | mod_timer(&rr3->rx_timeout, jiffies + delay); |
459 | 461 | ||
460 | memcpy(&tmp32, sig_data + RR3_PAUSE_OFFSET, sizeof(tmp32)); | 462 | memcpy(&tmp32, sig_data + RR3_PAUSE_OFFSET, sizeof(tmp32)); |
@@ -503,6 +505,9 @@ static void redrat3_process_ir_data(struct redrat3_dev *rr3) | |||
503 | rawir.pulse = true; | 505 | rawir.pulse = true; |
504 | 506 | ||
505 | rawir.duration = US_TO_NS(single_len); | 507 | rawir.duration = US_TO_NS(single_len); |
508 | /* Save initial pulse length to fudge trailer */ | ||
509 | if (i == 0) | ||
510 | trailer = rawir.duration; | ||
506 | /* cap the value to IR_MAX_DURATION */ | 511 | /* cap the value to IR_MAX_DURATION */ |
507 | rawir.duration &= IR_MAX_DURATION; | 512 | rawir.duration &= IR_MAX_DURATION; |
508 | 513 | ||
@@ -515,7 +520,10 @@ static void redrat3_process_ir_data(struct redrat3_dev *rr3) | |||
515 | if (i % 2) { | 520 | if (i % 2) { |
516 | rawir.pulse = false; | 521 | rawir.pulse = false; |
517 | /* this duration is made up, and may not be ideal... */ | 522 | /* this duration is made up, and may not be ideal... */ |
518 | rawir.duration = rr3->rc->timeout / 2; | 523 | if (trailer < US_TO_NS(1000)) |
524 | rawir.duration = US_TO_NS(2800); | ||
525 | else | ||
526 | rawir.duration = trailer; | ||
519 | rr3_dbg(dev, "storing trailing space with duration %d\n", | 527 | rr3_dbg(dev, "storing trailing space with duration %d\n", |
520 | rawir.duration); | 528 | rawir.duration); |
521 | ir_raw_event_store_with_filter(rr3->rc, &rawir); | 529 | ir_raw_event_store_with_filter(rr3->rc, &rawir); |
@@ -619,36 +627,31 @@ static inline void redrat3_delete(struct redrat3_dev *rr3, | |||
619 | kfree(rr3); | 627 | kfree(rr3); |
620 | } | 628 | } |
621 | 629 | ||
622 | static u32 redrat3_get_timeout(struct device *dev, | 630 | static u32 redrat3_get_timeout(struct redrat3_dev *rr3) |
623 | struct rc_dev *rc, struct usb_device *udev) | ||
624 | { | 631 | { |
625 | u32 *tmp; | 632 | u32 *tmp; |
626 | u32 timeout = MS_TO_NS(150); /* a sane default, if things go haywire */ | 633 | u32 timeout = MS_TO_US(150); /* a sane default, if things go haywire */ |
627 | int len, ret, pipe; | 634 | int len, ret, pipe; |
628 | 635 | ||
629 | len = sizeof(*tmp); | 636 | len = sizeof(*tmp); |
630 | tmp = kzalloc(len, GFP_KERNEL); | 637 | tmp = kzalloc(len, GFP_KERNEL); |
631 | if (!tmp) { | 638 | if (!tmp) { |
632 | dev_warn(dev, "Memory allocation faillure\n"); | 639 | dev_warn(rr3->dev, "Memory allocation faillure\n"); |
633 | return timeout; | 640 | return timeout; |
634 | } | 641 | } |
635 | 642 | ||
636 | pipe = usb_rcvctrlpipe(udev, 0); | 643 | pipe = usb_rcvctrlpipe(rr3->udev, 0); |
637 | ret = usb_control_msg(udev, pipe, RR3_GET_IR_PARAM, | 644 | ret = usb_control_msg(rr3->udev, pipe, RR3_GET_IR_PARAM, |
638 | USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, | 645 | USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, |
639 | RR3_IR_IO_SIG_TIMEOUT, 0, tmp, len, HZ * 5); | 646 | RR3_IR_IO_SIG_TIMEOUT, 0, tmp, len, HZ * 5); |
640 | if (ret != len) { | 647 | if (ret != len) { |
641 | dev_warn(dev, "Failed to read timeout from hardware\n"); | 648 | dev_warn(rr3->dev, "Failed to read timeout from hardware\n"); |
642 | return timeout; | 649 | return timeout; |
643 | } | 650 | } |
644 | 651 | ||
645 | timeout = US_TO_NS(redrat3_len_to_us(be32_to_cpu(*tmp))); | 652 | timeout = redrat3_len_to_us(be32_to_cpu(*tmp)); |
646 | if (timeout < rc->min_timeout) | ||
647 | timeout = rc->min_timeout; | ||
648 | else if (timeout > rc->max_timeout) | ||
649 | timeout = rc->max_timeout; | ||
650 | 653 | ||
651 | rr3_dbg(dev, "Got timeout of %d ms\n", timeout / (1000 * 1000)); | 654 | rr3_dbg(rr3->dev, "Got timeout of %d ms\n", timeout / 1000); |
652 | return timeout; | 655 | return timeout; |
653 | } | 656 | } |
654 | 657 | ||
@@ -1100,9 +1103,7 @@ static struct rc_dev *redrat3_init_rc_dev(struct redrat3_dev *rr3) | |||
1100 | rc->priv = rr3; | 1103 | rc->priv = rr3; |
1101 | rc->driver_type = RC_DRIVER_IR_RAW; | 1104 | rc->driver_type = RC_DRIVER_IR_RAW; |
1102 | rc->allowed_protos = RC_TYPE_ALL; | 1105 | rc->allowed_protos = RC_TYPE_ALL; |
1103 | rc->min_timeout = MS_TO_NS(RR3_RX_MIN_TIMEOUT); | 1106 | rc->timeout = US_TO_NS(2750); |
1104 | rc->max_timeout = MS_TO_NS(RR3_RX_MAX_TIMEOUT); | ||
1105 | rc->timeout = redrat3_get_timeout(dev, rc, rr3->udev); | ||
1106 | rc->tx_ir = redrat3_transmit_ir; | 1107 | rc->tx_ir = redrat3_transmit_ir; |
1107 | rc->s_tx_carrier = redrat3_set_tx_carrier; | 1108 | rc->s_tx_carrier = redrat3_set_tx_carrier; |
1108 | rc->driver_name = DRIVER_NAME; | 1109 | rc->driver_name = DRIVER_NAME; |
@@ -1232,6 +1233,9 @@ static int __devinit redrat3_dev_probe(struct usb_interface *intf, | |||
1232 | if (retval < 0) | 1233 | if (retval < 0) |
1233 | goto error; | 1234 | goto error; |
1234 | 1235 | ||
1236 | /* store current hardware timeout, in us, will use for kfifo resets */ | ||
1237 | rr3->hw_timeout = redrat3_get_timeout(rr3); | ||
1238 | |||
1235 | /* default.. will get overridden by any sends with a freq defined */ | 1239 | /* default.. will get overridden by any sends with a freq defined */ |
1236 | rr3->carrier = 38000; | 1240 | rr3->carrier = 38000; |
1237 | 1241 | ||
@@ -1270,6 +1274,7 @@ static void __devexit redrat3_dev_disconnect(struct usb_interface *intf) | |||
1270 | 1274 | ||
1271 | usb_set_intfdata(intf, NULL); | 1275 | usb_set_intfdata(intf, NULL); |
1272 | rc_unregister_device(rr3->rc); | 1276 | rc_unregister_device(rr3->rc); |
1277 | del_timer_sync(&rr3->rx_timeout); | ||
1273 | redrat3_delete(rr3, udev); | 1278 | redrat3_delete(rr3, udev); |
1274 | 1279 | ||
1275 | rr3_ftr(&intf->dev, "RedRat3 IR Transceiver now disconnected\n"); | 1280 | rr3_ftr(&intf->dev, "RedRat3 IR Transceiver now disconnected\n"); |