diff --git a/src/ipa/rpi/cam_helper/cam_helper_imx258.cpp b/src/ipa/rpi/cam_helper/cam_helper_imx258.cpp
new file mode 100644
index 00000000..12c0332a
--- /dev/null
+++ b/src/ipa/rpi/cam_helper/cam_helper_imx258.cpp
@@ -0,0 +1,60 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+/*
+ * Copyright (C) 2024 Ideas On Board Oy
+ *
+ * camera helper for imx258 sensor
+ * based on Raspberry Pi's imx290 helper
+ */
+
+#include <cmath>
+
+#include "cam_helper.h"
+
+using namespace RPiController;
+
+class CamHelperImx258 : public CamHelper
+{
+public:
+	CamHelperImx258();
+	uint32_t gainCode(double gain) const override;
+	double gain(uint32_t gainCode) const override;
+	void getDelays(int &exposureDelay, int &gainDelay,
+		       int &vblankDelay, int &hblankDelay) const override;
+private:
+	/*
+	 * Smallest difference between the frame length and integration time,
+	 * in units of lines.
+	 */
+	static constexpr int frameIntegrationDiff = 2;
+};
+
+CamHelperImx258::CamHelperImx258()
+	: CamHelper({}, frameIntegrationDiff)
+{
+}
+
+uint32_t CamHelperImx258::gainCode(double gain) const
+{
+	return static_cast<uint32_t>(512 - 512 / gain);
+}
+
+double CamHelperImx258::gain(uint32_t gainCode) const
+{
+	return 512.0 / (512.0 - gainCode);
+}
+
+void CamHelperImx258::getDelays(int &exposureDelay, int &gainDelay,
+				int &vblankDelay, int &hblankDelay) const
+{
+	exposureDelay = 2;
+	gainDelay = 2;
+	vblankDelay = 2;
+	hblankDelay = 2;
+}
+
+static CamHelper *create()
+{
+	return new CamHelperImx258();
+}
+
+static RegisterCamHelper reg("imx258", &create);
diff --git a/src/ipa/rpi/cam_helper/meson.build b/src/ipa/rpi/cam_helper/meson.build
index 03e88fe0..a8245e42 100644
--- a/src/ipa/rpi/cam_helper/meson.build
+++ b/src/ipa/rpi/cam_helper/meson.build
@@ -4,6 +4,7 @@ rpi_ipa_cam_helper_sources = files([
     'cam_helper.cpp',
     'cam_helper_ov5647.cpp',
     'cam_helper_imx219.cpp',
+    'cam_helper_imx258.cpp',
     'cam_helper_imx283.cpp',
     'cam_helper_imx290.cpp',
     'cam_helper_imx296.cpp',
