[{"id":459,"web_url":"https://patchwork.libcamera.org/comment/459/","msgid":"<20190121202317.GC4439@pendragon.ideasonboard.com>","date":"2019-01-21T20:23:17","subject":"Re: [libcamera-devel] [PATCH v4 1/2] libcamera: pipeline: Add Intel\n\tIPU3 pipeline","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Jacopo,\n\nThank you for the patch.\n\nOn Mon, Jan 21, 2019 at 04:07:55PM +0100, Jacopo Mondi wrote:\n> Add a pipeline handler for the Intel IPU3 device.\n> \n> The pipeline handler creates a Camera for each image sensor it finds to be\n> connected to an IPU3 CSI-2 receiver, and enables the link between the two.\n> \n> Tested on Soraka, listing detected cameras on the system, verifying the\n> pipeline handler gets matched and links properly enabled.\n> \n> Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>\n\nReviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n\n> ---\n>  src/libcamera/pipeline/ipu3/ipu3.cpp    | 185 ++++++++++++++++++++++++\n>  src/libcamera/pipeline/ipu3/meson.build |   3 +\n>  src/libcamera/pipeline/meson.build      |   2 +\n>  3 files changed, 190 insertions(+)\n>  create mode 100644 src/libcamera/pipeline/ipu3/ipu3.cpp\n>  create mode 100644 src/libcamera/pipeline/ipu3/meson.build\n> \n> diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp\n> new file mode 100644\n> index 0000000..daf681c\n> --- /dev/null\n> +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp\n> @@ -0,0 +1,185 @@\n> +/* SPDX-License-Identifier: LGPL-2.1-or-later */\n> +/*\n> + * Copyright (C) 2019, Google Inc.\n> + *\n> + * ipu3.cpp - Pipeline handler for Intel IPU3\n> + */\n> +\n> +#include <memory>\n> +#include <vector>\n> +\n> +#include <libcamera/camera.h>\n> +#include <libcamera/camera_manager.h>\n> +\n> +#include \"device_enumerator.h\"\n> +#include \"log.h\"\n> +#include \"media_device.h\"\n> +#include \"pipeline_handler.h\"\n> +\n> +namespace libcamera {\n> +\n> +class PipelineHandlerIPU3 : public PipelineHandler\n> +{\n> +public:\n> +\tPipelineHandlerIPU3();\n> +\t~PipelineHandlerIPU3();\n> +\n> +\tbool match(CameraManager *manager, DeviceEnumerator *enumerator);\n> +\n> +private:\n> +\tMediaDevice *cio2_;\n> +\tMediaDevice *imgu_;\n> +\n> +\tvoid registerCameras(CameraManager *manager);\n> +};\n> +\n> +PipelineHandlerIPU3::PipelineHandlerIPU3()\n> +\t: cio2_(nullptr), imgu_(nullptr)\n> +{\n> +}\n> +\n> +PipelineHandlerIPU3::~PipelineHandlerIPU3()\n> +{\n> +\tif (cio2_)\n> +\t\tcio2_->release();\n> +\n> +\tif (imgu_)\n> +\t\timgu_->release();\n> +\n> +\tcio2_ = nullptr;\n> +\timgu_ = nullptr;\n> +}\n> +\n> +bool PipelineHandlerIPU3::match(CameraManager *manager, DeviceEnumerator *enumerator)\n> +{\n> +\tDeviceMatch cio2_dm(\"ipu3-cio2\");\n> +\tcio2_dm.add(\"ipu3-csi2 0\");\n> +\tcio2_dm.add(\"ipu3-cio2 0\");\n> +\tcio2_dm.add(\"ipu3-csi2 1\");\n> +\tcio2_dm.add(\"ipu3-cio2 1\");\n> +\tcio2_dm.add(\"ipu3-csi2 2\");\n> +\tcio2_dm.add(\"ipu3-cio2 2\");\n> +\tcio2_dm.add(\"ipu3-csi2 3\");\n> +\tcio2_dm.add(\"ipu3-cio2 3\");\n> +\n> +\tDeviceMatch imgu_dm(\"ipu3-imgu\");\n> +\timgu_dm.add(\"ipu3-imgu 0\");\n> +\timgu_dm.add(\"ipu3-imgu 0 input\");\n> +\timgu_dm.add(\"ipu3-imgu 0 parameters\");\n> +\timgu_dm.add(\"ipu3-imgu 0 output\");\n> +\timgu_dm.add(\"ipu3-imgu 0 viewfinder\");\n> +\timgu_dm.add(\"ipu3-imgu 0 3a stat\");\n> +\timgu_dm.add(\"ipu3-imgu 1\");\n> +\timgu_dm.add(\"ipu3-imgu 1 input\");\n> +\timgu_dm.add(\"ipu3-imgu 1 parameters\");\n> +\timgu_dm.add(\"ipu3-imgu 1 output\");\n> +\timgu_dm.add(\"ipu3-imgu 1 viewfinder\");\n> +\timgu_dm.add(\"ipu3-imgu 1 3a stat\");\n> +\n> +\tcio2_ = enumerator->search(cio2_dm);\n> +\tif (!cio2_)\n> +\t\treturn false;\n> +\n> +\timgu_ = enumerator->search(imgu_dm);\n> +\tif (!imgu_)\n> +\t\treturn false;\n> +\n> +\t/*\n> +\t * It is safe to acquire both media devices at this point as\n> +\t * DeviceEnumerator::search() skips the busy ones for us.\n> +\t */\n> +\tcio2_->acquire();\n> +\timgu_->acquire();\n> +\n> +\t/*\n> +\t * Disable all links that are enabled by default on CIO2, as camera\n> +\t * creation enables all valid links it finds.\n> +\t *\n> +\t * Close the CIO2 media device after, as links are enabled and should\n> +\t * not need to be changed after.\n> +\t */\n> +\tif (cio2_->open())\n> +\t\tgoto error_release_mdev;\n> +\n> +\tif (cio2_->disableLinks())\n> +\t\tgoto error_close_cio2;\n> +\n> +\tregisterCameras(manager);\n> +\n> +\tcio2_->close();\n> +\n> +\treturn true;\n> +\n> +error_close_cio2:\n> +\tcio2_->close();\n> +\n> +error_release_mdev:\n> +\tcio2_->release();\n> +\timgu_->release();\n> +\n> +\treturn false;\n> +}\n> +\n> +/*\n> + * Cameras are created associating an image sensor (represented by a\n> + * media entity with function MEDIA_ENT_F_CAM_SENSOR) to one of the four\n> + * CIO2 CSI-2 receivers.\n> + */\n> +void PipelineHandlerIPU3::registerCameras(CameraManager *manager)\n> +{\n> +\t/*\n> +\t * For each CSI-2 receiver on the IPU3, create a Camera if an\n> +\t * image sensor is connected to it.\n> +\t */\n> +\tunsigned int numCameras = 0;\n> +\tfor (unsigned int id = 0; id < 4; ++id) {\n> +\t\tstd::string csi2Name = \"ipu3-csi2 \" + std::to_string(id);\n> +\t\tMediaEntity *csi2 = cio2_->getEntityByName(csi2Name);\n> +\n> +\t\t/*\n> +\t\t * This shall not happen, as the device enumerator matched\n> +\t\t * all entities described in the cio2_dm DeviceMatch.\n> +\t\t *\n> +\t\t * As this check is basically free, better stay safe than sorry.\n> +\t\t */\n> +\t\tif (!csi2)\n> +\t\t\tcontinue;\n> +\n> +\t\tconst std::vector<MediaPad *> &pads = csi2->pads();\n> +\t\tif (pads.empty())\n> +\t\t\tcontinue;\n> +\n> +\t\t/* IPU3 CSI-2 receivers have a single sink pad at index 0. */\n> +\t\tMediaPad *sink = pads[0];\n> +\t\tconst std::vector<MediaLink *> &links = sink->links();\n> +\t\tif (links.empty())\n> +\t\t\tcontinue;\n> +\n> +\t\t/*\n> +\t\t * Verify that the receiver is connected to a sensor, enable\n> +\t\t * the media link between the two, and create a Camera with\n> +\t\t * a unique name.\n> +\t\t */\n> +\t\tMediaLink *link = links[0];\n> +\t\tMediaEntity *sensor = link->source()->entity();\n> +\t\tif (sensor->function() != MEDIA_ENT_F_CAM_SENSOR)\n> +\t\t\tcontinue;\n> +\n> +\t\tif (link->setEnabled(true))\n> +\t\t\tcontinue;\n> +\n> +\t\tstd::string cameraName = sensor->name() + \" \" + std::to_string(id);\n> +\t\tstd::shared_ptr<Camera> camera = Camera::create(cameraName);\n> +\t\tmanager->addCamera(std::move(camera));\n> +\n> +\t\tLOG(Info) << \"Registered Camera[\" << numCameras << \"] \\\"\"\n> +\t\t\t  << cameraName << \"\\\"\"\n> +\t\t\t  << \" connected to CSI-2 receiver \" << id;\n> +\n> +\t\tnumCameras++;\n> +\t}\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> new file mode 100644\n> index 0000000..0ab766a\n> --- /dev/null\n> +++ b/src/libcamera/pipeline/ipu3/meson.build\n> @@ -0,0 +1,3 @@\n> +libcamera_sources += files([\n> +    'ipu3.cpp',\n> +])\n> diff --git a/src/libcamera/pipeline/meson.build b/src/libcamera/pipeline/meson.build\n> index 615ecd2..811c075 100644\n> --- a/src/libcamera/pipeline/meson.build\n> +++ b/src/libcamera/pipeline/meson.build\n> @@ -1,3 +1,5 @@\n>  libcamera_sources += files([\n>      'vimc.cpp',\n>  ])\n> +\n> +subdir('ipu3')","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 9149560B1D\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 21 Jan 2019 21:23:18 +0100 (CET)","from pendragon.ideasonboard.com\n\t(dfj612yhrgyx302h3jwwy-3.rev.dnainternet.fi\n\t[IPv6:2001:14ba:21f5:5b00:ce28:277f:58d7:3ca4])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 28DED53E;\n\tMon, 21 Jan 2019 21:23:18 +0100 (CET)"],"DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1548102198;\n\tbh=T90P1vbSnXU0G5AaREDw/vFXc0oEms78CH1X8CZJb7s=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=Q9vactpfbbZwYBZpALy0nM+q1Mn+T1qLNMETX4TV8gYbRxmCXM8pXnJk/LzjehAeo\n\tmtKrK2jevTD0dqH302YSBpd68IT6x9N/P+ABjQ/jb7eqn724iiZ5XVuRHuFr1qwuS1\n\tx3Ic7i4z0rzFCN7FYjmN9QHNEV/GoDRH4P3YMRJc=","Date":"Mon, 21 Jan 2019 22:23:17 +0200","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Jacopo Mondi <jacopo@jmondi.org>","Cc":"libcamera-devel@lists.libcamera.org","Message-ID":"<20190121202317.GC4439@pendragon.ideasonboard.com>","References":"<20190121150756.14982-1-jacopo@jmondi.org>\n\t<20190121150756.14982-2-jacopo@jmondi.org>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<20190121150756.14982-2-jacopo@jmondi.org>","User-Agent":"Mutt/1.10.1 (2018-07-13)","Subject":"Re: [libcamera-devel] [PATCH v4 1/2] libcamera: pipeline: Add Intel\n\tIPU3 pipeline","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.23","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":"Mon, 21 Jan 2019 20:23:18 -0000"}}]