aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@infradead.org>2006-06-04 09:34:12 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2006-06-25 01:05:04 -0400
commitc820cc45366377a84a5f66066db4e16b7a6e5b8c (patch)
tree26ea15ce2b35a200b8ab9f891ff77da1e218b4a3 /drivers/media
parent401998fa96fe18b057af3f906527196522dd2d9d (diff)
V4L/DVB (4066): Vivi.c were ported to the newer videodev2 format.
Several common handling codes were removed. Maybe even more stuff may be handled at common infrastructure. Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/video/vivi.c622
1 files changed, 283 insertions, 339 deletions
diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c
index d002561aeb4c..0aa54fb7727f 100644
--- a/drivers/media/video/vivi.c
+++ b/drivers/media/video/vivi.c
@@ -48,24 +48,15 @@
48 48
49#include "font.h" 49#include "font.h"
50 50
51MODULE_DESCRIPTION("Video Technology Magazine Virtual Video Capture Board");
52MODULE_AUTHOR("Mauro Carvalho Chehab, Ted Walther and John Sokol");
53MODULE_LICENSE("Dual BSD/GPL");
54
55#define VIVI_MAJOR_VERSION 0 51#define VIVI_MAJOR_VERSION 0
56#define VIVI_MINOR_VERSION 4 52#define VIVI_MINOR_VERSION 4
57#define VIVI_RELEASE 0 53#define VIVI_RELEASE 0
58#define VIVI_VERSION KERNEL_VERSION(VIVI_MAJOR_VERSION, VIVI_MINOR_VERSION, VIVI_RELEASE) 54#define VIVI_VERSION KERNEL_VERSION(VIVI_MAJOR_VERSION, VIVI_MINOR_VERSION, VIVI_RELEASE)
59 55
60static int video_nr = -1; /* /dev/videoN, -1 for autodetect */ 56/* Declare static vars that will be used as parameters */
61module_param(video_nr, int, 0); 57static unsigned int vid_limit = 16; /* Video memory limit, in Mb */
62 58static struct video_device vivi; /* Video device */
63static int debug = 0; 59static int video_nr = -1; /* /dev/videoN, -1 for autodetect */
64module_param(debug, int, 0);
65
66static unsigned int vid_limit = 16;
67module_param(vid_limit,int,0644);
68MODULE_PARM_DESC(vid_limit,"capture memory limit in megabytes");
69 60
70/* supported controls */ 61/* supported controls */
71static struct v4l2_queryctrl vivi_qctrl[] = { 62static struct v4l2_queryctrl vivi_qctrl[] = {
@@ -119,10 +110,10 @@ static struct v4l2_queryctrl vivi_qctrl[] = {
119 110
120static int qctl_regs[ARRAY_SIZE(vivi_qctrl)]; 111static int qctl_regs[ARRAY_SIZE(vivi_qctrl)];
121 112
122#define dprintk(level,fmt, arg...) \ 113#define dprintk(level,fmt, arg...) \
123 do { \ 114 do { \
124 if (debug >= (level)) \ 115 if (vivi.debug >= (level)) \
125 printk(KERN_DEBUG "vivi: " fmt , ## arg); \ 116 printk(KERN_DEBUG "vivi: " fmt , ## arg); \
126 } while (0) 117 } while (0)
127 118
128/* ------------------------------------------------------------------ 119/* ------------------------------------------------------------------
@@ -180,7 +171,7 @@ struct vivi_dev {
180 171
181 /* various device info */ 172 /* various device info */
182 unsigned int resources; 173 unsigned int resources;
183 struct video_device video_dev; 174 struct video_device vfd;
184 175
185 struct vivi_dmaqueue vidq; 176 struct vivi_dmaqueue vidq;
186 177
@@ -830,7 +821,80 @@ static struct videobuf_queue_ops vivi_video_qops = {
830 IOCTL handling 821 IOCTL handling
831 ------------------------------------------------------------------*/ 822 ------------------------------------------------------------------*/
832 823
833static int vivi_try_fmt(struct vivi_dev *dev, struct vivi_fh *fh, 824
825static int res_get(struct vivi_dev *dev, struct vivi_fh *fh)
826{
827 /* is it free? */
828 down(&dev->lock);
829 if (dev->resources) {
830 /* no, someone else uses it */
831 up(&dev->lock);
832 return 0;
833 }
834 /* it's free, grab it */
835 dev->resources =1;
836 dprintk(1,"res: get\n");
837 up(&dev->lock);
838 return 1;
839}
840
841static int res_locked(struct vivi_dev *dev)
842{
843 return (dev->resources);
844}
845
846static void res_free(struct vivi_dev *dev, struct vivi_fh *fh)
847{
848 down(&dev->lock);
849 dev->resources = 0;
850 dprintk(1,"res: put\n");
851 up(&dev->lock);
852}
853
854/* ------------------------------------------------------------------
855 IOCTL vidioc handling
856 ------------------------------------------------------------------*/
857static int vidioc_querycap (struct file *file, void *priv,
858 struct v4l2_capability *cap)
859{
860 strcpy(cap->driver, "vivi");
861 strcpy(cap->card, "vivi");
862 cap->version = VIVI_VERSION;
863 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE |
864 V4L2_CAP_STREAMING |
865 V4L2_CAP_READWRITE;
866 return 0;
867}
868
869static int vidioc_enum_fmt_cap (struct file *file, void *priv,
870 struct v4l2_fmtdesc *f)
871{
872 if (f->index > 0)
873 return -EINVAL;
874
875 strlcpy(f->description,format.name,sizeof(f->description));
876 f->pixelformat = format.fourcc;
877 return 0;
878}
879
880static int vidioc_g_fmt_cap (struct file *file, void *priv,
881 struct v4l2_format *f)
882{
883 struct vivi_fh *fh=priv;
884
885 f->fmt.pix.width = fh->width;
886 f->fmt.pix.height = fh->height;
887 f->fmt.pix.field = fh->vb_vidq.field;
888 f->fmt.pix.pixelformat = fh->fmt->fourcc;
889 f->fmt.pix.bytesperline =
890 (f->fmt.pix.width * fh->fmt->depth) >> 3;
891 f->fmt.pix.sizeimage =
892 f->fmt.pix.height * f->fmt.pix.bytesperline;
893
894 return (0);
895}
896
897static int vidioc_try_fmt_cap (struct file *file, void *priv,
834 struct v4l2_format *f) 898 struct v4l2_format *f)
835{ 899{
836 struct vivi_fmt *fmt; 900 struct vivi_fmt *fmt;
@@ -838,7 +902,8 @@ static int vivi_try_fmt(struct vivi_dev *dev, struct vivi_fh *fh,
838 unsigned int maxw, maxh; 902 unsigned int maxw, maxh;
839 903
840 if (format.fourcc != f->fmt.pix.pixelformat) { 904 if (format.fourcc != f->fmt.pix.pixelformat) {
841 dprintk(1,"Fourcc format invalid.\n"); 905 dprintk(1,"Fourcc format (0x%08x) invalid. Driver accepts "
906 "only 0x%08x\n",f->fmt.pix.pixelformat,format.fourcc);
842 return -EINVAL; 907 return -EINVAL;
843 } 908 }
844 fmt=&format; 909 fmt=&format;
@@ -874,356 +939,196 @@ static int vivi_try_fmt(struct vivi_dev *dev, struct vivi_fh *fh,
874 return 0; 939 return 0;
875} 940}
876 941
877static int res_get(struct vivi_dev *dev, struct vivi_fh *fh) 942/*FIXME: This seems to be generic enough to be at videodev2 */
943static int vidioc_s_fmt_cap (struct file *file, void *priv,
944 struct v4l2_format *f)
878{ 945{
879 /* is it free? */ 946 struct vivi_fh *fh=priv;
880 down(&dev->lock); 947 int ret = vidioc_try_fmt_cap(file,fh,f);
881 if (dev->resources) { 948 if (ret < 0)
882 /* no, someone else uses it */ 949 return (ret);
883 up(&dev->lock); 950
884 return 0; 951 fh->fmt = &format;
885 } 952 fh->width = f->fmt.pix.width;
886 /* it's free, grab it */ 953 fh->height = f->fmt.pix.height;
887 dev->resources =1; 954 fh->vb_vidq.field = f->fmt.pix.field;
888 dprintk(1,"res: get\n"); 955 fh->type = f->type;
889 up(&dev->lock); 956
890 return 1; 957 return (0);
891} 958}
892 959
893static int res_locked(struct vivi_dev *dev) 960static int vidioc_reqbufs (struct file *file, void *priv, struct v4l2_requestbuffers *p)
894{ 961{
895 return (dev->resources); 962 struct vivi_fh *fh=priv;
896}
897 963
898static void res_free(struct vivi_dev *dev, struct vivi_fh *fh) 964 return (videobuf_reqbufs(&fh->vb_vidq, p));
899{
900 down(&dev->lock);
901 dev->resources = 0;
902 dprintk(1,"res: put\n");
903 up(&dev->lock);
904} 965}
905 966
906static int vivi_do_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *arg) 967static int vidioc_querybuf (struct file *file, void *priv, struct v4l2_buffer *p)
907{ 968{
908 struct vivi_fh *fh = file->private_data; 969 struct vivi_fh *fh=priv;
909 struct vivi_dev *dev = fh->dev;
910 int ret=0;
911 970
912 if (debug) { 971 return (videobuf_querybuf(&fh->vb_vidq, p));
913 if (_IOC_DIR(cmd) & _IOC_WRITE) 972}
914 v4l_printk_ioctl_arg("vivi(w)",cmd, arg);
915 else if (!_IOC_DIR(cmd) & _IOC_READ) {
916 v4l_print_ioctl("vivi", cmd);
917 }
918 }
919 973
920 switch(cmd) { 974static int vidioc_qbuf (struct file *file, void *priv, struct v4l2_buffer *p)
921 /* --- capabilities ------------------------------------------ */ 975{
922 case VIDIOC_QUERYCAP: 976 struct vivi_fh *fh=priv;
923 {
924 struct v4l2_capability *cap = (struct v4l2_capability*)arg;
925
926 memset(cap, 0, sizeof(*cap));
927
928 strcpy(cap->driver, "vivi");
929 strcpy(cap->card, "vivi");
930 cap->version = VIVI_VERSION;
931 cap->capabilities =
932 V4L2_CAP_VIDEO_CAPTURE |
933 V4L2_CAP_STREAMING |
934 V4L2_CAP_READWRITE;
935 break;
936 }
937 /* --- capture ioctls ---------------------------------------- */
938 case VIDIOC_ENUM_FMT:
939 {
940 struct v4l2_fmtdesc *f = arg;
941 enum v4l2_buf_type type;
942 unsigned int index;
943 977
944 index = f->index; 978 return (videobuf_qbuf(&fh->vb_vidq, p));
945 type = f->type; 979}
946 980
947 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { 981static int vidioc_dqbuf (struct file *file, void *priv, struct v4l2_buffer *p)
948 ret=-EINVAL; 982{
949 break; 983 struct vivi_fh *fh=priv;
950 }
951 984
952 switch (type) { 985 return (videobuf_dqbuf(&fh->vb_vidq, p,
953 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 986 file->f_flags & O_NONBLOCK));
954 if (index > 0){ 987}
955 ret=-EINVAL;
956 break;
957 }
958 memset(f,0,sizeof(*f));
959 988
960 f->index = index; 989#ifdef HAVE_V4L1
961 f->type = type; 990static int vidiocgmbuf (struct file *file, void *priv, struct video_mbuf *mbuf)
962 strlcpy(f->description,format.name,sizeof(f->description)); 991{
963 f->pixelformat = format.fourcc; 992 struct vivi_fh *fh=priv;
964 break; 993 struct videobuf_queue *q=&fh->vb_vidq;
965 default: 994 struct v4l2_requestbuffers req;
966 ret=-EINVAL; 995 unsigned int i, ret;
967 } 996
968 break; 997 req.type = q->type;
998 req.count = 8;
999 req.memory = V4L2_MEMORY_MMAP;
1000 ret = videobuf_reqbufs(q,&req);
1001 if (ret < 0)
1002 return (ret);
1003 memset(mbuf,0,sizeof(*mbuf));
1004 mbuf->frames = req.count;
1005 mbuf->size = 0;
1006 for (i = 0; i < mbuf->frames; i++) {
1007 mbuf->offsets[i] = q->bufs[i]->boff;
1008 mbuf->size += q->bufs[i]->bsize;
969 } 1009 }
970 case VIDIOC_G_FMT: 1010 return (0);
971 { 1011}
972 struct v4l2_format *f = (struct v4l2_format *)arg; 1012#endif
973 1013
974 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { 1014int vidioc_streamon (struct file *file, void *priv, enum v4l2_buf_type i)
975 ret=-EINVAL; 1015{
976 break; 1016 struct vivi_fh *fh=priv;
977 } 1017 struct vivi_dev *dev = fh->dev;
978 1018
979 memset(&f->fmt.pix,0,sizeof(f->fmt.pix)); 1019 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
980 f->fmt.pix.width = fh->width; 1020 return -EINVAL;
981 f->fmt.pix.height = fh->height; 1021 if (i != fh->type)
982 f->fmt.pix.field = fh->vb_vidq.field; 1022 return -EINVAL;
983 f->fmt.pix.pixelformat = fh->fmt->fourcc;
984 f->fmt.pix.bytesperline =
985 (f->fmt.pix.width * fh->fmt->depth) >> 3;
986 f->fmt.pix.sizeimage =
987 f->fmt.pix.height * f->fmt.pix.bytesperline;
988 break;
989 }
990 case VIDIOC_S_FMT:
991 {
992 struct v4l2_format *f = arg;
993 1023
994 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { 1024 if (!res_get(dev,fh))
995 dprintk(1,"Only capture supported.\n"); 1025 return -EBUSY;
996 ret=-EINVAL; 1026 return (videobuf_streamon(&fh->vb_vidq));
997 break; 1027}
998 }
999 1028
1000 ret = vivi_try_fmt(dev,fh,f); 1029int vidioc_streamoff (struct file *file, void *priv, enum v4l2_buf_type i)
1001 if (ret < 0) 1030{
1002 break; 1031 struct vivi_fh *fh=priv;
1032 struct vivi_dev *dev = fh->dev;
1003 1033
1004 fh->fmt = &format; 1034 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1005 fh->width = f->fmt.pix.width; 1035 return -EINVAL;
1006 fh->height = f->fmt.pix.height; 1036 if (i != fh->type)
1007 fh->vb_vidq.field = f->fmt.pix.field; 1037 return -EINVAL;
1008 fh->type = f->type;
1009 1038
1010 break; 1039 videobuf_streamoff(&fh->vb_vidq);
1011 } 1040 res_free(dev,fh);
1012 case VIDIOC_TRY_FMT:
1013 {
1014 struct v4l2_format *f = arg;
1015 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1016 ret=-EINVAL;
1017 break;
1018 }
1019 1041
1020 ret=vivi_try_fmt(dev,fh,f); 1042 return (0);
1021 break; 1043}
1022 } 1044
1023 case VIDIOC_REQBUFS: 1045static struct v4l2_tvnorm tvnorms[] = {
1024 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1025 ret=-EINVAL;
1026 break;
1027 }
1028 ret=videobuf_reqbufs(&fh->vb_vidq, arg);
1029 break;
1030 case VIDIOC_QUERYBUF:
1031 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1032 ret=-EINVAL;
1033 break;
1034 }
1035 ret=videobuf_querybuf(&fh->vb_vidq, arg);
1036 break;
1037 case VIDIOC_QBUF:
1038 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1039 ret=-EINVAL;
1040 break;
1041 }
1042 ret=videobuf_qbuf(&fh->vb_vidq, arg);
1043 break;
1044 case VIDIOC_DQBUF:
1045 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1046 ret=-EINVAL;
1047 break;
1048 }
1049 ret=videobuf_dqbuf(&fh->vb_vidq, arg,
1050 file->f_flags & O_NONBLOCK);
1051 break;
1052#ifdef HAVE_V4L1
1053 /* --- streaming capture ------------------------------------- */
1054 case VIDIOCGMBUF:
1055 {
1056 struct video_mbuf *mbuf = arg;
1057 struct videobuf_queue *q=&fh->vb_vidq;
1058 struct v4l2_requestbuffers req;
1059 unsigned int i;
1060
1061 memset(&req,0,sizeof(req));
1062 req.type = q->type;
1063 req.count = 8;
1064 req.memory = V4L2_MEMORY_MMAP;
1065 ret = videobuf_reqbufs(q,&req);
1066 if (ret < 0)
1067 break;
1068 memset(mbuf,0,sizeof(*mbuf));
1069 mbuf->frames = req.count;
1070 mbuf->size = 0;
1071 for (i = 0; i < mbuf->frames; i++) {
1072 mbuf->offsets[i] = q->bufs[i]->boff;
1073 mbuf->size += q->bufs[i]->bsize;
1074 }
1075 break;
1076 }
1077#endif
1078 case VIDIOC_STREAMON:
1079 {
1080 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1081 return -EINVAL;
1082 if (!res_get(dev,fh))
1083 return -EBUSY;
1084 ret=videobuf_streamon(&fh->vb_vidq);
1085 break;
1086 }
1087 case VIDIOC_STREAMOFF:
1088 { 1046 {
1089 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { 1047 .name = "NTSC-M",
1090 ret=-EINVAL; 1048 .id = V4L2_STD_NTSC_M,
1091 break;
1092 }
1093 ret = videobuf_streamoff(&fh->vb_vidq);
1094 if (ret < 0)
1095 break;
1096 res_free(dev,fh);
1097 break;
1098 } 1049 }
1099 /* ---------- tv norms ---------- */ 1050};
1100 case VIDIOC_ENUMSTD:
1101 {
1102 struct v4l2_standard *e = arg;
1103 1051
1104 if (e->index>0) { 1052static int vidioc_s_std (struct file *file, void *priv, v4l2_std_id a)
1105 ret=-EINVAL; 1053{
1106 break;
1107 }
1108 ret = v4l2_video_std_construct(e, V4L2_STD_NTSC_M, "NTSC-M");
1109 1054
1110 /* Allows vivi to use different fps from video std */ 1055 return 0;
1111 e->frameperiod.numerator = WAKE_NUMERATOR; 1056}
1112 e->frameperiod.denominator = WAKE_DENOMINATOR;
1113 1057
1114 break; 1058/* only one input in this sample driver */
1115 } 1059static int vidioc_enum_input (struct file *file, void *priv,
1116 case VIDIOC_G_STD: 1060 struct v4l2_input *inp)
1117 { 1061{
1118 v4l2_std_id *id = arg; 1062 if (inp->index != 0)
1063 return -EINVAL;
1119 1064
1120 *id = V4L2_STD_NTSC_M; 1065 inp->type = V4L2_INPUT_TYPE_CAMERA;
1121 break; 1066 inp->std = V4L2_STD_NTSC_M;
1122 } 1067 strcpy(inp->name,"Camera");
1123 case VIDIOC_S_STD:
1124 {
1125 break;
1126 }
1127 /* ------ input switching ---------- */
1128 case VIDIOC_ENUMINPUT:
1129 { /* only one input in this sample driver */
1130 struct v4l2_input *inp = arg;
1131 1068
1132 if (inp->index != 0) { 1069 return (0);
1133 ret=-EINVAL; 1070}
1134 break;
1135 }
1136 memset(inp, 0, sizeof(*inp));
1137 1071
1138 inp->index = 0; 1072static int vidioc_g_input (struct file *file, void *priv, unsigned int *i)
1139 inp->type = V4L2_INPUT_TYPE_CAMERA; 1073{
1140 inp->std = V4L2_STD_NTSC_M; 1074 *i = 0;
1141 strcpy(inp->name,"Camera");
1142 break;
1143 }
1144 case VIDIOC_G_INPUT:
1145 {
1146 unsigned int *i = arg;
1147 1075
1148 *i = 0; 1076 return (0);
1149 break; 1077}
1150 } 1078static int vidioc_s_input (struct file *file, void *priv, unsigned int i)
1151 case VIDIOC_S_INPUT: 1079{
1152 { 1080 if (i > 0)
1153 unsigned int *i = arg; 1081 return -EINVAL;
1154 1082
1155 if (*i > 0) 1083 return (0);
1156 ret=-EINVAL; 1084}
1157 break;
1158 }
1159 1085
1160 /* --- controls ---------------------------------------------- */ 1086 /* --- controls ---------------------------------------------- */
1161 case VIDIOC_QUERYCTRL: 1087static int vidioc_queryctrl (struct file *file, void *priv,
1162 { 1088 struct v4l2_queryctrl *qc)
1163 struct v4l2_queryctrl *qc = arg; 1089{
1164 int i; 1090 int i;
1165
1166 for (i = 0; i < ARRAY_SIZE(vivi_qctrl); i++)
1167 if (qc->id && qc->id == vivi_qctrl[i].id) {
1168 memcpy(qc, &(vivi_qctrl[i]),
1169 sizeof(*qc));
1170 break;
1171 }
1172 1091
1173 ret=-EINVAL; 1092 for (i = 0; i < ARRAY_SIZE(vivi_qctrl); i++)
1174 break; 1093 if (qc->id && qc->id == vivi_qctrl[i].id) {
1175 } 1094 memcpy(qc, &(vivi_qctrl[i]),
1176 case VIDIOC_G_CTRL: 1095 sizeof(*qc));
1177 { 1096 return (0);
1178 struct v4l2_control *ctrl = arg; 1097 }
1179 int i;
1180 1098
1181 for (i = 0; i < ARRAY_SIZE(vivi_qctrl); i++) 1099 return -EINVAL;
1182 if (ctrl->id == vivi_qctrl[i].id) { 1100}
1183 ctrl->value=qctl_regs[i];
1184 break;
1185 }
1186 1101
1187 ret=-EINVAL; 1102static int vidioc_g_ctrl (struct file *file, void *priv,
1188 break; 1103 struct v4l2_control *ctrl)
1189 } 1104{
1190 case VIDIOC_S_CTRL: 1105 int i;
1191 {
1192 struct v4l2_control *ctrl = arg;
1193 int i;
1194 for (i = 0; i < ARRAY_SIZE(vivi_qctrl); i++)
1195 if (ctrl->id == vivi_qctrl[i].id) {
1196 if (ctrl->value <
1197 vivi_qctrl[i].minimum
1198 || ctrl->value >
1199 vivi_qctrl[i].maximum) {
1200 ret=-ERANGE;
1201 break;
1202 }
1203 qctl_regs[i]=ctrl->value;
1204 break;
1205 }
1206 ret=-EINVAL;
1207 break;
1208 }
1209 default:
1210 ret=v4l_compat_translate_ioctl(inode,file,cmd,arg,vivi_do_ioctl);
1211 }
1212 1106
1213 if (debug) { 1107 for (i = 0; i < ARRAY_SIZE(vivi_qctrl); i++)
1214 if (ret<0) { 1108 if (ctrl->id == vivi_qctrl[i].id) {
1215 v4l_print_ioctl("vivi(err)", cmd); 1109 ctrl->value=qctl_regs[i];
1216 dprintk(1,"errcode=%d\n",ret); 1110 return (0);
1217 } else if (_IOC_DIR(cmd) & _IOC_READ) 1111 }
1218 v4l_printk_ioctl_arg("vivi(r)",cmd, arg);
1219 }
1220 1112
1221 return ret; 1113 return -EINVAL;
1222} 1114}
1223 1115static int vidioc_s_ctrl (struct file *file, void *priv,
1224static int vivi_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) 1116 struct v4l2_control *ctrl)
1225{ 1117{
1226 return video_usercopy(inode, file, cmd, arg, vivi_do_ioctl); 1118 int i;
1119
1120 for (i = 0; i < ARRAY_SIZE(vivi_qctrl); i++)
1121 if (ctrl->id == vivi_qctrl[i].id) {
1122 if (ctrl->value <
1123 vivi_qctrl[i].minimum
1124 || ctrl->value >
1125 vivi_qctrl[i].maximum) {
1126 return (-ERANGE);
1127 }
1128 qctl_regs[i]=ctrl->value;
1129 return (0);
1130 }
1131 return -EINVAL;
1227} 1132}
1228 1133
1229/* ------------------------------------------------------------------ 1134/* ------------------------------------------------------------------
@@ -1245,7 +1150,7 @@ static int vivi_open(struct inode *inode, struct file *file)
1245 1150
1246 list_for_each(list,&vivi_devlist) { 1151 list_for_each(list,&vivi_devlist) {
1247 h = list_entry(list, struct vivi_dev, vivi_devlist); 1152 h = list_entry(list, struct vivi_dev, vivi_devlist);
1248 if (h->video_dev.minor == minor) { 1153 if (h->vfd.minor == minor) {
1249 dev = h; 1154 dev = h;
1250 type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1155 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1251 } 1156 }
@@ -1254,6 +1159,7 @@ static int vivi_open(struct inode *inode, struct file *file)
1254 return -ENODEV; 1159 return -ENODEV;
1255 1160
1256 1161
1162
1257 /* If more than one user, mutex should be added */ 1163 /* If more than one user, mutex should be added */
1258 dev->users++; 1164 dev->users++;
1259 1165
@@ -1269,6 +1175,7 @@ static int vivi_open(struct inode *inode, struct file *file)
1269 1175
1270 file->private_data = fh; 1176 file->private_data = fh;
1271 fh->dev = dev; 1177 fh->dev = dev;
1178
1272 fh->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1179 fh->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1273 fh->fmt = &format; 1180 fh->fmt = &format;
1274 fh->width = 640; 1181 fh->width = 640;
@@ -1304,7 +1211,7 @@ static int vivi_open(struct inode *inode, struct file *file)
1304static ssize_t 1211static ssize_t
1305vivi_read(struct file *file, char __user *data, size_t count, loff_t *ppos) 1212vivi_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
1306{ 1213{
1307 struct vivi_fh *fh = file->private_data; 1214 struct vivi_fh *fh = file->private_data;
1308 1215
1309 if (fh->type==V4L2_BUF_TYPE_VIDEO_CAPTURE) { 1216 if (fh->type==V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1310 if (res_locked(fh->dev)) 1217 if (res_locked(fh->dev))
@@ -1318,8 +1225,8 @@ vivi_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
1318static unsigned int 1225static unsigned int
1319vivi_poll(struct file *file, struct poll_table_struct *wait) 1226vivi_poll(struct file *file, struct poll_table_struct *wait)
1320{ 1227{
1321 struct vivi_fh *fh = file->private_data; 1228 struct vivi_fh *fh = file->private_data;
1322 struct vivi_buffer *buf; 1229 struct vivi_buffer *buf;
1323 1230
1324 dprintk(1,"%s\n",__FUNCTION__); 1231 dprintk(1,"%s\n",__FUNCTION__);
1325 1232
@@ -1348,8 +1255,8 @@ vivi_poll(struct file *file, struct poll_table_struct *wait)
1348 1255
1349static int vivi_release(struct inode *inode, struct file *file) 1256static int vivi_release(struct inode *inode, struct file *file)
1350{ 1257{
1351 struct vivi_fh *fh = file->private_data; 1258 struct vivi_fh *fh = file->private_data;
1352 struct vivi_dev *dev = fh->dev; 1259 struct vivi_dev *dev = fh->dev;
1353 struct vivi_dmaqueue *vidq = &dev->vidq; 1260 struct vivi_dmaqueue *vidq = &dev->vidq;
1354 1261
1355 int minor = iminor(inode); 1262 int minor = iminor(inode);
@@ -1369,7 +1276,7 @@ static int vivi_release(struct inode *inode, struct file *file)
1369static int 1276static int
1370vivi_mmap(struct file *file, struct vm_area_struct * vma) 1277vivi_mmap(struct file *file, struct vm_area_struct * vma)
1371{ 1278{
1372 struct vivi_fh *fh = file->private_data; 1279 struct vivi_fh *fh = file->private_data;
1373 int ret; 1280 int ret;
1374 1281
1375 dprintk (1,"mmap called, vma=0x%08lx\n",(unsigned long)vma); 1282 dprintk (1,"mmap called, vma=0x%08lx\n",(unsigned long)vma);
@@ -1390,20 +1297,44 @@ static struct file_operations vivi_fops = {
1390 .release = vivi_release, 1297 .release = vivi_release,
1391 .read = vivi_read, 1298 .read = vivi_read,
1392 .poll = vivi_poll, 1299 .poll = vivi_poll,
1393 .ioctl = vivi_ioctl, 1300 .ioctl = video_ioctl2, /* V4L2 ioctl handler */
1394 .mmap = vivi_mmap, 1301 .mmap = vivi_mmap,
1395 .llseek = no_llseek, 1302 .llseek = no_llseek,
1396}; 1303};
1397 1304
1398static struct video_device vivi = { 1305static struct video_device vivi = {
1399 .name = "VTM Virtual Video Capture Board", 1306 .name = "vivi",
1400 .type = VID_TYPE_CAPTURE, 1307 .type = VID_TYPE_CAPTURE,
1401 .hardware = 0, 1308 .hardware = 0,
1402 .fops = &vivi_fops, 1309 .fops = &vivi_fops,
1403 .minor = -1, 1310 .minor = -1,
1404// .release = video_device_release, 1311// .release = video_device_release,
1312
1313 .vidioc_querycap = vidioc_querycap,
1314 .vidioc_enum_fmt_cap = vidioc_enum_fmt_cap,
1315 .vidioc_g_fmt_cap = vidioc_g_fmt_cap,
1316 .vidioc_try_fmt_cap = vidioc_try_fmt_cap,
1317 .vidioc_s_fmt_cap = vidioc_s_fmt_cap,
1318 .vidioc_reqbufs = vidioc_reqbufs,
1319 .vidioc_querybuf = vidioc_querybuf,
1320 .vidioc_qbuf = vidioc_qbuf,
1321 .vidioc_dqbuf = vidioc_dqbuf,
1322 .vidioc_s_std = vidioc_s_std,
1323 .vidioc_enum_input = vidioc_enum_input,
1324 .vidioc_g_input = vidioc_g_input,
1325 .vidioc_s_input = vidioc_s_input,
1326 .vidioc_queryctrl = vidioc_queryctrl,
1327 .vidioc_g_ctrl = vidioc_g_ctrl,
1328 .vidioc_s_ctrl = vidioc_s_ctrl,
1329 .vidioc_streamon = vidioc_streamon,
1330 .vidioc_streamoff = vidioc_streamoff,
1331#ifdef HAVE_V4L1
1332 .vidiocgmbuf = vidiocgmbuf,
1333#endif
1334 .tvnorms = tvnorms,
1335 .tvnormsize = ARRAY_SIZE(tvnorms),
1405}; 1336};
1406/* ------------------------------------------------------------------ 1337/* -----------------------------------------------------------------
1407 Initialization and module stuff 1338 Initialization and module stuff
1408 ------------------------------------------------------------------*/ 1339 ------------------------------------------------------------------*/
1409 1340
@@ -1447,3 +1378,16 @@ static void __exit vivi_exit(void)
1447 1378
1448module_init(vivi_init); 1379module_init(vivi_init);
1449module_exit(vivi_exit); 1380module_exit(vivi_exit);
1381
1382MODULE_DESCRIPTION("Video Technology Magazine Virtual Video Capture Board");
1383MODULE_AUTHOR("Mauro Carvalho Chehab, Ted Walther and John Sokol");
1384MODULE_LICENSE("Dual BSD/GPL");
1385
1386module_param(video_nr, int, 0);
1387
1388module_param_named(debug,vivi.debug, int, 0644);
1389MODULE_PARM_DESC(debug,"activates debug info");
1390
1391module_param(vid_limit,int,0644);
1392MODULE_PARM_DESC(vid_limit,"capture memory limit in megabytes");
1393