diff options
Diffstat (limited to 'drivers/media/video/soc_camera.c')
-rw-r--r-- | drivers/media/video/soc_camera.c | 29 |
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 | |||
44 | static LIST_HEAD(hosts); | 49 | static LIST_HEAD(hosts); |
45 | static LIST_HEAD(devices); | 50 | static LIST_HEAD(devices); |
46 | static DEFINE_MUTEX(list_lock); /* Protects the list of hosts */ | 51 | static 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 | ||
385 | egfmt: | 390 | egfmt: |
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; |