[1/5] ipa: rpi: cam_helper: Add Mira016 cam helper
diff mbox series

Message ID 20261111-b4-mira016-v1-1-340bdb923426@ideasonboard.com
State New
Headers show
Series
  • libcamera: Add Mira016 support
Related show

Commit Message

Jacopo Mondi Nov. 11, 2026, 4:48 p.m. UTC
Add a cam_helper to the RaspberryPi IPA for the AMS-OSRAM Mira016 sensor.

The sensor black level has been measured by averaging the pixel value
while covering the lens.

The mira016 driver gain interface is index-based. The gain() and
gainCode() function use a lookup table that translates the desired
gain value to an index on the table (and vice-versa).

Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
---
 src/ipa/rpi/cam_helper/cam_helper_mira016.cpp | 88 +++++++++++++++++++++++++++
 src/ipa/rpi/cam_helper/meson.build            |  1 +
 2 files changed, 89 insertions(+)

Patch
diff mbox series

diff --git a/src/ipa/rpi/cam_helper/cam_helper_mira016.cpp b/src/ipa/rpi/cam_helper/cam_helper_mira016.cpp
new file mode 100644
index 000000000000..0bc3aefca1ea
--- /dev/null
+++ b/src/ipa/rpi/cam_helper/cam_helper_mira016.cpp
@@ -0,0 +1,88 @@ 
+/* SPDX-License-Identifier: BSD-2-Clause */
+/*
+ * Copyright (C) 2026, ams-OSRAM
+ * Copyright (C) 2026, Ideas on Board Oy
+ *
+ * Camera helper for Mira016 sensor
+ */
+
+#include <assert.h>
+
+#include "cam_helper.h"
+
+namespace {
+
+using namespace RPiController;
+
+class CamHelperMira016 : public CamHelper
+{
+public:
+	CamHelperMira016();
+	uint32_t gainCode(double gain) const override;
+	double gain(uint32_t code) const override;
+
+private:
+	/*
+	 * The sensor manual doesn't really specify a minimum difference between
+	 * the exposure time and the frame duration, so pick a safe value of
+	 * 4 frames. The mira016 driver uses the same value as the exposure
+	 * margin.
+	 */
+	static constexpr int frameIntegrationDiff = 4;
+
+	static constexpr float gainLut[] = {
+		1, 1.018, 1.056, 1.075, 1.118, 1.14, 1.188, 1.213, 1.267, 1.295,
+		1.326, 1.373, 1.425, 1.462, 1.5, 1.541, 1.583, 1.652, 1.701,
+		1.727, 1.781, 1.839, 1.9, 1.966, 2, 2.073, 2.151, 2.192, 2.28,
+		2.327, 2.426, 2.478, 2.533, 2.651, 2.714, 2.78, 2.886, 2.961,
+		3.04, 3.167, 3.257, 3.353, 3.455, 3.563, 3.619, 3.738, 3.864, 4,
+		4.071, 4.222, 4.302, 4.471, 4.56, 4.75, 4.851, 5.067, 5.182,
+		5.302, 5.494, 5.7, 5.846, 6, 6.247, 6.423, 6.609, 6.806, 7.015,
+		7.238, 7.355, 7.6, 7.862, 8.143, 8.291, 8.604, 8.769, 9.12,
+		9.306, 9.702, 9.913, 10.133, 10.605, 10.857, 11.259, 11.544,
+		11.844, 12.324, 12.667, 13.029, 13.412, 13.818, 14.25, 14.71,
+		14.951, 15.458, 16,
+	};
+	uint32_t sizeLut = sizeof(gainLut) / sizeof(gainLut[0]);
+};
+
+CamHelperMira016::CamHelperMira016()
+	: CamHelper({}, frameIntegrationDiff)
+{
+}
+
+uint32_t CamHelperMira016::gainCode(double gain) const
+{
+	uint32_t gainCode = 0;
+
+	while (gainCode < sizeLut - 1) {
+		if (gain < gainLut[gainCode + 1])
+			break;
+
+		gainCode++;
+	}
+
+	/*
+	 * The V4L2_CID_ANALOGUE_GAIN control is 1-indexed while the lookup
+	 * table is 0-indexed. Return index+1 here, the driver adjusts it to its
+	 * 0-indexed table.
+	 */
+	return gainCode + 1;
+}
+
+double CamHelperMira016::gain(uint32_t gainCode) const
+{
+	if (gainCode >= sizeLut)
+		gainCode = sizeLut - 1;
+
+	return (double)(gainLut[gainCode]);
+}
+
+static CamHelper *create()
+{
+	return new CamHelperMira016();
+}
+
+static RegisterCamHelper reg("mira016", &create);
+
+} /* namespace */
diff --git a/src/ipa/rpi/cam_helper/meson.build b/src/ipa/rpi/cam_helper/meson.build
index 6935cecf885f..6fc5f5c12f37 100644
--- a/src/ipa/rpi/cam_helper/meson.build
+++ b/src/ipa/rpi/cam_helper/meson.build
@@ -12,6 +12,7 @@  rpi_ipa_cam_helper_sources = files([
     'cam_helper_imx477.cpp',
     'cam_helper_imx519.cpp',
     'cam_helper_imx708.cpp',
+    'cam_helper_mira016.cpp',
     'cam_helper_mira220.cpp',
     'cam_helper_ov64a40.cpp',
     'cam_helper_ov7251.cpp',