mirror of
				https://github.com/Ysurac/openmptcprouter.git
				synced 2025-03-09 15:40:20 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			135 lines
		
	
	
	
		
			4.9 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			135 lines
		
	
	
	
		
			4.9 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| From b16f03e493b83b4fe35af6bd1d5df3de5b8bbd6a Mon Sep 17 00:00:00 2001
 | |
| From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
 | |
| Date: Sun, 16 Oct 2022 09:15:22 +0300
 | |
| Subject: [PATCH] media: i2c: imx290: Add crop selection targets support
 | |
| 
 | |
| Upstream commit b4ab57b07c5b.
 | |
| 
 | |
| Implement read-only access to crop selection rectangles to expose the
 | |
| analogue crop rectangle. The public (leaked) IMX290 documentation is not
 | |
| very clear on how cropping is implemented and configured exactly, so
 | |
| the margins may not be entirely accurate.
 | |
| 
 | |
| Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
 | |
| Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
 | |
| ---
 | |
|  drivers/media/i2c/imx290.c | 94 ++++++++++++++++++++++++++++++++++++++
 | |
|  1 file changed, 94 insertions(+)
 | |
| 
 | |
| --- a/drivers/media/i2c/imx290.c
 | |
| +++ b/drivers/media/i2c/imx290.c
 | |
| @@ -105,6 +105,53 @@
 | |
|  
 | |
|  #define IMX290_VMAX_DEFAULT				1125
 | |
|  
 | |
| +
 | |
| +/*
 | |
| + * The IMX290 pixel array is organized as follows:
 | |
| + *
 | |
| + *     +------------------------------------+
 | |
| + *     |           Optical Black            |     }  Vertical effective optical black (10)
 | |
| + * +---+------------------------------------+---+
 | |
| + * |   |                                    |   | }  Effective top margin (8)
 | |
| + * |   |   +----------------------------+   |   | \
 | |
| + * |   |   |                            |   |   |  |
 | |
| + * |   |   |                            |   |   |  |
 | |
| + * |   |   |                            |   |   |  |
 | |
| + * |   |   |    Recording Pixel Area    |   |   |  | Recommended height (1080)
 | |
| + * |   |   |                            |   |   |  |
 | |
| + * |   |   |                            |   |   |  |
 | |
| + * |   |   |                            |   |   |  |
 | |
| + * |   |   +----------------------------+   |   | /
 | |
| + * |   |                                    |   | }  Effective bottom margin (9)
 | |
| + * +---+------------------------------------+---+
 | |
| + *  <-> <-> <--------------------------> <-> <->
 | |
| + *                                            \----  Ignored right margin (4)
 | |
| + *                                        \--------  Effective right margin (9)
 | |
| + *                       \-------------------------  Recommended width (1920)
 | |
| + *       \-----------------------------------------  Effective left margin (8)
 | |
| + *   \---------------------------------------------  Ignored left margin (4)
 | |
| + *
 | |
| + * The optical black lines are output over CSI-2 with a separate data type.
 | |
| + *
 | |
| + * The pixel array is meant to have 1920x1080 usable pixels after image
 | |
| + * processing in an ISP. It has 8 (9) extra active pixels usable for color
 | |
| + * processing in the ISP on the top and left (bottom and right) sides of the
 | |
| + * image. In addition, 4 additional pixels are present on the left and right
 | |
| + * sides of the image, documented as "ignored area".
 | |
| + *
 | |
| + * As far as is understood, all pixels of the pixel array (ignored area, color
 | |
| + * processing margins and recording area) can be output by the sensor.
 | |
| + */
 | |
| +
 | |
| +#define IMX290_PIXEL_ARRAY_WIDTH			1945
 | |
| +#define IMX290_PIXEL_ARRAY_HEIGHT			1097
 | |
| +#define IMX920_PIXEL_ARRAY_MARGIN_LEFT			12
 | |
| +#define IMX920_PIXEL_ARRAY_MARGIN_RIGHT			13
 | |
| +#define IMX920_PIXEL_ARRAY_MARGIN_TOP			8
 | |
| +#define IMX920_PIXEL_ARRAY_MARGIN_BOTTOM		9
 | |
| +#define IMX290_PIXEL_ARRAY_RECORDING_WIDTH		1920
 | |
| +#define IMX290_PIXEL_ARRAY_RECORDING_HEIGHT		1080
 | |
| +
 | |
|  static const char * const imx290_supply_name[] = {
 | |
|  	"vdda",
 | |
|  	"vddd",
 | |
| @@ -667,6 +714,52 @@ static int imx290_set_fmt(struct v4l2_su
 | |
|  	return 0;
 | |
|  }
 | |
|  
 | |
| +static int imx290_get_selection(struct v4l2_subdev *sd,
 | |
| +				struct v4l2_subdev_state *sd_state,
 | |
| +				struct v4l2_subdev_selection *sel)
 | |
| +{
 | |
| +	struct imx290 *imx290 = to_imx290(sd);
 | |
| +	struct v4l2_mbus_framefmt *format;
 | |
| +
 | |
| +	switch (sel->target) {
 | |
| +	case V4L2_SEL_TGT_CROP: {
 | |
| +		format = imx290_get_pad_format(imx290, sd_state, sel->which);
 | |
| +
 | |
| +		mutex_lock(&imx290->lock);
 | |
| +
 | |
| +		sel->r.top = IMX920_PIXEL_ARRAY_MARGIN_TOP
 | |
| +			   + (IMX290_PIXEL_ARRAY_RECORDING_HEIGHT - format->height) / 2;
 | |
| +		sel->r.left = IMX920_PIXEL_ARRAY_MARGIN_LEFT
 | |
| +			    + (IMX290_PIXEL_ARRAY_RECORDING_WIDTH - format->width) / 2;
 | |
| +		sel->r.width = format->width;
 | |
| +		sel->r.height = format->height;
 | |
| +
 | |
| +		mutex_unlock(&imx290->lock);
 | |
| +		return 0;
 | |
| +	}
 | |
| +
 | |
| +	case V4L2_SEL_TGT_NATIVE_SIZE:
 | |
| +	case V4L2_SEL_TGT_CROP_BOUNDS:
 | |
| +		sel->r.top = 0;
 | |
| +		sel->r.left = 0;
 | |
| +		sel->r.width = IMX290_PIXEL_ARRAY_WIDTH;
 | |
| +		sel->r.height = IMX290_PIXEL_ARRAY_HEIGHT;
 | |
| +
 | |
| +		return 0;
 | |
| +
 | |
| +	case V4L2_SEL_TGT_CROP_DEFAULT:
 | |
| +		sel->r.top = IMX920_PIXEL_ARRAY_MARGIN_TOP;
 | |
| +		sel->r.left = IMX920_PIXEL_ARRAY_MARGIN_LEFT;
 | |
| +		sel->r.width = IMX290_PIXEL_ARRAY_RECORDING_WIDTH;
 | |
| +		sel->r.height = IMX290_PIXEL_ARRAY_RECORDING_HEIGHT;
 | |
| +
 | |
| +		return 0;
 | |
| +
 | |
| +	default:
 | |
| +		return -EINVAL;
 | |
| +	}
 | |
| +}
 | |
| +
 | |
|  static int imx290_entity_init_cfg(struct v4l2_subdev *subdev,
 | |
|  				  struct v4l2_subdev_state *sd_state)
 | |
|  {
 | |
| @@ -883,6 +976,7 @@ static const struct v4l2_subdev_pad_ops
 | |
|  	.enum_frame_size = imx290_enum_frame_size,
 | |
|  	.get_fmt = imx290_get_fmt,
 | |
|  	.set_fmt = imx290_set_fmt,
 | |
| +	.get_selection = imx290_get_selection,
 | |
|  };
 | |
|  
 | |
|  static const struct v4l2_subdev_ops imx290_subdev_ops = {
 |