aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorDavid Härdeman <david@hardeman.nu>2011-04-28 10:14:03 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-08-13 18:59:41 -0400
commitf8e00d5fa86fbc4462647da162152d4e74db784c (patch)
tree142c42d64707914aea0b6194322c3cd6db47c9c3 /drivers/media
parent0a67fe458471cc13adeb0e10694e10674bf383eb (diff)
[media] rc-core: move timeout and checks to lirc
The lirc TX functionality expects the process which writes (TX) data to the lirc dev to sleep until the actual data has been transmitted by the hardware. Since the same timeout calculation is duplicated in more than one driver (and would have to be duplicated in even more drivers as they gain TX support), it makes sense to move this timeout calculation to the lirc layer instead. At the same time, centralize some of the sanity checks. Signed-off-by: David Härdeman <david@hardeman.nu> Cc: Jarod Wilson <jwilson@redhat.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/rc/ir-lirc-codec.c33
-rw-r--r--drivers/media/rc/mceusb.c18
-rw-r--r--drivers/media/rc/rc-loopback.c12
3 files changed, 29 insertions, 34 deletions
diff --git a/drivers/media/rc/ir-lirc-codec.c b/drivers/media/rc/ir-lirc-codec.c
index d2fd064474aa..6ad4a0770613 100644
--- a/drivers/media/rc/ir-lirc-codec.c
+++ b/drivers/media/rc/ir-lirc-codec.c
@@ -107,6 +107,12 @@ static ssize_t ir_lirc_transmit_ir(struct file *file, const char __user *buf,
107 unsigned int *txbuf; /* buffer with values to transmit */ 107 unsigned int *txbuf; /* buffer with values to transmit */
108 ssize_t ret = -EINVAL; 108 ssize_t ret = -EINVAL;
109 size_t count; 109 size_t count;
110 ktime_t start;
111 s64 towait;
112 unsigned int duration = 0; /* signal duration in us */
113 int i;
114
115 start = ktime_get();
110 116
111 lirc = lirc_get_pdata(file); 117 lirc = lirc_get_pdata(file);
112 if (!lirc) 118 if (!lirc)
@@ -129,11 +135,30 @@ static ssize_t ir_lirc_transmit_ir(struct file *file, const char __user *buf,
129 goto out; 135 goto out;
130 } 136 }
131 137
132 if (dev->tx_ir) 138 if (!dev->tx_ir) {
133 ret = dev->tx_ir(dev, txbuf, count); 139 ret = -ENOSYS;
140 goto out;
141 }
142
143 ret = dev->tx_ir(dev, txbuf, (u32)n);
144 if (ret < 0)
145 goto out;
146
147 for (i = 0; i < ret; i++)
148 duration += txbuf[i];
134 149
135 if (ret > 0) 150 ret *= sizeof(unsigned int);
136 ret *= sizeof(unsigned); 151
152 /*
153 * The lircd gap calculation expects the write function to
154 * wait for the actual IR signal to be transmitted before
155 * returning.
156 */
157 towait = ktime_us_delta(ktime_add_us(start, duration), ktime_get());
158 if (towait > 0) {
159 set_current_state(TASK_INTERRUPTIBLE);
160 schedule_timeout(usecs_to_jiffies(towait));
161 }
137 162
138out: 163out:
139 kfree(txbuf); 164 kfree(txbuf);
diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c
index d289fd42729f..a5c6c1c2af82 100644
--- a/drivers/media/rc/mceusb.c
+++ b/drivers/media/rc/mceusb.c
@@ -791,10 +791,6 @@ static int mceusb_tx_ir(struct rc_dev *dev, unsigned *txbuf, unsigned count)
791 int i, ret = 0; 791 int i, ret = 0;
792 int cmdcount = 0; 792 int cmdcount = 0;
793 unsigned char *cmdbuf; /* MCE command buffer */ 793 unsigned char *cmdbuf; /* MCE command buffer */
794 long signal_duration = 0; /* Singnal length in us */
795 struct timeval start_time, end_time;
796
797 do_gettimeofday(&start_time);
798 794
799 cmdbuf = kzalloc(sizeof(unsigned) * MCE_CMDBUF_SIZE, GFP_KERNEL); 795 cmdbuf = kzalloc(sizeof(unsigned) * MCE_CMDBUF_SIZE, GFP_KERNEL);
800 if (!cmdbuf) 796 if (!cmdbuf)
@@ -807,7 +803,6 @@ static int mceusb_tx_ir(struct rc_dev *dev, unsigned *txbuf, unsigned count)
807 803
808 /* Generate mce packet data */ 804 /* Generate mce packet data */
809 for (i = 0; (i < count) && (cmdcount < MCE_CMDBUF_SIZE); i++) { 805 for (i = 0; (i < count) && (cmdcount < MCE_CMDBUF_SIZE); i++) {
810 signal_duration += txbuf[i];
811 txbuf[i] = txbuf[i] / MCE_TIME_UNIT; 806 txbuf[i] = txbuf[i] / MCE_TIME_UNIT;
812 807
813 do { /* loop to support long pulses/spaces > 127*50us=6.35ms */ 808 do { /* loop to support long pulses/spaces > 127*50us=6.35ms */
@@ -850,19 +845,6 @@ static int mceusb_tx_ir(struct rc_dev *dev, unsigned *txbuf, unsigned count)
850 /* Transmit the command to the mce device */ 845 /* Transmit the command to the mce device */
851 mce_async_out(ir, cmdbuf, cmdcount); 846 mce_async_out(ir, cmdbuf, cmdcount);
852 847
853 /*
854 * The lircd gap calculation expects the write function to
855 * wait the time it takes for the ircommand to be sent before
856 * it returns.
857 */
858 do_gettimeofday(&end_time);
859 signal_duration -= (end_time.tv_usec - start_time.tv_usec) +
860 (end_time.tv_sec - start_time.tv_sec) * 1000000;
861
862 /* delay with the closest number of ticks */
863 set_current_state(TASK_INTERRUPTIBLE);
864 schedule_timeout(usecs_to_jiffies(signal_duration));
865
866out: 848out:
867 kfree(cmdbuf); 849 kfree(cmdbuf);
868 return ret ? ret : count; 850 return ret ? ret : count;
diff --git a/drivers/media/rc/rc-loopback.c b/drivers/media/rc/rc-loopback.c
index fae1615e0ff2..f9be68132c67 100644
--- a/drivers/media/rc/rc-loopback.c
+++ b/drivers/media/rc/rc-loopback.c
@@ -105,18 +105,9 @@ static int loop_tx_ir(struct rc_dev *dev, unsigned *txbuf, unsigned count)
105{ 105{
106 struct loopback_dev *lodev = dev->priv; 106 struct loopback_dev *lodev = dev->priv;
107 u32 rxmask; 107 u32 rxmask;
108 unsigned total_duration = 0;
109 unsigned i; 108 unsigned i;
110 DEFINE_IR_RAW_EVENT(rawir); 109 DEFINE_IR_RAW_EVENT(rawir);
111 110
112 for (i = 0; i < count; i++)
113 total_duration += abs(txbuf[i]);
114
115 if (total_duration == 0) {
116 dprintk("invalid tx data, total duration zero\n");
117 return -EINVAL;
118 }
119
120 if (lodev->txcarrier < lodev->rxcarriermin || 111 if (lodev->txcarrier < lodev->rxcarriermin ||
121 lodev->txcarrier > lodev->rxcarriermax) { 112 lodev->txcarrier > lodev->rxcarriermax) {
122 dprintk("ignoring tx, carrier out of range\n"); 113 dprintk("ignoring tx, carrier out of range\n");
@@ -148,9 +139,6 @@ static int loop_tx_ir(struct rc_dev *dev, unsigned *txbuf, unsigned count)
148 ir_raw_event_handle(dev); 139 ir_raw_event_handle(dev);
149 140
150out: 141out:
151 /* Lirc expects this function to take as long as the total duration */
152 set_current_state(TASK_INTERRUPTIBLE);
153 schedule_timeout(usecs_to_jiffies(total_duration));
154 return count; 142 return count;
155} 143}
156 144