diff options
author | Andrey Konovalov <andrey.konovalov@linaro.org> | 2020-08-14 22:54:01 +0200 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab+huawei@kernel.org> | 2020-08-29 08:17:40 +0200 |
commit | c90f1178dcac30dee5ddd29ec0513e7589aa866e (patch) | |
tree | 20d64c01db695db5dc0954b3f2d1bdc5e71b9b77 /drivers/media | |
parent | f287e3ecb617b66f60b4e4641ee10054fffd00be (diff) | |
download | linux-c90f1178dcac30dee5ddd29ec0513e7589aa866e.tar.bz2 |
media: camss: Make use of V4L2_CAP_IO_MC
Implement mbus_code filtering for format enumeration.
Without this patch libcamera errors out with:
"ERROR V4L2 v4l2_videodevice.cpp:982 /dev/video0[cap]: Media bus code
filtering not supported by the device"
Signed-off-by: Andrey Konovalov <andrey.konovalov@linaro.org>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/platform/qcom/camss/camss-video.c | 67 |
1 files changed, 54 insertions, 13 deletions
diff --git a/drivers/media/platform/qcom/camss/camss-video.c b/drivers/media/platform/qcom/camss/camss-video.c index 0e2fcee97eeb..322532f758dc 100644 --- a/drivers/media/platform/qcom/camss/camss-video.c +++ b/drivers/media/platform/qcom/camss/camss-video.c @@ -529,17 +529,16 @@ static int video_querycap(struct file *file, void *fh, return 0; } -static int video_enum_fmt(struct file *file, void *fh, struct v4l2_fmtdesc *f) +/* + * Returns the index in the video->formats[] array of the element which + * has the "ndx"th unique value of pixelformat field. + * If not found (no more unique pixelformat's) returns -EINVAL. + */ +static int video_get_unique_pixelformat_by_index(struct camss_video *video, + int ndx) { - struct camss_video *video = video_drvdata(file); int i, j, k; - if (f->type != video->type) - return -EINVAL; - - if (f->index >= video->nformats) - return -EINVAL; - /* find index "i" of "k"th unique pixelformat in formats array */ k = -1; for (i = 0; i < video->nformats; i++) { @@ -552,11 +551,53 @@ static int video_enum_fmt(struct file *file, void *fh, struct v4l2_fmtdesc *f) if (j == i) k++; - if (k == f->index) - break; + if (k == ndx) + return i; + } + + return -EINVAL; +} + +/* + * Returns the index in the video->formats[] array of the element which + * has code equal to mcode. + * If not found returns -EINVAL. + */ +static int video_get_pixelformat_by_mbus_code(struct camss_video *video, + u32 mcode) +{ + int i; + + for (i = 0; i < video->nformats; i++) { + if (video->formats[i].code == mcode) + return i; + } + + return -EINVAL; +} + +static int video_enum_fmt(struct file *file, void *fh, struct v4l2_fmtdesc *f) +{ + struct camss_video *video = video_drvdata(file); + int i; + + if (f->type != video->type) + return -EINVAL; + + if (f->index >= video->nformats) + return -EINVAL; + + if (f->mbus_code) { + /* Each entry in formats[] table has unique mbus_code */ + if (f->index > 0) + return -EINVAL; + + i = video_get_pixelformat_by_mbus_code(video, f->mbus_code); + } else { + i = video_get_unique_pixelformat_by_index(video, f->index); } - if (k < f->index) + if (i < 0) return -EINVAL; f->pixelformat = video->formats[i].pixelformat; @@ -911,8 +952,8 @@ int msm_video_register(struct camss_video *video, struct v4l2_device *v4l2_dev, } vdev->fops = &msm_vid_fops; - vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_STREAMING | - V4L2_CAP_READWRITE; + vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_STREAMING + | V4L2_CAP_READWRITE | V4L2_CAP_IO_MC; vdev->ioctl_ops = &msm_vid_ioctl_ops; vdev->release = msm_video_release; vdev->v4l2_dev = v4l2_dev; |