diff options
Diffstat (limited to 'drivers/media/v4l2-core/v4l2-ioctl.c')
| -rw-r--r-- | drivers/media/v4l2-core/v4l2-ioctl.c | 77 | 
1 files changed, 46 insertions, 31 deletions
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c index 51b912743f0f..003b7422aeef 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c @@ -932,12 +932,22 @@ static int check_ext_ctrls(struct v4l2_ext_controls *c, int allow_priv)  static int check_fmt(struct file *file, enum v4l2_buf_type type)  { +	const u32 vid_caps = V4L2_CAP_VIDEO_CAPTURE | +			     V4L2_CAP_VIDEO_CAPTURE_MPLANE | +			     V4L2_CAP_VIDEO_OUTPUT | +			     V4L2_CAP_VIDEO_OUTPUT_MPLANE | +			     V4L2_CAP_VIDEO_M2M | V4L2_CAP_VIDEO_M2M_MPLANE; +	const u32 meta_caps = V4L2_CAP_META_CAPTURE | +			      V4L2_CAP_META_OUTPUT;  	struct video_device *vfd = video_devdata(file);  	const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops; -	bool is_vid = vfd->vfl_type == VFL_TYPE_GRABBER; +	bool is_vid = vfd->vfl_type == VFL_TYPE_GRABBER && +		      (vfd->device_caps & vid_caps);  	bool is_vbi = vfd->vfl_type == VFL_TYPE_VBI;  	bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR;  	bool is_tch = vfd->vfl_type == VFL_TYPE_TOUCH; +	bool is_meta = vfd->vfl_type == VFL_TYPE_GRABBER && +		       (vfd->device_caps & meta_caps);  	bool is_rx = vfd->vfl_dir != VFL_DIR_TX;  	bool is_tx = vfd->vfl_dir != VFL_DIR_RX; @@ -996,11 +1006,11 @@ static int check_fmt(struct file *file, enum v4l2_buf_type type)  			return 0;  		break;  	case V4L2_BUF_TYPE_META_CAPTURE: -		if (is_vid && is_rx && ops->vidioc_g_fmt_meta_cap) +		if (is_meta && is_rx && ops->vidioc_g_fmt_meta_cap)  			return 0;  		break;  	case V4L2_BUF_TYPE_META_OUTPUT: -		if (is_vid && is_tx && ops->vidioc_g_fmt_meta_out) +		if (is_meta && is_tx && ops->vidioc_g_fmt_meta_out)  			return 0;  		break;  	default: @@ -1330,6 +1340,7 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt)  	case V4L2_META_FMT_VSP1_HGT:	descr = "R-Car VSP1 2-D Histogram"; break;  	case V4L2_META_FMT_UVC:		descr = "UVC Payload Header Metadata"; break;  	case V4L2_META_FMT_D4XX:	descr = "Intel D4xx UVC Metadata"; break; +	case V4L2_META_FMT_VIVID:       descr = "Vivid Metadata"; break;  	default:  		/* Compressed formats */ @@ -1356,6 +1367,7 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt)  		case V4L2_PIX_FMT_VP8_FRAME:    descr = "VP8 Frame"; break;  		case V4L2_PIX_FMT_VP9:		descr = "VP9"; break;  		case V4L2_PIX_FMT_HEVC:		descr = "HEVC"; break; /* aka H.265 */ +		case V4L2_PIX_FMT_HEVC_SLICE:	descr = "HEVC Parsed Slice Data"; break;  		case V4L2_PIX_FMT_FWHT:		descr = "FWHT"; break; /* used in vicodec */  		case V4L2_PIX_FMT_FWHT_STATELESS:	descr = "FWHT Stateless"; break; /* used in vicodec */  		case V4L2_PIX_FMT_CPIA1:	descr = "GSPCA CPiA YUV"; break; @@ -1466,10 +1478,26 @@ static int v4l_enum_fmt(const struct v4l2_ioctl_ops *ops,  	return ret;  } +static void v4l_pix_format_touch(struct v4l2_pix_format *p) +{ +	/* +	 * The v4l2_pix_format structure contains fields that make no sense for +	 * touch. Set them to default values in this case. +	 */ + +	p->field = V4L2_FIELD_NONE; +	p->colorspace = V4L2_COLORSPACE_RAW; +	p->flags = 0; +	p->ycbcr_enc = 0; +	p->quantization = 0; +	p->xfer_func = 0; +} +  static int v4l_g_fmt(const struct v4l2_ioctl_ops *ops,  				struct file *file, void *fh, void *arg)  {  	struct v4l2_format *p = arg; +	struct video_device *vfd = video_devdata(file);  	int ret = check_fmt(file, p->type);  	if (ret) @@ -1507,6 +1535,8 @@ static int v4l_g_fmt(const struct v4l2_ioctl_ops *ops,  		ret = ops->vidioc_g_fmt_vid_cap(file, fh, arg);  		/* just in case the driver zeroed it again */  		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC; +		if (vfd->vfl_type == VFL_TYPE_TOUCH) +			v4l_pix_format_touch(&p->fmt.pix);  		return ret;  	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:  		return ops->vidioc_g_fmt_vid_cap_mplane(file, fh, arg); @@ -1544,21 +1574,6 @@ static int v4l_g_fmt(const struct v4l2_ioctl_ops *ops,  	return -EINVAL;  } -static void v4l_pix_format_touch(struct v4l2_pix_format *p) -{ -	/* -	 * The v4l2_pix_format structure contains fields that make no sense for -	 * touch. Set them to default values in this case. -	 */ - -	p->field = V4L2_FIELD_NONE; -	p->colorspace = V4L2_COLORSPACE_RAW; -	p->flags = 0; -	p->ycbcr_enc = 0; -	p->quantization = 0; -	p->xfer_func = 0; -} -  static int v4l_s_fmt(const struct v4l2_ioctl_ops *ops,  				struct file *file, void *fh, void *arg)  { @@ -1602,12 +1617,12 @@ static int v4l_s_fmt(const struct v4l2_ioctl_ops *ops,  	case V4L2_BUF_TYPE_VBI_CAPTURE:  		if (unlikely(!ops->vidioc_s_fmt_vbi_cap))  			break; -		CLEAR_AFTER_FIELD(p, fmt.vbi); +		CLEAR_AFTER_FIELD(p, fmt.vbi.flags);  		return ops->vidioc_s_fmt_vbi_cap(file, fh, arg);  	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:  		if (unlikely(!ops->vidioc_s_fmt_sliced_vbi_cap))  			break; -		CLEAR_AFTER_FIELD(p, fmt.sliced); +		CLEAR_AFTER_FIELD(p, fmt.sliced.io_size);  		return ops->vidioc_s_fmt_sliced_vbi_cap(file, fh, arg);  	case V4L2_BUF_TYPE_VIDEO_OUTPUT:  		if (unlikely(!ops->vidioc_s_fmt_vid_out)) @@ -1633,22 +1648,22 @@ static int v4l_s_fmt(const struct v4l2_ioctl_ops *ops,  	case V4L2_BUF_TYPE_VBI_OUTPUT:  		if (unlikely(!ops->vidioc_s_fmt_vbi_out))  			break; -		CLEAR_AFTER_FIELD(p, fmt.vbi); +		CLEAR_AFTER_FIELD(p, fmt.vbi.flags);  		return ops->vidioc_s_fmt_vbi_out(file, fh, arg);  	case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:  		if (unlikely(!ops->vidioc_s_fmt_sliced_vbi_out))  			break; -		CLEAR_AFTER_FIELD(p, fmt.sliced); +		CLEAR_AFTER_FIELD(p, fmt.sliced.io_size);  		return ops->vidioc_s_fmt_sliced_vbi_out(file, fh, arg);  	case V4L2_BUF_TYPE_SDR_CAPTURE:  		if (unlikely(!ops->vidioc_s_fmt_sdr_cap))  			break; -		CLEAR_AFTER_FIELD(p, fmt.sdr); +		CLEAR_AFTER_FIELD(p, fmt.sdr.buffersize);  		return ops->vidioc_s_fmt_sdr_cap(file, fh, arg);  	case V4L2_BUF_TYPE_SDR_OUTPUT:  		if (unlikely(!ops->vidioc_s_fmt_sdr_out))  			break; -		CLEAR_AFTER_FIELD(p, fmt.sdr); +		CLEAR_AFTER_FIELD(p, fmt.sdr.buffersize);  		return ops->vidioc_s_fmt_sdr_out(file, fh, arg);  	case V4L2_BUF_TYPE_META_CAPTURE:  		if (unlikely(!ops->vidioc_s_fmt_meta_cap)) @@ -1704,12 +1719,12 @@ static int v4l_try_fmt(const struct v4l2_ioctl_ops *ops,  	case V4L2_BUF_TYPE_VBI_CAPTURE:  		if (unlikely(!ops->vidioc_try_fmt_vbi_cap))  			break; -		CLEAR_AFTER_FIELD(p, fmt.vbi); +		CLEAR_AFTER_FIELD(p, fmt.vbi.flags);  		return ops->vidioc_try_fmt_vbi_cap(file, fh, arg);  	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:  		if (unlikely(!ops->vidioc_try_fmt_sliced_vbi_cap))  			break; -		CLEAR_AFTER_FIELD(p, fmt.sliced); +		CLEAR_AFTER_FIELD(p, fmt.sliced.io_size);  		return ops->vidioc_try_fmt_sliced_vbi_cap(file, fh, arg);  	case V4L2_BUF_TYPE_VIDEO_OUTPUT:  		if (unlikely(!ops->vidioc_try_fmt_vid_out)) @@ -1735,22 +1750,22 @@ static int v4l_try_fmt(const struct v4l2_ioctl_ops *ops,  	case V4L2_BUF_TYPE_VBI_OUTPUT:  		if (unlikely(!ops->vidioc_try_fmt_vbi_out))  			break; -		CLEAR_AFTER_FIELD(p, fmt.vbi); +		CLEAR_AFTER_FIELD(p, fmt.vbi.flags);  		return ops->vidioc_try_fmt_vbi_out(file, fh, arg);  	case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:  		if (unlikely(!ops->vidioc_try_fmt_sliced_vbi_out))  			break; -		CLEAR_AFTER_FIELD(p, fmt.sliced); +		CLEAR_AFTER_FIELD(p, fmt.sliced.io_size);  		return ops->vidioc_try_fmt_sliced_vbi_out(file, fh, arg);  	case V4L2_BUF_TYPE_SDR_CAPTURE:  		if (unlikely(!ops->vidioc_try_fmt_sdr_cap))  			break; -		CLEAR_AFTER_FIELD(p, fmt.sdr); +		CLEAR_AFTER_FIELD(p, fmt.sdr.buffersize);  		return ops->vidioc_try_fmt_sdr_cap(file, fh, arg);  	case V4L2_BUF_TYPE_SDR_OUTPUT:  		if (unlikely(!ops->vidioc_try_fmt_sdr_out))  			break; -		CLEAR_AFTER_FIELD(p, fmt.sdr); +		CLEAR_AFTER_FIELD(p, fmt.sdr.buffersize);  		return ops->vidioc_try_fmt_sdr_out(file, fh, arg);  	case V4L2_BUF_TYPE_META_CAPTURE:  		if (unlikely(!ops->vidioc_try_fmt_meta_cap)) @@ -2637,7 +2652,7 @@ struct v4l2_ioctl_info {  /* Zero struct from after the field to the end */  #define INFO_FL_CLEAR(v4l2_struct, field)			\  	((offsetof(struct v4l2_struct, field) +			\ -	  sizeof(((struct v4l2_struct *)0)->field)) << 16) +	  sizeof_field(struct v4l2_struct, field)) << 16)  #define INFO_FL_CLEAR_MASK	(_IOC_SIZEMASK << 16)  #define DEFINE_V4L_STUB_FUNC(_vidioc)				\  |