aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/soc_camera.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/soc_camera.c')
-rw-r--r--drivers/media/video/soc_camera.c29
1 files changed, 18 insertions, 11 deletions
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c
index ddb4c091dedc..398864370267 100644
--- a/drivers/media/video/soc_camera.c
+++ b/drivers/media/video/soc_camera.c
@@ -41,6 +41,11 @@
41#define DEFAULT_WIDTH 640 41#define DEFAULT_WIDTH 640
42#define DEFAULT_HEIGHT 480 42#define DEFAULT_HEIGHT 480
43 43
44#define is_streaming(ici, icd) \
45 (((ici)->ops->init_videobuf) ? \
46 (icd)->vb_vidq.streaming : \
47 vb2_is_streaming(&(icd)->vb2_vidq))
48
44static LIST_HEAD(hosts); 49static LIST_HEAD(hosts);
45static LIST_HEAD(devices); 50static LIST_HEAD(devices);
46static DEFINE_MUTEX(list_lock); /* Protects the list of hosts */ 51static DEFINE_MUTEX(list_lock); /* Protects the list of hosts */
@@ -358,8 +363,6 @@ static int soc_camera_init_user_formats(struct soc_camera_device *icd)
358 if (!icd->user_formats) 363 if (!icd->user_formats)
359 return -ENOMEM; 364 return -ENOMEM;
360 365
361 icd->num_user_formats = fmts;
362
363 dev_dbg(&icd->dev, "Found %d supported formats.\n", fmts); 366 dev_dbg(&icd->dev, "Found %d supported formats.\n", fmts);
364 367
365 /* Second pass - actually fill data formats */ 368 /* Second pass - actually fill data formats */
@@ -367,9 +370,10 @@ static int soc_camera_init_user_formats(struct soc_camera_device *icd)
367 for (i = 0; i < raw_fmts; i++) 370 for (i = 0; i < raw_fmts; i++)
368 if (!ici->ops->get_formats) { 371 if (!ici->ops->get_formats) {
369 v4l2_subdev_call(sd, video, enum_mbus_fmt, i, &code); 372 v4l2_subdev_call(sd, video, enum_mbus_fmt, i, &code);
370 icd->user_formats[i].host_fmt = 373 icd->user_formats[fmts].host_fmt =
371 soc_mbus_get_fmtdesc(code); 374 soc_mbus_get_fmtdesc(code);
372 icd->user_formats[i].code = code; 375 if (icd->user_formats[fmts].host_fmt)
376 icd->user_formats[fmts++].code = code;
373 } else { 377 } else {
374 ret = ici->ops->get_formats(icd, i, 378 ret = ici->ops->get_formats(icd, i,
375 &icd->user_formats[fmts]); 379 &icd->user_formats[fmts]);
@@ -378,12 +382,12 @@ static int soc_camera_init_user_formats(struct soc_camera_device *icd)
378 fmts += ret; 382 fmts += ret;
379 } 383 }
380 384
385 icd->num_user_formats = fmts;
381 icd->current_fmt = &icd->user_formats[0]; 386 icd->current_fmt = &icd->user_formats[0];
382 387
383 return 0; 388 return 0;
384 389
385egfmt: 390egfmt:
386 icd->num_user_formats = 0;
387 vfree(icd->user_formats); 391 vfree(icd->user_formats);
388 return ret; 392 return ret;
389} 393}
@@ -662,7 +666,7 @@ static int soc_camera_s_fmt_vid_cap(struct file *file, void *priv,
662 if (icd->streamer && icd->streamer != file) 666 if (icd->streamer && icd->streamer != file)
663 return -EBUSY; 667 return -EBUSY;
664 668
665 if (icd->vb_vidq.bufs[0]) { 669 if (is_streaming(to_soc_camera_host(icd->dev.parent), icd)) {
666 dev_err(&icd->dev, "S_FMT denied: queue initialised\n"); 670 dev_err(&icd->dev, "S_FMT denied: queue initialised\n");
667 return -EBUSY; 671 return -EBUSY;
668 } 672 }
@@ -903,14 +907,17 @@ static int soc_camera_s_crop(struct file *file, void *fh,
903 if (ret < 0) { 907 if (ret < 0) {
904 dev_err(&icd->dev, 908 dev_err(&icd->dev,
905 "S_CROP denied: getting current crop failed\n"); 909 "S_CROP denied: getting current crop failed\n");
906 } else if (icd->vb_vidq.bufs[0] && 910 } else if ((a->c.width == current_crop.c.width &&
907 (a->c.width != current_crop.c.width || 911 a->c.height == current_crop.c.height) ||
908 a->c.height != current_crop.c.height)) { 912 !is_streaming(ici, icd)) {
913 /* same size or not streaming - use .set_crop() */
914 ret = ici->ops->set_crop(icd, a);
915 } else if (ici->ops->set_livecrop) {
916 ret = ici->ops->set_livecrop(icd, a);
917 } else {
909 dev_err(&icd->dev, 918 dev_err(&icd->dev,
910 "S_CROP denied: queue initialised and sizes differ\n"); 919 "S_CROP denied: queue initialised and sizes differ\n");
911 ret = -EBUSY; 920 ret = -EBUSY;
912 } else {
913 ret = ici->ops->set_crop(icd, a);
914 } 921 }
915 922
916 return ret; 923 return ret;