diff options
author | Hans Verkuil <hans.verkuil@cisco.com> | 2013-04-14 11:07:13 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2013-04-16 17:09:57 -0400 |
commit | 1f1988706d77083040113094a4bee2e9e1bdc34f (patch) | |
tree | b9dff012fec01c1826c548cb4be7f9a8f2d35839 | |
parent | a6aa0dc482d7aad5fc4366d4c92d07a10d712b82 (diff) |
[media] cx25821: setup output nodes correctly
Drop the custom ioctls and enable the video output nodes again, this time
using standard ioctls.
The next step will be to provide a proper write() interface.
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.c | 30 | ||||
-rw-r--r-- | drivers/media/pci/cx25821/cx25821-video.c | 214 | ||||
-rw-r--r-- | drivers/media/pci/cx25821/cx25821-video.h | 7 | ||||
-rw-r--r-- | drivers/media/pci/cx25821/cx25821.h | 16 |
4 files changed, 67 insertions, 200 deletions
diff --git a/drivers/media/pci/cx25821/cx25821-core.c b/drivers/media/pci/cx25821/cx25821-core.c index ba417c978415..9068d53a5b8f 100644 --- a/drivers/media/pci/cx25821/cx25821-core.c +++ b/drivers/media/pci/cx25821/cx25821-core.c | |||
@@ -956,36 +956,6 @@ static int cx25821_dev_setup(struct cx25821_dev *dev) | |||
956 | return 0; | 956 | return 0; |
957 | } | 957 | } |
958 | 958 | ||
959 | void cx25821_start_upstream_video_ch1(struct cx25821_dev *dev, | ||
960 | struct upstream_user_struct *up_data) | ||
961 | { | ||
962 | dev->_isNTSC = !strcmp(dev->vid_stdname, "NTSC") ? 1 : 0; | ||
963 | |||
964 | dev->tvnorm = !dev->_isNTSC ? V4L2_STD_PAL_BG : V4L2_STD_NTSC_M; | ||
965 | medusa_set_videostandard(dev); | ||
966 | |||
967 | cx25821_vidupstream_init_ch1(dev, dev->channel_select, | ||
968 | dev->pixel_format); | ||
969 | } | ||
970 | |||
971 | void cx25821_start_upstream_video_ch2(struct cx25821_dev *dev, | ||
972 | struct upstream_user_struct *up_data) | ||
973 | { | ||
974 | dev->_isNTSC_ch2 = !strcmp(dev->vid_stdname_ch2, "NTSC") ? 1 : 0; | ||
975 | |||
976 | dev->tvnorm = !dev->_isNTSC_ch2 ? V4L2_STD_PAL_BG : V4L2_STD_NTSC_M; | ||
977 | medusa_set_videostandard(dev); | ||
978 | |||
979 | cx25821_vidupstream_init_ch2(dev, dev->channel_select_ch2, | ||
980 | dev->pixel_format_ch2); | ||
981 | } | ||
982 | |||
983 | void cx25821_start_upstream_audio(struct cx25821_dev *dev, | ||
984 | struct upstream_user_struct *up_data) | ||
985 | { | ||
986 | cx25821_audio_upstream_init(dev, AUDIO_UPSTREAM_SRAM_CHANNEL_B); | ||
987 | } | ||
988 | |||
989 | void cx25821_dev_unregister(struct cx25821_dev *dev) | 959 | void cx25821_dev_unregister(struct cx25821_dev *dev) |
990 | { | 960 | { |
991 | int i; | 961 | int i; |
diff --git a/drivers/media/pci/cx25821/cx25821-video.c b/drivers/media/pci/cx25821/cx25821-video.c index 49686447cc4a..8d5d13bb5f09 100644 --- a/drivers/media/pci/cx25821/cx25821-video.c +++ b/drivers/media/pci/cx25821/cx25821-video.c | |||
@@ -826,140 +826,27 @@ static int cx25821_s_ctrl(struct v4l2_ctrl *ctrl) | |||
826 | return 0; | 826 | return 0; |
827 | } | 827 | } |
828 | 828 | ||
829 | static long video_ioctl_upstream9(struct file *file, unsigned int cmd, | 829 | static int cx25821_vidioc_enum_output(struct file *file, void *priv, |
830 | unsigned long arg) | 830 | struct v4l2_output *o) |
831 | { | 831 | { |
832 | struct cx25821_channel *chan = video_drvdata(file); | 832 | if (o->index) |
833 | struct cx25821_dev *dev = chan->dev; | 833 | return -EINVAL; |
834 | int command = 0; | ||
835 | struct upstream_user_struct *data_from_user; | ||
836 | |||
837 | data_from_user = (struct upstream_user_struct *)arg; | ||
838 | |||
839 | if (!data_from_user) { | ||
840 | pr_err("%s(): Upstream data is INVALID. Returning\n", __func__); | ||
841 | return 0; | ||
842 | } | ||
843 | |||
844 | command = data_from_user->command; | ||
845 | |||
846 | if (command != UPSTREAM_START_VIDEO && command != UPSTREAM_STOP_VIDEO) | ||
847 | return 0; | ||
848 | |||
849 | dev->input_filename = data_from_user->input_filename; | ||
850 | dev->input_audiofilename = data_from_user->input_filename; | ||
851 | dev->vid_stdname = data_from_user->vid_stdname; | ||
852 | dev->pixel_format = data_from_user->pixel_format; | ||
853 | dev->channel_select = data_from_user->channel_select; | ||
854 | dev->command = data_from_user->command; | ||
855 | |||
856 | switch (command) { | ||
857 | case UPSTREAM_START_VIDEO: | ||
858 | cx25821_start_upstream_video_ch1(dev, data_from_user); | ||
859 | break; | ||
860 | |||
861 | case UPSTREAM_STOP_VIDEO: | ||
862 | cx25821_stop_upstream_video_ch1(dev); | ||
863 | break; | ||
864 | } | ||
865 | 834 | ||
835 | o->type = V4L2_INPUT_TYPE_CAMERA; | ||
836 | o->std = CX25821_NORMS; | ||
837 | strcpy(o->name, "Composite"); | ||
866 | return 0; | 838 | return 0; |
867 | } | 839 | } |
868 | 840 | ||
869 | static long video_ioctl_upstream10(struct file *file, unsigned int cmd, | 841 | static int cx25821_vidioc_g_output(struct file *file, void *priv, unsigned int *o) |
870 | unsigned long arg) | ||
871 | { | 842 | { |
872 | struct cx25821_channel *chan = video_drvdata(file); | 843 | *o = 0; |
873 | struct cx25821_dev *dev = chan->dev; | ||
874 | int command = 0; | ||
875 | struct upstream_user_struct *data_from_user; | ||
876 | |||
877 | data_from_user = (struct upstream_user_struct *)arg; | ||
878 | |||
879 | if (!data_from_user) { | ||
880 | pr_err("%s(): Upstream data is INVALID. Returning\n", __func__); | ||
881 | return 0; | ||
882 | } | ||
883 | |||
884 | command = data_from_user->command; | ||
885 | |||
886 | if (command != UPSTREAM_START_VIDEO && command != UPSTREAM_STOP_VIDEO) | ||
887 | return 0; | ||
888 | |||
889 | dev->input_filename_ch2 = data_from_user->input_filename; | ||
890 | dev->input_audiofilename = data_from_user->input_filename; | ||
891 | dev->vid_stdname_ch2 = data_from_user->vid_stdname; | ||
892 | dev->pixel_format_ch2 = data_from_user->pixel_format; | ||
893 | dev->channel_select_ch2 = data_from_user->channel_select; | ||
894 | dev->command_ch2 = data_from_user->command; | ||
895 | |||
896 | switch (command) { | ||
897 | case UPSTREAM_START_VIDEO: | ||
898 | cx25821_start_upstream_video_ch2(dev, data_from_user); | ||
899 | break; | ||
900 | |||
901 | case UPSTREAM_STOP_VIDEO: | ||
902 | cx25821_stop_upstream_video_ch2(dev); | ||
903 | break; | ||
904 | } | ||
905 | |||
906 | return 0; | 844 | return 0; |
907 | } | 845 | } |
908 | 846 | ||
909 | static long video_ioctl_upstream11(struct file *file, unsigned int cmd, | 847 | static int cx25821_vidioc_s_output(struct file *file, void *priv, unsigned int o) |
910 | unsigned long arg) | ||
911 | { | 848 | { |
912 | struct cx25821_channel *chan = video_drvdata(file); | 849 | return o ? -EINVAL : 0; |
913 | struct cx25821_dev *dev = chan->dev; | ||
914 | int command = 0; | ||
915 | struct upstream_user_struct *data_from_user; | ||
916 | |||
917 | data_from_user = (struct upstream_user_struct *)arg; | ||
918 | |||
919 | if (!data_from_user) { | ||
920 | pr_err("%s(): Upstream data is INVALID. Returning\n", __func__); | ||
921 | return 0; | ||
922 | } | ||
923 | |||
924 | command = data_from_user->command; | ||
925 | |||
926 | if (command != UPSTREAM_START_AUDIO && command != UPSTREAM_STOP_AUDIO) | ||
927 | return 0; | ||
928 | |||
929 | dev->input_filename = data_from_user->input_filename; | ||
930 | dev->input_audiofilename = data_from_user->input_filename; | ||
931 | dev->vid_stdname = data_from_user->vid_stdname; | ||
932 | dev->pixel_format = data_from_user->pixel_format; | ||
933 | dev->channel_select = data_from_user->channel_select; | ||
934 | dev->command = data_from_user->command; | ||
935 | |||
936 | switch (command) { | ||
937 | case UPSTREAM_START_AUDIO: | ||
938 | cx25821_start_upstream_audio(dev, data_from_user); | ||
939 | break; | ||
940 | |||
941 | case UPSTREAM_STOP_AUDIO: | ||
942 | cx25821_stop_upstream_audio(dev); | ||
943 | break; | ||
944 | } | ||
945 | |||
946 | return 0; | ||
947 | } | ||
948 | |||
949 | static long cx25821_video_ioctl(struct file *file, | ||
950 | unsigned int cmd, unsigned long arg) | ||
951 | { | ||
952 | struct cx25821_channel *chan = video_drvdata(file); | ||
953 | |||
954 | /* check to see if it's the video upstream */ | ||
955 | if (chan->id == SRAM_CH09) | ||
956 | return video_ioctl_upstream9(file, cmd, arg); | ||
957 | if (chan->id == SRAM_CH10) | ||
958 | return video_ioctl_upstream10(file, cmd, arg); | ||
959 | if (chan->id == SRAM_CH11) | ||
960 | return video_ioctl_upstream11(file, cmd, arg); | ||
961 | |||
962 | return video_ioctl2(file, cmd, arg); | ||
963 | } | 850 | } |
964 | 851 | ||
965 | static const struct v4l2_ctrl_ops cx25821_ctrl_ops = { | 852 | static const struct v4l2_ctrl_ops cx25821_ctrl_ops = { |
@@ -973,7 +860,7 @@ static const struct v4l2_file_operations video_fops = { | |||
973 | .read = video_read, | 860 | .read = video_read, |
974 | .poll = video_poll, | 861 | .poll = video_poll, |
975 | .mmap = cx25821_video_mmap, | 862 | .mmap = cx25821_video_mmap, |
976 | .unlocked_ioctl = cx25821_video_ioctl, | 863 | .unlocked_ioctl = video_ioctl2, |
977 | }; | 864 | }; |
978 | 865 | ||
979 | static const struct v4l2_ioctl_ops video_ioctl_ops = { | 866 | static const struct v4l2_ioctl_ops video_ioctl_ops = { |
@@ -1007,6 +894,32 @@ static const struct video_device cx25821_video_device = { | |||
1007 | .tvnorms = CX25821_NORMS, | 894 | .tvnorms = CX25821_NORMS, |
1008 | }; | 895 | }; |
1009 | 896 | ||
897 | static const struct v4l2_file_operations video_out_fops = { | ||
898 | .owner = THIS_MODULE, | ||
899 | .open = v4l2_fh_open, | ||
900 | .release = v4l2_fh_release, | ||
901 | .unlocked_ioctl = video_ioctl2, | ||
902 | }; | ||
903 | |||
904 | static const struct v4l2_ioctl_ops video_out_ioctl_ops = { | ||
905 | .vidioc_querycap = cx25821_vidioc_querycap, | ||
906 | .vidioc_g_std = cx25821_vidioc_g_std, | ||
907 | .vidioc_s_std = cx25821_vidioc_s_std, | ||
908 | .vidioc_enum_output = cx25821_vidioc_enum_output, | ||
909 | .vidioc_g_output = cx25821_vidioc_g_output, | ||
910 | .vidioc_s_output = cx25821_vidioc_s_output, | ||
911 | .vidioc_log_status = vidioc_log_status, | ||
912 | }; | ||
913 | |||
914 | static const struct video_device cx25821_video_out_device = { | ||
915 | .name = "cx25821-video", | ||
916 | .fops = &video_out_fops, | ||
917 | .release = video_device_release_empty, | ||
918 | .minor = -1, | ||
919 | .ioctl_ops = &video_out_ioctl_ops, | ||
920 | .tvnorms = CX25821_NORMS, | ||
921 | }; | ||
922 | |||
1010 | void cx25821_video_unregister(struct cx25821_dev *dev, int chan_num) | 923 | void cx25821_video_unregister(struct cx25821_dev *dev, int chan_num) |
1011 | { | 924 | { |
1012 | cx_clear(PCI_INT_MSK, 1); | 925 | cx_clear(PCI_INT_MSK, 1); |
@@ -1030,30 +943,33 @@ int cx25821_video_register(struct cx25821_dev *dev) | |||
1030 | 943 | ||
1031 | spin_lock_init(&dev->slock); | 944 | spin_lock_init(&dev->slock); |
1032 | 945 | ||
1033 | for (i = 0; i < VID_CHANNEL_NUM; ++i) { | 946 | for (i = 0; i < MAX_VID_CHANNEL_NUM - 1; ++i) { |
1034 | struct cx25821_channel *chan = &dev->channels[i]; | 947 | struct cx25821_channel *chan = &dev->channels[i]; |
1035 | struct video_device *vdev = &chan->vdev; | 948 | struct video_device *vdev = &chan->vdev; |
1036 | struct v4l2_ctrl_handler *hdl = &chan->hdl; | 949 | struct v4l2_ctrl_handler *hdl = &chan->hdl; |
950 | bool is_output = i > SRAM_CH08; | ||
1037 | 951 | ||
1038 | if (i == SRAM_CH08) /* audio channel */ | 952 | if (i == SRAM_CH08) /* audio channel */ |
1039 | continue; | 953 | continue; |
1040 | 954 | ||
1041 | v4l2_ctrl_handler_init(hdl, 4); | 955 | if (!is_output) { |
1042 | v4l2_ctrl_new_std(hdl, &cx25821_ctrl_ops, | 956 | v4l2_ctrl_handler_init(hdl, 4); |
1043 | V4L2_CID_BRIGHTNESS, 0, 10000, 1, 6200); | 957 | v4l2_ctrl_new_std(hdl, &cx25821_ctrl_ops, |
1044 | v4l2_ctrl_new_std(hdl, &cx25821_ctrl_ops, | 958 | V4L2_CID_BRIGHTNESS, 0, 10000, 1, 6200); |
1045 | V4L2_CID_CONTRAST, 0, 10000, 1, 5000); | 959 | v4l2_ctrl_new_std(hdl, &cx25821_ctrl_ops, |
1046 | v4l2_ctrl_new_std(hdl, &cx25821_ctrl_ops, | 960 | V4L2_CID_CONTRAST, 0, 10000, 1, 5000); |
1047 | V4L2_CID_SATURATION, 0, 10000, 1, 5000); | 961 | v4l2_ctrl_new_std(hdl, &cx25821_ctrl_ops, |
1048 | v4l2_ctrl_new_std(hdl, &cx25821_ctrl_ops, | 962 | V4L2_CID_SATURATION, 0, 10000, 1, 5000); |
1049 | V4L2_CID_HUE, 0, 10000, 1, 5000); | 963 | v4l2_ctrl_new_std(hdl, &cx25821_ctrl_ops, |
1050 | if (hdl->error) { | 964 | V4L2_CID_HUE, 0, 10000, 1, 5000); |
1051 | err = hdl->error; | 965 | if (hdl->error) { |
1052 | goto fail_unreg; | 966 | err = hdl->error; |
967 | goto fail_unreg; | ||
968 | } | ||
969 | err = v4l2_ctrl_handler_setup(hdl); | ||
970 | if (err) | ||
971 | goto fail_unreg; | ||
1053 | } | 972 | } |
1054 | err = v4l2_ctrl_handler_setup(hdl); | ||
1055 | if (err) | ||
1056 | goto fail_unreg; | ||
1057 | 973 | ||
1058 | cx25821_risc_stopper(dev->pci, &chan->dma_vidq.stopper, | 974 | cx25821_risc_stopper(dev->pci, &chan->dma_vidq.stopper, |
1059 | chan->sram_channels->dma_ctl, 0x11, 0); | 975 | chan->sram_channels->dma_ctl, 0x11, 0); |
@@ -1081,15 +997,19 @@ int cx25821_video_register(struct cx25821_dev *dev) | |||
1081 | chan->dma_vidq.timeout.data = (unsigned long)&chan->timeout_data; | 997 | chan->dma_vidq.timeout.data = (unsigned long)&chan->timeout_data; |
1082 | init_timer(&chan->dma_vidq.timeout); | 998 | init_timer(&chan->dma_vidq.timeout); |
1083 | 999 | ||
1084 | videobuf_queue_sg_init(&chan->vidq, &cx25821_video_qops, &dev->pci->dev, | 1000 | if (!is_output) |
1085 | &dev->slock, V4L2_BUF_TYPE_VIDEO_CAPTURE, | 1001 | videobuf_queue_sg_init(&chan->vidq, &cx25821_video_qops, &dev->pci->dev, |
1086 | V4L2_FIELD_INTERLACED, sizeof(struct cx25821_buffer), | 1002 | &dev->slock, V4L2_BUF_TYPE_VIDEO_CAPTURE, |
1087 | chan, &dev->lock); | 1003 | V4L2_FIELD_INTERLACED, sizeof(struct cx25821_buffer), |
1004 | chan, &dev->lock); | ||
1088 | 1005 | ||
1089 | /* register v4l devices */ | 1006 | /* register v4l devices */ |
1090 | *vdev = cx25821_video_device; | 1007 | *vdev = is_output ? cx25821_video_out_device : cx25821_video_device; |
1091 | vdev->v4l2_dev = &dev->v4l2_dev; | 1008 | vdev->v4l2_dev = &dev->v4l2_dev; |
1092 | vdev->ctrl_handler = hdl; | 1009 | if (!is_output) |
1010 | vdev->ctrl_handler = hdl; | ||
1011 | else | ||
1012 | vdev->vfl_dir = VFL_DIR_TX; | ||
1093 | vdev->lock = &dev->lock; | 1013 | vdev->lock = &dev->lock; |
1094 | set_bit(V4L2_FL_USE_FH_PRIO, &vdev->flags); | 1014 | set_bit(V4L2_FL_USE_FH_PRIO, &vdev->flags); |
1095 | snprintf(vdev->name, sizeof(vdev->name), "%s #%d", dev->name, i); | 1015 | snprintf(vdev->name, sizeof(vdev->name), "%s #%d", dev->name, i); |
diff --git a/drivers/media/pci/cx25821/cx25821-video.h b/drivers/media/pci/cx25821/cx25821-video.h index 8871c4e737e8..ab63b3858acf 100644 --- a/drivers/media/pci/cx25821/cx25821-video.h +++ b/drivers/media/pci/cx25821/cx25821-video.h | |||
@@ -49,13 +49,6 @@ do { \ | |||
49 | printk(KERN_DEBUG "%s/0: " fmt, dev->name, ##arg); \ | 49 | printk(KERN_DEBUG "%s/0: " fmt, dev->name, ##arg); \ |
50 | } while (0) | 50 | } while (0) |
51 | 51 | ||
52 | /* For IOCTL to identify running upstream */ | ||
53 | #define UPSTREAM_START_VIDEO 700 | ||
54 | #define UPSTREAM_STOP_VIDEO 701 | ||
55 | #define UPSTREAM_START_AUDIO 702 | ||
56 | #define UPSTREAM_STOP_AUDIO 703 | ||
57 | #define UPSTREAM_DUMP_REGISTERS 702 | ||
58 | |||
59 | #define FORMAT_FLAGS_PACKED 0x01 | 52 | #define FORMAT_FLAGS_PACKED 0x01 |
60 | extern void cx25821_video_wakeup(struct cx25821_dev *dev, | 53 | extern void cx25821_video_wakeup(struct cx25821_dev *dev, |
61 | struct cx25821_dmaqueue *q, u32 count); | 54 | struct cx25821_dmaqueue *q, u32 count); |
diff --git a/drivers/media/pci/cx25821/cx25821.h b/drivers/media/pci/cx25821/cx25821.h index 67b3c550e454..156ad6f2c634 100644 --- a/drivers/media/pci/cx25821/cx25821.h +++ b/drivers/media/pci/cx25821/cx25821.h | |||
@@ -329,14 +329,6 @@ struct cx25821_dev { | |||
329 | int command; | 329 | int command; |
330 | }; | 330 | }; |
331 | 331 | ||
332 | struct upstream_user_struct { | ||
333 | char *input_filename; | ||
334 | char *vid_stdname; | ||
335 | int pixel_format; | ||
336 | int channel_select; | ||
337 | int command; | ||
338 | }; | ||
339 | |||
340 | static inline struct cx25821_dev *get_cx25821(struct v4l2_device *v4l2_dev) | 332 | static inline struct cx25821_dev *get_cx25821(struct v4l2_device *v4l2_dev) |
341 | { | 333 | { |
342 | return container_of(v4l2_dev, struct cx25821_dev, v4l2_dev); | 334 | return container_of(v4l2_dev, struct cx25821_dev, v4l2_dev); |
@@ -480,14 +472,6 @@ extern int cx25821_audio_upstream_init(struct cx25821_dev *dev, | |||
480 | extern void cx25821_free_mem_upstream_ch1(struct cx25821_dev *dev); | 472 | extern void cx25821_free_mem_upstream_ch1(struct cx25821_dev *dev); |
481 | extern void cx25821_free_mem_upstream_ch2(struct cx25821_dev *dev); | 473 | extern void cx25821_free_mem_upstream_ch2(struct cx25821_dev *dev); |
482 | extern void cx25821_free_mem_upstream_audio(struct cx25821_dev *dev); | 474 | extern void cx25821_free_mem_upstream_audio(struct cx25821_dev *dev); |
483 | extern void cx25821_start_upstream_video_ch1(struct cx25821_dev *dev, | ||
484 | struct upstream_user_struct | ||
485 | *up_data); | ||
486 | extern void cx25821_start_upstream_video_ch2(struct cx25821_dev *dev, | ||
487 | struct upstream_user_struct | ||
488 | *up_data); | ||
489 | extern void cx25821_start_upstream_audio(struct cx25821_dev *dev, | ||
490 | struct upstream_user_struct *up_data); | ||
491 | extern void cx25821_stop_upstream_video_ch1(struct cx25821_dev *dev); | 475 | extern void cx25821_stop_upstream_video_ch1(struct cx25821_dev *dev); |
492 | extern void cx25821_stop_upstream_video_ch2(struct cx25821_dev *dev); | 476 | extern void cx25821_stop_upstream_video_ch2(struct cx25821_dev *dev); |
493 | extern void cx25821_stop_upstream_audio(struct cx25821_dev *dev); | 477 | extern void cx25821_stop_upstream_audio(struct cx25821_dev *dev); |