aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/ivtv/ivtv-streams.c
diff options
context:
space:
mode:
authorHans Verkuil <hverkuil@xs4all.nl>2007-08-18 10:46:05 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2007-10-09 21:05:31 -0400
commit3562c43be8cfd6e300508d7c33acebf3369eacd3 (patch)
tree3b2aab0d4e078ddf5445d2ab82eea2838bcf01ba /drivers/media/video/ivtv/ivtv-streams.c
parentda80be21362376443c6ee9918dfff408e83e0c39 (diff)
V4L/DVB (6045): ivtv: fix handling of INITIALIZE_INPUT fw call
The CX2341X_ENC_INITIALIZE_INPUT firmware call requires careful handling, otherwise the computer can freeze or the top-third of the screen can start flickering. This patch ensures that CX2341X_ENC_INITIALIZE_INPUT is called at the right time and in the right way. In addition the stop capture handling was improved so that the last pending DMA transfer is also processed. Otherwise this would be the first data that arrived when a new capture was started which is not what you want. Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/video/ivtv/ivtv-streams.c')
-rw-r--r--drivers/media/video/ivtv/ivtv-streams.c28
1 files changed, 5 insertions, 23 deletions
diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c
index 405e2e3fcb49..0582b9d57c55 100644
--- a/drivers/media/video/ivtv/ivtv-streams.c
+++ b/drivers/media/video/ivtv/ivtv-streams.c
@@ -554,9 +554,10 @@ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s)
554 clear_bit(IVTV_F_I_EOS, &itv->i_flags); 554 clear_bit(IVTV_F_I_EOS, &itv->i_flags);
555 555
556 /* Initialize Digitizer for Capture */ 556 /* Initialize Digitizer for Capture */
557 itv->video_dec_func(itv, VIDIOC_STREAMOFF, 0);
558 ivtv_msleep_timeout(300, 1);
557 ivtv_vapi(itv, CX2341X_ENC_INITIALIZE_INPUT, 0); 559 ivtv_vapi(itv, CX2341X_ENC_INITIALIZE_INPUT, 0);
558 560 itv->video_dec_func(itv, VIDIOC_STREAMON, 0);
559 ivtv_msleep_timeout(100, 0);
560 } 561 }
561 562
562 /* begin_capture */ 563 /* begin_capture */
@@ -713,7 +714,6 @@ int ivtv_stop_v4l2_encode_stream(struct ivtv_stream *s, int gop_end)
713 int cap_type; 714 int cap_type;
714 unsigned long then; 715 unsigned long then;
715 int stopmode; 716 int stopmode;
716 u32 data[CX2341X_MBOX_MAX_DATA];
717 717
718 if (s->v4l2dev == NULL) 718 if (s->v4l2dev == NULL)
719 return -EINVAL; 719 return -EINVAL;
@@ -793,27 +793,9 @@ int ivtv_stop_v4l2_encode_stream(struct ivtv_stream *s, int gop_end)
793 } 793 }
794 794
795 then = jiffies; 795 then = jiffies;
796 /* Make sure DMA is complete */
797 add_wait_queue(&s->waitq, &wait);
798 do {
799 /* check if DMA is pending */
800 if ((s->type == IVTV_ENC_STREAM_TYPE_MPG) && /* MPG Only */
801 (read_reg(IVTV_REG_DMASTATUS) & 0x02)) {
802 /* Check for last DMA */
803 ivtv_vapi_result(itv, data, CX2341X_ENC_GET_SEQ_END, 2, 0, 0);
804
805 if (data[0] == 1) {
806 IVTV_DEBUG_DMA("%s: Last DMA of size 0x%08x\n", s->name, data[1]);
807 break;
808 }
809 } else if (read_reg(IVTV_REG_DMASTATUS) & 0x02) {
810 break;
811 }
812 } while (!ivtv_msleep_timeout(10, 1) &&
813 then + msecs_to_jiffies(2000) > jiffies);
814 796
815 set_current_state(TASK_RUNNING); 797 /* Handle any pending interrupts */
816 remove_wait_queue(&s->waitq, &wait); 798 ivtv_msleep_timeout(100, 1);
817 } 799 }
818 800
819 atomic_dec(&itv->capturing); 801 atomic_dec(&itv->capturing);