[libcamera-devel,v2] rkisp1: Add support for sensor test pattern control
diff mbox series

Message ID 20221109112753.2313327-1-paul.elder@ideasonboard.com
State New
Headers show
Series
  • [libcamera-devel,v2] rkisp1: Add support for sensor test pattern control
Related show

Commit Message

Paul Elder Nov. 9, 2022, 11:27 a.m. UTC
Add support for the TestPatternMode control.

Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>

---
Changes in v2:
- move the control initialization to the pipeline handler
---
 src/libcamera/pipeline/rkisp1/rkisp1.cpp | 58 +++++++++++++++++++++++-
 1 file changed, 57 insertions(+), 1 deletion(-)

Patch
diff mbox series

diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
index 455ee2a0..26d8439d 100644
--- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp
+++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
@@ -93,6 +93,9 @@  public:
 	PipelineHandlerRkISP1 *pipe();
 	int loadIPA(unsigned int hwRevision);
 
+	void initSensorTestPattern();
+	int setSensorTestPattern(const ControlList *controls);
+
 	Stream mainPathStream_;
 	Stream selfPathStream_;
 	std::unique_ptr<CameraSensor> sensor_;
@@ -104,6 +107,8 @@  public:
 	RkISP1MainPath *mainPath_;
 	RkISP1SelfPath *selfPath_;
 
+	controls::draft::TestPatternModeEnum testPatternMode_;
+
 	std::unique_ptr<ipa::rkisp1::IPAProxyRkISP1> ipa_;
 
 private:
@@ -357,6 +362,47 @@  int RkISP1CameraData::loadIPA(unsigned int hwRevision)
 	return 0;
 }
 
+void RkISP1CameraData::initSensorTestPattern()
+{
+	const ControlInfoMap &sensorControls = sensor_->controls();
+
+	ControlInfoMap::Map ctrlMap = {};
+	for (const auto &ipaControl : controlInfo_)
+		ctrlMap[ipaControl.first] = ipaControl.second;
+
+	auto tpgInfo = sensorControls.find(V4L2_CID_TEST_PATTERN);
+	if (tpgInfo != sensorControls.end()) {
+		ctrlMap.emplace(&controls::draft::TestPatternMode,
+				ControlInfo(tpgInfo->second.values()));
+	}
+
+	controlInfo_ = ControlInfoMap(std::move(ctrlMap), controls::controls);
+}
+
+int RkISP1CameraData::setSensorTestPattern(const ControlList *controls)
+{
+	if (!controls)
+		return 0;
+
+	const auto &testPattern = controls->get(controls::draft::TestPatternMode);
+
+	if (!testPattern)
+		return 0;
+
+	if (testPattern && *testPattern == testPatternMode_)
+		return 0;
+
+	testPatternMode_ = static_cast<controls::draft::TestPatternModeEnum>(*testPattern);
+
+	int ret = sensor_->setTestPatternMode(testPatternMode_);
+	if (ret && !sensor_->testPatternModes().empty())
+		return ret;
+
+	LOG(RkISP1, Debug) << "Set test pattern to " << static_cast<int>(testPatternMode_);
+
+	return 0;
+}
+
 void RkISP1CameraData::paramFilled(unsigned int frame)
 {
 	PipelineHandlerRkISP1 *pipe = RkISP1CameraData::pipe();
@@ -820,11 +866,15 @@  int PipelineHandlerRkISP1::freeBuffers(Camera *camera)
 	return 0;
 }
 
-int PipelineHandlerRkISP1::start(Camera *camera, [[maybe_unused]] const ControlList *controls)
+int PipelineHandlerRkISP1::start(Camera *camera, const ControlList *controls)
 {
 	RkISP1CameraData *data = cameraData(camera);
 	int ret;
 
+	ret = data->setSensorTestPattern(controls);
+	if (ret)
+		return ret;
+
 	/* Allocate buffers for internal pipeline usage. */
 	ret = allocateBuffers(camera);
 	if (ret)
@@ -923,6 +973,10 @@  int PipelineHandlerRkISP1::queueRequestDevice(Camera *camera, Request *request)
 {
 	RkISP1CameraData *data = cameraData(camera);
 
+	int ret = data->setSensorTestPattern(&request->controls());
+	if (ret)
+		return ret;
+
 	RkISP1FrameInfo *info = data->frameInfo_.create(data, request);
 	if (!info)
 		return -ENOENT;
@@ -1027,6 +1081,8 @@  int PipelineHandlerRkISP1::createCamera(MediaEntity *sensor)
 	if (ret)
 		return ret;
 
+	data->initSensorTestPattern();
+
 	std::set<Stream *> streams{
 		&data->mainPathStream_,
 		&data->selfPathStream_,