new file mode 100644
@@ -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 */
@@ -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',
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(+)