]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/media/video/soc_camera.c
V4L/DVB (11027): soc-camera: configure drivers with a default format at probe time
[linux-2.6-omap-h63xx.git] / drivers / media / video / soc_camera.c
index fcd6b2ce9c19b0b2780685081c669e23cace1c98..6d8bfd4d97e20ba49303b26b133665045f5a61a9 100644 (file)
@@ -286,7 +286,9 @@ static int soc_camera_set_fmt(struct soc_camera_file *icf,
 
        icd->width              = pix->width;
        icd->height             = pix->height;
-       icf->vb_vidq.field      = pix->field;
+       icf->vb_vidq.field      =
+               icd->field      = pix->field;
+
        if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
                dev_warn(&icd->dev, "Attention! Wrong buf-type %d\n",
                         f->type);
@@ -339,27 +341,24 @@ static int soc_camera_open(struct file *file)
 
        /* Now we really have to activate the camera */
        if (icd->use_count == 1) {
+               /* Restore parameters before the last close() per V4L2 API */
                struct v4l2_format f = {
                        .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
                        .fmt.pix = {
-                               .width          = DEFAULT_WIDTH,
-                               .height         = DEFAULT_HEIGHT,
-                               .field          = V4L2_FIELD_ANY,
+                               .width          = icd->width,
+                               .height         = icd->height,
+                               .field          = icd->field,
+                               .pixelformat    = icd->current_fmt->fourcc,
+                               .colorspace     = icd->current_fmt->colorspace,
                        },
                };
 
-               ret = soc_camera_init_user_formats(icd);
-               if (ret < 0)
-                       goto eiufmt;
                ret = ici->ops->add(icd);
                if (ret < 0) {
                        dev_err(&icd->dev, "Couldn't activate the camera: %d\n", ret);
                        goto eiciadd;
                }
 
-               f.fmt.pix.pixelformat   = icd->current_fmt->fourcc;
-               f.fmt.pix.colorspace    = icd->current_fmt->colorspace;
-
                /* Try to configure with default parameters */
                ret = soc_camera_set_fmt(icf, &f);
                if (ret < 0)
@@ -382,8 +381,6 @@ static int soc_camera_open(struct file *file)
 esfmt:
        ici->ops->remove(icd);
 eiciadd:
-       soc_camera_free_user_formats(icd);
-eiufmt:
        icd->use_count--;
        mutex_unlock(&icd->video_lock);
        module_put(ici->ops->owner);
@@ -403,10 +400,9 @@ static int soc_camera_close(struct file *file)
 
        mutex_lock(&icd->video_lock);
        icd->use_count--;
-       if (!icd->use_count) {
+       if (!icd->use_count)
                ici->ops->remove(icd);
-               soc_camera_free_user_formats(icd);
-       }
+
        mutex_unlock(&icd->video_lock);
 
        module_put(icd->ops->owner);
@@ -874,9 +870,18 @@ static int soc_camera_probe(struct device *dev)
                qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_EXPOSURE);
                icd->exposure = qctrl ? qctrl->default_value :
                        (unsigned short)~0;
+
+               ret = soc_camera_init_user_formats(icd);
+               if (ret < 0)
+                       goto eiufmt;
+
+               icd->height     = DEFAULT_HEIGHT;
+               icd->width      = DEFAULT_WIDTH;
+               icd->field      = V4L2_FIELD_ANY;
        }
-       ici->ops->remove(icd);
 
+eiufmt:
+       ici->ops->remove(icd);
 eiadd:
        mutex_unlock(&icd->video_lock);
        module_put(ici->ops->owner);
@@ -895,6 +900,8 @@ static int soc_camera_remove(struct device *dev)
        if (icd->ops->remove)
                icd->ops->remove(icd);
 
+       soc_camera_free_user_formats(icd);
+
        return 0;
 }