[WIP,RFC,08/26] libcamera: camera_sensor_raw: Read the new CFA_PATTERN control
diff mbox series

Message ID 20261023-b4-raw-model-v1-8-eadb9948901b@ideasonboard.com
State New
Headers show
Series
  • Support the new common raw sensor model
Related show

Commit Message

Jai Luthra Oct. 23, 2026, 10:58 a.m. UTC
The raw sensor model now supports generic media bus codes, and new V4L2
controls on the sensor subdevice for querying the color filter array
order and if flips affect the readout order.

Make sure both controls are present, and use them instead.

TODO: Use the CFA_PATTERN_FLIP control instead of reading the
MODIFY_LAYOUT flag of H/VFLIP controls.

Signed-off-by: Jai Luthra <jai.luthra@ideasonboard.com>
---
 src/libcamera/sensor/camera_sensor_raw.cpp | 58 ++++++++++++++++++------------
 1 file changed, 35 insertions(+), 23 deletions(-)

Patch
diff mbox series

diff --git a/src/libcamera/sensor/camera_sensor_raw.cpp b/src/libcamera/sensor/camera_sensor_raw.cpp
index 59799a1c150c..b7ac9d90f523 100644
--- a/src/libcamera/sensor/camera_sensor_raw.cpp
+++ b/src/libcamera/sensor/camera_sensor_raw.cpp
@@ -346,29 +346,6 @@  std::optional<int> CameraSensorRaw::init()
 	 * array order for the image stream.
 	 */
 
-	/*
-	 * Get the native sensor CFA pattern. It is simpler to retrieve it from
-	 * the internal image sink pad as it is guaranteed to expose a single
-	 * format, and is not affected by flips.
-	 */
-	V4L2Subdevice::Formats formats = subdev_->formats(streams_.image.sink);
-	if (formats.size() != 1) {
-		LOG(CameraSensor, Error)
-			<< "Image pad has " << formats.size()
-			<< " formats, expected 1";
-		return { -EINVAL };
-	}
-
-	uint32_t nativeFormat = formats.cbegin()->first;
-	const BayerFormat &bayerFormat = BayerFormat::fromMbusCode(nativeFormat);
-	if (!bayerFormat.isValid()) {
-		LOG(CameraSensor, Error)
-			<< "Invalid native format " << nativeFormat;
-		return { 0 };
-	}
-
-	cfaPattern_ = bayerFormat.order;
-
 	/*
 	 * Retrieve and cache the media bus codes and sizes on the source image
 	 * stream.
@@ -454,6 +431,8 @@  std::optional<int> CameraSensorRaw::init()
 	static constexpr uint32_t mandatoryControls[] = {
 		V4L2_CID_ANALOGUE_GAIN,
 		V4L2_CID_CAMERA_ORIENTATION,
+		V4L2_CID_CFA_PATTERN,
+		V4L2_CID_CFA_PATTERN_FLIP,
 		V4L2_CID_EXPOSURE,
 		V4L2_CID_HBLANK,
 		V4L2_CID_PIXEL_RATE,
@@ -479,6 +458,38 @@  std::optional<int> CameraSensorRaw::init()
 		return { ret };
 	}
 
+	/*
+	 * Get the native sensor CFA pattern.
+	 */
+	ControlList ctrls = subdev_->getControls({ { V4L2_CID_CFA_PATTERN } });
+	if (ctrls.empty()) {
+		LOG(CameraSensor, Error)
+			<< "Failed to retrieve CFA_PATTERN control";
+		return -EINVAL;
+	}
+
+	int cfaPattern = ctrls.get(V4L2_CID_CFA_PATTERN).get<int32_t>();
+
+	switch (cfaPattern) {
+	case V4L2_CFA_PATTERN_GRBG:
+		cfaPattern_ = BayerFormat::GRBG;
+		break;
+	case V4L2_CFA_PATTERN_RGGB:
+		cfaPattern_ = BayerFormat::RGGB;
+		break;
+	case V4L2_CFA_PATTERN_BGGR:
+		cfaPattern_ = BayerFormat::BGGR;
+		break;
+	case V4L2_CFA_PATTERN_GBRG:
+		cfaPattern_ = BayerFormat::GBRG;
+		break;
+	default:
+		LOG(CameraSensor, Error)
+			<< "Unsupported CFA pattern "
+			<< cfaPattern;
+		return -EINVAL;
+	}
+
 	/* Verify if sensor supports horizontal/vertical flips. */
 	auto queryFlip = [&](uint32_t id, const char *name) -> std::pair<bool, bool> {
 		const struct v4l2_query_ext_ctrl *flipInfo = subdev_->controlInfo(id);
@@ -491,6 +502,7 @@  std::optional<int> CameraSensorRaw::init()
 		return { true, flipInfo->flags & V4L2_CTRL_FLAG_MODIFY_LAYOUT };
 	};
 
+	/* FIXME: Replace with query to V4L2_CID_CFA_PATTERN_FLIP */
 	auto hflip = queryFlip(V4L2_CID_HFLIP, "horizontal");
 	auto vflip = queryFlip(V4L2_CID_VFLIP, "vertical");