Re: [PATCH v4 09/21] media: camss: Add files which handle the video device nodes

2017-08-08 Thread Sakari Ailus
Hi Todor,

On Tue, Aug 08, 2017 at 04:30:06PM +0300, Todor Tomov wrote:
...
> +static int video_start_streaming(struct vb2_queue *q, unsigned int count)
> +{
> + struct camss_video *video = vb2_get_drv_priv(q);
> + struct video_device *vdev = >vdev;
> + struct media_entity *entity;
> + struct media_pad *pad;
> + struct v4l2_subdev *subdev;
> + int ret;
> +
> + ret = media_pipeline_start(>entity, >pipe);
> + if (ret < 0)
> + return ret;
> +
> + ret = video_check_format(video);
> + if (ret < 0)
> + goto error;
> +
> + entity = >entity;
> + while (1) {
> + pad = >pads[0];
> + if (!(pad->flags & MEDIA_PAD_FL_SINK))
> + break;

Could you align starting and stopping the streaming with this patch:



I'll send a pull request on it shortly.

Feel free to postpone for now, this isn't urgent.

> +
> + pad = media_entity_remote_pad(pad);
> + if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
> + break;
> +
> + entity = pad->entity;
> + subdev = media_entity_to_v4l2_subdev(entity);
> +
> + ret = v4l2_subdev_call(subdev, video, s_stream, 1);
> + if (ret < 0 && ret != -ENOIOCTLCMD)
> + goto error;
> + }
> +
> + return 0;
> +
> +error:
> + media_pipeline_stop(>entity);
> +
> + video->ops->flush_buffers(video, VB2_BUF_STATE_QUEUED);
> +
> + return ret;
> +}
> +
> +static void video_stop_streaming(struct vb2_queue *q)
> +{
> + struct camss_video *video = vb2_get_drv_priv(q);
> + struct video_device *vdev = >vdev;
> + struct media_entity *entity;
> + struct media_pad *pad;
> + struct v4l2_subdev *subdev;
> + struct v4l2_subdev *subdev_vfe = NULL;
> +
> + entity = >entity;
> + while (1) {
> + pad = >pads[0];
> + if (!(pad->flags & MEDIA_PAD_FL_SINK))
> + break;
> +
> + pad = media_entity_remote_pad(pad);
> + if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
> + break;
> +
> + entity = pad->entity;
> + subdev = media_entity_to_v4l2_subdev(entity);
> +
> + if (strstr(subdev->name, "vfe")) {
> + subdev_vfe = subdev;
> + } else if (strstr(subdev->name, "ispif")) {
> + v4l2_subdev_call(subdev, video, s_stream, 0);
> + v4l2_subdev_call(subdev_vfe, video, s_stream, 0);
> + } else {
> + v4l2_subdev_call(subdev, video, s_stream, 0);
> + }
> + }
> +
> + media_pipeline_stop(>entity);
> +
> + video->ops->flush_buffers(video, VB2_BUF_STATE_ERROR);
> +}

-- 
Regards,

Sakari Ailus
e-mail: sakari.ai...@iki.fi XMPP: sai...@retiisi.org.uk


[PATCH v4 09/21] media: camss: Add files which handle the video device nodes

2017-08-08 Thread Todor Tomov
These files handle the video device nodes of the camss driver.

Signed-off-by: Todor Tomov 
---
 .../media/platform/qcom/camss-8x16/camss-video.c   | 681 +
 .../media/platform/qcom/camss-8x16/camss-video.h   |  64 ++
 2 files changed, 745 insertions(+)
 create mode 100644 drivers/media/platform/qcom/camss-8x16/camss-video.c
 create mode 100644 drivers/media/platform/qcom/camss-8x16/camss-video.h

diff --git a/drivers/media/platform/qcom/camss-8x16/camss-video.c 
b/drivers/media/platform/qcom/camss-8x16/camss-video.c
new file mode 100644
index 000..2e3f012
--- /dev/null
+++ b/drivers/media/platform/qcom/camss-8x16/camss-video.c
@@ -0,0 +1,681 @@
+/*
+ * camss-video.c
+ *
+ * Qualcomm MSM Camera Subsystem - V4L2 device node
+ *
+ * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
+ * Copyright (C) 2015-2017 Linaro Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "camss-video.h"
+#include "camss.h"
+
+/*
+ * struct camss_format_info - ISP media bus format information
+ * @code: V4L2 media bus format code
+ * @pixelformat: V4L2 pixel format FCC identifier
+ * @bpp: Bits per pixel when stored in memory
+ */
+static const struct camss_format_info {
+   u32 code;
+   u32 pixelformat;
+   unsigned int bpp;
+} formats[] = {
+   { MEDIA_BUS_FMT_UYVY8_2X8, V4L2_PIX_FMT_UYVY, 16 },
+   { MEDIA_BUS_FMT_VYUY8_2X8, V4L2_PIX_FMT_VYUY, 16 },
+   { MEDIA_BUS_FMT_YUYV8_2X8, V4L2_PIX_FMT_YUYV, 16 },
+   { MEDIA_BUS_FMT_YVYU8_2X8, V4L2_PIX_FMT_YVYU, 16 },
+   { MEDIA_BUS_FMT_SBGGR8_1X8, V4L2_PIX_FMT_SBGGR8, 8 },
+   { MEDIA_BUS_FMT_SGBRG8_1X8, V4L2_PIX_FMT_SGBRG8, 8 },
+   { MEDIA_BUS_FMT_SGRBG8_1X8, V4L2_PIX_FMT_SGRBG8, 8 },
+   { MEDIA_BUS_FMT_SRGGB8_1X8, V4L2_PIX_FMT_SRGGB8, 8 },
+   { MEDIA_BUS_FMT_SBGGR10_1X10, V4L2_PIX_FMT_SBGGR10P, 10 },
+   { MEDIA_BUS_FMT_SGBRG10_1X10, V4L2_PIX_FMT_SGBRG10P, 10 },
+   { MEDIA_BUS_FMT_SGRBG10_1X10, V4L2_PIX_FMT_SGRBG10P, 10 },
+   { MEDIA_BUS_FMT_SRGGB10_1X10, V4L2_PIX_FMT_SRGGB10P, 10 },
+   { MEDIA_BUS_FMT_SBGGR12_1X12, V4L2_PIX_FMT_SBGGR12P, 12 },
+   { MEDIA_BUS_FMT_SGBRG12_1X12, V4L2_PIX_FMT_SGBRG12P, 12 },
+   { MEDIA_BUS_FMT_SGRBG12_1X12, V4L2_PIX_FMT_SGRBG12P, 12 },
+   { MEDIA_BUS_FMT_SRGGB12_1X12, V4L2_PIX_FMT_SRGGB12P, 12 }
+};
+
+/* 
-
+ * Helper functions
+ */
+
+/*
+ * video_mbus_to_pix_mp - Convert v4l2_mbus_framefmt to v4l2_pix_format_mplane
+ * @mbus: v4l2_mbus_framefmt format (input)
+ * @pix: v4l2_pix_format_mplane format (output)
+ *
+ * Fill the output pix structure with information from the input mbus format.
+ *
+ * Return 0 on success or a negative error code otherwise
+ */
+static unsigned int video_mbus_to_pix_mp(const struct v4l2_mbus_framefmt *mbus,
+struct v4l2_pix_format_mplane *pix)
+{
+   unsigned int i;
+   u32 bytesperline;
+
+   memset(pix, 0, sizeof(*pix));
+   v4l2_fill_pix_format_mplane(pix, mbus);
+
+   for (i = 0; i < ARRAY_SIZE(formats); ++i) {
+   if (formats[i].code == mbus->code)
+   break;
+   }
+
+   if (WARN_ON(i == ARRAY_SIZE(formats)))
+   return -EINVAL;
+
+   pix->pixelformat = formats[i].pixelformat;
+   pix->num_planes = 1;
+   bytesperline = pix->width * formats[i].bpp / 8;
+   bytesperline = ALIGN(bytesperline, 8);
+   pix->plane_fmt[0].bytesperline = bytesperline;
+   pix->plane_fmt[0].sizeimage = bytesperline * pix->height;
+
+   return 0;
+}
+
+static struct v4l2_subdev *video_remote_subdev(struct camss_video *video,
+  u32 *pad)
+{
+   struct media_pad *remote;
+
+   remote = media_entity_remote_pad(>pad);
+
+   if (!remote || !is_media_entity_v4l2_subdev(remote->entity))
+   return NULL;
+
+   if (pad)
+   *pad = remote->index;
+
+   return media_entity_to_v4l2_subdev(remote->entity);
+}
+
+static int video_get_subdev_format(struct camss_video *video,
+  struct v4l2_format *format)
+{
+   struct v4l2_subdev_format fmt;
+   struct v4l2_subdev *subdev;
+   u32 pad;
+   int ret;
+
+   subdev = video_remote_subdev(video, );
+   if (subdev == NULL)
+   return -EPIPE;
+
+   fmt.pad = pad;
+