Patch Detail
Show a patch.
GET /api/patches/25459/?format=api
{ "id": 25459, "url": "https://patchwork.libcamera.org/api/patches/25459/?format=api", "web_url": "https://patchwork.libcamera.org/patch/25459/", "project": { "id": 1, "url": "https://patchwork.libcamera.org/api/projects/1/?format=api", "name": "libcamera", "link_name": "libcamera", "list_id": "libcamera_core", "list_email": "libcamera-devel@lists.libcamera.org", "web_url": "", "scm_url": "", "webscm_url": "" }, "msgid": "<20251210-mali-cru-v2-2-e26421de202b@ideasonboard.com>", "date": "2025-12-10T14:39:18", "name": "[v2,2/7] libcamera: mali-c55: Split TPG and Inline camera handling", "commit_ref": null, "pull_url": null, "state": "superseded", "archived": false, "hash": "090dc118adafe33399b2cfbb305a26db9715e060", "submitter": { "id": 143, "url": "https://patchwork.libcamera.org/api/people/143/?format=api", "name": "Jacopo Mondi", "email": "jacopo.mondi@ideasonboard.com" }, "delegate": null, "mbox": "https://patchwork.libcamera.org/patch/25459/mbox/", "series": [ { "id": 5649, "url": "https://patchwork.libcamera.org/api/series/5649/?format=api", "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=5649", "date": "2025-12-10T14:39:16", "name": "libcamera: mali-c55: Add support for memory-to-memory", "version": 2, "mbox": "https://patchwork.libcamera.org/series/5649/mbox/" } ], "comments": "https://patchwork.libcamera.org/api/patches/25459/comments/", "check": "pending", "checks": "https://patchwork.libcamera.org/api/patches/25459/checks/", "tags": {}, "headers": { "Return-Path": "<libcamera-devel-bounces@lists.libcamera.org>", "X-Original-To": "parsemail@patchwork.libcamera.org", "Delivered-To": "parsemail@patchwork.libcamera.org", "Received": [ "from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id E075DBD1F1\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 10 Dec 2025 14:39:37 +0000 (UTC)", "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 44ABE61499;\n\tWed, 10 Dec 2025 15:39:36 +0100 (CET)", "from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id B459D613CB\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 10 Dec 2025 15:39:32 +0100 (CET)", "from [192.168.1.106] (mob-5-90-55-146.net.vodafone.it\n\t[5.90.55.146])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 4BB3A6DC;\n\tWed, 10 Dec 2025 15:39:31 +0100 (CET)" ], "Authentication-Results": "lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"CCF/5ziw\"; dkim-atps=neutral", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1765377571;\n\tbh=oENpKKBBloUwF+GHLDNipl1ATndf6nx/0uDbs5A8PEI=;\n\th=From:Date:Subject:References:In-Reply-To:To:Cc:From;\n\tb=CCF/5ziwnB6wyXXr66/67bunUss0wOPkz11sRTNYWGS3WlATtAY5AyqdCEmWGiwHc\n\t2gRtCmxcYB9ksblg66hn4fvNiYUUTKlu4LWyJRtlYkPG9JD+tAPPuA3SMdbclOliho\n\tpGr0z1boY7P1O4AEosDE1BVreGp5Zyo1TNxygO6Q=", "From": "Jacopo Mondi <jacopo.mondi@ideasonboard.com>", "Date": "Wed, 10 Dec 2025 15:39:18 +0100", "Subject": "[PATCH v2 2/7] libcamera: mali-c55: Split TPG and Inline camera\n\thandling", "MIME-Version": "1.0", "Content-Type": "text/plain; charset=\"utf-8\"", "Content-Transfer-Encoding": "7bit", "Message-Id": "<20251210-mali-cru-v2-2-e26421de202b@ideasonboard.com>", "References": "<20251210-mali-cru-v2-0-e26421de202b@ideasonboard.com>", "In-Reply-To": "<20251210-mali-cru-v2-0-e26421de202b@ideasonboard.com>", "To": "Daniel Scally <dan.scally@ideasonboard.com>, \n\tlibcamera-devel@lists.libcamera.org", "Cc": "Jacopo Mondi <jacopo.mondi@ideasonboard.com>", "X-Mailer": "b4 0.14.2", "X-Developer-Signature": "v=1; a=openpgp-sha256; l=16136;\n\ti=jacopo.mondi@ideasonboard.com; h=from:subject:message-id;\n\tbh=oENpKKBBloUwF+GHLDNipl1ATndf6nx/0uDbs5A8PEI=;\n\tb=owEBbQKS/ZANAwAKAXI0Bo8WoVY8AcsmYgBpOYYi2XLm3gXdBdevdGRzIaG88oVIm3bHDKZqR\n\tZqCNUO9F+WJAjMEAAEKAB0WIQS1xD1IgJogio9YOMByNAaPFqFWPAUCaTmGIgAKCRByNAaPFqFW\n\tPBlwEACs2DORDzMrXJIV+Yyn21+m/FGV6gexhjA3WkM95nwQcBimWEcCpWec6WGJqj3AgRynuTE\n\ttRgYqfV/PITnKy7QW/B4G7Uc4Y5/z/YQmFxJFp203ITOHJ/ta+kEPH9ruDNl5xlZSr5O1Juploh\n\tJ6dxv0mXqcS2OXd3qmPuHMlm++XwEL1mUryln6VCfqk3Ujw/h9iUeSonVc3CbZOcS33ay+wnKeD\n\tui5drq/V7hgqo4cC0o55GTj8w+Edt4dsnONB+9oSpoX3913AcWmchO4PcajyUPSuG867uwaPBwm\n\tAlK5VP+0GzWyAfoli2ZeLwJbMxaqkDNU2lE78B5iuaOQnraNpq+kjg/PD1LFxoH4w9ltbi41Xbe\n\thHFko1jMsrgak+SKaQp28lH0WMEN46W3mdiHUH64TWCYBK81d0EEpzApagGjGrhmNuQ4iDfv658\n\tmhwmpemCX1e9rJ7soE28zgAiidIRp2GpD1oxhxR2wK/vH91oxjjDugB8CLXUKMiKRbAM4xvAjMt\n\tXPKv1qEEygqMVgc/QLjU8qZwSBEsxZ0Zn+PGHbOW3cnmOTJKmSsoOERYD7x1d5zIwJgquomINGY\n\tbcLFOJrejZQHMHHerkHTdvrK1f5wggyzuaRjyKv4OF4Qz5tEROkhKIAnF3z3oIn1aNGaOTEKo4o\n\tOdx1u+9ipqaAj3g==", "X-Developer-Key": "i=jacopo.mondi@ideasonboard.com; a=openpgp;\n\tfpr=72392EDC88144A65C701EA9BA5826A2587AD026B", "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>", "Errors-To": "libcamera-devel-bounces@lists.libcamera.org", "Sender": "\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>" }, "content": "In order to prepare to support memory input cameras, split the handling of\nthe TPG and Inline camera cases.\n\nThe Mali C55 pipeline handler uses the entity and subdevice stored in the\nCameraData to support both the handling of the TPG and of the [CSI-2 +\nsensor] use cases. Adding support for memory cameras by using the CRU unit\nwould add yet-another special case making the code harder to follow and\nmore prone to errors.\n\nSplit the handling of the TPG and inline cameras by introducing the\nMaliC55CameraData class hierarchy, to deflect functions called on the\ncamera data to the correct entities.\n\nSigned-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>\n---\n src/libcamera/pipeline/mali-c55/mali-c55.cpp | 287 +++++++++++++++++----------\n 1 file changed, 185 insertions(+), 102 deletions(-)", "diff": "diff --git a/src/libcamera/pipeline/mali-c55/mali-c55.cpp b/src/libcamera/pipeline/mali-c55/mali-c55.cpp\nindex cf0cb15f8bb39143eea38aa8acb8d2b1268f5530..552a258a6b849a2518fa6c83226cf9ab4e657717 100644\n--- a/src/libcamera/pipeline/mali-c55/mali-c55.cpp\n+++ b/src/libcamera/pipeline/mali-c55/mali-c55.cpp\n@@ -92,17 +92,28 @@ struct MaliC55FrameInfo {\n class MaliC55CameraData : public Camera::Private\n {\n public:\n-\tMaliC55CameraData(PipelineHandler *pipe, MediaEntity *entity)\n-\t\t: Camera::Private(pipe), entity_(entity)\n+\tenum CameraType {\n+\t\tTpg,\n+\t\tInline,\n+\t};\n+\n+\tMaliC55CameraData(PipelineHandler *pipe)\n+\t\t: Camera::Private(pipe)\n \t{\n \t}\n \n-\tint init();\n \tint loadIPA();\n \n+\tCameraType type() const { return type_; }\n+\n \t/* Deflect these functionalities to either TPG or CameraSensor. */\n-\tstd::vector<Size> sizes(unsigned int mbusCode) const;\n-\tSize resolution() const;\n+\tvirtual int init(MediaEntity *entity) = 0;\n+\n+\tvirtual std::vector<Size> sizes(unsigned int mbusCode) const = 0;\n+\tvirtual V4L2Subdevice *subdev() const = 0;\n+\tvirtual CameraSensor *sensor() const = 0;\n+\tvirtual V4L2Subdevice *csi2() const = 0;\n+\tvirtual Size resolution() const = 0;\n \n \tint pixfmtToMbusCode(const PixelFormat &pixFmt) const;\n \tconst PixelFormat &bestRawFormat() const;\n@@ -112,11 +123,6 @@ public:\n \tPixelFormat adjustRawFormat(const PixelFormat &pixFmt) const;\n \tSize adjustRawSizes(const PixelFormat &pixFmt, const Size &rawSize) const;\n \n-\tstd::unique_ptr<CameraSensor> sensor_;\n-\n-\tMediaEntity *entity_;\n-\tstd::unique_ptr<V4L2Subdevice> csi_;\n-\tstd::unique_ptr<V4L2Subdevice> sd_;\n \tStream frStream_;\n \tStream dsStream_;\n \n@@ -126,58 +132,106 @@ public:\n \n \tstd::unique_ptr<DelayedControls> delayedCtrls_;\n \n+protected:\n+\tCameraType type_;\n+\n private:\n-\tvoid initTPGData();\n \tvoid setSensorControls(const ControlList &sensorControls);\n-\n \tstd::string id_;\n-\tSize tpgResolution_;\n };\n \n-int MaliC55CameraData::init()\n+class MaliC55TpgCameraData : public MaliC55CameraData\n {\n-\tint ret;\n+public:\n+\tMaliC55TpgCameraData(PipelineHandler *pipe);\n \n-\tsd_ = std::make_unique<V4L2Subdevice>(entity_);\n-\tret = sd_->open();\n-\tif (ret) {\n-\t\tLOG(MaliC55, Error) << \"Failed to open sensor subdevice\";\n-\t\treturn ret;\n+\tint init(MediaEntity *entity) override;\n+\n+\tstd::vector<Size> sizes(unsigned int mbusCode) const override;\n+\n+\tSize resolution() const override\n+\t{\n+\t\treturn resolution_;\n \t}\n \n-\t/* If this camera is created from TPG, we return here. */\n-\tif (entity_->name() == \"mali-c55 tpg\") {\n-\t\tinitTPGData();\n-\t\treturn 0;\n+\tV4L2Subdevice *subdev() const override\n+\t{\n+\t\treturn sd_.get();\n \t}\n \n-\t/*\n-\t * Register a CameraSensor if we connect to a sensor and create\n-\t * an entity for the connected CSI-2 receiver.\n-\t */\n-\tsensor_ = CameraSensorFactoryBase::create(entity_);\n-\tif (!sensor_)\n-\t\treturn -ENODEV;\n+\tCameraSensor *sensor() const override\n+\t{\n+\t\tASSERT(false);\n+\t\treturn nullptr;\n+\t}\n \n-\tconst MediaPad *sourcePad = entity_->getPadByIndex(0);\n-\tMediaEntity *csiEntity = sourcePad->links()[0]->sink()->entity();\n+\tV4L2Subdevice *csi2() const override\n+\t{\n+\t\tASSERT(false);\n+\t\treturn nullptr;\n+\t}\n \n-\tcsi_ = std::make_unique<V4L2Subdevice>(csiEntity);\n-\tret = csi_->open();\n-\tif (ret) {\n-\t\tLOG(MaliC55, Error) << \"Failed to open CSI-2 subdevice\";\n-\t\treturn ret;\n+private:\n+\tSize resolution_;\n+\tstd::unique_ptr<V4L2Subdevice> sd_;\n+};\n+\n+class MaliC55InlineCameraData : public MaliC55CameraData\n+{\n+public:\n+\tMaliC55InlineCameraData(PipelineHandler *pipe);\n+\n+\tint init(MediaEntity *entity) override;\n+\n+\tstd::vector<Size> sizes(unsigned int mbusCode) const override\n+\t{\n+\t\treturn sensor_->sizes(mbusCode);\n \t}\n \n-\treturn 0;\n+\tSize resolution() const override\n+\t{\n+\t\treturn sensor_->resolution();\n+\t}\n+\n+\tV4L2Subdevice *subdev() const override\n+\t{\n+\t\treturn sensor_->device();\n+\t}\n+\n+\tCameraSensor *sensor() const override\n+\t{\n+\t\treturn sensor_.get();\n+\t}\n+\n+\tV4L2Subdevice *csi2() const override\n+\t{\n+\t\treturn csi2_.get();\n+\t}\n+\n+private:\n+\tstd::unique_ptr<V4L2Subdevice> csi2_;\n+\tstd::unique_ptr<CameraSensor> sensor_;\n+};\n+\n+MaliC55TpgCameraData::MaliC55TpgCameraData(PipelineHandler *pipe)\n+\t: MaliC55CameraData(pipe)\n+{\n+\ttype_ = CameraType::Tpg;\n }\n \n-void MaliC55CameraData::initTPGData()\n+int MaliC55TpgCameraData::init(MediaEntity *tpg)\n {\n+\tsd_ = std::make_unique<V4L2Subdevice>(tpg);\n+\tint ret = sd_->open();\n+\tif (ret) {\n+\t\tLOG(MaliC55, Error) << \"Failed to open TPG subdevice\";\n+\t\treturn ret;\n+\t}\n+\n \t/* Replicate the CameraSensor implementation for TPG. */\n \tV4L2Subdevice::Formats formats = sd_->formats(0);\n \tif (formats.empty())\n-\t\treturn;\n+\t\treturn -EINVAL;\n \n \tstd::vector<Size> tpgSizes;\n \n@@ -187,19 +241,13 @@ void MaliC55CameraData::initTPGData()\n \t\t\t [](const SizeRange &range) { return range.max; });\n \t}\n \n-\ttpgResolution_ = tpgSizes.back();\n-}\n+\tresolution_ = tpgSizes.back();\n \n-void MaliC55CameraData::setSensorControls(const ControlList &sensorControls)\n-{\n-\tdelayedCtrls_->push(sensorControls);\n+\treturn 0;\n }\n \n-std::vector<Size> MaliC55CameraData::sizes(unsigned int mbusCode) const\n+std::vector<Size> MaliC55TpgCameraData::sizes(unsigned int mbusCode) const\n {\n-\tif (sensor_)\n-\t\treturn sensor_->sizes(mbusCode);\n-\n \tV4L2Subdevice::Formats formats = sd_->formats(0);\n \tif (formats.empty())\n \t\treturn {};\n@@ -218,12 +266,35 @@ std::vector<Size> MaliC55CameraData::sizes(unsigned int mbusCode) const\n \treturn sizes;\n }\n \n-Size MaliC55CameraData::resolution() const\n+MaliC55InlineCameraData::MaliC55InlineCameraData(PipelineHandler *pipe)\n+\t: MaliC55CameraData(pipe)\n {\n-\tif (sensor_)\n-\t\treturn sensor_->resolution();\n+\ttype_ = CameraType::Inline;\n+}\n \n-\treturn tpgResolution_;\n+int MaliC55InlineCameraData::init(MediaEntity *sensor)\n+{\n+\t/* Register a CameraSensor create an entity for the CSI-2 receiver. */\n+\tsensor_ = CameraSensorFactoryBase::create(sensor);\n+\tif (!sensor_)\n+\t\treturn -EINVAL;\n+\n+\tconst MediaPad *sourcePad = sensor->getPadByIndex(0);\n+\tMediaEntity *csiEntity = sourcePad->links()[0]->sink()->entity();\n+\n+\tcsi2_ = std::make_unique<V4L2Subdevice>(csiEntity);\n+\tint ret = csi2_->open();\n+\tif (ret) {\n+\t\tLOG(MaliC55, Error) << \"Failed to open CSI-2 subdevice\";\n+\t\treturn ret;\n+\t}\n+\n+\treturn ret;\n+}\n+\n+void MaliC55CameraData::setSensorControls(const ControlList &sensorControls)\n+{\n+\tdelayedCtrls_->push(sensorControls);\n }\n \n /*\n@@ -242,7 +313,7 @@ int MaliC55CameraData::pixfmtToMbusCode(const PixelFormat &pixFmt) const\n \tif (!bayerFormat.isValid())\n \t\treturn -EINVAL;\n \n-\tV4L2Subdevice::Formats formats = sd_->formats(0);\n+\tV4L2Subdevice::Formats formats = subdev()->formats(0);\n \tunsigned int sensorMbusCode = 0;\n \tunsigned int bitDepth = 0;\n \n@@ -280,7 +351,7 @@ const PixelFormat &MaliC55CameraData::bestRawFormat() const\n {\n \tstatic const PixelFormat invalidPixFmt = {};\n \n-\tfor (const auto &fmt : sd_->formats(0)) {\n+\tfor (const auto &fmt : subdev()->formats(0)) {\n \t\tBayerFormat sensorBayer = BayerFormat::fromMbusCode(fmt.first);\n \n \t\tif (!sensorBayer.isValid())\n@@ -302,11 +373,11 @@ const PixelFormat &MaliC55CameraData::bestRawFormat() const\n \n void MaliC55CameraData::updateControls(const ControlInfoMap &ipaControls)\n {\n-\tif (!sensor_)\n+\tif (type_ == CameraType::Tpg)\n \t\treturn;\n \n \tIPACameraSensorInfo sensorInfo;\n-\tint ret = sensor_->sensorInfo(&sensorInfo);\n+\tint ret = sensor()->sensorInfo(&sensorInfo);\n \tif (ret) {\n \t\tLOG(MaliC55, Error) << \"Failed to retrieve sensor info\";\n \t\treturn;\n@@ -379,7 +450,7 @@ int MaliC55CameraData::loadIPA()\n \tint ret;\n \n \t/* Do not initialize IPA for TPG. */\n-\tif (!sensor_)\n+\tif (type_ == CameraType::Tpg)\n \t\treturn 0;\n \n \tipa_ = IPAManager::createIPA<ipa::mali_c55::IPAProxyMaliC55>(pipe(), 1, 1);\n@@ -388,20 +459,20 @@ int MaliC55CameraData::loadIPA()\n \n \tipa_->setSensorControls.connect(this, &MaliC55CameraData::setSensorControls);\n \n-\tstd::string ipaTuningFile = ipa_->configurationFile(sensor_->model() + \".yaml\",\n+\tstd::string ipaTuningFile = ipa_->configurationFile(sensor()->model() + \".yaml\",\n \t\t\t\t\t\t\t \"uncalibrated.yaml\");\n \n \t/* We need to inform the IPA of the sensor configuration */\n \tipa::mali_c55::IPAConfigInfo ipaConfig{};\n \n-\tret = sensor_->sensorInfo(&ipaConfig.sensorInfo);\n+\tret = sensor()->sensorInfo(&ipaConfig.sensorInfo);\n \tif (ret)\n \t\treturn ret;\n \n-\tipaConfig.sensorControls = sensor_->controls();\n+\tipaConfig.sensorControls = sensor()->controls();\n \n \tControlInfoMap ipaControls;\n-\tret = ipa_->init({ ipaTuningFile, sensor_->model() }, ipaConfig,\n+\tret = ipa_->init({ ipaTuningFile, sensor()->model() }, ipaConfig,\n \t\t\t &ipaControls);\n \tif (ret) {\n \t\tLOG(MaliC55, Error) << \"Failed to initialise the Mali-C55 IPA\";\n@@ -444,13 +515,13 @@ CameraConfiguration::Status MaliC55CameraConfiguration::validate()\n \t * The TPG doesn't support flips, so we only need to calculate a\n \t * transform if we have a sensor.\n \t */\n-\tif (data_->sensor_) {\n+\tif (data_->type() == MaliC55CameraData::CameraType::Tpg) {\n+\t\tcombinedTransform_ = Transform::Rot0;\n+\t} else {\n \t\tOrientation requestedOrientation = orientation;\n-\t\tcombinedTransform_ = data_->sensor_->computeTransform(&orientation);\n+\t\tcombinedTransform_ = data_->sensor()->computeTransform(&orientation);\n \t\tif (orientation != requestedOrientation)\n \t\t\tstatus = Adjusted;\n-\t} else {\n-\t\tcombinedTransform_ = Transform::Rot0;\n \t}\n \n \t/* Only 2 streams available. */\n@@ -927,11 +998,17 @@ int PipelineHandlerMaliC55::configure(Camera *camera,\n \n \t/* Link the graph depending if we are operating the TPG or a sensor. */\n \tMaliC55CameraData *data = cameraData(camera);\n-\tif (data->csi_) {\n-\t\tconst MediaEntity *csiEntity = data->csi_->entity();\n-\t\tret = csiEntity->getPadByIndex(1)->links()[0]->setEnabled(true);\n-\t} else {\n-\t\tret = data->entity_->getPadByIndex(0)->links()[0]->setEnabled(true);\n+\tswitch (data->type()) {\n+\tcase MaliC55CameraData::CameraType::Tpg: {\n+\t\tconst MediaEntity *tpgEntity = data->subdev()->entity();\n+\t\tret = tpgEntity->getPadByIndex(0)->links()[0]->setEnabled(true);\n+\t\tbreak;\n+\t}\n+\tcase MaliC55CameraData::CameraType::Inline: {\n+\t\tconst MediaEntity *csi2Entity = data->csi2()->entity();\n+\t\tret = csi2Entity->getPadByIndex(1)->links()[0]->setEnabled(true);\n+\t\tbreak;\n+\t}\n \t}\n \tif (ret)\n \t\treturn ret;\n@@ -939,26 +1016,30 @@ int PipelineHandlerMaliC55::configure(Camera *camera,\n \tMaliC55CameraConfiguration *maliConfig =\n \t\tstatic_cast<MaliC55CameraConfiguration *>(config);\n \tV4L2SubdeviceFormat subdevFormat = maliConfig->sensorFormat_;\n-\tret = data->sd_->getFormat(0, &subdevFormat);\n-\tif (ret)\n-\t\treturn ret;\n \n-\tif (data->sensor_) {\n-\t\tret = data->sensor_->setFormat(&subdevFormat,\n-\t\t\t\t\t maliConfig->combinedTransform());\n-\t\tif (ret)\n-\t\t\treturn ret;\n+\t/* Apply format to the origin of the pipeline and propagate it. */\n+\tswitch (data->type()) {\n+\tcase MaliC55CameraData::CameraType::Tpg: {\n+\t\tret = data->subdev()->setFormat(0, &subdevFormat);\n+\t\tbreak;\n \t}\n-\n-\tif (data->csi_) {\n-\t\tret = data->csi_->setFormat(0, &subdevFormat);\n+\tcase MaliC55CameraData::CameraType::Inline: {\n+\t\tret = data->sensor()->setFormat(&subdevFormat,\n+\t\t\t\t\t\tmaliConfig->combinedTransform());\n \t\tif (ret)\n \t\t\treturn ret;\n \n-\t\tret = data->csi_->getFormat(1, &subdevFormat);\n+\t\tret = data->csi2()->setFormat(0, &subdevFormat);\n \t\tif (ret)\n \t\t\treturn ret;\n+\n+\t\tret = data->csi2()->getFormat(1, &subdevFormat);\n+\n+\t\tbreak;\n+\t}\n \t}\n+\tif (ret)\n+\t\treturn ret;\n \n \tV4L2DeviceFormat statsFormat;\n \tret = stats_->getFormat(&statsFormat);\n@@ -973,8 +1054,6 @@ int PipelineHandlerMaliC55::configure(Camera *camera,\n \t/*\n \t * Propagate the format to the ISP sink pad and configure the input\n \t * crop rectangle (no crop at the moment).\n-\t *\n-\t * \\todo Configure the CSI-2 receiver.\n \t */\n \tret = isp_->setFormat(0, &subdevFormat);\n \tif (ret)\n@@ -1058,18 +1137,18 @@ int PipelineHandlerMaliC55::configure(Camera *camera,\n \t/* We need to inform the IPA of the sensor configuration */\n \tipa::mali_c55::IPAConfigInfo ipaConfig{};\n \n-\tret = data->sensor_->sensorInfo(&ipaConfig.sensorInfo);\n+\tret = data->sensor()->sensorInfo(&ipaConfig.sensorInfo);\n \tif (ret)\n \t\treturn ret;\n \n-\tipaConfig.sensorControls = data->sensor_->controls();\n+\tipaConfig.sensorControls = data->sensor()->controls();\n \n \t/*\n \t * And we also need to tell the IPA the bayerOrder of the data (as\n \t * affected by any flips that we've configured)\n \t */\n \tconst Transform &combinedTransform = maliConfig->combinedTransform();\n-\tBayerFormat::Order bayerOrder = data->sensor_->bayerOrder(combinedTransform);\n+\tBayerFormat::Order bayerOrder = data->sensor()->bayerOrder(combinedTransform);\n \n \tControlInfoMap ipaControls;\n \tret = data->ipa_->configure(ipaConfig, utils::to_underlying(bayerOrder),\n@@ -1283,7 +1362,7 @@ void PipelineHandlerMaliC55::applyScalerCrop(Camera *camera,\n \tif (!scalerCrop)\n \t\treturn;\n \n-\tif (!data->sensor_) {\n+\tif (data->type() == MaliC55CameraData::CameraType::Tpg) {\n \t\tLOG(MaliC55, Error) << \"ScalerCrop not supported for TPG\";\n \t\treturn;\n \t}\n@@ -1291,7 +1370,7 @@ void PipelineHandlerMaliC55::applyScalerCrop(Camera *camera,\n \tRectangle nativeCrop = *scalerCrop;\n \n \tIPACameraSensorInfo sensorInfo;\n-\tint ret = data->sensor_->sensorInfo(&sensorInfo);\n+\tint ret = data->sensor()->sensorInfo(&sensorInfo);\n \tif (ret) {\n \t\tLOG(MaliC55, Error) << \"Failed to retrieve sensor info\";\n \t\treturn;\n@@ -1573,10 +1652,11 @@ bool PipelineHandlerMaliC55::registerTPGCamera(MediaLink *link)\n \t}\n \n \tstd::unique_ptr<MaliC55CameraData> data =\n-\t\tstd::make_unique<MaliC55CameraData>(this, link->source()->entity());\n+\t\tstd::make_unique<MaliC55TpgCameraData>(this);\n \n-\tif (data->init())\n-\t\treturn false;\n+\tint ret = data->init(link->source()->entity());\n+\tif (ret)\n+\t\treturn ret;\n \n \treturn registerMaliCamera(std::move(data), name);\n }\n@@ -1600,21 +1680,24 @@ bool PipelineHandlerMaliC55::registerSensorCamera(MediaLink *ispLink)\n \t\t\tcontinue;\n \n \t\tstd::unique_ptr<MaliC55CameraData> data =\n-\t\t\tstd::make_unique<MaliC55CameraData>(this, sensor);\n-\t\tif (data->init())\n-\t\t\treturn false;\n+\t\t\tstd::make_unique<MaliC55InlineCameraData>(this);\n+\n+\t\tint ret = data->init(sensor);\n+\t\tif (ret)\n+\t\t\treturn ret;\n \n-\t\tdata->properties_ = data->sensor_->properties();\n+\t\tdata->properties_ = data->sensor()->properties();\n \n-\t\tconst CameraSensorProperties::SensorDelays &delays = data->sensor_->sensorDelays();\n+\t\tconst CameraSensorProperties::SensorDelays &delays =\n+\t\t\tdata->sensor()->sensorDelays();\n \t\tstd::unordered_map<uint32_t, DelayedControls::ControlParams> params = {\n \t\t\t{ V4L2_CID_ANALOGUE_GAIN, { delays.gainDelay, false } },\n \t\t\t{ V4L2_CID_EXPOSURE, { delays.exposureDelay, false } },\n \t\t};\n \n-\t\tdata->delayedCtrls_ =\n-\t\t\tstd::make_unique<DelayedControls>(data->sensor_->device(),\n-\t\t\t\t\t\t\t params);\n+\t\tV4L2Subdevice *sensorSubdev = data->sensor()->device();\n+\t\tdata->delayedCtrls_ = std::make_unique<DelayedControls>(sensorSubdev,\n+\t\t\t\t\t\t\t\t\tparams);\n \t\tisp_->frameStart.connect(data->delayedCtrls_.get(),\n \t\t\t\t\t &DelayedControls::applyControls);\n \n", "prefixes": [ "v2", "2/7" ] }