[libcamera-devel,v3,3/4] libcamera: ipu3: Make sure sensor provides a compatible format

Message ID 20190314155106.30106-4-jacopo@jmondi.org
State Superseded
Headers show
Series
  • libcamera: ipu3: Pre-ImgU support
Related show

Commit Message

Jacopo Mondi March 14, 2019, 3:51 p.m. UTC
When creating a camera, make sure a the image sensor provides images in
a format compatible with IPU3 CIO2 unit requirements.

Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
---
 src/libcamera/pipeline/ipu3/ipu3.cpp | 58 +++++++++++++++++++++++++++-
 1 file changed, 56 insertions(+), 2 deletions(-)

Patch

diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp
index 55489c31df2d..90faef1bdece 100644
--- a/src/libcamera/pipeline/ipu3/ipu3.cpp
+++ b/src/libcamera/pipeline/ipu3/ipu3.cpp
@@ -8,6 +8,8 @@ 
 #include <memory>
 #include <vector>
 
+#include <linux/media-bus-format.h>
+
 #include <libcamera/camera.h>
 #include <libcamera/request.h>
 #include <libcamera/stream.h>
@@ -78,6 +80,8 @@  private:
 			PipelineHandler::cameraData(camera));
 	}
 
+	int mediaBusToCIO2Format(unsigned int code);
+
 	void registerCameras();
 
 	std::shared_ptr<MediaDevice> cio2_;
@@ -327,6 +331,38 @@  bool PipelineHandlerIPU3::match(DeviceEnumerator *enumerator)
 	return true;
 }
 
+int PipelineHandlerIPU3::mediaBusToCIO2Format(unsigned int code)
+{
+	switch(code) {
+	case MEDIA_BUS_FMT_SBGGR8_1X8:
+	case MEDIA_BUS_FMT_SBGGR10_1X10:
+	case MEDIA_BUS_FMT_SBGGR12_1X12:
+	case MEDIA_BUS_FMT_SBGGR14_1X14:
+	case MEDIA_BUS_FMT_SBGGR16_1X16:
+		return V4L2_PIX_FMT_IPU3_SBGGR10;
+	case MEDIA_BUS_FMT_SGBRG8_1X8:
+	case MEDIA_BUS_FMT_SGBRG10_1X10:
+	case MEDIA_BUS_FMT_SGBRG12_1X12:
+	case MEDIA_BUS_FMT_SGBRG14_1X14:
+	case MEDIA_BUS_FMT_SGBRG16_1X16:
+		return V4L2_PIX_FMT_IPU3_SGBRG10;
+	case MEDIA_BUS_FMT_SGRBG8_1X8:
+	case MEDIA_BUS_FMT_SGRBG10_1X10:
+	case MEDIA_BUS_FMT_SGRBG12_1X12:
+	case MEDIA_BUS_FMT_SGRBG14_1X14:
+	case MEDIA_BUS_FMT_SGRBG16_1X16:
+		return V4L2_PIX_FMT_IPU3_SGRBG10;
+	case MEDIA_BUS_FMT_SRGGB8_1X8:
+	case MEDIA_BUS_FMT_SRGGB10_1X10:
+	case MEDIA_BUS_FMT_SRGGB12_1X12:
+	case MEDIA_BUS_FMT_SRGGB14_1X14:
+	case MEDIA_BUS_FMT_SRGGB16_1X16:
+		return V4L2_PIX_FMT_IPU3_SRGGB10;
+	default:
+		return -EINVAL;
+	}
+}
+
 /*
  * Cameras are created associating an image sensor (represented by a
  * media entity with function MEDIA_ENT_F_CAM_SENSOR) to one of the four
@@ -404,18 +440,36 @@  void PipelineHandlerIPU3::registerCameras()
 		if (ret)
 			continue;
 
-		data->cio2_->bufferReady.connect(data.get(), &IPU3CameraData::bufferReady);
-
+		/*
+		 * Make sure the sensor produces at least one image format
+		 * compatible with IPU3 CIO2 requirements.
+		 */
 		data->sensor_ = new V4L2Subdevice(sensor);
 		ret = data->sensor_->open();
 		if (ret)
 			continue;
 
+		const FormatEnum formats = data->sensor_->formats(0);
+		auto it = formats.begin();
+		for (; it != formats.end(); ++it) {
+			if (mediaBusToCIO2Format(it->first) != -EINVAL)
+				break;
+		}
+		if (it == formats.end()) {
+		LOG(IPU3, Info) << "Sensor '" << data->sensor_->deviceName()
+				<< "' detected, but no supported image format "
+				<< " found: skip camera creation";
+			continue;
+		}
+
 		data->csi2_ = new V4L2Subdevice(csi2);
 		ret = data->csi2_->open();
 		if (ret)
 			continue;
 
+		data->cio2_->bufferReady.connect(data.get(),
+						&IPU3CameraData::bufferReady);
+
 		registerCamera(std::move(camera), std::move(data));
 
 		LOG(IPU3, Info)