aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Verkuil <hans.verkuil@cisco.com>2013-04-14 11:02:19 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2013-04-16 17:12:34 -0400
commitea3f7ac6e931f9aaa45e0a8445406f14e2a62011 (patch)
tree7d1bdfbe00e326943c3c69640c5cc10c1b917f34
parent7087d31b0c9dddbca71b8e33d3f0a3b719afa397 (diff)
[media] cx25821: replace custom ioctls with write()
Ideally this should be implemented with vb2, but it'll do for now. Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--drivers/media/pci/cx25821/cx25821-core.c3
-rw-r--r--drivers/media/pci/cx25821/cx25821-video-upstream.c248
-rw-r--r--drivers/media/pci/cx25821/cx25821-video.c37
-rw-r--r--drivers/media/pci/cx25821/cx25821.h12
4 files changed, 72 insertions, 228 deletions
diff --git a/drivers/media/pci/cx25821/cx25821-core.c b/drivers/media/pci/cx25821/cx25821-core.c
index 230bd8641576..35bea792b5e4 100644
--- a/drivers/media/pci/cx25821/cx25821-core.c
+++ b/drivers/media/pci/cx25821/cx25821-core.c
@@ -775,8 +775,8 @@ void cx25821_set_pixel_format(struct cx25821_dev *dev, int channel_select,
775 if (channel_select <= 7 && channel_select >= 0) { 775 if (channel_select <= 7 && channel_select >= 0) {
776 cx_write(dev->channels[channel_select].sram_channels->pix_frmt, 776 cx_write(dev->channels[channel_select].sram_channels->pix_frmt,
777 format); 777 format);
778 dev->channels[channel_select].pixel_formats = format;
779 } 778 }
779 dev->channels[channel_select].pixel_formats = format;
780} 780}
781 781
782static void cx25821_set_vip_mode(struct cx25821_dev *dev, 782static void cx25821_set_vip_mode(struct cx25821_dev *dev,
@@ -820,6 +820,7 @@ static void cx25821_initialize(struct cx25821_dev *dev)
820 /* Probably only affect Downstream */ 820 /* Probably only affect Downstream */
821 for (i = VID_UPSTREAM_SRAM_CHANNEL_I; 821 for (i = VID_UPSTREAM_SRAM_CHANNEL_I;
822 i <= VID_UPSTREAM_SRAM_CHANNEL_J; i++) { 822 i <= VID_UPSTREAM_SRAM_CHANNEL_J; i++) {
823 dev->channels[i].pixel_formats = PIXEL_FRMT_422;
823 cx25821_set_vip_mode(dev, dev->channels[i].sram_channels); 824 cx25821_set_vip_mode(dev, dev->channels[i].sram_channels);
824 } 825 }
825 826
diff --git a/drivers/media/pci/cx25821/cx25821-video-upstream.c b/drivers/media/pci/cx25821/cx25821-video-upstream.c
index 37cfc834e5c0..88ffef410c50 100644
--- a/drivers/media/pci/cx25821/cx25821-video-upstream.c
+++ b/drivers/media/pci/cx25821/cx25821-video-upstream.c
@@ -25,16 +25,11 @@
25#include "cx25821-video.h" 25#include "cx25821-video.h"
26#include "cx25821-video-upstream.h" 26#include "cx25821-video-upstream.h"
27 27
28#include <linux/fs.h>
29#include <linux/errno.h> 28#include <linux/errno.h>
30#include <linux/kernel.h> 29#include <linux/kernel.h>
31#include <linux/init.h> 30#include <linux/init.h>
32#include <linux/module.h> 31#include <linux/module.h>
33#include <linux/syscalls.h>
34#include <linux/file.h>
35#include <linux/fcntl.h>
36#include <linux/slab.h> 32#include <linux/slab.h>
37#include <linux/uaccess.h>
38 33
39MODULE_DESCRIPTION("v4l2 driver module for cx25821 based TV cards"); 34MODULE_DESCRIPTION("v4l2 driver module for cx25821 based TV cards");
40MODULE_AUTHOR("Hiep Huynh <hiep.huynh@conexant.com>"); 35MODULE_AUTHOR("Hiep Huynh <hiep.huynh@conexant.com>");
@@ -258,6 +253,10 @@ void cx25821_stop_upstream_video(struct cx25821_channel *chan)
258 pr_info("No video file is currently running so return!\n"); 253 pr_info("No video file is currently running so return!\n");
259 return; 254 return;
260 } 255 }
256
257 /* Set the interrupt mask register, disable irq. */
258 cx_set(PCI_INT_MSK, cx_read(PCI_INT_MSK) & ~(1 << sram_ch->irq_bit));
259
261 /* Disable RISC interrupts */ 260 /* Disable RISC interrupts */
262 tmp = cx_read(sram_ch->int_msk); 261 tmp = cx_read(sram_ch->int_msk);
263 cx_write(sram_ch->int_msk, tmp & ~_intr_msk); 262 cx_write(sram_ch->int_msk, tmp & ~_intr_msk);
@@ -266,6 +265,8 @@ void cx25821_stop_upstream_video(struct cx25821_channel *chan)
266 tmp = cx_read(sram_ch->dma_ctl); 265 tmp = cx_read(sram_ch->dma_ctl);
267 cx_write(sram_ch->dma_ctl, tmp & ~(FLD_VID_FIFO_EN | FLD_VID_RISC_EN)); 266 cx_write(sram_ch->dma_ctl, tmp & ~(FLD_VID_FIFO_EN | FLD_VID_RISC_EN));
268 267
268 free_irq(dev->pci->irq, chan);
269
269 /* Clear data buffer memory */ 270 /* Clear data buffer memory */
270 if (out->_data_buf_virt_addr) 271 if (out->_data_buf_virt_addr)
271 memset(out->_data_buf_virt_addr, 0, out->_data_buf_size); 272 memset(out->_data_buf_virt_addr, 0, out->_data_buf_size);
@@ -275,11 +276,6 @@ void cx25821_stop_upstream_video(struct cx25821_channel *chan)
275 out->_frame_count = 0; 276 out->_frame_count = 0;
276 out->_file_status = END_OF_FILE; 277 out->_file_status = END_OF_FILE;
277 278
278 destroy_workqueue(out->_irq_queues);
279 out->_irq_queues = NULL;
280
281 kfree(out->_filename);
282
283 tmp = cx_read(VID_CH_MODE_SEL); 279 tmp = cx_read(VID_CH_MODE_SEL);
284 cx_write(VID_CH_MODE_SEL, tmp & 0xFFFFFE00); 280 cx_write(VID_CH_MODE_SEL, tmp & 0xFFFFFE00);
285} 281}
@@ -306,25 +302,15 @@ void cx25821_free_mem_upstream(struct cx25821_channel *chan)
306 } 302 }
307} 303}
308 304
309static int cx25821_get_frame(struct cx25821_channel *chan, 305int cx25821_write_frame(struct cx25821_channel *chan,
310 const struct sram_channel *sram_ch) 306 const char __user *data, size_t count)
311{ 307{
312 struct cx25821_video_out_data *out = chan->out; 308 struct cx25821_video_out_data *out = chan->out;
313 struct file *myfile;
314 int frame_index_temp = out->_frame_index;
315 int i = 0;
316 int line_size = (out->_pixel_format == PIXEL_FRMT_411) ? 309 int line_size = (out->_pixel_format == PIXEL_FRMT_411) ?
317 Y411_LINE_SZ : Y422_LINE_SZ; 310 Y411_LINE_SZ : Y422_LINE_SZ;
318 int frame_size = 0; 311 int frame_size = 0;
319 int frame_offset = 0; 312 int frame_offset = 0;
320 ssize_t vfs_read_retval = 0; 313 int curpos = out->curpos;
321 char mybuf[line_size];
322 loff_t file_offset;
323 loff_t pos;
324 mm_segment_t old_fs;
325
326 if (out->_file_status == END_OF_FILE)
327 return 0;
328 314
329 if (out->is_60hz) 315 if (out->is_60hz)
330 frame_size = (line_size == Y411_LINE_SZ) ? 316 frame_size = (line_size == Y411_LINE_SZ) ?
@@ -333,160 +319,27 @@ static int cx25821_get_frame(struct cx25821_channel *chan,
333 frame_size = (line_size == Y411_LINE_SZ) ? 319 frame_size = (line_size == Y411_LINE_SZ) ?
334 FRAME_SIZE_PAL_Y411 : FRAME_SIZE_PAL_Y422; 320 FRAME_SIZE_PAL_Y411 : FRAME_SIZE_PAL_Y422;
335 321
336 frame_offset = (frame_index_temp > 0) ? frame_size : 0; 322 if (curpos == 0) {
337 file_offset = out->_frame_count * frame_size; 323 out->cur_frame_index = out->_frame_index;
338 324 if (wait_event_interruptible(out->waitq, out->cur_frame_index != out->_frame_index))
339 myfile = filp_open(out->_filename, O_RDONLY | O_LARGEFILE, 0); 325 return -EINTR;
340 326 out->cur_frame_index = out->_frame_index;
341 if (IS_ERR(myfile)) {
342 const int open_errno = -PTR_ERR(myfile);
343 pr_err("%s(): ERROR opening file(%s) with errno = %d!\n",
344 __func__, out->_filename, open_errno);
345 return PTR_ERR(myfile);
346 } else {
347 if (!(myfile->f_op)) {
348 pr_err("%s(): File has no file operations registered!\n",
349 __func__);
350 filp_close(myfile, NULL);
351 return -EIO;
352 }
353
354 if (!myfile->f_op->read) {
355 pr_err("%s(): File has no READ operations registered!\n",
356 __func__);
357 filp_close(myfile, NULL);
358 return -EIO;
359 }
360
361 pos = myfile->f_pos;
362 old_fs = get_fs();
363 set_fs(KERNEL_DS);
364
365 for (i = 0; i < out->_lines_count; i++) {
366 pos = file_offset;
367
368 vfs_read_retval = vfs_read(myfile, mybuf, line_size,
369 &pos);
370
371 if (vfs_read_retval > 0 && vfs_read_retval == line_size
372 && out->_data_buf_virt_addr != NULL) {
373 memcpy((void *)(out->_data_buf_virt_addr +
374 frame_offset / 4), mybuf,
375 vfs_read_retval);
376 }
377
378 file_offset += vfs_read_retval;
379 frame_offset += vfs_read_retval;
380
381 if (vfs_read_retval < line_size) {
382 pr_info("Done: exit %s() since no more bytes to read from Video file\n",
383 __func__);
384 break;
385 }
386 }
387
388 if (i > 0)
389 out->_frame_count++;
390
391 out->_file_status = (vfs_read_retval == line_size) ?
392 IN_PROGRESS : END_OF_FILE;
393
394 set_fs(old_fs);
395 filp_close(myfile, NULL);
396 } 327 }
397 328
398 return 0; 329 frame_offset = out->cur_frame_index ? frame_size : 0;
399}
400
401static void cx25821_vidups_handler(struct work_struct *work)
402{
403 struct cx25821_video_out_data *out =
404 container_of(work, struct cx25821_video_out_data, _irq_work_entry);
405
406 cx25821_get_frame(out->chan, out->chan->sram_channels);
407}
408 330
409static int cx25821_openfile(struct cx25821_channel *chan, 331 if (frame_size - curpos < count)
410 const struct sram_channel *sram_ch) 332 count = frame_size - curpos;
411{ 333 memcpy((char *)out->_data_buf_virt_addr + frame_offset + curpos,
412 struct cx25821_video_out_data *out = chan->out; 334 data, count);
413 struct file *myfile; 335 curpos += count;
414 int i = 0, j = 0; 336 if (curpos == frame_size) {
415 int line_size = (out->_pixel_format == PIXEL_FRMT_411) ? 337 out->_frame_count++;
416 Y411_LINE_SZ : Y422_LINE_SZ; 338 curpos = 0;
417 ssize_t vfs_read_retval = 0;
418 char mybuf[line_size];
419 loff_t pos;
420 loff_t offset = (unsigned long)0;
421 mm_segment_t old_fs;
422
423 myfile = filp_open(out->_filename, O_RDONLY | O_LARGEFILE, 0);
424
425 if (IS_ERR(myfile)) {
426 const int open_errno = -PTR_ERR(myfile);
427 pr_err("%s(): ERROR opening file(%s) with errno = %d!\n",
428 __func__, out->_filename, open_errno);
429 return PTR_ERR(myfile);
430 } else {
431 if (!(myfile->f_op)) {
432 pr_err("%s(): File has no file operations registered!\n",
433 __func__);
434 filp_close(myfile, NULL);
435 return -EIO;
436 }
437
438 if (!myfile->f_op->read) {
439 pr_err("%s(): File has no READ operations registered! Returning\n",
440 __func__);
441 filp_close(myfile, NULL);
442 return -EIO;
443 }
444
445 pos = myfile->f_pos;
446 old_fs = get_fs();
447 set_fs(KERNEL_DS);
448
449 for (j = 0; j < NUM_FRAMES; j++) {
450 for (i = 0; i < out->_lines_count; i++) {
451 pos = offset;
452
453 vfs_read_retval = vfs_read(myfile, mybuf,
454 line_size, &pos);
455
456 if (vfs_read_retval > 0
457 && vfs_read_retval == line_size
458 && out->_data_buf_virt_addr != NULL) {
459 memcpy((void *)(out->
460 _data_buf_virt_addr +
461 offset / 4), mybuf,
462 vfs_read_retval);
463 }
464
465 offset += vfs_read_retval;
466
467 if (vfs_read_retval < line_size) {
468 pr_info("Done: exit %s() since no more bytes to read from Video file\n",
469 __func__);
470 break;
471 }
472 }
473
474 if (i > 0)
475 out->_frame_count++;
476
477 if (vfs_read_retval < line_size)
478 break;
479 }
480
481 out->_file_status = (vfs_read_retval == line_size) ?
482 IN_PROGRESS : END_OF_FILE;
483
484 set_fs(old_fs);
485 myfile->f_pos = 0;
486 filp_close(myfile, NULL);
487 } 339 }
340 out->curpos = curpos;
488 341
489 return 0; 342 return count;
490} 343}
491 344
492static int cx25821_upstream_buffer_prepare(struct cx25821_channel *chan, 345static int cx25821_upstream_buffer_prepare(struct cx25821_channel *chan,
@@ -536,10 +389,6 @@ static int cx25821_upstream_buffer_prepare(struct cx25821_channel *chan,
536 /* Clear memory at address */ 389 /* Clear memory at address */
537 memset(out->_data_buf_virt_addr, 0, out->_data_buf_size); 390 memset(out->_data_buf_virt_addr, 0, out->_data_buf_size);
538 391
539 ret = cx25821_openfile(chan, sram_ch);
540 if (ret < 0)
541 return ret;
542
543 /* Create RISC programs */ 392 /* Create RISC programs */
544 ret = cx25821_risc_buffer_upstream(chan, dev->pci, 0, bpl, 393 ret = cx25821_risc_buffer_upstream(chan, dev->pci, 0, bpl,
545 out->_lines_count); 394 out->_lines_count);
@@ -576,12 +425,12 @@ static int cx25821_video_upstream_irq(struct cx25821_channel *chan, u32 status)
576 cx_write(channel->int_msk, int_msk_tmp & ~_intr_msk); 425 cx_write(channel->int_msk, int_msk_tmp & ~_intr_msk);
577 cx_write(channel->int_stat, _intr_msk); 426 cx_write(channel->int_stat, _intr_msk);
578 427
428 wake_up(&out->waitq);
429
579 spin_lock(&dev->slock); 430 spin_lock(&dev->slock);
580 431
581 out->_frame_index = prog_cnt; 432 out->_frame_index = prog_cnt;
582 433
583 queue_work(out->_irq_queues, &out->_irq_work_entry);
584
585 if (out->_is_first_frame) { 434 if (out->_is_first_frame) {
586 out->_is_first_frame = 0; 435 out->_is_first_frame = 0;
587 436
@@ -762,7 +611,6 @@ int cx25821_vidupstream_init(struct cx25821_channel *chan,
762 int err = 0; 611 int err = 0;
763 int data_frame_size = 0; 612 int data_frame_size = 0;
764 int risc_buffer_size = 0; 613 int risc_buffer_size = 0;
765 int str_length = 0;
766 614
767 if (out->_is_running) { 615 if (out->_is_running) {
768 pr_info("Video Channel is still running so return!\n"); 616 pr_info("Video Channel is still running so return!\n");
@@ -771,13 +619,8 @@ int cx25821_vidupstream_init(struct cx25821_channel *chan,
771 619
772 sram_ch = chan->sram_channels; 620 sram_ch = chan->sram_channels;
773 621
774 INIT_WORK(&out->_irq_work_entry, cx25821_vidups_handler); 622 out->is_60hz = dev->tvnorm & V4L2_STD_525_60;
775 out->_irq_queues = create_singlethread_workqueue("cx25821_workqueue");
776 623
777 if (!out->_irq_queues) {
778 pr_err("create_singlethread_workqueue() for Video FAILED!\n");
779 return -ENOMEM;
780 }
781 /* 656/VIP SRC Upstream Channel I & J and 7 - Host Bus Interface for 624 /* 656/VIP SRC Upstream Channel I & J and 7 - Host Bus Interface for
782 * channel A-C 625 * channel A-C
783 */ 626 */
@@ -795,39 +638,6 @@ int cx25821_vidupstream_init(struct cx25821_channel *chan,
795 risc_buffer_size = out->is_60hz ? 638 risc_buffer_size = out->is_60hz ?
796 NTSC_RISC_BUF_SIZE : PAL_RISC_BUF_SIZE; 639 NTSC_RISC_BUF_SIZE : PAL_RISC_BUF_SIZE;
797 640
798 if (out->input_filename) {
799 str_length = strlen(out->input_filename);
800 out->_filename = kmemdup(out->input_filename, str_length + 1,
801 GFP_KERNEL);
802
803 if (!out->_filename) {
804 err = -ENOENT;
805 goto error;
806 }
807 } else {
808 str_length = strlen(out->_defaultname);
809 out->_filename = kmemdup(out->_defaultname, str_length + 1,
810 GFP_KERNEL);
811
812 if (!out->_filename) {
813 err = -ENOENT;
814 goto error;
815 }
816 }
817
818 /* Default if filename is empty string */
819 if (strcmp(out->_filename, "") == 0) {
820 if (out->is_60hz) {
821 out->_filename =
822 (out->_pixel_format == PIXEL_FRMT_411) ?
823 "/root/vid411.yuv" : "/root/vidtest.yuv";
824 } else {
825 out->_filename =
826 (out->_pixel_format == PIXEL_FRMT_411) ?
827 "/root/pal411.yuv" : "/root/pal422.yuv";
828 }
829 }
830
831 out->_is_running = 0; 641 out->_is_running = 0;
832 out->_frame_count = 0; 642 out->_frame_count = 0;
833 out->_file_status = RESET_STATUS; 643 out->_file_status = RESET_STATUS;
@@ -835,6 +645,8 @@ int cx25821_vidupstream_init(struct cx25821_channel *chan,
835 out->_pixel_format = pixel_format; 645 out->_pixel_format = pixel_format;
836 out->_line_size = (out->_pixel_format == PIXEL_FRMT_422) ? 646 out->_line_size = (out->_pixel_format == PIXEL_FRMT_422) ?
837 (WIDTH_D1 * 2) : (WIDTH_D1 * 3) / 2; 647 (WIDTH_D1 * 2) : (WIDTH_D1 * 3) / 2;
648 out->curpos = 0;
649 init_waitqueue_head(&out->waitq);
838 650
839 err = cx25821_sram_channel_setup_upstream(dev, sram_ch, 651 err = cx25821_sram_channel_setup_upstream(dev, sram_ch,
840 out->_line_size, 0); 652 out->_line_size, 0);
diff --git a/drivers/media/pci/cx25821/cx25821-video.c b/drivers/media/pci/cx25821/cx25821-video.c
index dde0ba3d3401..b194138961df 100644
--- a/drivers/media/pci/cx25821/cx25821-video.c
+++ b/drivers/media/pci/cx25821/cx25821-video.c
@@ -893,15 +893,47 @@ static int vidioc_s_fmt_vid_out(struct file *file, void *priv,
893 return 0; 893 return 0;
894} 894}
895 895
896static ssize_t video_write(struct file *file, const char __user *data, size_t count,
897 loff_t *ppos)
898{
899 struct cx25821_channel *chan = video_drvdata(file);
900 struct cx25821_dev *dev = chan->dev;
901 struct v4l2_fh *fh = file->private_data;
902 int err = 0;
903
904 if (mutex_lock_interruptible(&dev->lock))
905 return -ERESTARTSYS;
906 if (chan->streaming_fh && chan->streaming_fh != fh) {
907 err = -EBUSY;
908 goto unlock;
909 }
910 if (!chan->streaming_fh) {
911 err = cx25821_vidupstream_init(chan, chan->pixel_formats);
912 if (err)
913 goto unlock;
914 chan->streaming_fh = fh;
915 }
916
917 err = cx25821_write_frame(chan, data, count);
918 count -= err;
919 *ppos += err;
920
921unlock:
922 mutex_unlock(&dev->lock);
923 return err;
924}
925
896static int video_out_release(struct file *file) 926static int video_out_release(struct file *file)
897{ 927{
898 struct cx25821_channel *chan = video_drvdata(file); 928 struct cx25821_channel *chan = video_drvdata(file);
899 struct cx25821_video_out_data *out = chan->out;
900 struct cx25821_dev *dev = chan->dev; 929 struct cx25821_dev *dev = chan->dev;
930 struct v4l2_fh *fh = file->private_data;
901 931
902 mutex_lock(&dev->lock); 932 mutex_lock(&dev->lock);
903 if ((chan->id == SRAM_CH09 || chan->id == SRAM_CH10) && out->_is_running) 933 if (chan->streaming_fh == fh) {
904 cx25821_stop_upstream_video(chan); 934 cx25821_stop_upstream_video(chan);
935 chan->streaming_fh = NULL;
936 }
905 mutex_unlock(&dev->lock); 937 mutex_unlock(&dev->lock);
906 938
907 return v4l2_fh_release(file); 939 return v4l2_fh_release(file);
@@ -955,6 +987,7 @@ static const struct video_device cx25821_video_device = {
955static const struct v4l2_file_operations video_out_fops = { 987static const struct v4l2_file_operations video_out_fops = {
956 .owner = THIS_MODULE, 988 .owner = THIS_MODULE,
957 .open = v4l2_fh_open, 989 .open = v4l2_fh_open,
990 .write = video_write,
958 .release = video_out_release, 991 .release = video_out_release,
959 .unlocked_ioctl = video_ioctl2, 992 .unlocked_ioctl = video_ioctl2,
960}; 993};
diff --git a/drivers/media/pci/cx25821/cx25821.h b/drivers/media/pci/cx25821/cx25821.h
index b0bc2e626ae7..90bdc196929f 100644
--- a/drivers/media/pci/cx25821/cx25821.h
+++ b/drivers/media/pci/cx25821/cx25821.h
@@ -197,15 +197,11 @@ struct cx25821_video_out_data {
197 197
198 u32 upstream_riscbuf_size; 198 u32 upstream_riscbuf_size;
199 u32 upstream_databuf_size; 199 u32 upstream_databuf_size;
200 struct workqueue_struct *_irq_queues;
201 struct work_struct _irq_work_entry;
202 int is_60hz; 200 int is_60hz;
203 int _frame_index; 201 int _frame_index;
204 char *input_filename; 202 int cur_frame_index;
205 char *vid_stdname; 203 int curpos;
206 int pixel_format; 204 wait_queue_head_t waitq;
207 char *_filename;
208 char *_defaultname;
209}; 205};
210 206
211struct cx25821_channel { 207struct cx25821_channel {
@@ -440,6 +436,8 @@ extern int cx25821_sram_channel_setup_audio(struct cx25821_dev *dev,
440extern int cx25821_vidupstream_init(struct cx25821_channel *chan, int pixel_format); 436extern int cx25821_vidupstream_init(struct cx25821_channel *chan, int pixel_format);
441extern int cx25821_audio_upstream_init(struct cx25821_dev *dev, 437extern int cx25821_audio_upstream_init(struct cx25821_dev *dev,
442 int channel_select); 438 int channel_select);
439extern int cx25821_write_frame(struct cx25821_channel *chan,
440 const char __user *data, size_t count);
443extern void cx25821_free_mem_upstream(struct cx25821_channel *chan); 441extern void cx25821_free_mem_upstream(struct cx25821_channel *chan);
444extern void cx25821_free_mem_upstream_audio(struct cx25821_dev *dev); 442extern void cx25821_free_mem_upstream_audio(struct cx25821_dev *dev);
445extern void cx25821_stop_upstream_video(struct cx25821_channel *chan); 443extern void cx25821_stop_upstream_video(struct cx25821_channel *chan);