aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Verkuil <hans.verkuil@cisco.com>2013-04-14 11:07:13 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2013-04-16 17:09:57 -0400
commit1f1988706d77083040113094a4bee2e9e1bdc34f (patch)
treeb9dff012fec01c1826c548cb4be7f9a8f2d35839
parenta6aa0dc482d7aad5fc4366d4c92d07a10d712b82 (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.c30
-rw-r--r--drivers/media/pci/cx25821/cx25821-video.c214
-rw-r--r--drivers/media/pci/cx25821/cx25821-video.h7
-rw-r--r--drivers/media/pci/cx25821/cx25821.h16
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
959void 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
971void 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
983void 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
989void cx25821_dev_unregister(struct cx25821_dev *dev) 959void 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
829static long video_ioctl_upstream9(struct file *file, unsigned int cmd, 829static 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
869static long video_ioctl_upstream10(struct file *file, unsigned int cmd, 841static 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
909static long video_ioctl_upstream11(struct file *file, unsigned int cmd, 847static 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
949static 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
965static const struct v4l2_ctrl_ops cx25821_ctrl_ops = { 852static 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
979static const struct v4l2_ioctl_ops video_ioctl_ops = { 866static 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
897static 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
904static 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
914static 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
1010void cx25821_video_unregister(struct cx25821_dev *dev, int chan_num) 923void 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
60extern void cx25821_video_wakeup(struct cx25821_dev *dev, 53extern 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
332struct upstream_user_struct {
333 char *input_filename;
334 char *vid_stdname;
335 int pixel_format;
336 int channel_select;
337 int command;
338};
339
340static inline struct cx25821_dev *get_cx25821(struct v4l2_device *v4l2_dev) 332static 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,
480extern void cx25821_free_mem_upstream_ch1(struct cx25821_dev *dev); 472extern void cx25821_free_mem_upstream_ch1(struct cx25821_dev *dev);
481extern void cx25821_free_mem_upstream_ch2(struct cx25821_dev *dev); 473extern void cx25821_free_mem_upstream_ch2(struct cx25821_dev *dev);
482extern void cx25821_free_mem_upstream_audio(struct cx25821_dev *dev); 474extern void cx25821_free_mem_upstream_audio(struct cx25821_dev *dev);
483extern void cx25821_start_upstream_video_ch1(struct cx25821_dev *dev,
484 struct upstream_user_struct
485 *up_data);
486extern void cx25821_start_upstream_video_ch2(struct cx25821_dev *dev,
487 struct upstream_user_struct
488 *up_data);
489extern void cx25821_start_upstream_audio(struct cx25821_dev *dev,
490 struct upstream_user_struct *up_data);
491extern void cx25821_stop_upstream_video_ch1(struct cx25821_dev *dev); 475extern void cx25821_stop_upstream_video_ch1(struct cx25821_dev *dev);
492extern void cx25821_stop_upstream_video_ch2(struct cx25821_dev *dev); 476extern void cx25821_stop_upstream_video_ch2(struct cx25821_dev *dev);
493extern void cx25821_stop_upstream_audio(struct cx25821_dev *dev); 477extern void cx25821_stop_upstream_audio(struct cx25821_dev *dev);