diff options
Diffstat (limited to 'drivers/media/platform/vimc/vimc-common.c')
| -rw-r--r-- | drivers/media/platform/vimc/vimc-common.c | 313 | 
1 files changed, 132 insertions, 181 deletions
diff --git a/drivers/media/platform/vimc/vimc-common.c b/drivers/media/platform/vimc/vimc-common.c index c1a74bb2df58..fad7c7c6de93 100644 --- a/drivers/media/platform/vimc/vimc-common.c +++ b/drivers/media/platform/vimc/vimc-common.c @@ -20,192 +20,139 @@  #include "vimc-common.h" -/* - * NOTE: non-bayer formats need to come first (necessary for enum_mbus_code - * in the scaler) - */ -static const struct vimc_pix_map vimc_pix_map_list[] = { -	/* TODO: add all missing formats */ - -	/* RGB formats */ -	{ -		.code = MEDIA_BUS_FMT_BGR888_1X24, -		.pixelformat = V4L2_PIX_FMT_BGR24, -		.bpp = 3, -		.bayer = false, -	}, -	{ -		.code = MEDIA_BUS_FMT_RGB888_1X24, -		.pixelformat = V4L2_PIX_FMT_RGB24, -		.bpp = 3, -		.bayer = false, -	}, -	{ -		.code = MEDIA_BUS_FMT_ARGB8888_1X32, -		.pixelformat = V4L2_PIX_FMT_ARGB32, -		.bpp = 4, -		.bayer = false, -	}, - -	/* Bayer formats */ -	{ -		.code = MEDIA_BUS_FMT_SBGGR8_1X8, -		.pixelformat = V4L2_PIX_FMT_SBGGR8, -		.bpp = 1, -		.bayer = true, -	}, -	{ -		.code = MEDIA_BUS_FMT_SGBRG8_1X8, -		.pixelformat = V4L2_PIX_FMT_SGBRG8, -		.bpp = 1, -		.bayer = true, -	}, -	{ -		.code = MEDIA_BUS_FMT_SGRBG8_1X8, -		.pixelformat = V4L2_PIX_FMT_SGRBG8, -		.bpp = 1, -		.bayer = true, -	}, -	{ -		.code = MEDIA_BUS_FMT_SRGGB8_1X8, -		.pixelformat = V4L2_PIX_FMT_SRGGB8, -		.bpp = 1, -		.bayer = true, -	}, -	{ -		.code = MEDIA_BUS_FMT_SBGGR10_1X10, -		.pixelformat = V4L2_PIX_FMT_SBGGR10, -		.bpp = 2, -		.bayer = true, -	}, -	{ -		.code = MEDIA_BUS_FMT_SGBRG10_1X10, -		.pixelformat = V4L2_PIX_FMT_SGBRG10, -		.bpp = 2, -		.bayer = true, -	}, -	{ -		.code = MEDIA_BUS_FMT_SGRBG10_1X10, -		.pixelformat = V4L2_PIX_FMT_SGRBG10, -		.bpp = 2, -		.bayer = true, -	}, -	{ -		.code = MEDIA_BUS_FMT_SRGGB10_1X10, -		.pixelformat = V4L2_PIX_FMT_SRGGB10, -		.bpp = 2, -		.bayer = true, -	}, - -	/* 10bit raw bayer a-law compressed to 8 bits */ -	{ -		.code = MEDIA_BUS_FMT_SBGGR10_ALAW8_1X8, -		.pixelformat = V4L2_PIX_FMT_SBGGR10ALAW8, -		.bpp = 1, -		.bayer = true, -	}, -	{ -		.code = MEDIA_BUS_FMT_SGBRG10_ALAW8_1X8, -		.pixelformat = V4L2_PIX_FMT_SGBRG10ALAW8, -		.bpp = 1, -		.bayer = true, -	}, -	{ -		.code = MEDIA_BUS_FMT_SGRBG10_ALAW8_1X8, -		.pixelformat = V4L2_PIX_FMT_SGRBG10ALAW8, -		.bpp = 1, -		.bayer = true, -	}, -	{ -		.code = MEDIA_BUS_FMT_SRGGB10_ALAW8_1X8, -		.pixelformat = V4L2_PIX_FMT_SRGGB10ALAW8, -		.bpp = 1, -		.bayer = true, -	}, - -	/* 10bit raw bayer DPCM compressed to 8 bits */ -	{ -		.code = MEDIA_BUS_FMT_SBGGR10_DPCM8_1X8, -		.pixelformat = V4L2_PIX_FMT_SBGGR10DPCM8, -		.bpp = 1, -		.bayer = true, -	}, -	{ -		.code = MEDIA_BUS_FMT_SGBRG10_DPCM8_1X8, -		.pixelformat = V4L2_PIX_FMT_SGBRG10DPCM8, -		.bpp = 1, -		.bayer = true, -	}, -	{ -		.code = MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8, -		.pixelformat = V4L2_PIX_FMT_SGRBG10DPCM8, -		.bpp = 1, -		.bayer = true, -	}, -	{ -		.code = MEDIA_BUS_FMT_SRGGB10_DPCM8_1X8, -		.pixelformat = V4L2_PIX_FMT_SRGGB10DPCM8, -		.bpp = 1, -		.bayer = true, -	}, -	{ -		.code = MEDIA_BUS_FMT_SBGGR12_1X12, -		.pixelformat = V4L2_PIX_FMT_SBGGR12, -		.bpp = 2, -		.bayer = true, -	}, -	{ -		.code = MEDIA_BUS_FMT_SGBRG12_1X12, -		.pixelformat = V4L2_PIX_FMT_SGBRG12, -		.bpp = 2, -		.bayer = true, -	}, -	{ -		.code = MEDIA_BUS_FMT_SGRBG12_1X12, -		.pixelformat = V4L2_PIX_FMT_SGRBG12, -		.bpp = 2, -		.bayer = true, -	}, -	{ -		.code = MEDIA_BUS_FMT_SRGGB12_1X12, -		.pixelformat = V4L2_PIX_FMT_SRGGB12, -		.bpp = 2, -		.bayer = true, -	}, +static const __u32 vimc_mbus_list[] = { +	MEDIA_BUS_FMT_FIXED, +	MEDIA_BUS_FMT_RGB444_1X12, +	MEDIA_BUS_FMT_RGB444_2X8_PADHI_BE, +	MEDIA_BUS_FMT_RGB444_2X8_PADHI_LE, +	MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE, +	MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE, +	MEDIA_BUS_FMT_RGB565_1X16, +	MEDIA_BUS_FMT_BGR565_2X8_BE, +	MEDIA_BUS_FMT_BGR565_2X8_LE, +	MEDIA_BUS_FMT_RGB565_2X8_BE, +	MEDIA_BUS_FMT_RGB565_2X8_LE, +	MEDIA_BUS_FMT_RGB666_1X18, +	MEDIA_BUS_FMT_RBG888_1X24, +	MEDIA_BUS_FMT_RGB666_1X24_CPADHI, +	MEDIA_BUS_FMT_RGB666_1X7X3_SPWG, +	MEDIA_BUS_FMT_BGR888_1X24, +	MEDIA_BUS_FMT_GBR888_1X24, +	MEDIA_BUS_FMT_RGB888_1X24, +	MEDIA_BUS_FMT_RGB888_2X12_BE, +	MEDIA_BUS_FMT_RGB888_2X12_LE, +	MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, +	MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA, +	MEDIA_BUS_FMT_ARGB8888_1X32, +	MEDIA_BUS_FMT_RGB888_1X32_PADHI, +	MEDIA_BUS_FMT_RGB101010_1X30, +	MEDIA_BUS_FMT_RGB121212_1X36, +	MEDIA_BUS_FMT_RGB161616_1X48, +	MEDIA_BUS_FMT_Y8_1X8, +	MEDIA_BUS_FMT_UV8_1X8, +	MEDIA_BUS_FMT_UYVY8_1_5X8, +	MEDIA_BUS_FMT_VYUY8_1_5X8, +	MEDIA_BUS_FMT_YUYV8_1_5X8, +	MEDIA_BUS_FMT_YVYU8_1_5X8, +	MEDIA_BUS_FMT_UYVY8_2X8, +	MEDIA_BUS_FMT_VYUY8_2X8, +	MEDIA_BUS_FMT_YUYV8_2X8, +	MEDIA_BUS_FMT_YVYU8_2X8, +	MEDIA_BUS_FMT_Y10_1X10, +	MEDIA_BUS_FMT_Y10_2X8_PADHI_LE, +	MEDIA_BUS_FMT_UYVY10_2X10, +	MEDIA_BUS_FMT_VYUY10_2X10, +	MEDIA_BUS_FMT_YUYV10_2X10, +	MEDIA_BUS_FMT_YVYU10_2X10, +	MEDIA_BUS_FMT_Y12_1X12, +	MEDIA_BUS_FMT_UYVY12_2X12, +	MEDIA_BUS_FMT_VYUY12_2X12, +	MEDIA_BUS_FMT_YUYV12_2X12, +	MEDIA_BUS_FMT_YVYU12_2X12, +	MEDIA_BUS_FMT_UYVY8_1X16, +	MEDIA_BUS_FMT_VYUY8_1X16, +	MEDIA_BUS_FMT_YUYV8_1X16, +	MEDIA_BUS_FMT_YVYU8_1X16, +	MEDIA_BUS_FMT_YDYUYDYV8_1X16, +	MEDIA_BUS_FMT_UYVY10_1X20, +	MEDIA_BUS_FMT_VYUY10_1X20, +	MEDIA_BUS_FMT_YUYV10_1X20, +	MEDIA_BUS_FMT_YVYU10_1X20, +	MEDIA_BUS_FMT_VUY8_1X24, +	MEDIA_BUS_FMT_YUV8_1X24, +	MEDIA_BUS_FMT_UYYVYY8_0_5X24, +	MEDIA_BUS_FMT_UYVY12_1X24, +	MEDIA_BUS_FMT_VYUY12_1X24, +	MEDIA_BUS_FMT_YUYV12_1X24, +	MEDIA_BUS_FMT_YVYU12_1X24, +	MEDIA_BUS_FMT_YUV10_1X30, +	MEDIA_BUS_FMT_UYYVYY10_0_5X30, +	MEDIA_BUS_FMT_AYUV8_1X32, +	MEDIA_BUS_FMT_UYYVYY12_0_5X36, +	MEDIA_BUS_FMT_YUV12_1X36, +	MEDIA_BUS_FMT_YUV16_1X48, +	MEDIA_BUS_FMT_UYYVYY16_0_5X48, +	MEDIA_BUS_FMT_SBGGR8_1X8, +	MEDIA_BUS_FMT_SGBRG8_1X8, +	MEDIA_BUS_FMT_SGRBG8_1X8, +	MEDIA_BUS_FMT_SRGGB8_1X8, +	MEDIA_BUS_FMT_SBGGR10_ALAW8_1X8, +	MEDIA_BUS_FMT_SGBRG10_ALAW8_1X8, +	MEDIA_BUS_FMT_SGRBG10_ALAW8_1X8, +	MEDIA_BUS_FMT_SRGGB10_ALAW8_1X8, +	MEDIA_BUS_FMT_SBGGR10_DPCM8_1X8, +	MEDIA_BUS_FMT_SGBRG10_DPCM8_1X8, +	MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8, +	MEDIA_BUS_FMT_SRGGB10_DPCM8_1X8, +	MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_BE, +	MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE, +	MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_BE, +	MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_LE, +	MEDIA_BUS_FMT_SBGGR10_1X10, +	MEDIA_BUS_FMT_SGBRG10_1X10, +	MEDIA_BUS_FMT_SGRBG10_1X10, +	MEDIA_BUS_FMT_SRGGB10_1X10, +	MEDIA_BUS_FMT_SBGGR12_1X12, +	MEDIA_BUS_FMT_SGBRG12_1X12, +	MEDIA_BUS_FMT_SGRBG12_1X12, +	MEDIA_BUS_FMT_SRGGB12_1X12, +	MEDIA_BUS_FMT_SBGGR14_1X14, +	MEDIA_BUS_FMT_SGBRG14_1X14, +	MEDIA_BUS_FMT_SGRBG14_1X14, +	MEDIA_BUS_FMT_SRGGB14_1X14, +	MEDIA_BUS_FMT_SBGGR16_1X16, +	MEDIA_BUS_FMT_SGBRG16_1X16, +	MEDIA_BUS_FMT_SGRBG16_1X16, +	MEDIA_BUS_FMT_SRGGB16_1X16, +	MEDIA_BUS_FMT_JPEG_1X8, +	MEDIA_BUS_FMT_S5C_UYVY_JPEG_1X8, +	MEDIA_BUS_FMT_AHSV8888_1X32,  }; -const struct vimc_pix_map *vimc_pix_map_by_index(unsigned int i) -{ -	if (i >= ARRAY_SIZE(vimc_pix_map_list)) -		return NULL; - -	return &vimc_pix_map_list[i]; -} -EXPORT_SYMBOL_GPL(vimc_pix_map_by_index); - -const struct vimc_pix_map *vimc_pix_map_by_code(u32 code) +/* Helper function to check mbus codes */ +bool vimc_mbus_code_supported(__u32 code)  {  	unsigned int i; -	for (i = 0; i < ARRAY_SIZE(vimc_pix_map_list); i++) { -		if (vimc_pix_map_list[i].code == code) -			return &vimc_pix_map_list[i]; -	} -	return NULL; +	for (i = 0; i < ARRAY_SIZE(vimc_mbus_list); i++) +		if (code == vimc_mbus_list[i]) +			return true; +	return false;  } -EXPORT_SYMBOL_GPL(vimc_pix_map_by_code); +EXPORT_SYMBOL_GPL(vimc_mbus_code_supported); -const struct vimc_pix_map *vimc_pix_map_by_pixelformat(u32 pixelformat) +/* Helper function to enumerate mbus codes */ +int vimc_enum_mbus_code(struct v4l2_subdev *sd, +			struct v4l2_subdev_pad_config *cfg, +			struct v4l2_subdev_mbus_code_enum *code)  { -	unsigned int i; +	if (code->index >= ARRAY_SIZE(vimc_mbus_list)) +		return -EINVAL; -	for (i = 0; i < ARRAY_SIZE(vimc_pix_map_list); i++) { -		if (vimc_pix_map_list[i].pixelformat == pixelformat) -			return &vimc_pix_map_list[i]; -	} -	return NULL; +	code->code = vimc_mbus_list[code->index]; +	return 0;  } -EXPORT_SYMBOL_GPL(vimc_pix_map_by_pixelformat); +EXPORT_SYMBOL_GPL(vimc_enum_mbus_code);  /* Helper function to allocate and initialize pads */  struct media_pad *vimc_pads_init(u16 num_pads, const unsigned long *pads_flag) @@ -277,15 +224,13 @@ static int vimc_get_mbus_format(struct media_pad *pad,  							 struct video_device,  							 entity);  		struct vimc_ent_device *ved = video_get_drvdata(vdev); -		const struct vimc_pix_map *vpix;  		struct v4l2_pix_format vdev_fmt;  		if (!ved->vdev_get_format)  			return -ENOIOCTLCMD;  		ved->vdev_get_format(ved, &vdev_fmt); -		vpix = vimc_pix_map_by_pixelformat(vdev_fmt.pixelformat); -		v4l2_fill_mbus_format(&fmt->format, &vdev_fmt, vpix->code); +		v4l2_fill_mbus_format(&fmt->format, &vdev_fmt, 0);  	} else {  		return -EINVAL;  	} @@ -325,8 +270,12 @@ int vimc_link_validate(struct media_link *link)  	/* The width, height and code must match. */  	if (source_fmt.format.width != sink_fmt.format.width  	    || source_fmt.format.height != sink_fmt.format.height -	    || source_fmt.format.code != sink_fmt.format.code) +	    || (source_fmt.format.code && sink_fmt.format.code && +		source_fmt.format.code != sink_fmt.format.code)) { +		pr_err("vimc: format doesn't match in link %s->%s\n", +			link->source->entity->name, link->sink->entity->name);  		return -EPIPE; +	}  	/*  	 * The field order must match, or the sink field order must be NONE @@ -380,6 +329,7 @@ int vimc_ent_sd_register(struct vimc_ent_device *ved,  			 u32 function,  			 u16 num_pads,  			 const unsigned long *pads_flag, +			 const struct v4l2_subdev_internal_ops *sd_int_ops,  			 const struct v4l2_subdev_ops *sd_ops)  {  	int ret; @@ -394,6 +344,7 @@ int vimc_ent_sd_register(struct vimc_ent_device *ved,  	/* Initialize the subdev */  	v4l2_subdev_init(sd, sd_ops); +	sd->internal_ops = sd_int_ops;  	sd->entity.function = function;  	sd->entity.ops = &vimc_ent_sd_mops;  	sd->owner = THIS_MODULE; @@ -431,9 +382,9 @@ EXPORT_SYMBOL_GPL(vimc_ent_sd_register);  void vimc_ent_sd_unregister(struct vimc_ent_device *ved, struct v4l2_subdev *sd)  { -	v4l2_device_unregister_subdev(sd);  	media_entity_cleanup(ved->ent);  	vimc_pads_cleanup(ved->pads); +	v4l2_device_unregister_subdev(sd);  }  EXPORT_SYMBOL_GPL(vimc_ent_sd_unregister);  |