diff options
Diffstat (limited to 'isp')
| -rw-r--r-- | isp/omap3isp-priv.h | 2 | ||||
| -rw-r--r-- | isp/omap3isp.c | 118 | 
2 files changed, 61 insertions, 59 deletions
| diff --git a/isp/omap3isp-priv.h b/isp/omap3isp-priv.h index 9706ba8..b143b13 100644 --- a/isp/omap3isp-priv.h +++ b/isp/omap3isp-priv.h @@ -51,6 +51,7 @@ enum omap3_isp_entity_type {   * @entity: Media entity information   * @sink: Sink pad   * @source: Sink pad + * @last: Indicates whether this is the last entity in the pipeline   */  struct omap3_isp_entity {  	struct list_entry list; @@ -58,6 +59,7 @@ struct omap3_isp_entity {  	struct media_entity *entity;  	struct omap3_isp_pad sink;  	struct omap3_isp_pad source; +	bool last;  };  /* diff --git a/isp/omap3isp.c b/isp/omap3isp.c index 7ab90c4..24d956c 100644 --- a/isp/omap3isp.c +++ b/isp/omap3isp.c @@ -88,6 +88,26 @@ static __u32 mbus_to_pix(enum v4l2_mbus_pixelcode code)  	}  } +static enum v4l2_mbus_pixelcode pix_to_mbus(__u32 pixelformat) +{ +	switch (pixelformat) { +	case V4L2_PIX_FMT_SBGGR10: +		return V4L2_MBUS_FMT_SBGGR10_1X10; +	case V4L2_PIX_FMT_SGBRG10: +		return V4L2_MBUS_FMT_SGBRG10_1X10; +	case V4L2_PIX_FMT_SGRBG10: +		return V4L2_MBUS_FMT_SGRBG10_1X10; +	case V4L2_PIX_FMT_SRGGB10: +		return V4L2_MBUS_FMT_SRGGB10_1X10; +	case V4L2_PIX_FMT_UYVY: +		return V4L2_MBUS_FMT_UYVY8_1X16; +	case V4L2_PIX_FMT_YUYV: +		return V4L2_MBUS_FMT_YUYV8_1X16; +	default: +		return 0; +	} +} +  static const char *entity_name(struct omap3_isp_entity *entity)  {  	if (entity == NULL) @@ -316,6 +336,7 @@ static int omap3_isp_pipeline_build(struct omap3_isp_device *isp,  	}  	pipe->output = to_omap3_isp_video(source); +	source->last = true;  	va_end(ap);  	ret = 0; @@ -333,9 +354,10 @@ static int omap3_isp_pipeline_try_format(struct omap3_isp_device *isp,  					 enum omap3_isp_scaler scaler)  {  	struct v4l2_mbus_framefmt format; +	struct v4l2_pix_format v4l2_fmt;  	struct omap3_isp_entity *source = NULL;  	struct omap3_isp_entity *sink; -	struct omap3_isp_entity *last = NULL; +	struct omap3_isp_video *video;  	struct media_entity_pad *pad;  	int ret; @@ -376,7 +398,11 @@ static int omap3_isp_pipeline_try_format(struct omap3_isp_device *isp,  				return ret;  			} -			format.code = ofmt->code; +			if (sink->last) +				format = *ofmt; +			else +				format.code = ofmt->code; +  			ret = v4l2_subdev_set_format(pad->entity, &format, pad->index,  						     V4L2_SUBDEV_FORMAT_TRY);  			if (ret < 0) { @@ -386,6 +412,8 @@ static int omap3_isp_pipeline_try_format(struct omap3_isp_device *isp,  			}  			source->source.format = format; +			if (sink->last) +				*ofmt = format;  		}  		if (sink->type == OMAP3_ISP_ENTITY_ENTITY) { @@ -401,24 +429,34 @@ static int omap3_isp_pipeline_try_format(struct omap3_isp_device *isp,  			}  			sink->sink.format = format; -			last = sink; -		} - -		source = sink; -	} +		} else if (sink->type == OMAP3_ISP_ENTITY_VIDEO) { +			video = to_omap3_isp_video(sink); + +			/* Set the capture format on the capture or output video +			 * node. If the connected source is a pool, v4l2_fmt +			 * already contains the format that has been setup on +			 * the associated capture video node. +			 */ +			if (source->type != OMAP3_ISP_ENTITY_POOL) { +				memset(&v4l2_fmt, 0, sizeof v4l2_fmt); +				v4l2_fmt.pixelformat = mbus_to_pix(format.code); +				v4l2_fmt.width = format.width; +				v4l2_fmt.height = format.height; +			} -	if (last != NULL) { -		pad = last->source.link->source; +			ret = v4l2_set_format(video->video, &v4l2_fmt); +			if (ret < 0) { +				printf("error: set format failed on %s.\n", +					sink->entity->info.name); +				return ret; +			} -		ret = v4l2_subdev_set_format(pad->entity, ofmt, pad->index, -					     V4L2_SUBDEV_FORMAT_TRY); -		if (ret < 0) { -			printf("error: set format failed on %s:%u.\n", -				pad->entity->info.name, pad->index); -			return ret; +			video->format.code = pix_to_mbus(v4l2_fmt.pixelformat); +			video->format.width = v4l2_fmt.width; +			video->format.height = v4l2_fmt.height;  		} -		last->source.format = *ofmt; +		source = sink;  	}  	return 0; @@ -430,7 +468,6 @@ static int omap3_isp_pipeline_activate(struct omap3_isp_device *isp,  	struct v4l2_mbus_framefmt format;  	struct omap3_isp_entity *source = NULL;  	struct omap3_isp_entity *sink; -	struct omap3_isp_entity *last = NULL;  	struct media_entity_pad *pad;  	int ret; @@ -475,7 +512,11 @@ static int omap3_isp_pipeline_activate(struct omap3_isp_device *isp,  				return ret;  			} -			format.code = source->source.format.code; +			if (sink->last) +				format = source->source.format; +			else +				format.code = source->source.format.code; +  			ret = v4l2_subdev_set_format(pad->entity, &format, pad->index,  						     V4L2_SUBDEV_FORMAT_ACTIVE);  			if (ret < 0) { @@ -496,26 +537,11 @@ static int omap3_isp_pipeline_activate(struct omap3_isp_device *isp,  					pad->entity->info.name, pad->index);  				return ret;  			} - -			last = sink;  		}  		source = sink;  	} -	if (last != NULL) { -		pad = last->source.link->source; -		format = last->source.format; - -		ret = v4l2_subdev_set_format(pad->entity, &format, pad->index, -					     V4L2_SUBDEV_FORMAT_ACTIVE); -		if (ret < 0) { -			printf("error: set format failed on %s:%u.\n", -				pad->entity->info.name, pad->index); -			return ret; -		} -	} -  	return 0;  } @@ -627,7 +653,6 @@ static int omap3_isp_viewfinder_setup_pipeline(struct omap3_isp_device *isp)  int omap3_isp_viewfinder_setup(struct omap3_isp_device *isp,  			       struct v4l2_mbus_framefmt *ofmt)  { -	struct v4l2_pix_format format;  	int ret;  	ret = omap3_isp_pipeline_build(isp, &isp->viewfinder, ENTITY_SENSOR, @@ -651,18 +676,6 @@ int omap3_isp_viewfinder_setup(struct omap3_isp_device *isp,  	if (ret < 0)  		return ret; -	/* Set the capture format on the output video node. */ -	memset(&format, 0, sizeof format); -	format.pixelformat = mbus_to_pix(ofmt->code); -	format.width = ofmt->width; -	format.height = ofmt->height; - -	ret = v4l2_set_format(isp->viewfinder.output->video, &format); -	if (ret < 0) -		return ret; - -	isp->viewfinder.output->format = *ofmt; -  	return 0;  } @@ -822,7 +835,6 @@ int omap3_isp_snapshot_setup(struct omap3_isp_device *isp,  			     struct v4l2_mbus_framefmt *ofmt)  {  	struct v4l2_video_buffer buffer; -	struct v4l2_pix_format format;  	struct media_entity *entity;  	unsigned int i;  	int ret; @@ -858,18 +870,6 @@ int omap3_isp_snapshot_setup(struct omap3_isp_device *isp,  	if (ret < 0)  		return ret; -	isp->snapshot.output->format = *ofmt; - -	/* Set the capture format on the output video node. */ -	memset(&format, 0, sizeof format); -	format.pixelformat = mbus_to_pix(ofmt->code); -	format.width = ofmt->width; -	format.height = ofmt->height; - -	ret = v4l2_set_format(isp->snapshot.output->video, &format); -	if (ret < 0) -		return ret; -  	/* Pre-allocate capture buffers. */  	isp->snapshot.output->pool = v4l2_buffers_pool_new(2);  	if (isp->snapshot.output->pool == NULL) { | 
