[{"id":4964,"web_url":"https://patchwork.libcamera.org/comment/4964/","msgid":"<20200602115003.rig4ibmtdrwtyxjq@uno.localdomain>","date":"2020-06-02T11:50:03","subject":"Re: [libcamera-devel] [PATCH 06/10] libcamera: ipu3: cio2: Move the\n\tCIO2Device class to separate files","submitter":{"id":3,"url":"https://patchwork.libcamera.org/api/people/3/","name":"Jacopo Mondi","email":"jacopo@jmondi.org"},"content":"Hi Niklas,\n\nOn Tue, Jun 02, 2020 at 03:39:05AM +0200, Niklas Söderlund wrote:\n> In preparation of refactoring the IPU3 pipeline handler breakout the\n> CIO2Device into its own .cpp and .h file, no functional change.\n>\n> Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>\n\nsnip\n\n> +\n> +V4L2PixelFormat CIO2Device::mediaBusToFormat(unsigned int code)\n> +{\n> +\tswitch (code) {\n> +\tcase MEDIA_BUS_FMT_SBGGR10_1X10:\n> +\t\treturn V4L2PixelFormat(V4L2_PIX_FMT_IPU3_SBGGR10);\n> +\tcase MEDIA_BUS_FMT_SGBRG10_1X10:\n> +\t\treturn V4L2PixelFormat(V4L2_PIX_FMT_IPU3_SGBRG10);\n> +\tcase MEDIA_BUS_FMT_SGRBG10_1X10:\n> +\t\treturn V4L2PixelFormat(V4L2_PIX_FMT_IPU3_SGRBG10);\n> +\tcase MEDIA_BUS_FMT_SRGGB10_1X10:\n> +\t\treturn V4L2PixelFormat(V4L2_PIX_FMT_IPU3_SRGGB10);\n> +\tdefault:\n> +\t\treturn {};\n> +\t}\n> +}\n\nPossibly missed in review of the previous patch, but wasn't this\ndropped ?\n\n> +\n> +} /* namespace libcamera */\n> diff --git a/src/libcamera/pipeline/ipu3/cio2.h b/src/libcamera/pipeline/ipu3/cio2.h\n> new file mode 100644\n> index 0000000000000000..d923038bb4ba356f\n> --- /dev/null\n> +++ b/src/libcamera/pipeline/ipu3/cio2.h\n> @@ -0,0 +1,64 @@\n> +/* SPDX-License-Identifier: LGPL-2.1-or-later */\n> +/*\n> + * Copyright (C) 2020, Google Inc.\n> + *\n> + * cio2.h - Intel IPU3 CIO2\n> + */\n> +#ifndef __LIBCAMERA_PIPELINE_IPU3_CIO2_H__\n> +#define __LIBCAMERA_PIPELINE_IPU3_CIO2_H__\n> +\n> +#include <queue>\n> +#include <vector>\n> +\n> +#include <linux/media-bus-format.h>\n> +\n> +#include \"libcamera/internal/camera_sensor.h\"\n> +#include \"libcamera/internal/media_device.h\"\n> +#include \"libcamera/internal/v4l2_subdevice.h\"\n> +#include \"libcamera/internal/v4l2_videodevice.h\"\n> +\n> +namespace libcamera {\n> +\n> +class CIO2Device\n> +{\n> +public:\n> +\tstatic constexpr unsigned int CIO2_BUFFER_COUNT = 4;\n> +\n> +\tCIO2Device()\n> +\t\t: output_(nullptr), csi2_(nullptr), sensor_(nullptr)\n> +\t{\n> +\t}\n> +\n> +\t~CIO2Device()\n> +\t{\n> +\t\tdelete output_;\n> +\t\tdelete csi2_;\n> +\t\tdelete sensor_;\n> +\t}\n> +\n> +\tint init(const MediaDevice *media, unsigned int index);\n> +\tint configure(const Size &size, V4L2DeviceFormat *outputFormat);\n> +\n> +\tint allocateBuffers();\n> +\tvoid freeBuffers();\n> +\n> +\tFrameBuffer *getBuffer();\n> +\tvoid putBuffer(FrameBuffer *buffer);\n> +\n> +\tint start();\n> +\tint stop();\n> +\n> +\tstatic V4L2PixelFormat mediaBusToFormat(unsigned int code);\n\nSame here\n\nThat apart, I like this patch\nReviewed-by: Jacopo Mondi <jacopo@jmondi.org>\n\nThanks\n  j\n\n> +\n> +\tV4L2VideoDevice *output_;\n> +\tV4L2Subdevice *csi2_;\n> +\tCameraSensor *sensor_;\n> +\n> +private:\n> +\tstd::vector<std::unique_ptr<FrameBuffer>> buffers_;\n> +\tstd::queue<FrameBuffer *> availableBuffers_;\n> +};\n> +\n> +} /* namespace libcamera */\n> +\n> +#endif /* __LIBCAMERA_PIPELINE_IPU3_CIO2_H__ */\n> diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp\n> index f4759715c6ae7572..2047deac299dbf75 100644\n> --- a/src/libcamera/pipeline/ipu3/ipu3.cpp\n> +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp\n> @@ -27,6 +27,8 @@\n>  #include \"libcamera/internal/v4l2_subdevice.h\"\n>  #include \"libcamera/internal/v4l2_videodevice.h\"\n>\n> +#include \"cio2.h\"\n> +\n>  namespace libcamera {\n>\n>  LOG_DEFINE_CATEGORY(IPU3)\n> @@ -103,45 +105,6 @@ public:\n>  \t/* \\todo Add param video device for 3A tuning */\n>  };\n>\n> -class CIO2Device\n> -{\n> -public:\n> -\tstatic constexpr unsigned int CIO2_BUFFER_COUNT = 4;\n> -\n> -\tCIO2Device()\n> -\t\t: output_(nullptr), csi2_(nullptr), sensor_(nullptr)\n> -\t{\n> -\t}\n> -\n> -\t~CIO2Device()\n> -\t{\n> -\t\tdelete output_;\n> -\t\tdelete csi2_;\n> -\t\tdelete sensor_;\n> -\t}\n> -\n> -\tint init(const MediaDevice *media, unsigned int index);\n> -\tint configure(const Size &size,\n> -\t\t      V4L2DeviceFormat *outputFormat);\n> -\n> -\tint allocateBuffers();\n> -\tvoid freeBuffers();\n> -\n> -\tFrameBuffer *getBuffer();\n> -\tvoid putBuffer(FrameBuffer *buffer);\n> -\n> -\tint start();\n> -\tint stop();\n> -\n> -\tV4L2VideoDevice *output_;\n> -\tV4L2Subdevice *csi2_;\n> -\tCameraSensor *sensor_;\n> -\n> -private:\n> -\tstd::vector<std::unique_ptr<FrameBuffer>> buffers_;\n> -\tstd::queue<FrameBuffer *> availableBuffers_;\n> -};\n> -\n>  class IPU3Stream : public Stream\n>  {\n>  public:\n> @@ -1407,214 +1370,6 @@ int ImgUDevice::enableLinks(bool enable)\n>  \treturn linkSetup(name_, PAD_STAT, statName, 0, enable);\n>  }\n>\n> -/*------------------------------------------------------------------------------\n> - * CIO2 Device\n> - */\n> -\n> -/**\n> - * \\brief Initialize components of the CIO2 device with \\a index\n> - * \\param[in] media The CIO2 media device\n> - * \\param[in] index The CIO2 device index\n> - *\n> - * Create and open the video device and subdevices in the CIO2 instance at \\a\n> - * index, if a supported image sensor is connected to the CSI-2 receiver of\n> - * this CIO2 instance.  Enable the media links connecting the CIO2 components\n> - * to prepare for capture operations and cached the sensor maximum size.\n> - *\n> - * \\return 0 on success or a negative error code otherwise\n> - * \\retval -ENODEV No supported image sensor is connected to this CIO2 instance\n> - */\n> -int CIO2Device::init(const MediaDevice *media, unsigned int index)\n> -{\n> -\tint ret;\n> -\n> -\t/*\n> -\t * Verify that a sensor subdevice is connected to this CIO2 instance\n> -\t * and enable the media link between the two.\n> -\t */\n> -\tstd::string csi2Name = \"ipu3-csi2 \" + std::to_string(index);\n> -\tMediaEntity *csi2Entity = media->getEntityByName(csi2Name);\n> -\tconst std::vector<MediaPad *> &pads = csi2Entity->pads();\n> -\tif (pads.empty())\n> -\t\treturn -ENODEV;\n> -\n> -\t/* IPU3 CSI-2 receivers have a single sink pad at index 0. */\n> -\tMediaPad *sink = pads[0];\n> -\tconst std::vector<MediaLink *> &links = sink->links();\n> -\tif (links.empty())\n> -\t\treturn -ENODEV;\n> -\n> -\tMediaLink *link = links[0];\n> -\tMediaEntity *sensorEntity = link->source()->entity();\n> -\tsensor_ = new CameraSensor(sensorEntity);\n> -\tret = sensor_->init();\n> -\tif (ret)\n> -\t\treturn ret;\n> -\n> -\tret = link->setEnabled(true);\n> -\tif (ret)\n> -\t\treturn ret;\n> -\n> -\t/*\n> -\t * Make sure the sensor produces at least one format compatible with\n> -\t * the CIO2 requirements.\n> -\t *\n> -\t * utils::set_overlap requires the ranges to be sorted, keep the\n> -\t * cio2Codes vector sorted in ascending order.\n> -\t */\n> -\tconst std::vector<unsigned int> cio2Codes{ MEDIA_BUS_FMT_SBGGR10_1X10,\n> -\t\t\t\t\t\t   MEDIA_BUS_FMT_SGRBG10_1X10,\n> -\t\t\t\t\t\t   MEDIA_BUS_FMT_SGBRG10_1X10,\n> -\t\t\t\t\t\t   MEDIA_BUS_FMT_SRGGB10_1X10 };\n> -\tconst std::vector<unsigned int> &sensorCodes = sensor_->mbusCodes();\n> -\tif (!utils::set_overlap(sensorCodes.begin(), sensorCodes.end(),\n> -\t\t\t\tcio2Codes.begin(), cio2Codes.end())) {\n> -\t\tLOG(IPU3, Error)\n> -\t\t\t<< \"Sensor \" << sensor_->entity()->name()\n> -\t\t\t<< \" has not format compatible with the IPU3\";\n> -\t\treturn -EINVAL;\n> -\t}\n> -\n> -\t/*\n> -\t * \\todo Define when to open and close video device nodes, as they\n> -\t * might impact on power consumption.\n> -\t */\n> -\n> -\tcsi2_ = new V4L2Subdevice(csi2Entity);\n> -\tret = csi2_->open();\n> -\tif (ret)\n> -\t\treturn ret;\n> -\n> -\tstd::string cio2Name = \"ipu3-cio2 \" + std::to_string(index);\n> -\toutput_ = V4L2VideoDevice::fromEntityName(media, cio2Name);\n> -\tret = output_->open();\n> -\tif (ret)\n> -\t\treturn ret;\n> -\n> -\treturn 0;\n> -}\n> -\n> -/**\n> - * \\brief Configure the CIO2 unit\n> - * \\param[in] size The requested CIO2 output frame size\n> - * \\param[out] outputFormat The CIO2 unit output image format\n> - * \\return 0 on success or a negative error code otherwise\n> - */\n> -int CIO2Device::configure(const Size &size,\n> -\t\t\t  V4L2DeviceFormat *outputFormat)\n> -{\n> -\tV4L2SubdeviceFormat sensorFormat;\n> -\tint ret;\n> -\n> -\t/*\n> -\t * Apply the selected format to the sensor, the CSI-2 receiver and\n> -\t * the CIO2 output device.\n> -\t */\n> -\tsensorFormat = sensor_->getFormat({ MEDIA_BUS_FMT_SBGGR10_1X10,\n> -\t\t\t\t\t    MEDIA_BUS_FMT_SGBRG10_1X10,\n> -\t\t\t\t\t    MEDIA_BUS_FMT_SGRBG10_1X10,\n> -\t\t\t\t\t    MEDIA_BUS_FMT_SRGGB10_1X10 },\n> -\t\t\t\t\t  size);\n> -\tret = sensor_->setFormat(&sensorFormat);\n> -\tif (ret)\n> -\t\treturn ret;\n> -\n> -\tret = csi2_->setFormat(0, &sensorFormat);\n> -\tif (ret)\n> -\t\treturn ret;\n> -\n> -\tV4L2PixelFormat v4l2Format;\n> -\tswitch (sensorFormat.mbus_code) {\n> -\tcase MEDIA_BUS_FMT_SBGGR10_1X10:\n> -\t\tv4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_IPU3_SBGGR10);\n> -\t\tbreak;\n> -\tcase MEDIA_BUS_FMT_SGBRG10_1X10:\n> -\t\tv4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_IPU3_SGBRG10);\n> -\t\tbreak;\n> -\tcase MEDIA_BUS_FMT_SGRBG10_1X10:\n> -\t\tv4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_IPU3_SGRBG10);\n> -\t\tbreak;\n> -\tcase MEDIA_BUS_FMT_SRGGB10_1X10:\n> -\t\tv4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_IPU3_SRGGB10);\n> -\t\tbreak;\n> -\tdefault:\n> -\t\treturn -EINVAL;\n> -\t}\n> -\n> -\toutputFormat->fourcc = v4l2Format;\n> -\toutputFormat->size = sensorFormat.size;\n> -\toutputFormat->planesCount = 1;\n> -\n> -\tret = output_->setFormat(outputFormat);\n> -\tif (ret)\n> -\t\treturn ret;\n> -\n> -\tLOG(IPU3, Debug) << \"CIO2 output format \" << outputFormat->toString();\n> -\n> -\treturn 0;\n> -}\n> -\n> -/**\n> - * \\brief Allocate frame buffers for the CIO2 output\n> - *\n> - * Allocate frame buffers in the CIO2 video device to be used to capture frames\n> - * from the CIO2 output. The buffers are stored in the CIO2Device::buffers_\n> - * vector.\n> - *\n> - * \\return Number of buffers allocated or negative error code\n> - */\n> -int CIO2Device::allocateBuffers()\n> -{\n> -\tint ret = output_->allocateBuffers(CIO2_BUFFER_COUNT, &buffers_);\n> -\tif (ret < 0)\n> -\t\treturn ret;\n> -\n> -\tfor (std::unique_ptr<FrameBuffer> &buffer : buffers_)\n> -\t\tavailableBuffers_.push(buffer.get());\n> -\n> -\treturn ret;\n> -}\n> -\n> -void CIO2Device::freeBuffers()\n> -{\n> -\t/* The default std::queue constructor is explicit with gcc 5 and 6. */\n> -\tavailableBuffers_ = std::queue<FrameBuffer *>{};\n> -\n> -\tbuffers_.clear();\n> -\n> -\tif (output_->releaseBuffers())\n> -\t\tLOG(IPU3, Error) << \"Failed to release CIO2 buffers\";\n> -}\n> -\n> -FrameBuffer *CIO2Device::getBuffer()\n> -{\n> -\tif (availableBuffers_.empty()) {\n> -\t\tLOG(IPU3, Error) << \"CIO2 buffer underrun\";\n> -\t\treturn nullptr;\n> -\t}\n> -\n> -\tFrameBuffer *buffer = availableBuffers_.front();\n> -\n> -\tavailableBuffers_.pop();\n> -\n> -\treturn buffer;\n> -}\n> -\n> -void CIO2Device::putBuffer(FrameBuffer *buffer)\n> -{\n> -\tavailableBuffers_.push(buffer);\n> -}\n> -\n> -int CIO2Device::start()\n> -{\n> -\treturn output_->streamOn();\n> -}\n> -\n> -int CIO2Device::stop()\n> -{\n> -\treturn output_->streamOff();\n> -}\n> -\n>  REGISTER_PIPELINE_HANDLER(PipelineHandlerIPU3);\n>\n>  } /* namespace libcamera */\n> diff --git a/src/libcamera/pipeline/ipu3/meson.build b/src/libcamera/pipeline/ipu3/meson.build\n> index 0e8c5a14f2b3317b..b2602d30123f908d 100644\n> --- a/src/libcamera/pipeline/ipu3/meson.build\n> +++ b/src/libcamera/pipeline/ipu3/meson.build\n> @@ -1,5 +1,6 @@\n>  # SPDX-License-Identifier: CC0-1.0\n>\n>  libcamera_sources += files([\n> +    'cio2.cpp',\n>      'ipu3.cpp',\n>  ])\n> --\n> 2.26.2\n>\n> _______________________________________________\n> libcamera-devel mailing list\n> libcamera-devel@lists.libcamera.org\n> https://lists.libcamera.org/listinfo/libcamera-devel","headers":{"Return-Path":"<jacopo@jmondi.org>","Received":["from relay9-d.mail.gandi.net (relay9-d.mail.gandi.net\n\t[217.70.183.199])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 6EC14603CB\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue,  2 Jun 2020 13:46:42 +0200 (CEST)","from uno.localdomain (2-224-242-101.ip172.fastwebnet.it\n\t[2.224.242.101]) (Authenticated sender: jacopo@jmondi.org)\n\tby relay9-d.mail.gandi.net (Postfix) with ESMTPSA id C3AEAFF80F;\n\tTue,  2 Jun 2020 11:46:41 +0000 (UTC)"],"X-Originating-IP":"2.224.242.101","Date":"Tue, 2 Jun 2020 13:50:03 +0200","From":"Jacopo Mondi <jacopo@jmondi.org>","To":"Niklas =?utf-8?q?S=C3=B6derlund?= <niklas.soderlund@ragnatech.se>","Cc":"libcamera-devel@lists.libcamera.org","Message-ID":"<20200602115003.rig4ibmtdrwtyxjq@uno.localdomain>","References":"<20200602013909.3170593-1-niklas.soderlund@ragnatech.se>\n\t<20200602013909.3170593-7-niklas.soderlund@ragnatech.se>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","Content-Transfer-Encoding":"8bit","In-Reply-To":"<20200602013909.3170593-7-niklas.soderlund@ragnatech.se>","Subject":"Re: [libcamera-devel] [PATCH 06/10] libcamera: ipu3: cio2: Move the\n\tCIO2Device class to separate files","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","X-List-Received-Date":"Tue, 02 Jun 2020 11:46:42 -0000"}},{"id":5003,"web_url":"https://patchwork.libcamera.org/comment/5003/","msgid":"<20200604031246.GP27695@pendragon.ideasonboard.com>","date":"2020-06-04T03:12:46","subject":"Re: [libcamera-devel] [PATCH 06/10] libcamera: ipu3: cio2: Move the\n\tCIO2Device class to separate files","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Niklas,\n\nThank you for the patch.\n\nOn Tue, Jun 02, 2020 at 03:39:05AM +0200, Niklas Söderlund wrote:\n> In preparation of refactoring the IPU3 pipeline handler breakout the\n> CIO2Device into its own .cpp and .h file, no functional change.\n> \n> Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>\n> ---\n>  src/libcamera/pipeline/ipu3/cio2.cpp    | 233 ++++++++++++++++++++++\n>  src/libcamera/pipeline/ipu3/cio2.h      |  64 ++++++\n>  src/libcamera/pipeline/ipu3/ipu3.cpp    | 249 +-----------------------\n>  src/libcamera/pipeline/ipu3/meson.build |   1 +\n>  4 files changed, 300 insertions(+), 247 deletions(-)\n>  create mode 100644 src/libcamera/pipeline/ipu3/cio2.cpp\n>  create mode 100644 src/libcamera/pipeline/ipu3/cio2.h\n> \n> diff --git a/src/libcamera/pipeline/ipu3/cio2.cpp b/src/libcamera/pipeline/ipu3/cio2.cpp\n> new file mode 100644\n> index 0000000000000000..113486e3e3d0f2f1\n> --- /dev/null\n> +++ b/src/libcamera/pipeline/ipu3/cio2.cpp\n> @@ -0,0 +1,233 @@\n> +/* SPDX-License-Identifier: LGPL-2.1-or-later */\n> +/*\n> + * Copyright (C) 2020, Google Inc.\n\nTechnically, shouldn't this still be 2019 ?\n\n> + *\n> + * cio2.cpp - Intel IPU3 CIO2\n> + */\n> +\n> +#include \"cio2.h\"\n\n#include \"libcamera/internal/log.h\"\n\nAnd other headers, as required, after using forward declarations in the\ncio2.h header.\n\n> +\n> +namespace libcamera {\n> +\n> +LOG_DECLARE_CATEGORY(IPU3)\n> +\n> +/**\n> + * \\brief Initialize components of the CIO2 device with \\a index\n> + * \\param[in] media The CIO2 media device\n> + * \\param[in] index The CIO2 device index\n> + *\n> + * Create and open the video device and subdevices in the CIO2 instance at \\a\n> + * index, if a supported image sensor is connected to the CSI-2 receiver of\n> + * this CIO2 instance.  Enable the media links connecting the CIO2 components\n> + * to prepare for capture operations and cached the sensor maximum size.\n> + *\n> + * \\return 0 on success or a negative error code otherwise\n> + * \\retval -ENODEV No supported image sensor is connected to this CIO2 instance\n> + */\n> +int CIO2Device::init(const MediaDevice *media, unsigned int index)\n> +{\n> +\tint ret;\n> +\n> +\t/*\n> +\t * Verify that a sensor subdevice is connected to this CIO2 instance\n> +\t * and enable the media link between the two.\n> +\t */\n> +\tstd::string csi2Name = \"ipu3-csi2 \" + std::to_string(index);\n> +\tMediaEntity *csi2Entity = media->getEntityByName(csi2Name);\n> +\tconst std::vector<MediaPad *> &pads = csi2Entity->pads();\n> +\tif (pads.empty())\n> +\t\treturn -ENODEV;\n> +\n> +\t/* IPU3 CSI-2 receivers have a single sink pad at index 0. */\n> +\tMediaPad *sink = pads[0];\n> +\tconst std::vector<MediaLink *> &links = sink->links();\n> +\tif (links.empty())\n> +\t\treturn -ENODEV;\n> +\n> +\tMediaLink *link = links[0];\n> +\tMediaEntity *sensorEntity = link->source()->entity();\n> +\tsensor_ = new CameraSensor(sensorEntity);\n> +\tret = sensor_->init();\n> +\tif (ret)\n> +\t\treturn ret;\n> +\n> +\tret = link->setEnabled(true);\n> +\tif (ret)\n> +\t\treturn ret;\n> +\n> +\t/*\n> +\t * Make sure the sensor produces at least one format compatible with\n> +\t * the CIO2 requirements.\n> +\t *\n> +\t * utils::set_overlap requires the ranges to be sorted, keep the\n> +\t * cio2Codes vector sorted in ascending order.\n> +\t */\n> +\tconst std::vector<unsigned int> cio2Codes{ MEDIA_BUS_FMT_SBGGR10_1X10,\n> +\t\t\t\t\t\t   MEDIA_BUS_FMT_SGRBG10_1X10,\n> +\t\t\t\t\t\t   MEDIA_BUS_FMT_SGBRG10_1X10,\n> +\t\t\t\t\t\t   MEDIA_BUS_FMT_SRGGB10_1X10 };\n> +\tconst std::vector<unsigned int> &sensorCodes = sensor_->mbusCodes();\n> +\tif (!utils::set_overlap(sensorCodes.begin(), sensorCodes.end(),\n> +\t\t\t\tcio2Codes.begin(), cio2Codes.end())) {\n> +\t\tLOG(IPU3, Error)\n> +\t\t\t<< \"Sensor \" << sensor_->entity()->name()\n> +\t\t\t<< \" has not format compatible with the IPU3\";\n> +\t\treturn -EINVAL;\n> +\t}\n> +\n> +\t/*\n> +\t * \\todo Define when to open and close video device nodes, as they\n> +\t * might impact on power consumption.\n> +\t */\n> +\n> +\tcsi2_ = new V4L2Subdevice(csi2Entity);\n> +\tret = csi2_->open();\n> +\tif (ret)\n> +\t\treturn ret;\n> +\n> +\tstd::string cio2Name = \"ipu3-cio2 \" + std::to_string(index);\n> +\toutput_ = V4L2VideoDevice::fromEntityName(media, cio2Name);\n> +\tret = output_->open();\n> +\tif (ret)\n> +\t\treturn ret;\n> +\n> +\treturn 0;\n> +}\n> +\n> +/**\n> + * \\brief Configure the CIO2 unit\n> + * \\param[in] size The requested CIO2 output frame size\n> + * \\param[out] outputFormat The CIO2 unit output image format\n> + * \\return 0 on success or a negative error code otherwise\n> + */\n> +int CIO2Device::configure(const Size &size, V4L2DeviceFormat *outputFormat)\n> +{\n> +\tV4L2SubdeviceFormat sensorFormat;\n> +\tint ret;\n> +\n> +\t/*\n> +\t * Apply the selected format to the sensor, the CSI-2 receiver and\n> +\t * the CIO2 output device.\n> +\t */\n> +\tsensorFormat = sensor_->getFormat({ MEDIA_BUS_FMT_SBGGR10_1X10,\n> +\t\t\t\t\t    MEDIA_BUS_FMT_SGBRG10_1X10,\n> +\t\t\t\t\t    MEDIA_BUS_FMT_SGRBG10_1X10,\n> +\t\t\t\t\t    MEDIA_BUS_FMT_SRGGB10_1X10 },\n> +\t\t\t\t\t  size);\n> +\tret = sensor_->setFormat(&sensorFormat);\n> +\tif (ret)\n> +\t\treturn ret;\n> +\n> +\tret = csi2_->setFormat(0, &sensorFormat);\n> +\tif (ret)\n> +\t\treturn ret;\n> +\n> +\tV4L2PixelFormat v4l2Format;\n> +\tswitch (sensorFormat.mbus_code) {\n> +\tcase MEDIA_BUS_FMT_SBGGR10_1X10:\n> +\t\tv4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_IPU3_SBGGR10);\n> +\t\tbreak;\n> +\tcase MEDIA_BUS_FMT_SGBRG10_1X10:\n> +\t\tv4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_IPU3_SGBRG10);\n> +\t\tbreak;\n> +\tcase MEDIA_BUS_FMT_SGRBG10_1X10:\n> +\t\tv4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_IPU3_SGRBG10);\n> +\t\tbreak;\n> +\tcase MEDIA_BUS_FMT_SRGGB10_1X10:\n> +\t\tv4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_IPU3_SRGGB10);\n> +\t\tbreak;\n> +\tdefault:\n> +\t\treturn -EINVAL;\n> +\t}\n> +\n> +\toutputFormat->fourcc = v4l2Format;\n> +\toutputFormat->size = sensorFormat.size;\n> +\toutputFormat->planesCount = 1;\n> +\n> +\tret = output_->setFormat(outputFormat);\n> +\tif (ret)\n> +\t\treturn ret;\n> +\n> +\tLOG(IPU3, Debug) << \"CIO2 output format \" << outputFormat->toString();\n> +\n> +\treturn 0;\n> +}\n> +\n> +/**\n> + * \\brief Allocate frame buffers for the CIO2 output\n> + *\n> + * Allocate frame buffers in the CIO2 video device to be used to capture frames\n> + * from the CIO2 output. The buffers are stored in the CIO2Device::buffers_\n> + * vector.\n> + *\n> + * \\return Number of buffers allocated or negative error code\n> + */\n> +int CIO2Device::allocateBuffers()\n> +{\n> +\tint ret = output_->allocateBuffers(CIO2_BUFFER_COUNT, &buffers_);\n> +\tif (ret < 0)\n> +\t\treturn ret;\n> +\n> +\tfor (std::unique_ptr<FrameBuffer> &buffer : buffers_)\n> +\t\tavailableBuffers_.push(buffer.get());\n> +\n> +\treturn ret;\n> +}\n> +\n> +void CIO2Device::freeBuffers()\n> +{\n> +\t/* The default std::queue constructor is explicit with gcc 5 and 6. */\n> +\tavailableBuffers_ = std::queue<FrameBuffer *>{};\n> +\n> +\tbuffers_.clear();\n> +\n> +\tif (output_->releaseBuffers())\n> +\t\tLOG(IPU3, Error) << \"Failed to release CIO2 buffers\";\n> +}\n> +\n> +FrameBuffer *CIO2Device::getBuffer()\n> +{\n> +\tif (availableBuffers_.empty()) {\n> +\t\tLOG(IPU3, Error) << \"CIO2 buffer underrun\";\n> +\t\treturn nullptr;\n> +\t}\n> +\n> +\tFrameBuffer *buffer = availableBuffers_.front();\n> +\n> +\tavailableBuffers_.pop();\n> +\n> +\treturn buffer;\n> +}\n> +\n> +void CIO2Device::putBuffer(FrameBuffer *buffer)\n> +{\n> +\tavailableBuffers_.push(buffer);\n> +}\n> +\n> +int CIO2Device::start()\n> +{\n> +\treturn output_->streamOn();\n> +}\n> +\n> +int CIO2Device::stop()\n> +{\n> +\treturn output_->streamOff();\n> +}\n> +\n> +V4L2PixelFormat CIO2Device::mediaBusToFormat(unsigned int code)\n> +{\n> +\tswitch (code) {\n> +\tcase MEDIA_BUS_FMT_SBGGR10_1X10:\n> +\t\treturn V4L2PixelFormat(V4L2_PIX_FMT_IPU3_SBGGR10);\n> +\tcase MEDIA_BUS_FMT_SGBRG10_1X10:\n> +\t\treturn V4L2PixelFormat(V4L2_PIX_FMT_IPU3_SGBRG10);\n> +\tcase MEDIA_BUS_FMT_SGRBG10_1X10:\n> +\t\treturn V4L2PixelFormat(V4L2_PIX_FMT_IPU3_SGRBG10);\n> +\tcase MEDIA_BUS_FMT_SRGGB10_1X10:\n> +\t\treturn V4L2PixelFormat(V4L2_PIX_FMT_IPU3_SRGGB10);\n> +\tdefault:\n> +\t\treturn {};\n> +\t}\n> +}\n\nAs Jacopo pointed out, you have dropped this in an earlier patch.\n\n> +\n> +} /* namespace libcamera */\n> diff --git a/src/libcamera/pipeline/ipu3/cio2.h b/src/libcamera/pipeline/ipu3/cio2.h\n> new file mode 100644\n> index 0000000000000000..d923038bb4ba356f\n> --- /dev/null\n> +++ b/src/libcamera/pipeline/ipu3/cio2.h\n> @@ -0,0 +1,64 @@\n> +/* SPDX-License-Identifier: LGPL-2.1-or-later */\n> +/*\n> + * Copyright (C) 2020, Google Inc.\n> + *\n> + * cio2.h - Intel IPU3 CIO2\n> + */\n> +#ifndef __LIBCAMERA_PIPELINE_IPU3_CIO2_H__\n> +#define __LIBCAMERA_PIPELINE_IPU3_CIO2_H__\n> +\n> +#include <queue>\n> +#include <vector>\n> +\n> +#include <linux/media-bus-format.h>\n\nThis header doesn't seem to be needed here.\n\n> +\n> +#include \"libcamera/internal/camera_sensor.h\"\n> +#include \"libcamera/internal/media_device.h\"\n> +#include \"libcamera/internal/v4l2_subdevice.h\"\n> +#include \"libcamera/internal/v4l2_videodevice.h\"\n\nCould we drop all these and use forward declarations instead ?\n\n> +\n> +namespace libcamera {\n> +\n> +class CIO2Device\n> +{\n> +public:\n> +\tstatic constexpr unsigned int CIO2_BUFFER_COUNT = 4;\n> +\n> +\tCIO2Device()\n> +\t\t: output_(nullptr), csi2_(nullptr), sensor_(nullptr)\n> +\t{\n> +\t}\n> +\n> +\t~CIO2Device()\n> +\t{\n> +\t\tdelete output_;\n> +\t\tdelete csi2_;\n> +\t\tdelete sensor_;\n> +\t}\n> +\n> +\tint init(const MediaDevice *media, unsigned int index);\n> +\tint configure(const Size &size, V4L2DeviceFormat *outputFormat);\n> +\n> +\tint allocateBuffers();\n> +\tvoid freeBuffers();\n> +\n> +\tFrameBuffer *getBuffer();\n> +\tvoid putBuffer(FrameBuffer *buffer);\n> +\n> +\tint start();\n> +\tint stop();\n> +\n> +\tstatic V4L2PixelFormat mediaBusToFormat(unsigned int code);\n> +\n> +\tV4L2VideoDevice *output_;\n> +\tV4L2Subdevice *csi2_;\n> +\tCameraSensor *sensor_;\n> +\n> +private:\n> +\tstd::vector<std::unique_ptr<FrameBuffer>> buffers_;\n> +\tstd::queue<FrameBuffer *> availableBuffers_;\n> +};\n> +\n> +} /* namespace libcamera */\n> +\n> +#endif /* __LIBCAMERA_PIPELINE_IPU3_CIO2_H__ */\n> diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp\n> index f4759715c6ae7572..2047deac299dbf75 100644\n> --- a/src/libcamera/pipeline/ipu3/ipu3.cpp\n> +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp\n> @@ -27,6 +27,8 @@\n>  #include \"libcamera/internal/v4l2_subdevice.h\"\n>  #include \"libcamera/internal/v4l2_videodevice.h\"\n>  \n> +#include \"cio2.h\"\n> +\n>  namespace libcamera {\n>  \n>  LOG_DEFINE_CATEGORY(IPU3)\n> @@ -103,45 +105,6 @@ public:\n>  \t/* \\todo Add param video device for 3A tuning */\n>  };\n>  \n> -class CIO2Device\n> -{\n> -public:\n> -\tstatic constexpr unsigned int CIO2_BUFFER_COUNT = 4;\n> -\n> -\tCIO2Device()\n> -\t\t: output_(nullptr), csi2_(nullptr), sensor_(nullptr)\n> -\t{\n> -\t}\n> -\n> -\t~CIO2Device()\n> -\t{\n> -\t\tdelete output_;\n> -\t\tdelete csi2_;\n> -\t\tdelete sensor_;\n> -\t}\n> -\n> -\tint init(const MediaDevice *media, unsigned int index);\n> -\tint configure(const Size &size,\n> -\t\t      V4L2DeviceFormat *outputFormat);\n> -\n> -\tint allocateBuffers();\n> -\tvoid freeBuffers();\n> -\n> -\tFrameBuffer *getBuffer();\n> -\tvoid putBuffer(FrameBuffer *buffer);\n> -\n> -\tint start();\n> -\tint stop();\n> -\n> -\tV4L2VideoDevice *output_;\n> -\tV4L2Subdevice *csi2_;\n> -\tCameraSensor *sensor_;\n> -\n> -private:\n> -\tstd::vector<std::unique_ptr<FrameBuffer>> buffers_;\n> -\tstd::queue<FrameBuffer *> availableBuffers_;\n> -};\n> -\n>  class IPU3Stream : public Stream\n>  {\n>  public:\n> @@ -1407,214 +1370,6 @@ int ImgUDevice::enableLinks(bool enable)\n>  \treturn linkSetup(name_, PAD_STAT, statName, 0, enable);\n>  }\n>  \n> -/*------------------------------------------------------------------------------\n> - * CIO2 Device\n> - */\n> -\n> -/**\n> - * \\brief Initialize components of the CIO2 device with \\a index\n> - * \\param[in] media The CIO2 media device\n> - * \\param[in] index The CIO2 device index\n> - *\n> - * Create and open the video device and subdevices in the CIO2 instance at \\a\n> - * index, if a supported image sensor is connected to the CSI-2 receiver of\n> - * this CIO2 instance.  Enable the media links connecting the CIO2 components\n> - * to prepare for capture operations and cached the sensor maximum size.\n> - *\n> - * \\return 0 on success or a negative error code otherwise\n> - * \\retval -ENODEV No supported image sensor is connected to this CIO2 instance\n> - */\n> -int CIO2Device::init(const MediaDevice *media, unsigned int index)\n> -{\n> -\tint ret;\n> -\n> -\t/*\n> -\t * Verify that a sensor subdevice is connected to this CIO2 instance\n> -\t * and enable the media link between the two.\n> -\t */\n> -\tstd::string csi2Name = \"ipu3-csi2 \" + std::to_string(index);\n> -\tMediaEntity *csi2Entity = media->getEntityByName(csi2Name);\n> -\tconst std::vector<MediaPad *> &pads = csi2Entity->pads();\n> -\tif (pads.empty())\n> -\t\treturn -ENODEV;\n> -\n> -\t/* IPU3 CSI-2 receivers have a single sink pad at index 0. */\n> -\tMediaPad *sink = pads[0];\n> -\tconst std::vector<MediaLink *> &links = sink->links();\n> -\tif (links.empty())\n> -\t\treturn -ENODEV;\n> -\n> -\tMediaLink *link = links[0];\n> -\tMediaEntity *sensorEntity = link->source()->entity();\n> -\tsensor_ = new CameraSensor(sensorEntity);\n> -\tret = sensor_->init();\n> -\tif (ret)\n> -\t\treturn ret;\n> -\n> -\tret = link->setEnabled(true);\n> -\tif (ret)\n> -\t\treturn ret;\n> -\n> -\t/*\n> -\t * Make sure the sensor produces at least one format compatible with\n> -\t * the CIO2 requirements.\n> -\t *\n> -\t * utils::set_overlap requires the ranges to be sorted, keep the\n> -\t * cio2Codes vector sorted in ascending order.\n> -\t */\n> -\tconst std::vector<unsigned int> cio2Codes{ MEDIA_BUS_FMT_SBGGR10_1X10,\n> -\t\t\t\t\t\t   MEDIA_BUS_FMT_SGRBG10_1X10,\n> -\t\t\t\t\t\t   MEDIA_BUS_FMT_SGBRG10_1X10,\n> -\t\t\t\t\t\t   MEDIA_BUS_FMT_SRGGB10_1X10 };\n> -\tconst std::vector<unsigned int> &sensorCodes = sensor_->mbusCodes();\n> -\tif (!utils::set_overlap(sensorCodes.begin(), sensorCodes.end(),\n> -\t\t\t\tcio2Codes.begin(), cio2Codes.end())) {\n> -\t\tLOG(IPU3, Error)\n> -\t\t\t<< \"Sensor \" << sensor_->entity()->name()\n> -\t\t\t<< \" has not format compatible with the IPU3\";\n> -\t\treturn -EINVAL;\n> -\t}\n> -\n> -\t/*\n> -\t * \\todo Define when to open and close video device nodes, as they\n> -\t * might impact on power consumption.\n> -\t */\n> -\n> -\tcsi2_ = new V4L2Subdevice(csi2Entity);\n> -\tret = csi2_->open();\n> -\tif (ret)\n> -\t\treturn ret;\n> -\n> -\tstd::string cio2Name = \"ipu3-cio2 \" + std::to_string(index);\n> -\toutput_ = V4L2VideoDevice::fromEntityName(media, cio2Name);\n> -\tret = output_->open();\n> -\tif (ret)\n> -\t\treturn ret;\n> -\n> -\treturn 0;\n> -}\n> -\n> -/**\n> - * \\brief Configure the CIO2 unit\n> - * \\param[in] size The requested CIO2 output frame size\n> - * \\param[out] outputFormat The CIO2 unit output image format\n> - * \\return 0 on success or a negative error code otherwise\n> - */\n> -int CIO2Device::configure(const Size &size,\n> -\t\t\t  V4L2DeviceFormat *outputFormat)\n> -{\n> -\tV4L2SubdeviceFormat sensorFormat;\n> -\tint ret;\n> -\n> -\t/*\n> -\t * Apply the selected format to the sensor, the CSI-2 receiver and\n> -\t * the CIO2 output device.\n> -\t */\n> -\tsensorFormat = sensor_->getFormat({ MEDIA_BUS_FMT_SBGGR10_1X10,\n> -\t\t\t\t\t    MEDIA_BUS_FMT_SGBRG10_1X10,\n> -\t\t\t\t\t    MEDIA_BUS_FMT_SGRBG10_1X10,\n> -\t\t\t\t\t    MEDIA_BUS_FMT_SRGGB10_1X10 },\n> -\t\t\t\t\t  size);\n> -\tret = sensor_->setFormat(&sensorFormat);\n> -\tif (ret)\n> -\t\treturn ret;\n> -\n> -\tret = csi2_->setFormat(0, &sensorFormat);\n> -\tif (ret)\n> -\t\treturn ret;\n> -\n> -\tV4L2PixelFormat v4l2Format;\n> -\tswitch (sensorFormat.mbus_code) {\n> -\tcase MEDIA_BUS_FMT_SBGGR10_1X10:\n> -\t\tv4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_IPU3_SBGGR10);\n> -\t\tbreak;\n> -\tcase MEDIA_BUS_FMT_SGBRG10_1X10:\n> -\t\tv4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_IPU3_SGBRG10);\n> -\t\tbreak;\n> -\tcase MEDIA_BUS_FMT_SGRBG10_1X10:\n> -\t\tv4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_IPU3_SGRBG10);\n> -\t\tbreak;\n> -\tcase MEDIA_BUS_FMT_SRGGB10_1X10:\n> -\t\tv4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_IPU3_SRGGB10);\n> -\t\tbreak;\n> -\tdefault:\n> -\t\treturn -EINVAL;\n> -\t}\n> -\n> -\toutputFormat->fourcc = v4l2Format;\n> -\toutputFormat->size = sensorFormat.size;\n> -\toutputFormat->planesCount = 1;\n> -\n> -\tret = output_->setFormat(outputFormat);\n> -\tif (ret)\n> -\t\treturn ret;\n> -\n> -\tLOG(IPU3, Debug) << \"CIO2 output format \" << outputFormat->toString();\n> -\n> -\treturn 0;\n> -}\n> -\n> -/**\n> - * \\brief Allocate frame buffers for the CIO2 output\n> - *\n> - * Allocate frame buffers in the CIO2 video device to be used to capture frames\n> - * from the CIO2 output. The buffers are stored in the CIO2Device::buffers_\n> - * vector.\n> - *\n> - * \\return Number of buffers allocated or negative error code\n> - */\n> -int CIO2Device::allocateBuffers()\n> -{\n> -\tint ret = output_->allocateBuffers(CIO2_BUFFER_COUNT, &buffers_);\n> -\tif (ret < 0)\n> -\t\treturn ret;\n> -\n> -\tfor (std::unique_ptr<FrameBuffer> &buffer : buffers_)\n> -\t\tavailableBuffers_.push(buffer.get());\n> -\n> -\treturn ret;\n> -}\n> -\n> -void CIO2Device::freeBuffers()\n> -{\n> -\t/* The default std::queue constructor is explicit with gcc 5 and 6. */\n> -\tavailableBuffers_ = std::queue<FrameBuffer *>{};\n> -\n> -\tbuffers_.clear();\n> -\n> -\tif (output_->releaseBuffers())\n> -\t\tLOG(IPU3, Error) << \"Failed to release CIO2 buffers\";\n> -}\n> -\n> -FrameBuffer *CIO2Device::getBuffer()\n> -{\n> -\tif (availableBuffers_.empty()) {\n> -\t\tLOG(IPU3, Error) << \"CIO2 buffer underrun\";\n> -\t\treturn nullptr;\n> -\t}\n> -\n> -\tFrameBuffer *buffer = availableBuffers_.front();\n> -\n> -\tavailableBuffers_.pop();\n> -\n> -\treturn buffer;\n> -}\n> -\n> -void CIO2Device::putBuffer(FrameBuffer *buffer)\n> -{\n> -\tavailableBuffers_.push(buffer);\n> -}\n> -\n> -int CIO2Device::start()\n> -{\n> -\treturn output_->streamOn();\n> -}\n> -\n> -int CIO2Device::stop()\n> -{\n> -\treturn output_->streamOff();\n> -}\n> -\n>  REGISTER_PIPELINE_HANDLER(PipelineHandlerIPU3);\n>  \n>  } /* namespace libcamera */\n> diff --git a/src/libcamera/pipeline/ipu3/meson.build b/src/libcamera/pipeline/ipu3/meson.build\n> index 0e8c5a14f2b3317b..b2602d30123f908d 100644\n> --- a/src/libcamera/pipeline/ipu3/meson.build\n> +++ b/src/libcamera/pipeline/ipu3/meson.build\n> @@ -1,5 +1,6 @@\n>  # SPDX-License-Identifier: CC0-1.0\n>  \n>  libcamera_sources += files([\n> +    'cio2.cpp',\n>      'ipu3.cpp',\n>  ])\n\nI really like this.\n\nReviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>","headers":{"Return-Path":"<laurent.pinchart@ideasonboard.com>","Received":["from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id D5A7061012\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu,  4 Jun 2020 05:13:02 +0200 (CEST)","from pendragon.ideasonboard.com (81-175-216-236.bb.dnainternet.fi\n\t[81.175.216.236])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 54E2429B;\n\tThu,  4 Jun 2020 05:13:02 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=ideasonboard.com\n\theader.i=@ideasonboard.com\n\theader.b=\"mvw87nQS\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1591240382;\n\tbh=M9CwoRwH0MgmR+YtsesWxSio13Y1bpH93SIpZpFBERc=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=mvw87nQSJwHUabMujz5qrCCBgbSa9tfWq9JiqKO4Wtc5YqElIpdyUVFwxGCUvggdU\n\t3V9I1S/uxZWwKx5ja+XMhqb5yyC0XVC7c7KsHYfoeYWrFPckI4JTxAj3hG3OWddmyy\n\tL4eSYLIKt7d0xrx8fqWdQ4h6KXjuWMMyKJFkNcmw=","Date":"Thu, 4 Jun 2020 06:12:46 +0300","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Niklas =?utf-8?q?S=C3=B6derlund?= <niklas.soderlund@ragnatech.se>","Cc":"libcamera-devel@lists.libcamera.org","Message-ID":"<20200604031246.GP27695@pendragon.ideasonboard.com>","References":"<20200602013909.3170593-1-niklas.soderlund@ragnatech.se>\n\t<20200602013909.3170593-7-niklas.soderlund@ragnatech.se>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","Content-Transfer-Encoding":"8bit","In-Reply-To":"<20200602013909.3170593-7-niklas.soderlund@ragnatech.se>","Subject":"Re: [libcamera-devel] [PATCH 06/10] libcamera: ipu3: cio2: Move the\n\tCIO2Device class to separate files","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","X-List-Received-Date":"Thu, 04 Jun 2020 03:13:03 -0000"}}]