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; |
