aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/media/video/soc_camera.c39
-rw-r--r--include/media/soc_camera.h1
2 files changed, 24 insertions, 16 deletions
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c
index fcd6b2ce9c19..6d8bfd4d97e2 100644
--- a/drivers/media/video/soc_camera.c
+++ b/drivers/media/video/soc_camera.c
@@ -286,7 +286,9 @@ static int soc_camera_set_fmt(struct soc_camera_file *icf,
286 286
287 icd->width = pix->width; 287 icd->width = pix->width;
288 icd->height = pix->height; 288 icd->height = pix->height;
289 icf->vb_vidq.field = pix->field; 289 icf->vb_vidq.field =
290 icd->field = pix->field;
291
290 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 292 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
291 dev_warn(&icd->dev, "Attention! Wrong buf-type %d\n", 293 dev_warn(&icd->dev, "Attention! Wrong buf-type %d\n",
292 f->type); 294 f->type);
@@ -339,27 +341,24 @@ static int soc_camera_open(struct file *file)
339 341
340 /* Now we really have to activate the camera */ 342 /* Now we really have to activate the camera */
341 if (icd->use_count == 1) { 343 if (icd->use_count == 1) {
344 /* Restore parameters before the last close() per V4L2 API */
342 struct v4l2_format f = { 345 struct v4l2_format f = {
343 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, 346 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
344 .fmt.pix = { 347 .fmt.pix = {
345 .width = DEFAULT_WIDTH, 348 .width = icd->width,
346 .height = DEFAULT_HEIGHT, 349 .height = icd->height,
347 .field = V4L2_FIELD_ANY, 350 .field = icd->field,
351 .pixelformat = icd->current_fmt->fourcc,
352 .colorspace = icd->current_fmt->colorspace,
348 }, 353 },
349 }; 354 };
350 355
351 ret = soc_camera_init_user_formats(icd);
352 if (ret < 0)
353 goto eiufmt;
354 ret = ici->ops->add(icd); 356 ret = ici->ops->add(icd);
355 if (ret < 0) { 357 if (ret < 0) {
356 dev_err(&icd->dev, "Couldn't activate the camera: %d\n", ret); 358 dev_err(&icd->dev, "Couldn't activate the camera: %d\n", ret);
357 goto eiciadd; 359 goto eiciadd;
358 } 360 }
359 361
360 f.fmt.pix.pixelformat = icd->current_fmt->fourcc;
361 f.fmt.pix.colorspace = icd->current_fmt->colorspace;
362
363 /* Try to configure with default parameters */ 362 /* Try to configure with default parameters */
364 ret = soc_camera_set_fmt(icf, &f); 363 ret = soc_camera_set_fmt(icf, &f);
365 if (ret < 0) 364 if (ret < 0)
@@ -382,8 +381,6 @@ static int soc_camera_open(struct file *file)
382esfmt: 381esfmt:
383 ici->ops->remove(icd); 382 ici->ops->remove(icd);
384eiciadd: 383eiciadd:
385 soc_camera_free_user_formats(icd);
386eiufmt:
387 icd->use_count--; 384 icd->use_count--;
388 mutex_unlock(&icd->video_lock); 385 mutex_unlock(&icd->video_lock);
389 module_put(ici->ops->owner); 386 module_put(ici->ops->owner);
@@ -403,10 +400,9 @@ static int soc_camera_close(struct file *file)
403 400
404 mutex_lock(&icd->video_lock); 401 mutex_lock(&icd->video_lock);
405 icd->use_count--; 402 icd->use_count--;
406 if (!icd->use_count) { 403 if (!icd->use_count)
407 ici->ops->remove(icd); 404 ici->ops->remove(icd);
408 soc_camera_free_user_formats(icd); 405
409 }
410 mutex_unlock(&icd->video_lock); 406 mutex_unlock(&icd->video_lock);
411 407
412 module_put(icd->ops->owner); 408 module_put(icd->ops->owner);
@@ -874,9 +870,18 @@ static int soc_camera_probe(struct device *dev)
874 qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_EXPOSURE); 870 qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_EXPOSURE);
875 icd->exposure = qctrl ? qctrl->default_value : 871 icd->exposure = qctrl ? qctrl->default_value :
876 (unsigned short)~0; 872 (unsigned short)~0;
873
874 ret = soc_camera_init_user_formats(icd);
875 if (ret < 0)
876 goto eiufmt;
877
878 icd->height = DEFAULT_HEIGHT;
879 icd->width = DEFAULT_WIDTH;
880 icd->field = V4L2_FIELD_ANY;
877 } 881 }
878 ici->ops->remove(icd);
879 882
883eiufmt:
884 ici->ops->remove(icd);
880eiadd: 885eiadd:
881 mutex_unlock(&icd->video_lock); 886 mutex_unlock(&icd->video_lock);
882 module_put(ici->ops->owner); 887 module_put(ici->ops->owner);
@@ -895,6 +900,8 @@ static int soc_camera_remove(struct device *dev)
895 if (icd->ops->remove) 900 if (icd->ops->remove)
896 icd->ops->remove(icd); 901 icd->ops->remove(icd);
897 902
903 soc_camera_free_user_formats(icd);
904
898 return 0; 905 return 0;
899} 906}
900 907
diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h
index e9eb60740aaa..013c81875d76 100644
--- a/include/media/soc_camera.h
+++ b/include/media/soc_camera.h
@@ -45,6 +45,7 @@ struct soc_camera_device {
45 int num_formats; 45 int num_formats;
46 struct soc_camera_format_xlate *user_formats; 46 struct soc_camera_format_xlate *user_formats;
47 int num_user_formats; 47 int num_user_formats;
48 enum v4l2_field field; /* Preserve field over close() */
48 struct module *owner; 49 struct module *owner;
49 void *host_priv; /* Per-device host private data */ 50 void *host_priv; /* Per-device host private data */
50 /* soc_camera.c private count. Only accessed with .video_lock held */ 51 /* soc_camera.c private count. Only accessed with .video_lock held */