[PATCH 3/8] tvp514x: Migrate to media-controller framework

Hans Verkuil hverkuil at xs4all.nl
Mon Sep 26 06:06:42 EDT 2011


(Sorry for the late reply, I'm plowing through weeks of backlog...)

On Thursday, September 08, 2011 15:35:00 Deepthy Ravi wrote:
> From: Vaibhav Hiremath <hvaibhav at ti.com>
> 
> Migrate tvp5146 driver to media controller framework. The
> driver registers as a sub-device entity to MC framwork
> and sub-device to V4L2 layer. The default format code was
> V4L2_MBUS_FMT_YUYV10_2X10. Changed it to V4L2_MBUS_FMT_UYVY8_2X8

Does this mean that the old 2X10 format code is no longer used?
This change basically not just sets a new default format code but removes
the old format code as well. Is that really intended?

If someone else is using that old format already, then this change may well
break his board.

Regards,

	Hans


> and hence added the new format code to ccdc and isp format
> arrays.
> 
> Signed-off-by: Vaibhav Hiremath <hvaibhav at ti.com>
> Signed-off-by: Deepthy Ravi <deepthy.ravi at ti.com>
> ---
>  drivers/media/video/omap3isp/ispccdc.c  |    1 +
>  drivers/media/video/omap3isp/ispvideo.c |    3 +
>  drivers/media/video/tvp514x.c           |  241 ++++++++++++++++++++++++++++---
>  include/media/v4l2-subdev.h             |    7 +-
>  4 files changed, 222 insertions(+), 30 deletions(-)
> 
> diff --git a/drivers/media/video/omap3isp/ispccdc.c b/drivers/media/video/omap3isp/ispccdc.c
> index 9d3459d..d58fe45 100644
> --- a/drivers/media/video/omap3isp/ispccdc.c
> +++ b/drivers/media/video/omap3isp/ispccdc.c
> @@ -57,6 +57,7 @@ static const unsigned int ccdc_fmts[] = {
>  	V4L2_MBUS_FMT_SRGGB12_1X12,
>  	V4L2_MBUS_FMT_SBGGR12_1X12,
>  	V4L2_MBUS_FMT_SGBRG12_1X12,
> +	V4L2_MBUS_FMT_UYVY8_2X8,
>  };
>  
>  /*
> diff --git a/drivers/media/video/omap3isp/ispvideo.c b/drivers/media/video/omap3isp/ispvideo.c
> index fd965ad..d5b8236 100644
> --- a/drivers/media/video/omap3isp/ispvideo.c
> +++ b/drivers/media/video/omap3isp/ispvideo.c
> @@ -100,6 +100,9 @@ static struct isp_format_info formats[] = {
>  	{ V4L2_MBUS_FMT_YUYV8_1X16, V4L2_MBUS_FMT_YUYV8_1X16,
>  	  V4L2_MBUS_FMT_YUYV8_1X16, 0,
>  	  V4L2_PIX_FMT_YUYV, 16, },
> +	{ V4L2_MBUS_FMT_UYVY8_2X8, V4L2_MBUS_FMT_UYVY8_2X8,
> +	  V4L2_MBUS_FMT_UYVY8_2X8, 0,
> +	  V4L2_PIX_FMT_UYVY, 16, },
>  };
>  
>  const struct isp_format_info *
> diff --git a/drivers/media/video/tvp514x.c b/drivers/media/video/tvp514x.c
> index 9b3e828..10f3e87 100644
> --- a/drivers/media/video/tvp514x.c
> +++ b/drivers/media/video/tvp514x.c
> @@ -32,11 +32,14 @@
>  #include <linux/slab.h>
>  #include <linux/delay.h>
>  #include <linux/videodev2.h>
> +#include <linux/v4l2-mediabus.h>
>  
>  #include <media/v4l2-device.h>
>  #include <media/v4l2-common.h>
> -#include <media/v4l2-mediabus.h>
>  #include <media/v4l2-chip-ident.h>
> +#include <media/v4l2-subdev.h>
> +#include <media/v4l2-ctrls.h>
> +
>  #include <media/v4l2-ctrls.h>
>  #include <media/tvp514x.h>
>  
> @@ -78,6 +81,8 @@ struct tvp514x_std_info {
>  	unsigned long height;
>  	u8 video_std;
>  	struct v4l2_standard standard;
> +	unsigned int mbus_code;
> +	struct v4l2_mbus_framefmt format;
>  };
>  
>  static struct tvp514x_reg tvp514x_reg_list_default[0x40];
> @@ -101,6 +106,7 @@ struct tvp514x_decoder {
>  	struct v4l2_ctrl_handler hdl;
>  	struct tvp514x_reg tvp514x_regs[ARRAY_SIZE(tvp514x_reg_list_default)];
>  	const struct tvp514x_platform_data *pdata;
> +	struct media_pad pad;
>  
>  	int ver;
>  	int streaming;
> @@ -207,29 +213,46 @@ static struct tvp514x_reg tvp514x_reg_list_default[] = {
>  static const struct tvp514x_std_info tvp514x_std_list[] = {
>  	/* Standard: STD_NTSC_MJ */
>  	[STD_NTSC_MJ] = {
> -	 .width = NTSC_NUM_ACTIVE_PIXELS,
> -	 .height = NTSC_NUM_ACTIVE_LINES,
> -	 .video_std = VIDEO_STD_NTSC_MJ_BIT,
> -	 .standard = {
> -		      .index = 0,
> -		      .id = V4L2_STD_NTSC,
> -		      .name = "NTSC",
> -		      .frameperiod = {1001, 30000},
> -		      .framelines = 525
> -		     },
> -	/* Standard: STD_PAL_BDGHIN */
> +		.width = NTSC_NUM_ACTIVE_PIXELS,
> +		.height = NTSC_NUM_ACTIVE_LINES,
> +		.video_std = VIDEO_STD_NTSC_MJ_BIT,
> +		.mbus_code = V4L2_MBUS_FMT_UYVY8_2X8,
> +		.standard = {
> +			.index = 0,
> +			.id = V4L2_STD_NTSC,
> +			.name = "NTSC",
> +			.frameperiod = {1001, 30000},
> +			.framelines = 525
> +		},
> +		.format = {
> +			.width = NTSC_NUM_ACTIVE_PIXELS,
> +			.height = NTSC_NUM_ACTIVE_LINES,
> +			.code = V4L2_MBUS_FMT_UYVY8_2X8,
> +			.field = V4L2_FIELD_INTERLACED,
> +			.colorspace = V4L2_COLORSPACE_SMPTE170M,
> +		}
> +
>  	},
> +	/* Standard: STD_PAL_BDGHIN */
>  	[STD_PAL_BDGHIN] = {
> -	 .width = PAL_NUM_ACTIVE_PIXELS,
> -	 .height = PAL_NUM_ACTIVE_LINES,
> -	 .video_std = VIDEO_STD_PAL_BDGHIN_BIT,
> -	 .standard = {
> -		      .index = 1,
> -		      .id = V4L2_STD_PAL,
> -		      .name = "PAL",
> -		      .frameperiod = {1, 25},
> -		      .framelines = 625
> -		     },
> +		.width = PAL_NUM_ACTIVE_PIXELS,
> +		.height = PAL_NUM_ACTIVE_LINES,
> +		.video_std = VIDEO_STD_PAL_BDGHIN_BIT,
> +		.mbus_code = V4L2_MBUS_FMT_UYVY8_2X8,
> +		.standard = {
> +			.index = 1,
> +			.id = V4L2_STD_PAL,
> +			.name = "PAL",
> +			.frameperiod = {1, 25},
> +			.framelines = 625
> +		},
> +		.format = {
> +			.width = PAL_NUM_ACTIVE_PIXELS,
> +			.height = PAL_NUM_ACTIVE_LINES,
> +			.code = V4L2_MBUS_FMT_UYVY8_2X8,
> +			.field = V4L2_FIELD_INTERLACED,
> +			.colorspace = V4L2_COLORSPACE_SMPTE170M,
> +		},
>  	},
>  	/* Standard: need to add for additional standard */
>  };
> @@ -792,7 +815,7 @@ tvp514x_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned index,
>  	if (index)
>  		return -EINVAL;
>  
> -	*code = V4L2_MBUS_FMT_YUYV10_2X10;
> +	*code = V4L2_MBUS_FMT_UYVY8_2X8;
>  	return 0;
>  }
>  
> @@ -815,7 +838,7 @@ tvp514x_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *f)
>  	/* Calculate height and width based on current standard */
>  	current_std = decoder->current_std;
>  
> -	f->code = V4L2_MBUS_FMT_YUYV10_2X10;
> +	f->code = V4L2_MBUS_FMT_UYVY8_2X8;
>  	f->width = decoder->std_list[current_std].width;
>  	f->height = decoder->std_list[current_std].height;
>  	f->field = V4L2_FIELD_INTERLACED;
> @@ -952,11 +975,154 @@ static int tvp514x_s_stream(struct v4l2_subdev *sd, int enable)
>  	return err;
>  }
>  
> +static int tvp514x_s_power(struct v4l2_subdev *sd, int on)
> +{
> +	struct tvp514x_decoder *decoder = to_decoder(sd);
> +
> +	if (decoder->pdata && decoder->pdata->s_power)
> +		return decoder->pdata->s_power(sd, on);
> +
> +	return 0;
> +}
> +
> +/*
> +* tvp514x_enum_mbus_code - V4L2 sensor interface handler for pad_ops
> +* @subdev: pointer to standard V4L2 sub-device structure
> +* @fh: pointer to standard V4L2 sub-device file handle
> +* @code: pointer to v4l2_subdev_pad_mbus_code_enum structure
> +*/
> +static int tvp514x_enum_mbus_code(struct v4l2_subdev *subdev,
> +		struct v4l2_subdev_fh *fh,
> +		struct v4l2_subdev_mbus_code_enum *code)
> +{
> +	if (code->index >= ARRAY_SIZE(tvp514x_std_list))
> +		return -EINVAL;
> +	code->code = V4L2_MBUS_FMT_UYVY8_2X8;
> +
> +	return 0;
> +}
> +
> +static int tvp514x_get_pad_format(struct v4l2_subdev *subdev,
> +		struct v4l2_subdev_fh *fh,
> +		struct v4l2_subdev_format *fmt)
> +{
> +	struct tvp514x_decoder *decoder = to_decoder(subdev);
> +	enum tvp514x_std current_std;
> +
> +	/* query the current standard */
> +	current_std = tvp514x_query_current_std(subdev);
> +	if (current_std == STD_INVALID) {
> +		v4l2_err(subdev, "Unable to query std\n");
> +		return -EINVAL;
> +	}
> +
> +	fmt->format = decoder->std_list[current_std].format;
> +
> +	return 0;
> +}
> +
> +static int tvp514x_set_pad_format(struct v4l2_subdev *subdev,
> +		struct v4l2_subdev_fh *fh,
> +		struct v4l2_subdev_format *fmt)
> +{
> +	struct tvp514x_decoder *decoder = to_decoder(subdev);
> +	enum tvp514x_std current_std;
> +
> +	/* query the current standard */
> +	current_std = tvp514x_query_current_std(subdev);
> +	if (current_std == STD_INVALID) {
> +		v4l2_err(subdev, "Unable to query std\n");
> +		return -EINVAL;
> +	}
> +
> +	fmt->format.width = decoder->std_list[current_std].width;
> +	fmt->format.height = decoder->std_list[current_std].height;
> +	fmt->format.code = V4L2_MBUS_FMT_UYVY8_2X8;
> +	fmt->format.field = V4L2_FIELD_INTERLACED;
> +	fmt->format.colorspace = V4L2_COLORSPACE_SMPTE170M;
> +
> +	return 0;
> +}
> +
> +static int tvp514x_enum_frame_size(struct v4l2_subdev *subdev,
> +		struct v4l2_subdev_fh *fh,
> +		struct v4l2_subdev_frame_size_enum *fse)
> +{
> +	struct tvp514x_decoder *decoder = to_decoder(subdev);
> +	enum tvp514x_std current_std;
> +
> +	if (fse->code != V4L2_MBUS_FMT_UYVY8_2X8)
> +		return -EINVAL;
> +
> +	/* query the current standard */
> +	current_std = tvp514x_query_current_std(subdev);
> +	if (current_std == STD_INVALID) {
> +		v4l2_err(subdev, "Unable to query std\n");
> +		return -EINVAL;
> +	}
> +
> +	fse->min_width = decoder->std_list[current_std].width;
> +	fse->min_height = decoder->std_list[current_std].height;
> +	fse->max_width = fse->min_width;
> +	fse->max_height = fse->min_height;
> +
> +	return 0;
> +}
> +
> +/*
> +* V4L2 subdev internal operations
> +*/
> +static int tvp514x_registered(struct v4l2_subdev *subdev)
> +{
> +	enum tvp514x_std current_std;
> +
> +	tvp514x_s_stream(subdev, 1);
> +	/* query the current standard */
> +	current_std = tvp514x_query_current_std(subdev);
> +	if (current_std == STD_INVALID) {
> +		v4l2_err(subdev, "Unable to query std\n");
> +		return -EINVAL;
> +	}
> +
> +	tvp514x_s_stream(subdev, 0);
> +
> +	return 0;
> +}
> +
> +static int tvp514x_open(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
> +{
> +	enum tvp514x_std current_std;
> +
> +	tvp514x_s_stream(subdev, 1);
> +	/* query the current standard */
> +	current_std = tvp514x_query_current_std(subdev);
> +	if (current_std == STD_INVALID) {
> +		v4l2_err(subdev, "Unable to query std\n");
> +		return -EINVAL;
> +	}
> +
> +	tvp514x_s_stream(subdev, 0);
> +
> +	return 0;
> +}
> +
> +/*
> +* V4L2 subdev core operations
> +*/
> +static int tvp514x_g_chip_ident(struct v4l2_subdev *subdev,
> +				struct v4l2_dbg_chip_ident *chip)
> +{
> +	struct i2c_client *client = v4l2_get_subdevdata(subdev);
> +
> +	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_TVP5146, 0);
> +}
> +
>  static const struct v4l2_ctrl_ops tvp514x_ctrl_ops = {
>  	.s_ctrl = tvp514x_s_ctrl,
>  };
>  
>  static const struct v4l2_subdev_core_ops tvp514x_core_ops = {
> +	.g_chip_ident = tvp514x_g_chip_ident,
>  	.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
>  	.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
>  	.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
> @@ -965,6 +1131,12 @@ static const struct v4l2_subdev_core_ops tvp514x_core_ops = {
>  	.queryctrl = v4l2_subdev_queryctrl,
>  	.querymenu = v4l2_subdev_querymenu,
>  	.s_std = tvp514x_s_std,
> +	.s_power = tvp514x_s_power,
> +};
> +
> +static struct v4l2_subdev_internal_ops tvp514x_subdev_internal_ops = {
> +	.registered	= tvp514x_registered,
> +	.open		= tvp514x_open,
>  };
>  
>  static const struct v4l2_subdev_video_ops tvp514x_video_ops = {
> @@ -979,9 +1151,17 @@ static const struct v4l2_subdev_video_ops tvp514x_video_ops = {
>  	.s_stream = tvp514x_s_stream,
>  };
>  
> +static const struct v4l2_subdev_pad_ops tvp514x_pad_ops = {
> +	.enum_mbus_code = tvp514x_enum_mbus_code,
> +	.enum_frame_size = tvp514x_enum_frame_size,
> +	.get_fmt = tvp514x_get_pad_format,
> +	.set_fmt = tvp514x_set_pad_format,
> +};
> +
>  static const struct v4l2_subdev_ops tvp514x_ops = {
>  	.core = &tvp514x_core_ops,
>  	.video = &tvp514x_video_ops,
> +	.pad = &tvp514x_pad_ops,
>  };
>  
>  static struct tvp514x_decoder tvp514x_dev = {
> @@ -1005,6 +1185,7 @@ tvp514x_probe(struct i2c_client *client, const struct i2c_device_id *id)
>  {
>  	struct tvp514x_decoder *decoder;
>  	struct v4l2_subdev *sd;
> +	int ret;
>  
>  	/* Check if the adapter supports the needed features */
>  	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
> @@ -1046,6 +1227,17 @@ tvp514x_probe(struct i2c_client *client, const struct i2c_device_id *id)
>  	sd = &decoder->sd;
>  	v4l2_i2c_subdev_init(sd, client, &tvp514x_ops);
>  
> +	decoder->sd.internal_ops = &tvp514x_subdev_internal_ops;
> +	sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
> +	decoder->pad.flags = MEDIA_PAD_FL_SOURCE;
> +	decoder->sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
> +	ret = media_entity_init(&decoder->sd.entity, 1, &decoder->pad, 0);
> +	if (ret < 0) {
> +		v4l2_err(client, "failed to register as a media entity!!\n");
> +		kfree(decoder);
> +		return ret;
> +	}
> +
>  	v4l2_ctrl_handler_init(&decoder->hdl, 5);
>  	v4l2_ctrl_new_std(&decoder->hdl, &tvp514x_ctrl_ops,
>  		V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
> @@ -1087,6 +1279,7 @@ static int tvp514x_remove(struct i2c_client *client)
>  
>  	v4l2_device_unregister_subdev(sd);
>  	v4l2_ctrl_handler_free(&decoder->hdl);
> +	media_entity_cleanup(&decoder->sd.entity);
>  	kfree(decoder);
>  	return 0;
>  }
> diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h
> index 257da1a..0e9aa30 100644
> --- a/include/media/v4l2-subdev.h
> +++ b/include/media/v4l2-subdev.h
> @@ -514,9 +514,8 @@ struct v4l2_subdev_internal_ops {
>     stand-alone or embedded in a larger struct.
>   */
>  struct v4l2_subdev {
> -#if defined(CONFIG_MEDIA_CONTROLLER)
>  	struct media_entity entity;
> -#endif
> +
>  	struct list_head list;
>  	struct module *owner;
>  	u32 flags;
> @@ -547,16 +546,13 @@ struct v4l2_subdev {
>   */
>  struct v4l2_subdev_fh {
>  	struct v4l2_fh vfh;
> -#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
>  	struct v4l2_mbus_framefmt *try_fmt;
>  	struct v4l2_rect *try_crop;
> -#endif
>  };
>  
>  #define to_v4l2_subdev_fh(fh)	\
>  	container_of(fh, struct v4l2_subdev_fh, vfh)
>  
> -#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
>  static inline struct v4l2_mbus_framefmt *
>  v4l2_subdev_get_try_format(struct v4l2_subdev_fh *fh, unsigned int pad)
>  {
> @@ -568,7 +564,6 @@ v4l2_subdev_get_try_crop(struct v4l2_subdev_fh *fh, unsigned int pad)
>  {
>  	return &fh->try_crop[pad];
>  }
> -#endif
>  
>  extern const struct v4l2_file_operations v4l2_subdev_fops;
>  
> 



More information about the linux-arm-kernel mailing list