[PATCH v12 61/86] media: imx219: Add support for generic raw formats

Sakari Ailus
2026-04-09T20:15:05Z

Add support for colour pattern agnostic raw formats, including controls to
convey the colour pattern and the configuration model (common raw sensor).

Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
---
drivers/media/i2c/imx219.c | 40 +++++++++++++++++++++++++++++++++++---
1 file changed, 37 insertions(+), 3 deletions(-)

diff --git a/drivers/media/i2c/imx219.c b/drivers/media/i2c/imx219.c
index e744b96a08f6..a7d59d16add5 100644
--- a/drivers/media/i2c/imx219.c
+++ b/drivers/media/i2c/imx219.c
@@ -290,6 +290,11 @@ static const u32 imx219_mbus_formats[] = {
MEDIA_BUS_FMT_SBGGR8_1X8,
};

+static const u32 imx219_mbus_formats_generic[] = {
+ MEDIA_BUS_FMT_RAW_10,
+ MEDIA_BUS_FMT_RAW_8,
+};
+
/*
* Initialisation delay between XCLR low->high and the moment when the sensor
* can start capture (i.e. can leave software stanby) must be not less than:
@@ -394,6 +399,10 @@ static u32 imx219_get_format_code(struct imx219 *imx219, u32 code)
{
unsigned int i;

+ for (i = 0; i < ARRAY_SIZE(imx219_mbus_formats_generic); i++)
+ if (imx219_mbus_formats_generic[i] == code)
+ return code;
+
for (i = 0; i < ARRAY_SIZE(imx219_mbus_formats); i++)
if (imx219_mbus_formats[i] == code)
break;
@@ -414,12 +423,14 @@ static u32 imx219_get_format_bpp(const struct v4l2_mbus_framefmt *format)
case MEDIA_BUS_FMT_SGRBG8_1X8:
case MEDIA_BUS_FMT_SGBRG8_1X8:
case MEDIA_BUS_FMT_SBGGR8_1X8:
+ case MEDIA_BUS_FMT_RAW_8:
return 8;

case MEDIA_BUS_FMT_SRGGB10_1X10:
case MEDIA_BUS_FMT_SGRBG10_1X10:
case MEDIA_BUS_FMT_SGBRG10_1X10:
case MEDIA_BUS_FMT_SBGGR10_1X10:
+ case MEDIA_BUS_FMT_RAW_10:
default:
return 10;
}
@@ -433,12 +444,14 @@ imx219_get_embedded_format_code(const struct v4l2_mbus_framefmt *format)
case MEDIA_BUS_FMT_SGRBG8_1X8:
case MEDIA_BUS_FMT_SGBRG8_1X8:
case MEDIA_BUS_FMT_SBGGR8_1X8:
+ case MEDIA_BUS_FMT_RAW_8:
return MEDIA_BUS_FMT_META_8;

case MEDIA_BUS_FMT_SRGGB10_1X10:
case MEDIA_BUS_FMT_SGRBG10_1X10:
case MEDIA_BUS_FMT_SGBRG10_1X10:
case MEDIA_BUS_FMT_SBGGR10_1X10:
+ case MEDIA_BUS_FMT_RAW_10:
default:
return MEDIA_BUS_FMT_META_10;
}
@@ -662,6 +675,20 @@ static int imx219_init_controls(struct imx219 *imx219)
/* The "Solid color" pattern is white by default */
}

+ v4l2_ctrl_new_std(ctrl_hdlr, NULL, V4L2_CID_CFA_PATTERN,
+ V4L2_CFA_PATTERN_RGGB, V4L2_CFA_PATTERN_RGGB,
+ 1, V4L2_CFA_PATTERN_RGGB);
+ v4l2_ctrl_new_std(ctrl_hdlr, NULL,
+ V4L2_CID_CFA_PATTERN_FLIP,
+ 0, V4L2_CFA_PATTERN_FLIP_BOTH,
+ 0, V4L2_CFA_PATTERN_FLIP_BOTH);
+ v4l2_ctrl_new_std(ctrl_hdlr, NULL, V4L2_CID_METADATA_LAYOUT,
+ 0, V4L2_METADATA_LAYOUT_CCS,
+ 1, V4L2_METADATA_LAYOUT_CCS);
+ v4l2_ctrl_new_std(ctrl_hdlr, NULL, V4L2_CID_CONFIG_MODEL,
+ 0, V4L2_CONFIG_MODEL_COMMON_RAW_SENSOR,
+ 0, V4L2_CONFIG_MODEL_COMMON_RAW_SENSOR);
+
if (ctrl_hdlr->error) {
ret = ctrl_hdlr->error;
dev_err_probe(&client->dev, ret, "Control init failed\n");
@@ -895,10 +922,17 @@ static int imx219_enum_mbus_code(struct v4l2_subdev *sd,
if (code->stream == IMX219_STREAM_IMAGE) {
u32 format;

- if (code->index >= ARRAY_SIZE(imx219_mbus_formats) / 4)
- return -EINVAL;
+ if (code->index >= ARRAY_SIZE(imx219_mbus_formats) / 4) {
+ u32 idx = code->index -
+ ARRAY_SIZE(imx219_mbus_formats) / 4;
+
+ if (idx >= ARRAY_SIZE(imx219_mbus_formats_generic))
+ return -EINVAL;

- format = imx219_mbus_formats[code->index * 4];
+ format = imx219_mbus_formats_generic[idx];
+ } else {
+ format = imx219_mbus_formats[code->index * 4];
+ }
code->code = imx219_get_format_code(imx219, format);
} else {
struct v4l2_mbus_framefmt *fmt;
--
2.47.3