diff options
-rw-r--r-- | drivers/media/platform/davinci/vpif_capture.c | 240 |
1 files changed, 22 insertions, 218 deletions
diff --git a/drivers/media/platform/davinci/vpif_capture.c b/drivers/media/platform/davinci/vpif_capture.c index 6ad9e09d2bb2..75015f42c2da 100644 --- a/drivers/media/platform/davinci/vpif_capture.c +++ b/drivers/media/platform/davinci/vpif_capture.c | |||
@@ -208,6 +208,12 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count) | |||
208 | } | 208 | } |
209 | } | 209 | } |
210 | 210 | ||
211 | ret = v4l2_subdev_call(ch->sd, video, s_stream, 1); | ||
212 | if (ret && ret != -ENOIOCTLCMD && ret != -ENODEV) { | ||
213 | vpif_dbg(1, debug, "stream on failed in subdev\n"); | ||
214 | goto err; | ||
215 | } | ||
216 | |||
211 | /* Call vpif_set_params function to set the parameters and addresses */ | 217 | /* Call vpif_set_params function to set the parameters and addresses */ |
212 | ret = vpif_set_video_params(vpif, ch->channel_id); | 218 | ret = vpif_set_video_params(vpif, ch->channel_id); |
213 | 219 | ||
@@ -275,6 +281,7 @@ static void vpif_stop_streaming(struct vb2_queue *vq) | |||
275 | struct channel_obj *ch = vb2_get_drv_priv(vq); | 281 | struct channel_obj *ch = vb2_get_drv_priv(vq); |
276 | struct common_obj *common; | 282 | struct common_obj *common; |
277 | unsigned long flags; | 283 | unsigned long flags; |
284 | int ret; | ||
278 | 285 | ||
279 | common = &ch->common[VPIF_VIDEO_INDEX]; | 286 | common = &ch->common[VPIF_VIDEO_INDEX]; |
280 | 287 | ||
@@ -290,6 +297,10 @@ static void vpif_stop_streaming(struct vb2_queue *vq) | |||
290 | } | 297 | } |
291 | common->started = 0; | 298 | common->started = 0; |
292 | 299 | ||
300 | ret = v4l2_subdev_call(ch->sd, video, s_stream, 0); | ||
301 | if (ret && ret != -ENOIOCTLCMD && ret != -ENODEV) | ||
302 | vpif_dbg(1, debug, "stream off failed in subdev\n"); | ||
303 | |||
293 | /* release all active buffers */ | 304 | /* release all active buffers */ |
294 | spin_lock_irqsave(&common->irqlock, flags); | 305 | spin_lock_irqsave(&common->irqlock, flags); |
295 | if (common->cur_frm == common->next_frm) { | 306 | if (common->cur_frm == common->next_frm) { |
@@ -751,218 +762,6 @@ static void vpif_config_addr(struct channel_obj *ch, int muxmode) | |||
751 | } | 762 | } |
752 | 763 | ||
753 | /** | 764 | /** |
754 | * vpif_reqbufs() - request buffer handler | ||
755 | * @file: file ptr | ||
756 | * @priv: file handle | ||
757 | * @reqbuf: request buffer structure ptr | ||
758 | */ | ||
759 | static int vpif_reqbufs(struct file *file, void *priv, | ||
760 | struct v4l2_requestbuffers *reqbuf) | ||
761 | { | ||
762 | struct video_device *vdev = video_devdata(file); | ||
763 | struct channel_obj *ch = video_get_drvdata(vdev); | ||
764 | struct common_obj *common; | ||
765 | u8 index = 0; | ||
766 | |||
767 | vpif_dbg(2, debug, "vpif_reqbufs\n"); | ||
768 | |||
769 | if (V4L2_BUF_TYPE_VIDEO_CAPTURE != reqbuf->type || !vpif_dev) | ||
770 | return -EINVAL; | ||
771 | |||
772 | index = VPIF_VIDEO_INDEX; | ||
773 | |||
774 | common = &ch->common[index]; | ||
775 | |||
776 | if (0 != common->io_usrs) | ||
777 | return -EBUSY; | ||
778 | |||
779 | /* Increment io usrs member of channel object to 1 */ | ||
780 | common->io_usrs = 1; | ||
781 | /* Store type of memory requested in channel object */ | ||
782 | common->memory = reqbuf->memory; | ||
783 | |||
784 | /* Allocate buffers */ | ||
785 | return vb2_reqbufs(&common->buffer_queue, reqbuf); | ||
786 | } | ||
787 | |||
788 | /** | ||
789 | * vpif_querybuf() - query buffer handler | ||
790 | * @file: file ptr | ||
791 | * @priv: file handle | ||
792 | * @buf: v4l2 buffer structure ptr | ||
793 | */ | ||
794 | static int vpif_querybuf(struct file *file, void *priv, | ||
795 | struct v4l2_buffer *buf) | ||
796 | { | ||
797 | struct video_device *vdev = video_devdata(file); | ||
798 | struct channel_obj *ch = video_get_drvdata(vdev); | ||
799 | struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; | ||
800 | |||
801 | vpif_dbg(2, debug, "vpif_querybuf\n"); | ||
802 | |||
803 | if (common->fmt.type != buf->type) | ||
804 | return -EINVAL; | ||
805 | |||
806 | if (common->memory != V4L2_MEMORY_MMAP) { | ||
807 | vpif_dbg(1, debug, "Invalid memory\n"); | ||
808 | return -EINVAL; | ||
809 | } | ||
810 | |||
811 | return vb2_querybuf(&common->buffer_queue, buf); | ||
812 | } | ||
813 | |||
814 | /** | ||
815 | * vpif_qbuf() - query buffer handler | ||
816 | * @file: file ptr | ||
817 | * @priv: file handle | ||
818 | * @buf: v4l2 buffer structure ptr | ||
819 | */ | ||
820 | static int vpif_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf) | ||
821 | { | ||
822 | |||
823 | struct video_device *vdev = video_devdata(file); | ||
824 | struct channel_obj *ch = video_get_drvdata(vdev); | ||
825 | struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; | ||
826 | struct v4l2_buffer tbuf = *buf; | ||
827 | |||
828 | vpif_dbg(2, debug, "vpif_qbuf\n"); | ||
829 | |||
830 | if (common->fmt.type != tbuf.type) { | ||
831 | vpif_err("invalid buffer type\n"); | ||
832 | return -EINVAL; | ||
833 | } | ||
834 | |||
835 | return vb2_qbuf(&common->buffer_queue, buf); | ||
836 | } | ||
837 | |||
838 | /** | ||
839 | * vpif_dqbuf() - query buffer handler | ||
840 | * @file: file ptr | ||
841 | * @priv: file handle | ||
842 | * @buf: v4l2 buffer structure ptr | ||
843 | */ | ||
844 | static int vpif_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf) | ||
845 | { | ||
846 | struct video_device *vdev = video_devdata(file); | ||
847 | struct channel_obj *ch = video_get_drvdata(vdev); | ||
848 | struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; | ||
849 | |||
850 | vpif_dbg(2, debug, "vpif_dqbuf\n"); | ||
851 | |||
852 | return vb2_dqbuf(&common->buffer_queue, buf, | ||
853 | (file->f_flags & O_NONBLOCK)); | ||
854 | } | ||
855 | |||
856 | /** | ||
857 | * vpif_streamon() - streamon handler | ||
858 | * @file: file ptr | ||
859 | * @priv: file handle | ||
860 | * @buftype: v4l2 buffer type | ||
861 | */ | ||
862 | static int vpif_streamon(struct file *file, void *priv, | ||
863 | enum v4l2_buf_type buftype) | ||
864 | { | ||
865 | struct video_device *vdev = video_devdata(file); | ||
866 | struct channel_obj *ch = video_get_drvdata(vdev); | ||
867 | struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; | ||
868 | struct channel_obj *oth_ch = vpif_obj.dev[!ch->channel_id]; | ||
869 | struct vpif_params *vpif; | ||
870 | int ret = 0; | ||
871 | |||
872 | vpif_dbg(2, debug, "vpif_streamon\n"); | ||
873 | |||
874 | vpif = &ch->vpifparams; | ||
875 | |||
876 | if (buftype != V4L2_BUF_TYPE_VIDEO_CAPTURE) { | ||
877 | vpif_dbg(1, debug, "buffer type not supported\n"); | ||
878 | return -EINVAL; | ||
879 | } | ||
880 | |||
881 | /* If Streaming is already started, return error */ | ||
882 | if (common->started) { | ||
883 | vpif_dbg(1, debug, "channel->started\n"); | ||
884 | return -EBUSY; | ||
885 | } | ||
886 | |||
887 | if ((ch->channel_id == VPIF_CHANNEL0_VIDEO && | ||
888 | oth_ch->common[VPIF_VIDEO_INDEX].started && | ||
889 | vpif->std_info.ycmux_mode == 0) || | ||
890 | ((ch->channel_id == VPIF_CHANNEL1_VIDEO) && | ||
891 | (2 == oth_ch->common[VPIF_VIDEO_INDEX].started))) { | ||
892 | vpif_dbg(1, debug, "other channel is being used\n"); | ||
893 | return -EBUSY; | ||
894 | } | ||
895 | |||
896 | ret = vpif_check_format(ch, &common->fmt.fmt.pix, 0); | ||
897 | if (ret) | ||
898 | return ret; | ||
899 | |||
900 | /* Enable streamon on the sub device */ | ||
901 | ret = v4l2_subdev_call(ch->sd, video, s_stream, 1); | ||
902 | |||
903 | if (ret && ret != -ENOIOCTLCMD && ret != -ENODEV) { | ||
904 | vpif_dbg(1, debug, "stream on failed in subdev\n"); | ||
905 | return ret; | ||
906 | } | ||
907 | |||
908 | /* Call vb2_streamon to start streaming in videobuf2 */ | ||
909 | ret = vb2_streamon(&common->buffer_queue, buftype); | ||
910 | if (ret) { | ||
911 | vpif_dbg(1, debug, "vb2_streamon\n"); | ||
912 | return ret; | ||
913 | } | ||
914 | |||
915 | return ret; | ||
916 | } | ||
917 | |||
918 | /** | ||
919 | * vpif_streamoff() - streamoff handler | ||
920 | * @file: file ptr | ||
921 | * @priv: file handle | ||
922 | * @buftype: v4l2 buffer type | ||
923 | */ | ||
924 | static int vpif_streamoff(struct file *file, void *priv, | ||
925 | enum v4l2_buf_type buftype) | ||
926 | { | ||
927 | |||
928 | struct video_device *vdev = video_devdata(file); | ||
929 | struct channel_obj *ch = video_get_drvdata(vdev); | ||
930 | struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; | ||
931 | int ret; | ||
932 | |||
933 | vpif_dbg(2, debug, "vpif_streamoff\n"); | ||
934 | |||
935 | if (buftype != V4L2_BUF_TYPE_VIDEO_CAPTURE) { | ||
936 | vpif_dbg(1, debug, "buffer type not supported\n"); | ||
937 | return -EINVAL; | ||
938 | } | ||
939 | |||
940 | /* If streaming is not started, return error */ | ||
941 | if (!common->started) { | ||
942 | vpif_dbg(1, debug, "channel->started\n"); | ||
943 | return -EINVAL; | ||
944 | } | ||
945 | |||
946 | /* disable channel */ | ||
947 | if (VPIF_CHANNEL0_VIDEO == ch->channel_id) { | ||
948 | enable_channel0(0); | ||
949 | channel0_intr_enable(0); | ||
950 | } else { | ||
951 | enable_channel1(0); | ||
952 | channel1_intr_enable(0); | ||
953 | } | ||
954 | |||
955 | common->started = 0; | ||
956 | |||
957 | ret = v4l2_subdev_call(ch->sd, video, s_stream, 0); | ||
958 | |||
959 | if (ret && ret != -ENOIOCTLCMD && ret != -ENODEV) | ||
960 | vpif_dbg(1, debug, "stream off failed in subdev\n"); | ||
961 | |||
962 | return vb2_streamoff(&common->buffer_queue, buftype); | ||
963 | } | ||
964 | |||
965 | /** | ||
966 | * vpif_input_to_subdev() - Maps input to sub device | 765 | * vpif_input_to_subdev() - Maps input to sub device |
967 | * @vpif_cfg - global config ptr | 766 | * @vpif_cfg - global config ptr |
968 | * @chan_cfg - channel config ptr | 767 | * @chan_cfg - channel config ptr |
@@ -1531,15 +1330,20 @@ static const struct v4l2_ioctl_ops vpif_ioctl_ops = { | |||
1531 | .vidioc_enum_input = vpif_enum_input, | 1330 | .vidioc_enum_input = vpif_enum_input, |
1532 | .vidioc_s_input = vpif_s_input, | 1331 | .vidioc_s_input = vpif_s_input, |
1533 | .vidioc_g_input = vpif_g_input, | 1332 | .vidioc_g_input = vpif_g_input, |
1534 | .vidioc_reqbufs = vpif_reqbufs, | 1333 | |
1535 | .vidioc_querybuf = vpif_querybuf, | 1334 | .vidioc_reqbufs = vb2_ioctl_reqbufs, |
1335 | .vidioc_create_bufs = vb2_ioctl_create_bufs, | ||
1336 | .vidioc_querybuf = vb2_ioctl_querybuf, | ||
1337 | .vidioc_qbuf = vb2_ioctl_qbuf, | ||
1338 | .vidioc_dqbuf = vb2_ioctl_dqbuf, | ||
1339 | .vidioc_expbuf = vb2_ioctl_expbuf, | ||
1340 | .vidioc_streamon = vb2_ioctl_streamon, | ||
1341 | .vidioc_streamoff = vb2_ioctl_streamoff, | ||
1342 | |||
1536 | .vidioc_querystd = vpif_querystd, | 1343 | .vidioc_querystd = vpif_querystd, |
1537 | .vidioc_s_std = vpif_s_std, | 1344 | .vidioc_s_std = vpif_s_std, |
1538 | .vidioc_g_std = vpif_g_std, | 1345 | .vidioc_g_std = vpif_g_std, |
1539 | .vidioc_qbuf = vpif_qbuf, | 1346 | |
1540 | .vidioc_dqbuf = vpif_dqbuf, | ||
1541 | .vidioc_streamon = vpif_streamon, | ||
1542 | .vidioc_streamoff = vpif_streamoff, | ||
1543 | .vidioc_cropcap = vpif_cropcap, | 1347 | .vidioc_cropcap = vpif_cropcap, |
1544 | .vidioc_enum_dv_timings = vpif_enum_dv_timings, | 1348 | .vidioc_enum_dv_timings = vpif_enum_dv_timings, |
1545 | .vidioc_query_dv_timings = vpif_query_dv_timings, | 1349 | .vidioc_query_dv_timings = vpif_query_dv_timings, |