diff options
author | Álvaro Fernández Rojas <noltari@gmail.com> | 2022-05-16 23:40:32 +0200 |
---|---|---|
committer | Álvaro Fernández Rojas <noltari@gmail.com> | 2022-05-17 15:11:22 +0200 |
commit | 20ea6adbf199097c4f5f591ffee088340630dae4 (patch) | |
tree | d6719d95e136611a1c25bbf7789652d6d402779d /target/linux/bcm27xx/patches-5.15/950-0522-media-i2c-imx519-Advertise-embedded-data-node-on-med.patch | |
parent | bca05bd072180dc38ef740b37ded9572a6db1981 (diff) | |
download | upstream-20ea6adbf199097c4f5f591ffee088340630dae4.tar.gz upstream-20ea6adbf199097c4f5f591ffee088340630dae4.tar.bz2 upstream-20ea6adbf199097c4f5f591ffee088340630dae4.zip |
bcm27xx: add support for linux v5.15
Build system: x86_64
Build-tested: bcm2708, bcm2709, bcm2710, bcm2711
Run-tested: bcm2708/RPiB+, bcm2709/RPi3B, bcm2710/RPi3B, bcm2711/RPi4B
Signed-off-by: Marty Jones <mj8263788@gmail.com>
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
Diffstat (limited to 'target/linux/bcm27xx/patches-5.15/950-0522-media-i2c-imx519-Advertise-embedded-data-node-on-med.patch')
-rw-r--r-- | target/linux/bcm27xx/patches-5.15/950-0522-media-i2c-imx519-Advertise-embedded-data-node-on-med.patch | 249 |
1 files changed, 249 insertions, 0 deletions
diff --git a/target/linux/bcm27xx/patches-5.15/950-0522-media-i2c-imx519-Advertise-embedded-data-node-on-med.patch b/target/linux/bcm27xx/patches-5.15/950-0522-media-i2c-imx519-Advertise-embedded-data-node-on-med.patch new file mode 100644 index 0000000000..cc40833433 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.15/950-0522-media-i2c-imx519-Advertise-embedded-data-node-on-med.patch @@ -0,0 +1,249 @@ +From 16a061b6cf7229db782615393f020d723640da69 Mon Sep 17 00:00:00 2001 +From: Arducam <admin@arducam.com> +Date: Wed, 15 Sep 2021 09:02:08 +0800 +Subject: [PATCH] media: i2c: imx519: Advertise embedded data node on + media pad 1 + +This commit updates the imx519 driver to adverise support for embedded +data streams. + +The imx519 sensor subdevice overloads the media pad to differentiate +between image stream (pad 0) and embedded data stream (pad 1) when +performing the v4l2_subdev_pad_ops functions. + +Signed-off-by: Lee Jackson <info@arducam.com> +--- + drivers/media/i2c/imx519.c | 138 +++++++++++++++++++++++++++---------- + 1 file changed, 103 insertions(+), 35 deletions(-) + +--- a/drivers/media/i2c/imx519.c ++++ b/drivers/media/i2c/imx519.c +@@ -93,6 +93,16 @@ + #define IMX519_TEST_PATTERN_B_DEFAULT 0 + #define IMX519_TEST_PATTERN_GB_DEFAULT 0 + ++/* Embedded metadata stream structure */ ++#define IMX519_EMBEDDED_LINE_WIDTH 16384 ++#define IMX519_NUM_EMBEDDED_LINES 1 ++ ++enum pad_types { ++ IMAGE_PAD, ++ METADATA_PAD, ++ NUM_PADS ++}; ++ + /* IMX519 native and active pixel array size. */ + #define IMX519_NATIVE_WIDTH 4672U + #define IMX519_NATIVE_HEIGHT 3648U +@@ -970,7 +980,7 @@ static const char * const imx519_supply_ + + struct imx519 { + struct v4l2_subdev sd; +- struct media_pad pad; ++ struct media_pad pad[NUM_PADS]; + + unsigned int fmt_code; + +@@ -1101,7 +1111,9 @@ static int imx519_open(struct v4l2_subde + { + struct imx519 *imx519 = to_imx519(sd); + struct v4l2_mbus_framefmt *try_fmt_img = +- v4l2_subdev_get_try_format(sd, fh->state, 0); ++ v4l2_subdev_get_try_format(sd, fh->state, IMAGE_PAD); ++ struct v4l2_mbus_framefmt *try_fmt_meta = ++ v4l2_subdev_get_try_format(sd, fh->state, METADATA_PAD); + struct v4l2_rect *try_crop; + + mutex_lock(&imx519->mutex); +@@ -1112,8 +1124,14 @@ static int imx519_open(struct v4l2_subde + try_fmt_img->code = imx519_get_format_code(imx519); + try_fmt_img->field = V4L2_FIELD_NONE; + ++ /* Initialize try_fmt for the embedded metadata pad */ ++ try_fmt_meta->width = IMX519_EMBEDDED_LINE_WIDTH; ++ try_fmt_meta->height = IMX519_NUM_EMBEDDED_LINES; ++ try_fmt_meta->code = MEDIA_BUS_FMT_SENSOR_DATA; ++ try_fmt_meta->field = V4L2_FIELD_NONE; ++ + /* Initialize try_crop */ +- try_crop = v4l2_subdev_get_try_crop(sd, fh->state, 0); ++ try_crop = v4l2_subdev_get_try_crop(sd, fh->state, IMAGE_PAD); + try_crop->left = IMX519_PIXEL_ARRAY_LEFT; + try_crop->top = IMX519_PIXEL_ARRAY_TOP; + try_crop->width = IMX519_PIXEL_ARRAY_WIDTH; +@@ -1246,10 +1264,20 @@ static int imx519_enum_mbus_code(struct + { + struct imx519 *imx519 = to_imx519(sd); + +- if (code->index > 0) ++ if (code->pad >= NUM_PADS) + return -EINVAL; + +- code->code = imx519_get_format_code(imx519); ++ if (code->pad == IMAGE_PAD) { ++ if (code->index > 0) ++ return -EINVAL; ++ ++ code->code = imx519_get_format_code(imx519); ++ } else { ++ if (code->index > 0) ++ return -EINVAL; ++ ++ code->code = MEDIA_BUS_FMT_SENSOR_DATA; ++ } + + return 0; + } +@@ -1260,16 +1288,29 @@ static int imx519_enum_frame_size(struct + { + struct imx519 *imx519 = to_imx519(sd); + +- if (fse->index >= ARRAY_SIZE(supported_modes_10bit)) ++ if (fse->pad >= NUM_PADS) + return -EINVAL; + +- if (fse->code != imx519_get_format_code(imx519)) +- return -EINVAL; ++ if (fse->pad == IMAGE_PAD) { ++ if (fse->index >= ARRAY_SIZE(supported_modes_10bit)) ++ return -EINVAL; ++ ++ if (fse->code != imx519_get_format_code(imx519)) ++ return -EINVAL; ++ ++ fse->min_width = supported_modes_10bit[fse->index].width; ++ fse->max_width = fse->min_width; ++ fse->min_height = supported_modes_10bit[fse->index].height; ++ fse->max_height = fse->min_height; ++ } else { ++ if (fse->code != MEDIA_BUS_FMT_SENSOR_DATA || fse->index > 0) ++ return -EINVAL; + +- fse->min_width = supported_modes_10bit[fse->index].width; +- fse->max_width = fse->min_width; +- fse->min_height = supported_modes_10bit[fse->index].height; +- fse->max_height = fse->min_height; ++ fse->min_width = IMX519_EMBEDDED_LINE_WIDTH; ++ fse->max_width = fse->min_width; ++ fse->min_height = IMX519_NUM_EMBEDDED_LINES; ++ fse->max_height = fse->min_height; ++ } + + return 0; + } +@@ -1294,13 +1335,21 @@ static void imx519_update_image_pad_form + imx519_reset_colorspace(&fmt->format); + } + ++static void imx519_update_metadata_pad_format(struct v4l2_subdev_format *fmt) ++{ ++ fmt->format.width = IMX519_EMBEDDED_LINE_WIDTH; ++ fmt->format.height = IMX519_NUM_EMBEDDED_LINES; ++ fmt->format.code = MEDIA_BUS_FMT_SENSOR_DATA; ++ fmt->format.field = V4L2_FIELD_NONE; ++} ++ + static int imx519_get_pad_format(struct v4l2_subdev *sd, + struct v4l2_subdev_state *sd_state, + struct v4l2_subdev_format *fmt) + { + struct imx519 *imx519 = to_imx519(sd); + +- if (fmt->pad != 0) ++ if (fmt->pad >= NUM_PADS) + return -EINVAL; + + mutex_lock(&imx519->mutex); +@@ -1310,12 +1359,19 @@ static int imx519_get_pad_format(struct + v4l2_subdev_get_try_format(&imx519->sd, sd_state, + fmt->pad); + /* update the code which could change due to vflip or hflip: */ +- try_fmt->code = imx519_get_format_code(imx519); ++ try_fmt->code = fmt->pad == IMAGE_PAD ? ++ imx519_get_format_code(imx519) : ++ MEDIA_BUS_FMT_SENSOR_DATA; + fmt->format = *try_fmt; + } else { +- imx519_update_image_pad_format(imx519, imx519->mode, +- fmt); +- fmt->format.code = imx519_get_format_code(imx519); ++ if (fmt->pad == IMAGE_PAD) { ++ imx519_update_image_pad_format(imx519, imx519->mode, ++ fmt); ++ fmt->format.code = ++ imx519_get_format_code(imx519); ++ } else { ++ imx519_update_metadata_pad_format(fmt); ++ } + } + + mutex_unlock(&imx519->mutex); +@@ -1376,28 +1432,39 @@ static int imx519_set_pad_format(struct + const struct imx519_mode *mode; + struct imx519 *imx519 = to_imx519(sd); + +- if (fmt->pad != 0) ++ if (fmt->pad >= NUM_PADS) + return -EINVAL; + + mutex_lock(&imx519->mutex); + +- /* Bayer order varies with flips */ +- fmt->format.code = imx519_get_format_code(imx519); ++ if (fmt->pad == IMAGE_PAD) { ++ /* Bayer order varies with flips */ ++ fmt->format.code = imx519_get_format_code(imx519); + +- mode = v4l2_find_nearest_size(supported_modes_10bit, +- ARRAY_SIZE(supported_modes_10bit), +- width, height, +- fmt->format.width, +- fmt->format.height); +- imx519_update_image_pad_format(imx519, mode, fmt); +- if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { +- framefmt = v4l2_subdev_get_try_format(sd, sd_state, +- fmt->pad); +- *framefmt = fmt->format; ++ mode = v4l2_find_nearest_size(supported_modes_10bit, ++ ARRAY_SIZE(supported_modes_10bit), ++ width, height, ++ fmt->format.width, ++ fmt->format.height); ++ imx519_update_image_pad_format(imx519, mode, fmt); ++ if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { ++ framefmt = v4l2_subdev_get_try_format(sd, sd_state, ++ fmt->pad); ++ *framefmt = fmt->format; ++ } else { ++ imx519->mode = mode; ++ imx519->fmt_code = fmt->format.code; ++ imx519_set_framing_limits(imx519); ++ } + } else { +- imx519->mode = mode; +- imx519->fmt_code = fmt->format.code; +- imx519_set_framing_limits(imx519); ++ if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { ++ framefmt = v4l2_subdev_get_try_format(sd, sd_state, ++ fmt->pad); ++ *framefmt = fmt->format; ++ } else { ++ /* Only one embedded data mode is supported */ ++ imx519_update_metadata_pad_format(fmt); ++ } + } + + mutex_unlock(&imx519->mutex); +@@ -1953,9 +2020,10 @@ static int imx519_probe(struct i2c_clien + imx519->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR; + + /* Initialize source pads */ +- imx519->pad.flags = MEDIA_PAD_FL_SOURCE; ++ imx519->pad[IMAGE_PAD].flags = MEDIA_PAD_FL_SOURCE; ++ imx519->pad[METADATA_PAD].flags = MEDIA_PAD_FL_SOURCE; + +- ret = media_entity_pads_init(&imx519->sd.entity, 1, &imx519->pad); ++ ret = media_entity_pads_init(&imx519->sd.entity, NUM_PADS, imx519->pad); + if (ret) { + dev_err(dev, "failed to init entity pads: %d\n", ret); + goto error_handler_free; |