aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/rc
diff options
context:
space:
mode:
authorJarod Wilson <jarod@redhat.com>2011-07-13 17:26:07 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2011-07-27 16:55:59 -0400
commitc53f9f00e5ddf72046698d6a378384e29fc9795f (patch)
tree31504404bb1635a9a4d9616e15ac1d0899ccd292 /drivers/media/rc
parent2c594ffae40306ba1a5a5d59186cd3d49dc3ad6a (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.c43
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
622static u32 redrat3_get_timeout(struct device *dev, 630static 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");