diff options
Diffstat (limited to 'drivers/media/video/ivtv')
-rw-r--r-- | drivers/media/video/ivtv/ivtv-controls.c | 10 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-fileops.c | 11 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-ioctl.c | 6 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-streams.c | 23 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtvfb.c | 14 |
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 | } |