[libcamera-devel] [PATCH] pipeline: rkisp1: Support media graph with separate CSI RX
Paul Elder
paul.elder at ideasonboard.com
Wed Jun 22 09:46:38 CEST 2022
The rkisp1 hardware supports a parallel interface, where the sensor
would be connected directly, as well as a CSI receiver. Although at the
moment the rkisp1 driver doesn't expose the CSI receiver as a separate
subdev, this patch allows the rkisp1 pipeline handler to continue
working even in the event that it eventually does.
Signed-off-by: Paul Elder <paul.elder at ideasonboard.com>
---
src/libcamera/pipeline/rkisp1/rkisp1.cpp | 35 ++++++++++++++++++++++--
1 file changed, 33 insertions(+), 2 deletions(-)
diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
index 43b76e14..a233c961 100644
--- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp
+++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
@@ -178,6 +178,7 @@ private:
std::unique_ptr<V4L2Subdevice> isp_;
std::unique_ptr<V4L2VideoDevice> param_;
std::unique_ptr<V4L2VideoDevice> stat_;
+ std::unique_ptr<V4L2Subdevice> csi_;
RkISP1MainPath mainPath_;
RkISP1SelfPath selfPath_;
@@ -591,6 +592,12 @@ int PipelineHandlerRkISP1::configure(Camera *camera, CameraConfiguration *c)
LOG(RkISP1, Debug) << "Sensor configured with " << format;
+ if (csi_) {
+ ret = csi_->setFormat(0, &format);
+ if (ret < 0)
+ return ret;
+ }
+
ret = isp_->setFormat(0, &format);
if (ret < 0)
return ret;
@@ -892,7 +899,7 @@ int PipelineHandlerRkISP1::initLinks(Camera *camera,
* Configure the sensor links: enable the link corresponding to this
* camera.
*/
- const MediaPad *pad = isp_->entity()->getPadByIndex(0);
+ const MediaPad *pad = (csi_ ? csi_ : isp_)->entity()->getPadByIndex(0);
for (MediaLink *link : pad->links()) {
if (link->source()->entity() != sensor->entity())
continue;
@@ -907,6 +914,18 @@ int PipelineHandlerRkISP1::initLinks(Camera *camera,
return ret;
}
+ if (csi_) {
+ const MediaPad *ispPad = isp_->entity()->getPadByIndex(0);
+ for (MediaLink *link : ispPad->links()) {
+ if (link->source()->entity() != csi_->entity())
+ continue;
+
+ ret = link->setEnabled(true);
+ if (ret < 0)
+ return ret;
+ }
+ }
+
for (const StreamConfiguration &cfg : config) {
if (cfg.stream() == &data->mainPathStream_)
ret = data->mainPath_->setEnabled(true);
@@ -1005,6 +1024,18 @@ bool PipelineHandlerRkISP1::match(DeviceEnumerator *enumerator)
if (isp_->open() < 0)
return false;
+ pad = isp_->entity()->getPadByIndex(0);
+ if (!pad || pad->links().size() != 1)
+ return false;
+
+ csi_ = std::make_unique<V4L2Subdevice>(pad->links().at(0)->source()->entity());
+ if (!csi_ || csi_->open() < 0)
+ return false;
+
+ /* If the media device has no 1th pad, it's the sensor */
+ if (!csi_->entity()->getPadByIndex(1))
+ csi_ = nullptr;
+
/* Locate and open the stats and params video nodes. */
stat_ = V4L2VideoDevice::fromEntityName(media_, "rkisp1_stats");
if (stat_->open() < 0)
@@ -1030,7 +1061,7 @@ bool PipelineHandlerRkISP1::match(DeviceEnumerator *enumerator)
* Enumerate all sensors connected to the ISP and create one
* camera instance for each of them.
*/
- pad = isp_->entity()->getPadByIndex(0);
+ pad = (csi_ ? csi_ : isp_)->entity()->getPadByIndex(0);
if (!pad)
return false;
--
2.30.2
More information about the libcamera-devel
mailing list