Re: [PATCH] media: imx283: Provide optical black mode

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Umang,

Thank you for the patch.

On Tue, Jul 30, 2024 at 12:09:53AM +0530, Umang Jain wrote:
> The IMX283 is capable of delivering optical black regions as part of
> the image capture. These regions support capture of the black levels
> for calibration and are added as extra pixels on top of the full
> resolution capture.
> 
> Supply an extra mode which accounts for this increased size that will
> produce black regions in the output image.

Sorry, but this shouldn't be an extra mode. We need a proper API, you
need to convert the driver to make it freely configurable. Furthermore,
the OB stream should probably be reported by .get_frame_desc().

> Signed-off-by: Umang Jain <umang.jain@xxxxxxxxxxxxxxxx>
> ---
> - YUYV capture sample with Pi5 ISP for side-by-side comparison of OB regions:
> https://gcdnb.pbrd.co/images/XQV29MedwXxg.png
> ---
>  drivers/media/i2c/imx283.c | 68 ++++++++++++++++++++++++++++++++------
>  1 file changed, 58 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/media/i2c/imx283.c b/drivers/media/i2c/imx283.c
> index 8490618c5071..9a0fe2c34a41 100644
> --- a/drivers/media/i2c/imx283.c
> +++ b/drivers/media/i2c/imx283.c
> @@ -66,6 +66,7 @@
>  #define IMX283_REG_HTRIMMING		CCI_REG8(0x300b)
>  #define   IMX283_MDVREV			BIT(0) /* VFLIP */
>  #define   IMX283_HTRIMMING_EN		BIT(4)
> +#define   IMX283_HOB_EN			BIT(5)
>  
>  #define IMX283_REG_VWINPOS		CCI_REG16_LE(0x300f)
>  #define IMX283_REG_VWIDCUT		CCI_REG16_LE(0x3011)
> @@ -306,6 +307,7 @@ static const struct imx283_input_frequency imx283_frequencies[] = {
>  
>  enum imx283_modes {
>  	IMX283_MODE_0,
> +	IMX283_MODE_0_OB,
>  	IMX283_MODE_1,
>  	IMX283_MODE_1A,
>  	IMX283_MODE_1S,
> @@ -327,6 +329,7 @@ struct imx283_readout_mode {
>  static const struct imx283_readout_mode imx283_readout_modes[] = {
>  	/* All pixel scan modes */
>  	[IMX283_MODE_0] = { 0x04, 0x03, 0x10, 0x00 }, /* 12 bit */
> +	[IMX283_MODE_0_OB] = { 0x04, 0x03, 0x10, 0x00 }, /* 12 bit */
>  	[IMX283_MODE_1] = { 0x04, 0x01, 0x00, 0x00 }, /* 10 bit */
>  	[IMX283_MODE_1A] = { 0x04, 0x01, 0x20, 0x50 }, /* 10 bit */
>  	[IMX283_MODE_1S] = { 0x04, 0x41, 0x20, 0x50 }, /* 10 bit */
> @@ -439,6 +442,36 @@ static const struct imx283_mode supported_modes_12bit[] = {
>  			.height = 3648,
>  		},
>  	},
> +	{
> +		/* 20MPix 21.40 fps readout mode 0 with optical blacks enabled */
> +		.mode = IMX283_MODE_0_OB,
> +		.bpp = 12,
> +		.width = 5472 + 96, /* width + Horizontal optical black */
> +		.height = 3648 + 16, /* height + Vertical optical black */
> +		.min_hmax = 5914, /* 887 @ 480MHz/72MHz */
> +		.min_vmax = 3793, /* Lines */
> +
> +		.veff = 3694,
> +		.vst = 0,
> +		.vct = 0,
> +
> +		.hbin_ratio = 1,
> +		.vbin_ratio = 1,
> +
> +		/* 20.00 FPS */
> +		.default_hmax = 6000, /* 900 @ 480MHz/72MHz */
> +		.default_vmax = 4000,
> +
> +		.min_shr = 11,
> +		.horizontal_ob = 96,
> +		.vertical_ob = 16,
> +		.crop = {
> +			.top = 40,
> +			.left = 108,
> +			.width = 5472 + 96,
> +			.height = 3648 + 16,
> +		},
> +	},
>  	{
>  		/*
>  		 * Readout mode 2 : 2/2 binned mode (2736x1824)
> @@ -793,17 +826,20 @@ static int imx283_set_ctrl(struct v4l2_ctrl *ctrl)
>  		break;
>  
>  	case V4L2_CID_VFLIP:
> +		u32 htrim = IMX283_HTRIMMING_EN;
> +
>  		/*
>  		 * VFLIP is managed by BIT(0) of IMX283_REG_HTRIMMING address, hence
>  		 * both need to be set simultaneously.
>  		 */
> -		if (ctrl->val) {
> -			cci_write(imx283->cci, IMX283_REG_HTRIMMING,
> -				  IMX283_HTRIMMING_EN | IMX283_MDVREV, &ret);
> -		} else {
> -			cci_write(imx283->cci, IMX283_REG_HTRIMMING,
> -				  IMX283_HTRIMMING_EN, &ret);
> -		}
> +		if (ctrl->val)
> +			htrim = IMX283_HTRIMMING_EN | IMX283_MDVREV;
> +
> +		if (mode->mode == IMX283_MODE_0_OB)
> +			htrim |= IMX283_HOB_EN;
> +
> +		cci_write(imx283->cci, IMX283_REG_HTRIMMING, htrim, &ret);
> +
>  		break;
>  
>  	case V4L2_CID_TEST_PATTERN:
> @@ -1010,6 +1046,8 @@ static int imx283_start_streaming(struct imx283 *imx283,
>  	s32 v_pos;
>  	u32 write_v_size;
>  	u32 y_out_size;
> +	u32 htrim_end;
> +	u32 ob_size_v = 0;
>  	int ret = 0;
>  
>  	fmt = v4l2_subdev_state_get_format(state, 0);
> @@ -1057,6 +1095,12 @@ static int imx283_start_streaming(struct imx283 *imx283,
>  		mode->crop.height);
>  
>  	y_out_size = mode->crop.height / mode->vbin_ratio;
> +
> +	if (mode->mode == IMX283_MODE_0_OB) {
> +		y_out_size -= mode->vertical_ob;
> +		ob_size_v = mode->vertical_ob;
> +	}
> +
>  	write_v_size = y_out_size + mode->vertical_ob;
>  	/*
>  	 * cropping start position = (VWINPOS – Vst) × 2
> @@ -1072,12 +1116,16 @@ static int imx283_start_streaming(struct imx283 *imx283,
>  	cci_write(imx283->cci, IMX283_REG_VWIDCUT, v_widcut, &ret);
>  	cci_write(imx283->cci, IMX283_REG_VWINPOS, v_pos, &ret);
>  
> -	cci_write(imx283->cci, IMX283_REG_OB_SIZE_V, mode->vertical_ob, &ret);
> +	cci_write(imx283->cci, IMX283_REG_OB_SIZE_V, ob_size_v, &ret);
> +
> +	htrim_end = mode->crop.left + mode->crop.width;
> +
> +	if (mode->mode == IMX283_MODE_0_OB)
> +		htrim_end -= mode->horizontal_ob * mode->hbin_ratio;
>  
>  	/* TODO: Validate mode->crop is fully contained within imx283_native_area */
>  	cci_write(imx283->cci, IMX283_REG_HTRIMMING_START, mode->crop.left, &ret);
> -	cci_write(imx283->cci, IMX283_REG_HTRIMMING_END,
> -		  mode->crop.left + mode->crop.width, &ret);
> +	cci_write(imx283->cci, IMX283_REG_HTRIMMING_END, htrim_end, &ret);
>  
>  	/* Disable embedded data */
>  	cci_write(imx283->cci, IMX283_REG_EBD_X_OUT_SIZE, 0, &ret);

-- 
Regards,

Laurent Pinchart




[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux