aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/ivtv
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/ivtv')
-rw-r--r--drivers/media/video/ivtv/ivtv-controls.c10
-rw-r--r--drivers/media/video/ivtv/ivtv-fileops.c11
-rw-r--r--drivers/media/video/ivtv/ivtv-ioctl.c6
-rw-r--r--drivers/media/video/ivtv/ivtv-streams.c23
-rw-r--r--drivers/media/video/ivtv/ivtvfb.c14
5 files changed, 49 insertions, 15 deletions
diff --git a/drivers/media/video/ivtv/ivtv-controls.c b/drivers/media/video/ivtv/ivtv-controls.c
index b59475bfc243..b588e30cbcf0 100644
--- a/drivers/media/video/ivtv/ivtv-controls.c
+++ b/drivers/media/video/ivtv/ivtv-controls.c
@@ -267,13 +267,13 @@ int ivtv_s_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c)
267 if (p.video_encoding != itv->params.video_encoding) { 267 if (p.video_encoding != itv->params.video_encoding) {
268 int is_mpeg1 = p.video_encoding == 268 int is_mpeg1 = p.video_encoding ==
269 V4L2_MPEG_VIDEO_ENCODING_MPEG_1; 269 V4L2_MPEG_VIDEO_ENCODING_MPEG_1;
270 struct v4l2_format fmt; 270 struct v4l2_mbus_framefmt fmt;
271 271
272 /* fix videodecoder resolution */ 272 /* fix videodecoder resolution */
273 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 273 fmt.width = itv->params.width / (is_mpeg1 ? 2 : 1);
274 fmt.fmt.pix.width = itv->params.width / (is_mpeg1 ? 2 : 1); 274 fmt.height = itv->params.height;
275 fmt.fmt.pix.height = itv->params.height; 275 fmt.code = V4L2_MBUS_FMT_FIXED;
276 v4l2_subdev_call(itv->sd_video, video, s_fmt, &fmt); 276 v4l2_subdev_call(itv->sd_video, video, s_mbus_fmt, &fmt);
277 } 277 }
278 err = cx2341x_update(itv, ivtv_api_func, &itv->params, &p); 278 err = cx2341x_update(itv, ivtv_api_func, &itv->params, &p);
279 if (!err && itv->params.stream_vbi_fmt != p.stream_vbi_fmt) 279 if (!err && itv->params.stream_vbi_fmt != p.stream_vbi_fmt)
diff --git a/drivers/media/video/ivtv/ivtv-fileops.c b/drivers/media/video/ivtv/ivtv-fileops.c
index abf410943cc9..3c2cc270ccd5 100644
--- a/drivers/media/video/ivtv/ivtv-fileops.c
+++ b/drivers/media/video/ivtv/ivtv-fileops.c
@@ -823,6 +823,12 @@ static void ivtv_stop_decoding(struct ivtv_open_id *id, int flags, u64 pts)
823 823
824 IVTV_DEBUG_FILE("close() of %s\n", s->name); 824 IVTV_DEBUG_FILE("close() of %s\n", s->name);
825 825
826 if (id->type == IVTV_DEC_STREAM_TYPE_YUV &&
827 test_bit(IVTV_F_I_DECODING_YUV, &itv->i_flags)) {
828 /* Restore registers we've changed & clean up any mess */
829 ivtv_yuv_close(itv);
830 }
831
826 /* Stop decoding */ 832 /* Stop decoding */
827 if (test_bit(IVTV_F_S_STREAMING, &s->s_flags)) { 833 if (test_bit(IVTV_F_S_STREAMING, &s->s_flags)) {
828 IVTV_DEBUG_INFO("close stopping decode\n"); 834 IVTV_DEBUG_INFO("close stopping decode\n");
@@ -832,10 +838,7 @@ static void ivtv_stop_decoding(struct ivtv_open_id *id, int flags, u64 pts)
832 } 838 }
833 clear_bit(IVTV_F_S_APPL_IO, &s->s_flags); 839 clear_bit(IVTV_F_S_APPL_IO, &s->s_flags);
834 clear_bit(IVTV_F_S_STREAMOFF, &s->s_flags); 840 clear_bit(IVTV_F_S_STREAMOFF, &s->s_flags);
835 if (id->type == IVTV_DEC_STREAM_TYPE_YUV && test_bit(IVTV_F_I_DECODING_YUV, &itv->i_flags)) { 841
836 /* Restore registers we've changed & clean up any mess we've made */
837 ivtv_yuv_close(itv);
838 }
839 if (itv->output_mode == OUT_UDMA_YUV && id->yuv_frames) 842 if (itv->output_mode == OUT_UDMA_YUV && id->yuv_frames)
840 itv->output_mode = OUT_NONE; 843 itv->output_mode = OUT_NONE;
841 844
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c
index fa9f0d958f96..11ac2fa33ef7 100644
--- a/drivers/media/video/ivtv/ivtv-ioctl.c
+++ b/drivers/media/video/ivtv/ivtv-ioctl.c
@@ -569,6 +569,7 @@ static int ivtv_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f
569 struct ivtv_open_id *id = fh; 569 struct ivtv_open_id *id = fh;
570 struct ivtv *itv = id->itv; 570 struct ivtv *itv = id->itv;
571 struct cx2341x_mpeg_params *p = &itv->params; 571 struct cx2341x_mpeg_params *p = &itv->params;
572 struct v4l2_mbus_framefmt mbus_fmt;
572 int ret = ivtv_try_fmt_vid_cap(file, fh, fmt); 573 int ret = ivtv_try_fmt_vid_cap(file, fh, fmt);
573 int w = fmt->fmt.pix.width; 574 int w = fmt->fmt.pix.width;
574 int h = fmt->fmt.pix.height; 575 int h = fmt->fmt.pix.height;
@@ -586,7 +587,10 @@ static int ivtv_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f
586 p->height = h; 587 p->height = h;
587 if (p->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1) 588 if (p->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1)
588 fmt->fmt.pix.width /= 2; 589 fmt->fmt.pix.width /= 2;
589 v4l2_subdev_call(itv->sd_video, video, s_fmt, fmt); 590 mbus_fmt.width = fmt->fmt.pix.width;
591 mbus_fmt.height = h;
592 mbus_fmt.code = V4L2_MBUS_FMT_FIXED;
593 v4l2_subdev_call(itv->sd_video, video, s_mbus_fmt, &mbus_fmt);
590 return ivtv_g_fmt_vid_cap(file, fh, fmt); 594 return ivtv_g_fmt_vid_cap(file, fh, fmt);
591} 595}
592 596
diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c
index de4288cc1889..9ecacab4b89b 100644
--- a/drivers/media/video/ivtv/ivtv-streams.c
+++ b/drivers/media/video/ivtv/ivtv-streams.c
@@ -618,12 +618,17 @@ static int ivtv_setup_v4l2_decode_stream(struct ivtv_stream *s)
618 struct ivtv *itv = s->itv; 618 struct ivtv *itv = s->itv;
619 struct cx2341x_mpeg_params *p = &itv->params; 619 struct cx2341x_mpeg_params *p = &itv->params;
620 int datatype; 620 int datatype;
621 u16 width;
622 u16 height;
621 623
622 if (s->vdev == NULL) 624 if (s->vdev == NULL)
623 return -EINVAL; 625 return -EINVAL;
624 626
625 IVTV_DEBUG_INFO("Setting some initial decoder settings\n"); 627 IVTV_DEBUG_INFO("Setting some initial decoder settings\n");
626 628
629 width = p->width;
630 height = p->height;
631
627 /* set audio mode to left/stereo for dual/stereo mode. */ 632 /* set audio mode to left/stereo for dual/stereo mode. */
628 ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode); 633 ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode);
629 634
@@ -646,7 +651,14 @@ static int ivtv_setup_v4l2_decode_stream(struct ivtv_stream *s)
646 2 = yuv_from_host */ 651 2 = yuv_from_host */
647 switch (s->type) { 652 switch (s->type) {
648 case IVTV_DEC_STREAM_TYPE_YUV: 653 case IVTV_DEC_STREAM_TYPE_YUV:
649 datatype = itv->output_mode == OUT_PASSTHROUGH ? 1 : 2; 654 if (itv->output_mode == OUT_PASSTHROUGH) {
655 datatype = 1;
656 } else {
657 /* Fake size to avoid switching video standard */
658 datatype = 2;
659 width = 720;
660 height = itv->is_out_50hz ? 576 : 480;
661 }
650 IVTV_DEBUG_INFO("Setup DEC YUV Stream data[0] = %d\n", datatype); 662 IVTV_DEBUG_INFO("Setup DEC YUV Stream data[0] = %d\n", datatype);
651 break; 663 break;
652 case IVTV_DEC_STREAM_TYPE_MPG: 664 case IVTV_DEC_STREAM_TYPE_MPG:
@@ -655,9 +667,13 @@ static int ivtv_setup_v4l2_decode_stream(struct ivtv_stream *s)
655 break; 667 break;
656 } 668 }
657 if (ivtv_vapi(itv, CX2341X_DEC_SET_DECODER_SOURCE, 4, datatype, 669 if (ivtv_vapi(itv, CX2341X_DEC_SET_DECODER_SOURCE, 4, datatype,
658 p->width, p->height, p->audio_properties)) { 670 width, height, p->audio_properties)) {
659 IVTV_DEBUG_WARN("Couldn't initialize decoder source\n"); 671 IVTV_DEBUG_WARN("Couldn't initialize decoder source\n");
660 } 672 }
673
674 /* Decoder sometimes dies here, so wait a moment */
675 ivtv_msleep_timeout(10, 0);
676
661 return 0; 677 return 0;
662} 678}
663 679
@@ -697,6 +713,9 @@ int ivtv_start_v4l2_decode_stream(struct ivtv_stream *s, int gop_offset)
697 /* start playback */ 713 /* start playback */
698 ivtv_vapi(itv, CX2341X_DEC_START_PLAYBACK, 2, gop_offset, 0); 714 ivtv_vapi(itv, CX2341X_DEC_START_PLAYBACK, 2, gop_offset, 0);
699 715
716 /* Let things settle before we actually start */
717 ivtv_msleep_timeout(10, 0);
718
700 /* Clear the following Interrupt mask bits for decoding */ 719 /* Clear the following Interrupt mask bits for decoding */
701 ivtv_clear_irq_mask(itv, IVTV_IRQ_MASK_DECODE); 720 ivtv_clear_irq_mask(itv, IVTV_IRQ_MASK_DECODE);
702 IVTV_DEBUG_IRQ("IRQ Mask is now: 0x%08x\n", itv->irqmask); 721 IVTV_DEBUG_IRQ("IRQ Mask is now: 0x%08x\n", itv->irqmask);
diff --git a/drivers/media/video/ivtv/ivtvfb.c b/drivers/media/video/ivtv/ivtvfb.c
index 49e1a283ed36..9ff3425891ed 100644
--- a/drivers/media/video/ivtv/ivtvfb.c
+++ b/drivers/media/video/ivtv/ivtvfb.c
@@ -1066,7 +1066,11 @@ static int ivtvfb_init_io(struct ivtv *itv)
1066 } 1066 }
1067 mutex_unlock(&itv->serialize_lock); 1067 mutex_unlock(&itv->serialize_lock);
1068 1068
1069 ivtvfb_get_framebuffer(itv, &oi->video_rbase, &oi->video_buffer_size); 1069 if (ivtvfb_get_framebuffer(itv, &oi->video_rbase,
1070 &oi->video_buffer_size) < 0) {
1071 IVTVFB_ERR("Firmware failed to respond\n");
1072 return -EIO;
1073 }
1070 1074
1071 /* The osd buffer size depends on the number of video buffers allocated 1075 /* The osd buffer size depends on the number of video buffers allocated
1072 on the PVR350 itself. For now we'll hardcode the smallest osd buffer 1076 on the PVR350 itself. For now we'll hardcode the smallest osd buffer
@@ -1158,8 +1162,11 @@ static int ivtvfb_init_card(struct ivtv *itv)
1158 } 1162 }
1159 1163
1160 /* Find & setup the OSD buffer */ 1164 /* Find & setup the OSD buffer */
1161 if ((rc = ivtvfb_init_io(itv))) 1165 rc = ivtvfb_init_io(itv);
1166 if (rc) {
1167 ivtvfb_release_buffers(itv);
1162 return rc; 1168 return rc;
1169 }
1163 1170
1164 /* Set the startup video mode information */ 1171 /* Set the startup video mode information */
1165 if ((rc = ivtvfb_init_vidmode(itv))) { 1172 if ((rc = ivtvfb_init_vidmode(itv))) {
@@ -1210,6 +1217,7 @@ static int ivtvfb_callback_cleanup(struct device *dev, void *p)
1210{ 1217{
1211 struct v4l2_device *v4l2_dev = dev_get_drvdata(dev); 1218 struct v4l2_device *v4l2_dev = dev_get_drvdata(dev);
1212 struct ivtv *itv = container_of(v4l2_dev, struct ivtv, v4l2_dev); 1219 struct ivtv *itv = container_of(v4l2_dev, struct ivtv, v4l2_dev);
1220 struct osd_info *oi = itv->osd_info;
1213 1221
1214 if (itv && (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) { 1222 if (itv && (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) {
1215 if (unregister_framebuffer(&itv->osd_info->ivtvfb_info)) { 1223 if (unregister_framebuffer(&itv->osd_info->ivtvfb_info)) {
@@ -1218,7 +1226,7 @@ static int ivtvfb_callback_cleanup(struct device *dev, void *p)
1218 return 0; 1226 return 0;
1219 } 1227 }
1220 IVTVFB_INFO("Unregister framebuffer %d\n", itv->instance); 1228 IVTVFB_INFO("Unregister framebuffer %d\n", itv->instance);
1221 ivtvfb_blank(FB_BLANK_POWERDOWN, &itv->osd_info->ivtvfb_info); 1229 ivtvfb_blank(FB_BLANK_VSYNC_SUSPEND, &oi->ivtvfb_info);
1222 ivtvfb_release_buffers(itv); 1230 ivtvfb_release_buffers(itv);
1223 itv->osd_video_pbase = 0; 1231 itv->osd_video_pbase = 0;
1224 } 1232 }