summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrey Konovalov <andrey.konovalov@linaro.org>2020-11-26 16:01:57 +0100
committerMauro Carvalho Chehab <mchehab+huawei@kernel.org>2020-12-03 08:53:20 +0100
commitdfb5d32897167cc4e6c833d3d360b48cd9343d5e (patch)
tree91356b7f3adbd529b798e02dbd08b52efa5c3b64
parenta3d412d4b9f3e1d016cd7c49dfa31a4711c7db90 (diff)
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" This is the second version of this change which handles the case of several pixel formats corresponding to one media bus format correctly. Signed-off-by: Andrey Konovalov <andrey.konovalov@linaro.org> Reviewed-by: Robert Foss <robert.foss@linaro.org> Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
-rw-r--r--drivers/media/platform/qcom/camss/camss-video.c28
1 files changed, 25 insertions, 3 deletions
diff --git a/drivers/media/platform/qcom/camss/camss-video.c b/drivers/media/platform/qcom/camss/camss-video.c
index 2dbe6b6e4f40..bd9334af1c73 100644
--- a/drivers/media/platform/qcom/camss/camss-video.c
+++ b/drivers/media/platform/qcom/camss/camss-video.c
@@ -539,6 +539,7 @@ static int video_enum_fmt(struct file *file, void *fh, struct v4l2_fmtdesc *f)
{
struct camss_video *video = video_drvdata(file);
int i, j, k;
+ u32 mcode = f->mbus_code;
if (f->type != video->type)
return -EINVAL;
@@ -546,10 +547,26 @@ static int video_enum_fmt(struct file *file, void *fh, struct v4l2_fmtdesc *f)
if (f->index >= video->nformats)
return -EINVAL;
- /* find index "i" of "k"th unique pixelformat in formats array */
+ /*
+ * Find index "i" of "k"th unique pixelformat in formats array.
+ *
+ * If f->mbus_code passed to video_enum_fmt() is not zero, a device
+ * with V4L2_CAP_IO_MC capability restricts enumeration to only the
+ * pixel formats that can be produced from that media bus code.
+ * This is implemented by skipping video->formats[] entries with
+ * code != f->mbus_code (if f->mbus_code is not zero).
+ * If the f->mbus_code passed to video_enum_fmt() is not supported,
+ * -EINVAL is returned.
+ * If f->mbus_code is zero, all the pixel formats are enumerated.
+ */
k = -1;
for (i = 0; i < video->nformats; i++) {
+ if (mcode != 0 && video->formats[i].code != mcode)
+ continue;
+
for (j = 0; j < i; j++) {
+ if (mcode != 0 && video->formats[j].code != mcode)
+ continue;
if (video->formats[i].pixelformat ==
video->formats[j].pixelformat)
break;
@@ -563,6 +580,11 @@ static int video_enum_fmt(struct file *file, void *fh, struct v4l2_fmtdesc *f)
}
if (k < f->index)
+ /*
+ * All the unique pixel formats matching the arguments
+ * have been enumerated (k >= 0 and f->index > 0), or
+ * no pixel formats match the non-zero f->mbus_code (k == -1).
+ */
return -EINVAL;
f->pixelformat = video->formats[i].pixelformat;
@@ -949,8 +971,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;