Staging: dt3155v4l: introduce state machine
authorMarin Mitov <mitov@issp.bas.bg>
Fri, 14 May 2010 08:15:38 +0000 (11:15 +0300)
committerGreg Kroah-Hartman <gregkh@suse.de>
Fri, 14 May 2010 21:00:55 +0000 (14:00 -0700)
This patch introduces a v4l2 state machine, so now
CONFIG_DT3155_STREAMING is no more needed.

Signed-off-by: Marin Mitov <mitov@issp.bas.bg>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/staging/dt3155v4l/Kconfig
drivers/staging/dt3155v4l/dt3155v4l.c
drivers/staging/dt3155v4l/dt3155v4l.h

index 5cef542..f49f4ac 100644 (file)
@@ -18,11 +18,3 @@ config DT3155_CCIR
        ---help---
          Select it for CCIR/50Hz (European region),
          or leave it unselected for RS-170/60Hz (North America).
-
-config DT3155_STREAMING
-       bool "Selects mmap streaming instead of read method"
-       depends on VIDEO_DT3155
-       default y
-       ---help---
-         Select it if you wish to try mmap streaming, or
-         or leave it unselected for using read method.
index 4946361..308fb45 100644 (file)
@@ -930,6 +930,7 @@ dt3155_release(struct file *filp)
                dt3155_stop_acq(pd);
                videobuf_stop(pd->vidq);
                pd->acq_fp = NULL;
+               pd->streaming = 0;
        }
        if (!pd->users) {
                kthread_stop(pd->thread);
@@ -949,11 +950,15 @@ dt3155_read(struct file *filp, char __user *user, size_t size, loff_t *loff)
 
        if (mutex_lock_interruptible(&pd->mux) == -EINTR)
                return -ERESTARTSYS;
-       if (!pd->acq_fp)
+       if (!pd->acq_fp) {
                pd->acq_fp = filp;
-       else if (pd->acq_fp != filp) {
+               pd->streaming = 0;
+       } else if (pd->acq_fp != filp) {
                ret = -EBUSY;
                goto done;
+       } else if (pd->streaming == 1) {
+               ret = -EINVAL;
+               goto done;
        }
        ret = videobuf_read_stream(pd->vidq, user, size, loff, 0,
                                                filp->f_flags & O_NONBLOCK);
@@ -1001,8 +1006,10 @@ dt3155_ioc_streamon(struct file *filp, void *p, enum v4l2_buf_type type)
                if (ret)
                        goto unlock;
                pd->acq_fp = filp;
+               pd->streaming = 1;
                wake_up_interruptible_sync(&pd->do_dma);
        } else if (pd->acq_fp == filp) {
+               pd->streaming = 1;
                ret = videobuf_streamon(pd->vidq);
                if (!ret)
                        wake_up_interruptible_sync(&pd->do_dma);
@@ -1043,11 +1050,8 @@ dt3155_ioc_querycap(struct file *filp, void *p, struct v4l2_capability *cap)
        cap->version =
               KERNEL_VERSION(DT3155_VER_MAJ, DT3155_VER_MIN, DT3155_VER_EXT);
        cap->capabilities = V4L2_CAP_VIDEO_CAPTURE |
-#ifdef CONFIG_DT3155_STREAMING
-                               V4L2_CAP_STREAMING;
-#else
+                               V4L2_CAP_STREAMING |
                                V4L2_CAP_READWRITE;
-#endif
        return 0;
 }
 
@@ -1095,7 +1099,28 @@ dt3155_ioc_try_fmt_vid_cap(struct file *filp, void *p, struct v4l2_format *f)
 static int
 dt3155_ioc_s_fmt_vid_cap(struct file *filp, void *p, struct v4l2_format *f)
 {
-       return dt3155_ioc_g_fmt_vid_cap(filp, p, f);
+       struct dt3155_priv *pd = video_drvdata(filp);
+       int ret =  -ERESTARTSYS;
+
+       if (mutex_lock_interruptible(&pd->mux) == -EINTR)
+               return ret;
+       if (!pd->acq_fp) {
+               pd->acq_fp = filp;
+               pd->streaming = 0;
+       } else if (pd->acq_fp != filp) {
+               ret = -EBUSY;
+               goto done;
+       }
+/*     FIXME: we don't change the format for now
+       if (pd->vidq->streaming || pd->vidq->reading || pd->curr_buff) {
+               ret = -EBUSY;
+               goto done;
+       }
+*/
+       ret = dt3155_ioc_g_fmt_vid_cap(filp, p, f);
+done:
+       mutex_unlock(&pd->mux);
+       return ret;
 }
 
 static int
@@ -1103,15 +1128,33 @@ dt3155_ioc_reqbufs(struct file *filp, void *p, struct v4l2_requestbuffers *b)
 {
        struct dt3155_priv *pd = video_drvdata(filp);
        struct videobuf_queue *q = pd->vidq;
+       int ret = -ERESTARTSYS;
 
        if (b->memory != V4L2_MEMORY_MMAP)
                return -EINVAL;
+       if (mutex_lock_interruptible(&pd->mux) == -EINTR)
+               return ret;
+       if (!pd->acq_fp)
+               pd->acq_fp = filp;
+       else if (pd->acq_fp != filp) {
+               ret = -EBUSY;
+               goto done;
+       }
+       pd->streaming = 1;
+       ret = 0;
+done:
+       mutex_unlock(&pd->mux);
+       if (ret)
+               return ret;
        if (b->count)
-               return videobuf_reqbufs(q, b);
+               ret = videobuf_reqbufs(q, b);
        else { /* FIXME: is it necessary? */
                printk(KERN_DEBUG "dt3155: request to free buffers\n");
-               return videobuf_mmap_free(q);
+               /* ret = videobuf_mmap_free(q); */
+               ret = dt3155_ioc_streamoff(filp, p,
+                                               V4L2_BUF_TYPE_VIDEO_CAPTURE);
        }
+       return ret;
 }
 
 static int
@@ -1128,8 +1171,12 @@ dt3155_ioc_qbuf(struct file *filp, void *p, struct v4l2_buffer *b)
 {
        struct dt3155_priv *pd = video_drvdata(filp);
        struct videobuf_queue *q = pd->vidq;
+       int ret;
 
-       return videobuf_qbuf(q, b);
+       ret = videobuf_qbuf(q, b);
+       if (ret)
+               return ret;
+       return videobuf_querybuf(q, b);
 }
 
 static int
@@ -1170,7 +1217,12 @@ dt3155_ioc_enum_input(struct file *filp, void *p, struct v4l2_input *input)
                return -EINVAL;
        strcpy(input->name, "Coax in");
        input->type = V4L2_INPUT_TYPE_CAMERA;
-       input->std = V4L2_STD_ALL;
+       /*
+        * FIXME: input->std = 0 according to v4l2 API
+        * VIDIOC_G_STD, VIDIOC_S_STD, VIDIOC_QUERYSTD and VIDIOC_ENUMSTD
+        * should return -EINVAL
+        */
+       input->std = DT3155_CURRENT_NORM;
        input->status = 0;/* FIXME: add sync detection & V4L2_IN_ST_NO_H_LOCK */
        return 0;
 }
@@ -1200,7 +1252,7 @@ dt3155_ioc_g_parm(struct file *filp, void *p, struct v4l2_streamparm *parms)
        parms->parm.capture.timeperframe.numerator = 1001;
        parms->parm.capture.timeperframe.denominator = frames_per_sec * 1000;
        parms->parm.capture.extendedmode = 0;
-       parms->parm.capture.readbuffers = 1;
+       parms->parm.capture.readbuffers = 1; /* FIXME: 2 buffers? */
        return 0;
 }
 
@@ -1214,7 +1266,7 @@ dt3155_ioc_s_parm(struct file *filp, void *p, struct v4l2_streamparm *parms)
        parms->parm.capture.timeperframe.numerator = 1001;
        parms->parm.capture.timeperframe.denominator = frames_per_sec * 1000;
        parms->parm.capture.extendedmode = 0;
-       parms->parm.capture.readbuffers = 1;
+       parms->parm.capture.readbuffers = 1; /* FIXME: 2 buffers? */
        return 0;
 }
 
@@ -1377,7 +1429,7 @@ static struct video_device dt3155_vdev = {
        .ioctl_ops = &dt3155_ioctl_ops,
        .minor = -1,
        .release = video_device_release,
-       .tvnorms = V4L2_STD_ALL,
+       .tvnorms = DT3155_CURRENT_NORM,
        .current_norm = DT3155_CURRENT_NORM,
 };
 
index 4c6a0ee..e65a81e 100644 (file)
@@ -30,7 +30,7 @@
 #define DT3155_NAME "dt3155"
 #define DT3155_VER_MAJ 1
 #define DT3155_VER_MIN 0
-#define DT3155_VER_EXT 2
+#define DT3155_VER_EXT 3
 #define DT3155_VERSION  __stringify(DT3155_VER_MAJ)    "."             \
                        __stringify(DT3155_VER_MIN)     "."             \
                        __stringify(DT3155_VER_EXT)
@@ -180,6 +180,7 @@ struct dt3155_stats {
  *
  * @vdev:              pointer to video_device structure
  * @acq_fp             pointer to filp that starts acquisition
+ * @streaming          streaming is negotiated
  * @pdev:              pointer to pci_dev structure
  * @vidq               pointer to videobuf_queue structure
  * @curr_buf:          pointer to curren buffer
@@ -200,6 +201,7 @@ struct dt3155_stats {
 struct dt3155_priv {
        struct video_device *vdev;
        struct file *acq_fp;
+       int streaming;
        struct pci_dev *pdev;
        struct videobuf_queue *vidq;
        struct videobuf_buffer *curr_buf;