diff --git a/src/libcamera/shaders/meson.build 
b/src/libcamera/shaders/meson.build
index c409ff9b0..546053051 100644
--- a/src/libcamera/shaders/meson.build
+++ b/src/libcamera/shaders/meson.build
@@ -7,6 +7,8 @@ shader_files = files([
      'bayer_unpacked.frag',
      'bayer_unpacked.vert',
      'identity.vert',
+    'raw_mono_1x_packed.frag',
+    'raw_mono_unpacked.frag',
  ])

  # Generate header from shaders
diff --git a/src/libcamera/shaders/raw_mono_1x_packed.frag 
b/src/libcamera/shaders/raw_mono_1x_packed.frag
new file mode 100644
index 000000000..983834cc8
--- /dev/null
+++ b/src/libcamera/shaders/raw_mono_1x_packed.frag
@@ -0,0 +1,50 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+/*
+ * Copyright (C) 2026, Alain Cousinié
+ * raw_mono_1x_packed.frag - Fragment shader for packed monochrome 
formats (R10_CSI2P)
+ */
+
+#ifdef GL_ES
+precision highp float;
+#endif
+
+#define BPP        1.25
+
+varying vec2 textureOut;
+
+uniform vec2 tex_size;
+uniform sampler2D tex_y;
+uniform float gamma;
+uniform float contrastExp;
+
+float apply_contrast(float value)
+{
+    if (value < 0.5)
+        return 0.5 * pow(value / 0.5, contrastExp);
+    else
+        return 1.0 - 0.5 * pow((1.0 - value) / 0.5, contrastExp);
+}
+
+void main(void)
+{
+    vec2 pixel_coords = floor(textureOut * tex_size);
+
+    vec2 center_pixel = pixel_coords + vec2(0.5);
+    vec2 center_bytes;
+    center_bytes.y = center_pixel.y;
+    center_bytes.x = floor(BPP * center_pixel.x);
+
+    center_bytes = center_bytes / tex_size;
+
+    /* Linear sampling: GPU merges byte transitions. */
+    float C = texture2D(tex_y, center_bytes).r;
+    vec3 rgb = vec3(C, C, C);
+
+    rgb = clamp(rgb, 0.0, 1.0);
+    rgb.r = apply_contrast(rgb.r);
+    rgb.g = apply_contrast(rgb.g);
+    rgb.b = apply_contrast(rgb.b);
+    rgb = pow(rgb, vec3(gamma));
+
+    gl_FragColor = vec4(rgb, 1.0);
+}
diff --git a/src/libcamera/shaders/raw_mono_unpacked.frag 
b/src/libcamera/shaders/raw_mono_unpacked.frag
new file mode 100644
index 000000000..f8a0c14ae
--- /dev/null
+++ b/src/libcamera/shaders/raw_mono_unpacked.frag
@@ -0,0 +1,47 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+/*
+ * Copyright (C) 2026, Alain Cousinié
+ * raw_mono_unpacked.frag - Fragment shader for raw unpacked monochrome 
formats (R10)
+ */
+
+#extension GL_EXT_texture_rg : enable
+
+#ifdef GL_ES
+precision highp float;
+#endif
+
+varying vec2 textureOut;
+
+uniform sampler2D tex_y;
+uniform float gamma;
+uniform float contrastExp;
+
+float apply_contrast(float value)
+{
+    if (value < 0.5)
+        return 0.5 * pow(value / 0.5, contrastExp);
+    else
+        return 1.0 - 0.5 * pow((1.0 - value) / 0.5, contrastExp);
+}
+
+void main(void)
+{
+    /* GL_RG format sampling (16 bits):
+     * The .r component contains the 8 MSBs,
+     * The .g component contains the remaining LSBs.
+     */
+    vec4 texel = texture2D(tex_y, textureOut);
+    float C = texel.r + texel.g / 256.0;
+
+    vec3 rgb = vec3(C, C, C);
+
+    /* Generic rendering processing */
+    rgb = clamp(rgb, 0.0, 1.0);
+    rgb.r = apply_contrast(rgb.r);
+    rgb.g = apply_contrast(rgb.g);
+    rgb.b = apply_contrast(rgb.b);
+    rgb = pow(rgb, vec3(gamma));
+
+    gl_FragColor = vec4(rgb, 1.0);
+}
+
diff --git a/src/libcamera/software_isp/debayer_egl.cpp 
b/src/libcamera/software_isp/debayer_egl.cpp
index 300822f9d..2a57fb7d4 100644
--- a/src/libcamera/software_isp/debayer_egl.cpp
+++ b/src/libcamera/software_isp/debayer_egl.cpp
@@ -61,6 +61,17 @@ int DebayerEGL::getInputConfig(PixelFormat 
inputFormat, DebayerInputConfig &conf
                             formats::XBGR8888,
                             formats::ABGR8888 };

+    /* Handle Monochrome case using bayerFormat */
+    if (bayerFormat.order == BayerFormat::Order::MONO) {
+        bool isPacked = (bayerFormat.packing == 
BayerFormat::Packing::CSI2);
+
+        config.bpp = bayerFormat.bitDepth; /* Dynamic (10 bits for this 
sensor) */
+        config.patternSize.width = isPacked ? 4 : 1;
+        config.patternSize.height = 1; /* No 2x2 pattern in monochrome */
+        config.outputFormats = outputFormats;
+        return 0;
+    }
+
