aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/vivi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/vivi.c')
-rw-r--r--drivers/media/video/vivi.c664
1 files changed, 299 insertions, 365 deletions
diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c
index 779db26771c0..41d23c8acbd8 100644
--- a/drivers/media/video/vivi.c
+++ b/drivers/media/video/vivi.c
@@ -48,34 +48,15 @@
48 48
49#include "font.h" 49#include "font.h"
50 50
51#ifndef kzalloc
52#define kzalloc(size, flags) \
53({ \
54 void *__ret = kmalloc(size, flags); \
55 if (__ret) \
56 memset(__ret, 0, size); \
57 __ret; \
58})
59#endif
60
61MODULE_DESCRIPTION("Video Technology Magazine Virtual Video Capture Board");
62MODULE_AUTHOR("Mauro Carvalho Chehab, Ted Walther and John Sokol");
63MODULE_LICENSE("Dual BSD/GPL");
64
65#define VIVI_MAJOR_VERSION 0 51#define VIVI_MAJOR_VERSION 0
66#define VIVI_MINOR_VERSION 4 52#define VIVI_MINOR_VERSION 4
67#define VIVI_RELEASE 0 53#define VIVI_RELEASE 0
68#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)
69 55
70static int video_nr = -1; /* /dev/videoN, -1 for autodetect */ 56/* Declare static vars that will be used as parameters */
71module_param(video_nr, int, 0); 57static unsigned int vid_limit = 16; /* Video memory limit, in Mb */
72 58static struct video_device vivi; /* Video device */
73static int debug = 0; 59static int video_nr = -1; /* /dev/videoN, -1 for autodetect */
74module_param(debug, int, 0);
75
76static unsigned int vid_limit = 16;
77module_param(vid_limit,int,0644);
78MODULE_PARM_DESC(vid_limit,"capture memory limit in megabytes");
79 60
80/* supported controls */ 61/* supported controls */
81static struct v4l2_queryctrl vivi_qctrl[] = { 62static struct v4l2_queryctrl vivi_qctrl[] = {
@@ -129,10 +110,10 @@ static struct v4l2_queryctrl vivi_qctrl[] = {
129 110
130static int qctl_regs[ARRAY_SIZE(vivi_qctrl)]; 111static int qctl_regs[ARRAY_SIZE(vivi_qctrl)];
131 112
132#define dprintk(level,fmt, arg...) \ 113#define dprintk(level,fmt, arg...) \
133 do { \ 114 do { \
134 if (debug >= (level)) \ 115 if (vivi.debug >= (level)) \
135 printk(KERN_DEBUG "vivi: " fmt , ## arg); \ 116 printk(KERN_DEBUG "vivi: " fmt , ## arg); \
136 } while (0) 117 } while (0)
137 118
138/* ------------------------------------------------------------------ 119/* ------------------------------------------------------------------
@@ -190,7 +171,7 @@ struct vivi_dev {
190 171
191 /* various device info */ 172 /* various device info */
192 unsigned int resources; 173 unsigned int resources;
193 struct video_device video_dev; 174 struct video_device vfd;
194 175
195 struct vivi_dmaqueue vidq; 176 struct vivi_dmaqueue vidq;
196 177
@@ -248,7 +229,8 @@ static u8 bars[8][3] = {
248#define TSTAMP_MAX_Y TSTAMP_MIN_Y+15 229#define TSTAMP_MAX_Y TSTAMP_MIN_Y+15
249#define TSTAMP_MIN_X 64 230#define TSTAMP_MIN_X 64
250 231
251void prep_to_addr(struct sg_to_addr to_addr[],struct videobuf_buffer *vb) 232static void prep_to_addr(struct sg_to_addr to_addr[],
233 struct videobuf_buffer *vb)
252{ 234{
253 int i, pos=0; 235 int i, pos=0;
254 236
@@ -259,7 +241,7 @@ void prep_to_addr(struct sg_to_addr to_addr[],struct videobuf_buffer *vb)
259 } 241 }
260} 242}
261 243
262inline int get_addr_pos(int pos, int pages, struct sg_to_addr to_addr[]) 244static int get_addr_pos(int pos, int pages, struct sg_to_addr to_addr[])
263{ 245{
264 int p1=0,p2=pages-1,p3=pages/2; 246 int p1=0,p2=pages-1,p3=pages/2;
265 247
@@ -280,8 +262,8 @@ inline int get_addr_pos(int pos, int pages, struct sg_to_addr to_addr[])
280 return (p1); 262 return (p1);
281} 263}
282 264
283void gen_line(struct sg_to_addr to_addr[],int inipos,int pages,int wmax, 265static void gen_line(struct sg_to_addr to_addr[],int inipos,int pages,int wmax,
284 int hmax, int line, char *timestr) 266 int hmax, int line, char *timestr)
285{ 267{
286 int w,i,j,pos=inipos,pgpos,oldpg,y; 268 int w,i,j,pos=inipos,pgpos,oldpg,y;
287 char *p,*s,*basep; 269 char *p,*s,*basep;
@@ -491,7 +473,7 @@ static void vivi_thread_tick(struct vivi_dmaqueue *dma_q)
491 dprintk(1,"%s: %d buffers handled (should be 1)\n",__FUNCTION__,bc); 473 dprintk(1,"%s: %d buffers handled (should be 1)\n",__FUNCTION__,bc);
492} 474}
493 475
494void vivi_sleep(struct vivi_dmaqueue *dma_q) 476static void vivi_sleep(struct vivi_dmaqueue *dma_q)
495{ 477{
496 int timeout; 478 int timeout;
497 DECLARE_WAITQUEUE(wait, current); 479 DECLARE_WAITQUEUE(wait, current);
@@ -526,7 +508,7 @@ void vivi_sleep(struct vivi_dmaqueue *dma_q)
526 try_to_freeze(); 508 try_to_freeze();
527} 509}
528 510
529int vivi_thread(void *data) 511static int vivi_thread(void *data)
530{ 512{
531 struct vivi_dmaqueue *dma_q=data; 513 struct vivi_dmaqueue *dma_q=data;
532 514
@@ -542,7 +524,7 @@ int vivi_thread(void *data)
542 return 0; 524 return 0;
543} 525}
544 526
545int vivi_start_thread(struct vivi_dmaqueue *dma_q) 527static int vivi_start_thread(struct vivi_dmaqueue *dma_q)
546{ 528{
547 dma_q->frame=0; 529 dma_q->frame=0;
548 dma_q->ini_jiffies=jiffies; 530 dma_q->ini_jiffies=jiffies;
@@ -560,7 +542,7 @@ int vivi_start_thread(struct vivi_dmaqueue *dma_q)
560 return 0; 542 return 0;
561} 543}
562 544
563void vivi_stop_thread(struct vivi_dmaqueue *dma_q) 545static void vivi_stop_thread(struct vivi_dmaqueue *dma_q)
564{ 546{
565 dprintk(1,"%s\n",__FUNCTION__); 547 dprintk(1,"%s\n",__FUNCTION__);
566 /* shutdown control thread */ 548 /* shutdown control thread */
@@ -666,8 +648,7 @@ buffer_setup(struct videobuf_queue *vq, unsigned int *count, unsigned int *size)
666 return 0; 648 return 0;
667} 649}
668 650
669void 651static void free_buffer(struct videobuf_queue *vq, struct vivi_buffer *buf)
670free_buffer(struct videobuf_queue *vq, struct vivi_buffer *buf)
671{ 652{
672 dprintk(1,"%s\n",__FUNCTION__); 653 dprintk(1,"%s\n",__FUNCTION__);
673 654
@@ -791,8 +772,8 @@ static void buffer_release(struct videobuf_queue *vq, struct videobuf_buffer *vb
791 free_buffer(vq,buf); 772 free_buffer(vq,buf);
792} 773}
793 774
794int vivi_map_sg (void *dev, struct scatterlist *sg, int nents, 775static int vivi_map_sg(void *dev, struct scatterlist *sg, int nents,
795 int direction) 776 int direction)
796{ 777{
797 int i; 778 int i;
798 779
@@ -808,15 +789,15 @@ int vivi_map_sg (void *dev, struct scatterlist *sg, int nents,
808 return nents; 789 return nents;
809} 790}
810 791
811int vivi_unmap_sg(void *dev,struct scatterlist *sglist,int nr_pages, 792static int vivi_unmap_sg(void *dev,struct scatterlist *sglist,int nr_pages,
812 int direction) 793 int direction)
813{ 794{
814 dprintk(1,"%s\n",__FUNCTION__); 795 dprintk(1,"%s\n",__FUNCTION__);
815 return 0; 796 return 0;
816} 797}
817 798
818int vivi_dma_sync_sg(void *dev,struct scatterlist *sglist,int nr_pages, 799static int vivi_dma_sync_sg(void *dev,struct scatterlist *sglist, int nr_pages,
819 int direction) 800 int direction)
820{ 801{
821// dprintk(1,"%s\n",__FUNCTION__); 802// dprintk(1,"%s\n",__FUNCTION__);
822 803
@@ -840,7 +821,80 @@ static struct videobuf_queue_ops vivi_video_qops = {
840 IOCTL handling 821 IOCTL handling
841 ------------------------------------------------------------------*/ 822 ------------------------------------------------------------------*/
842 823
843static 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,
844 struct v4l2_format *f) 898 struct v4l2_format *f)
845{ 899{
846 struct vivi_fmt *fmt; 900 struct vivi_fmt *fmt;
@@ -848,7 +902,8 @@ static int vivi_try_fmt(struct vivi_dev *dev, struct vivi_fh *fh,
848 unsigned int maxw, maxh; 902 unsigned int maxw, maxh;
849 903
850 if (format.fourcc != f->fmt.pix.pixelformat) { 904 if (format.fourcc != f->fmt.pix.pixelformat) {
851 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);
852 return -EINVAL; 907 return -EINVAL;
853 } 908 }
854 fmt=&format; 909 fmt=&format;
@@ -884,356 +939,196 @@ static int vivi_try_fmt(struct vivi_dev *dev, struct vivi_fh *fh,
884 return 0; 939 return 0;
885} 940}
886 941
887static 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)
888{ 945{
889 /* is it free? */ 946 struct vivi_fh *fh=priv;
890 down(&dev->lock); 947 int ret = vidioc_try_fmt_cap(file,fh,f);
891 if (dev->resources) { 948 if (ret < 0)
892 /* no, someone else uses it */ 949 return (ret);
893 up(&dev->lock); 950
894 return 0; 951 fh->fmt = &format;
895 } 952 fh->width = f->fmt.pix.width;
896 /* it's free, grab it */ 953 fh->height = f->fmt.pix.height;
897 dev->resources =1; 954 fh->vb_vidq.field = f->fmt.pix.field;
898 dprintk(1,"res: get\n"); 955 fh->type = f->type;
899 up(&dev->lock); 956
900 return 1; 957 return (0);
901} 958}
902 959
903static inline int res_locked(struct vivi_dev *dev) 960static int vidioc_reqbufs (struct file *file, void *priv, struct v4l2_requestbuffers *p)
904{ 961{
905 return (dev->resources); 962 struct vivi_fh *fh=priv;
906}
907 963
908static void res_free(struct vivi_dev *dev, struct vivi_fh *fh) 964 return (videobuf_reqbufs(&fh->vb_vidq, p));
909{
910 down(&dev->lock);
911 dev->resources = 0;
912 dprintk(1,"res: put\n");
913 up(&dev->lock);
914} 965}
915 966
916static 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)
917{ 968{
918 struct vivi_fh *fh = file->private_data; 969 struct vivi_fh *fh=priv;
919 struct vivi_dev *dev = fh->dev;
920 int ret=0;
921 970
922 if (debug) { 971 return (videobuf_querybuf(&fh->vb_vidq, p));
923 if (_IOC_DIR(cmd) & _IOC_WRITE) 972}
924 v4l_printk_ioctl_arg("vivi(w)",cmd, arg);
925 else if (!_IOC_DIR(cmd) & _IOC_READ) {
926 v4l_print_ioctl("vivi", cmd);
927 }
928 }
929 973
930 switch(cmd) { 974static int vidioc_qbuf (struct file *file, void *priv, struct v4l2_buffer *p)
931 /* --- capabilities ------------------------------------------ */ 975{
932 case VIDIOC_QUERYCAP: 976 struct vivi_fh *fh=priv;
933 {
934 struct v4l2_capability *cap = (struct v4l2_capability*)arg;
935
936 memset(cap, 0, sizeof(*cap));
937
938 strcpy(cap->driver, "vivi");
939 strcpy(cap->card, "vivi");
940 cap->version = VIVI_VERSION;
941 cap->capabilities =
942 V4L2_CAP_VIDEO_CAPTURE |
943 V4L2_CAP_STREAMING |
944 V4L2_CAP_READWRITE;
945 break;
946 }
947 /* --- capture ioctls ---------------------------------------- */
948 case VIDIOC_ENUM_FMT:
949 {
950 struct v4l2_fmtdesc *f = arg;
951 enum v4l2_buf_type type;
952 unsigned int index;
953 977
954 index = f->index; 978 return (videobuf_qbuf(&fh->vb_vidq, p));
955 type = f->type; 979}
956 980
957 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { 981static int vidioc_dqbuf (struct file *file, void *priv, struct v4l2_buffer *p)
958 ret=-EINVAL; 982{
959 break; 983 struct vivi_fh *fh=priv;
960 }
961 984
962 switch (type) { 985 return (videobuf_dqbuf(&fh->vb_vidq, p,
963 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 986 file->f_flags & O_NONBLOCK));
964 if (index > 0){ 987}
965 ret=-EINVAL;
966 break;
967 }
968 memset(f,0,sizeof(*f));
969 988
970 f->index = index; 989#ifdef HAVE_V4L1
971 f->type = type; 990static int vidiocgmbuf (struct file *file, void *priv, struct video_mbuf *mbuf)
972 strlcpy(f->description,format.name,sizeof(f->description)); 991{
973 f->pixelformat = format.fourcc; 992 struct vivi_fh *fh=priv;
974 break; 993 struct videobuf_queue *q=&fh->vb_vidq;
975 default: 994 struct v4l2_requestbuffers req;
976 ret=-EINVAL; 995 unsigned int i, ret;
977 } 996
978 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
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;
979 } 1009 }
980 case VIDIOC_G_FMT: 1010 return (0);
981 { 1011}
982 struct v4l2_format *f = (struct v4l2_format *)arg; 1012#endif
983 1013
984 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { 1014static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
985 ret=-EINVAL; 1015{
986 break; 1016 struct vivi_fh *fh=priv;
987 } 1017 struct vivi_dev *dev = fh->dev;
988 1018
989 memset(&f->fmt.pix,0,sizeof(f->fmt.pix)); 1019 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
990 f->fmt.pix.width = fh->width; 1020 return -EINVAL;
991 f->fmt.pix.height = fh->height; 1021 if (i != fh->type)
992 f->fmt.pix.field = fh->vb_vidq.field; 1022 return -EINVAL;
993 f->fmt.pix.pixelformat = fh->fmt->fourcc;
994 f->fmt.pix.bytesperline =
995 (f->fmt.pix.width * fh->fmt->depth) >> 3;
996 f->fmt.pix.sizeimage =
997 f->fmt.pix.height * f->fmt.pix.bytesperline;
998 break;
999 }
1000 case VIDIOC_S_FMT:
1001 {
1002 struct v4l2_format *f = arg;
1003 1023
1004 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { 1024 if (!res_get(dev,fh))
1005 dprintk(1,"Only capture supported.\n"); 1025 return -EBUSY;
1006 ret=-EINVAL; 1026 return (videobuf_streamon(&fh->vb_vidq));
1007 break; 1027}
1008 }
1009 1028
1010 ret = vivi_try_fmt(dev,fh,f); 1029static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
1011 if (ret < 0) 1030{
1012 break; 1031 struct vivi_fh *fh=priv;
1032 struct vivi_dev *dev = fh->dev;
1013 1033
1014 fh->fmt = &format; 1034 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1015 fh->width = f->fmt.pix.width; 1035 return -EINVAL;
1016 fh->height = f->fmt.pix.height; 1036 if (i != fh->type)
1017 fh->vb_vidq.field = f->fmt.pix.field; 1037 return -EINVAL;
1018 fh->type = f->type;
1019 1038
1020 break; 1039 videobuf_streamoff(&fh->vb_vidq);
1021 } 1040 res_free(dev,fh);
1022 case VIDIOC_TRY_FMT:
1023 {
1024 struct v4l2_format *f = arg;
1025 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1026 ret=-EINVAL;
1027 break;
1028 }
1029 1041
1030 ret=vivi_try_fmt(dev,fh,f); 1042 return (0);
1031 break; 1043}
1032 } 1044
1033 case VIDIOC_REQBUFS: 1045static struct v4l2_tvnorm tvnorms[] = {
1034 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1035 ret=-EINVAL;
1036 break;
1037 }
1038 ret=videobuf_reqbufs(&fh->vb_vidq, arg);
1039 break;
1040 case VIDIOC_QUERYBUF:
1041 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1042 ret=-EINVAL;
1043 break;
1044 }
1045 ret=videobuf_querybuf(&fh->vb_vidq, arg);
1046 break;
1047 case VIDIOC_QBUF:
1048 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1049 ret=-EINVAL;
1050 break;
1051 }
1052 ret=videobuf_qbuf(&fh->vb_vidq, arg);
1053 break;
1054 case VIDIOC_DQBUF:
1055 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1056 ret=-EINVAL;
1057 break;
1058 }
1059 ret=videobuf_dqbuf(&fh->vb_vidq, arg,
1060 file->f_flags & O_NONBLOCK);
1061 break;
1062#ifdef HAVE_V4L1
1063 /* --- streaming capture ------------------------------------- */
1064 case VIDIOCGMBUF:
1065 {
1066 struct video_mbuf *mbuf = arg;
1067 struct videobuf_queue *q=&fh->vb_vidq;
1068 struct v4l2_requestbuffers req;
1069 unsigned int i;
1070
1071 memset(&req,0,sizeof(req));
1072 req.type = q->type;
1073 req.count = 8;
1074 req.memory = V4L2_MEMORY_MMAP;
1075 ret = videobuf_reqbufs(q,&req);
1076 if (ret < 0)
1077 break;
1078 memset(mbuf,0,sizeof(*mbuf));
1079 mbuf->frames = req.count;
1080 mbuf->size = 0;
1081 for (i = 0; i < mbuf->frames; i++) {
1082 mbuf->offsets[i] = q->bufs[i]->boff;
1083 mbuf->size += q->bufs[i]->bsize;
1084 }
1085 break;
1086 }
1087#endif
1088 case VIDIOC_STREAMON:
1089 {
1090 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1091 return -EINVAL;
1092 if (!res_get(dev,fh))
1093 return -EBUSY;
1094 ret=videobuf_streamon(&fh->vb_vidq);
1095 break;
1096 }
1097 case VIDIOC_STREAMOFF:
1098 { 1046 {
1099 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { 1047 .name = "NTSC-M",
1100 ret=-EINVAL; 1048 .id = V4L2_STD_NTSC_M,
1101 break;
1102 }
1103 ret = videobuf_streamoff(&fh->vb_vidq);
1104 if (ret < 0)
1105 break;
1106 res_free(dev,fh);
1107 break;
1108 } 1049 }
1109 /* ---------- tv norms ---------- */ 1050};
1110 case VIDIOC_ENUMSTD:
1111 {
1112 struct v4l2_standard *e = arg;
1113 1051
1114 if (e->index>0) { 1052static int vidioc_s_std (struct file *file, void *priv, v4l2_std_id a)
1115 ret=-EINVAL; 1053{
1116 break;
1117 }
1118 ret = v4l2_video_std_construct(e, V4L2_STD_NTSC_M, "NTSC-M");
1119 1054
1120 /* Allows vivi to use different fps from video std */ 1055 return 0;
1121 e->frameperiod.numerator = WAKE_NUMERATOR; 1056}
1122 e->frameperiod.denominator = WAKE_DENOMINATOR;
1123 1057
1124 break; 1058/* only one input in this sample driver */
1125 } 1059static int vidioc_enum_input (struct file *file, void *priv,
1126 case VIDIOC_G_STD: 1060 struct v4l2_input *inp)
1127 { 1061{
1128 v4l2_std_id *id = arg; 1062 if (inp->index != 0)
1063 return -EINVAL;
1129 1064
1130 *id = V4L2_STD_NTSC_M; 1065 inp->type = V4L2_INPUT_TYPE_CAMERA;
1131 break; 1066 inp->std = V4L2_STD_NTSC_M;
1132 } 1067 strcpy(inp->name,"Camera");
1133 case VIDIOC_S_STD:
1134 {
1135 break;
1136 }
1137 /* ------ input switching ---------- */
1138 case VIDIOC_ENUMINPUT:
1139 { /* only one input in this sample driver */
1140 struct v4l2_input *inp = arg;
1141 1068
1142 if (inp->index != 0) { 1069 return (0);
1143 ret=-EINVAL; 1070}
1144 break;
1145 }
1146 memset(inp, 0, sizeof(*inp));
1147 1071
1148 inp->index = 0; 1072static int vidioc_g_input (struct file *file, void *priv, unsigned int *i)
1149 inp->type = V4L2_INPUT_TYPE_CAMERA; 1073{
1150 inp->std = V4L2_STD_NTSC_M; 1074 *i = 0;
1151 strcpy(inp->name,"Camera");
1152 break;
1153 }
1154 case VIDIOC_G_INPUT:
1155 {
1156 unsigned int *i = arg;
1157 1075
1158 *i = 0; 1076 return (0);
1159 break; 1077}
1160 } 1078static int vidioc_s_input (struct file *file, void *priv, unsigned int i)
1161 case VIDIOC_S_INPUT: 1079{
1162 { 1080 if (i > 0)
1163 unsigned int *i = arg; 1081 return -EINVAL;
1164 1082
1165 if (*i > 0) 1083 return (0);
1166 ret=-EINVAL; 1084}
1167 break;
1168 }
1169 1085
1170 /* --- controls ---------------------------------------------- */ 1086 /* --- controls ---------------------------------------------- */
1171 case VIDIOC_QUERYCTRL: 1087static int vidioc_queryctrl (struct file *file, void *priv,
1172 { 1088 struct v4l2_queryctrl *qc)
1173 struct v4l2_queryctrl *qc = arg; 1089{
1174 int i; 1090 int i;
1175
1176 for (i = 0; i < ARRAY_SIZE(vivi_qctrl); i++)
1177 if (qc->id && qc->id == vivi_qctrl[i].id) {
1178 memcpy(qc, &(vivi_qctrl[i]),
1179 sizeof(*qc));
1180 break;
1181 }
1182 1091
1183 ret=-EINVAL; 1092 for (i = 0; i < ARRAY_SIZE(vivi_qctrl); i++)
1184 break; 1093 if (qc->id && qc->id == vivi_qctrl[i].id) {
1185 } 1094 memcpy(qc, &(vivi_qctrl[i]),
1186 case VIDIOC_G_CTRL: 1095 sizeof(*qc));
1187 { 1096 return (0);
1188 struct v4l2_control *ctrl = arg; 1097 }
1189 int i;
1190 1098
1191 for (i = 0; i < ARRAY_SIZE(vivi_qctrl); i++) 1099 return -EINVAL;
1192 if (ctrl->id == vivi_qctrl[i].id) { 1100}
1193 ctrl->value=qctl_regs[i];
1194 break;
1195 }
1196 1101
1197 ret=-EINVAL; 1102static int vidioc_g_ctrl (struct file *file, void *priv,
1198 break; 1103 struct v4l2_control *ctrl)
1199 } 1104{
1200 case VIDIOC_S_CTRL: 1105 int i;
1201 {
1202 struct v4l2_control *ctrl = arg;
1203 int i;
1204 for (i = 0; i < ARRAY_SIZE(vivi_qctrl); i++)
1205 if (ctrl->id == vivi_qctrl[i].id) {
1206 if (ctrl->value <
1207 vivi_qctrl[i].minimum
1208 || ctrl->value >
1209 vivi_qctrl[i].maximum) {
1210 ret=-ERANGE;
1211 break;
1212 }
1213 qctl_regs[i]=ctrl->value;
1214 break;
1215 }
1216 ret=-EINVAL;
1217 break;
1218 }
1219 default:
1220 ret=v4l_compat_translate_ioctl(inode,file,cmd,arg,vivi_do_ioctl);
1221 }
1222 1106
1223 if (debug) { 1107 for (i = 0; i < ARRAY_SIZE(vivi_qctrl); i++)
1224 if (ret<0) { 1108 if (ctrl->id == vivi_qctrl[i].id) {
1225 v4l_print_ioctl("vivi(err)", cmd); 1109 ctrl->value=qctl_regs[i];
1226 dprintk(1,"errcode=%d\n",ret); 1110 return (0);
1227 } else if (_IOC_DIR(cmd) & _IOC_READ) 1111 }
1228 v4l_printk_ioctl_arg("vivi(r)",cmd, arg);
1229 }
1230 1112
1231 return ret; 1113 return -EINVAL;
1232} 1114}
1233 1115static int vidioc_s_ctrl (struct file *file, void *priv,
1234static int vivi_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) 1116 struct v4l2_control *ctrl)
1235{ 1117{
1236 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;
1237} 1132}
1238 1133
1239/* ------------------------------------------------------------------ 1134/* ------------------------------------------------------------------
@@ -1255,7 +1150,7 @@ static int vivi_open(struct inode *inode, struct file *file)
1255 1150
1256 list_for_each(list,&vivi_devlist) { 1151 list_for_each(list,&vivi_devlist) {
1257 h = list_entry(list, struct vivi_dev, vivi_devlist); 1152 h = list_entry(list, struct vivi_dev, vivi_devlist);
1258 if (h->video_dev.minor == minor) { 1153 if (h->vfd.minor == minor) {
1259 dev = h; 1154 dev = h;
1260 type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1155 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1261 } 1156 }
@@ -1264,6 +1159,7 @@ static int vivi_open(struct inode *inode, struct file *file)
1264 return -ENODEV; 1159 return -ENODEV;
1265 1160
1266 1161
1162
1267 /* If more than one user, mutex should be added */ 1163 /* If more than one user, mutex should be added */
1268 dev->users++; 1164 dev->users++;
1269 1165
@@ -1279,6 +1175,7 @@ static int vivi_open(struct inode *inode, struct file *file)
1279 1175
1280 file->private_data = fh; 1176 file->private_data = fh;
1281 fh->dev = dev; 1177 fh->dev = dev;
1178
1282 fh->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1179 fh->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1283 fh->fmt = &format; 1180 fh->fmt = &format;
1284 fh->width = 640; 1181 fh->width = 640;
@@ -1314,7 +1211,7 @@ static int vivi_open(struct inode *inode, struct file *file)
1314static ssize_t 1211static ssize_t
1315vivi_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)
1316{ 1213{
1317 struct vivi_fh *fh = file->private_data; 1214 struct vivi_fh *fh = file->private_data;
1318 1215
1319 if (fh->type==V4L2_BUF_TYPE_VIDEO_CAPTURE) { 1216 if (fh->type==V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1320 if (res_locked(fh->dev)) 1217 if (res_locked(fh->dev))
@@ -1328,8 +1225,8 @@ vivi_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
1328static unsigned int 1225static unsigned int
1329vivi_poll(struct file *file, struct poll_table_struct *wait) 1226vivi_poll(struct file *file, struct poll_table_struct *wait)
1330{ 1227{
1331 struct vivi_fh *fh = file->private_data; 1228 struct vivi_fh *fh = file->private_data;
1332 struct vivi_buffer *buf; 1229 struct vivi_buffer *buf;
1333 1230
1334 dprintk(1,"%s\n",__FUNCTION__); 1231 dprintk(1,"%s\n",__FUNCTION__);
1335 1232
@@ -1358,8 +1255,8 @@ vivi_poll(struct file *file, struct poll_table_struct *wait)
1358 1255
1359static int vivi_release(struct inode *inode, struct file *file) 1256static int vivi_release(struct inode *inode, struct file *file)
1360{ 1257{
1361 struct vivi_fh *fh = file->private_data; 1258 struct vivi_fh *fh = file->private_data;
1362 struct vivi_dev *dev = fh->dev; 1259 struct vivi_dev *dev = fh->dev;
1363 struct vivi_dmaqueue *vidq = &dev->vidq; 1260 struct vivi_dmaqueue *vidq = &dev->vidq;
1364 1261
1365 int minor = iminor(inode); 1262 int minor = iminor(inode);
@@ -1379,7 +1276,7 @@ static int vivi_release(struct inode *inode, struct file *file)
1379static int 1276static int
1380vivi_mmap(struct file *file, struct vm_area_struct * vma) 1277vivi_mmap(struct file *file, struct vm_area_struct * vma)
1381{ 1278{
1382 struct vivi_fh *fh = file->private_data; 1279 struct vivi_fh *fh = file->private_data;
1383 int ret; 1280 int ret;
1384 1281
1385 dprintk (1,"mmap called, vma=0x%08lx\n",(unsigned long)vma); 1282 dprintk (1,"mmap called, vma=0x%08lx\n",(unsigned long)vma);
@@ -1400,20 +1297,44 @@ static struct file_operations vivi_fops = {
1400 .release = vivi_release, 1297 .release = vivi_release,
1401 .read = vivi_read, 1298 .read = vivi_read,
1402 .poll = vivi_poll, 1299 .poll = vivi_poll,
1403 .ioctl = vivi_ioctl, 1300 .ioctl = video_ioctl2, /* V4L2 ioctl handler */
1404 .mmap = vivi_mmap, 1301 .mmap = vivi_mmap,
1405 .llseek = no_llseek, 1302 .llseek = no_llseek,
1406}; 1303};
1407 1304
1408static struct video_device vivi = { 1305static struct video_device vivi = {
1409 .name = "VTM Virtual Video Capture Board", 1306 .name = "vivi",
1410 .type = VID_TYPE_CAPTURE, 1307 .type = VID_TYPE_CAPTURE,
1411 .hardware = 0, 1308 .hardware = 0,
1412 .fops = &vivi_fops, 1309 .fops = &vivi_fops,
1413 .minor = -1, 1310 .minor = -1,
1414// .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),
1415}; 1336};
1416/* ------------------------------------------------------------------ 1337/* -----------------------------------------------------------------
1417 Initialization and module stuff 1338 Initialization and module stuff
1418 ------------------------------------------------------------------*/ 1339 ------------------------------------------------------------------*/
1419 1340
@@ -1457,3 +1378,16 @@ static void __exit vivi_exit(void)
1457 1378
1458module_init(vivi_init); 1379module_init(vivi_init);
1459module_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