diff options
Diffstat (limited to 'drivers/media/v4l2-core/v4l2-dev.c')
| -rw-r--r-- | drivers/media/v4l2-core/v4l2-dev.c | 112 | 
1 files changed, 67 insertions, 45 deletions
diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c index 4037689a945a..da42d172714a 100644 --- a/drivers/media/v4l2-core/v4l2-dev.c +++ b/drivers/media/v4l2-core/v4l2-dev.c @@ -533,13 +533,23 @@ static int get_index(struct video_device *vdev)   */  static void determine_valid_ioctls(struct video_device *vdev)  { +	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;  	DECLARE_BITMAP(valid_ioctls, BASE_VIDIOC_PRIVATE);  	const struct v4l2_ioctl_ops *ops = vdev->ioctl_ops; -	bool is_vid = vdev->vfl_type == VFL_TYPE_GRABBER; +	bool is_vid = vdev->vfl_type == VFL_TYPE_GRABBER && +		      (vdev->device_caps & vid_caps);  	bool is_vbi = vdev->vfl_type == VFL_TYPE_VBI;  	bool is_radio = vdev->vfl_type == VFL_TYPE_RADIO;  	bool is_sdr = vdev->vfl_type == VFL_TYPE_SDR;  	bool is_tch = vdev->vfl_type == VFL_TYPE_TOUCH; +	bool is_meta = vdev->vfl_type == VFL_TYPE_GRABBER && +		       (vdev->device_caps & meta_caps);  	bool is_rx = vdev->vfl_dir != VFL_DIR_TX;  	bool is_tx = vdev->vfl_dir != VFL_DIR_RX; @@ -571,8 +581,10 @@ static void determine_valid_ioctls(struct video_device *vdev)  		set_bit(_IOC_NR(VIDIOC_TRY_EXT_CTRLS), valid_ioctls);  	if (vdev->ctrl_handler || ops->vidioc_querymenu)  		set_bit(_IOC_NR(VIDIOC_QUERYMENU), valid_ioctls); -	SET_VALID_IOCTL(ops, VIDIOC_G_FREQUENCY, vidioc_g_frequency); -	SET_VALID_IOCTL(ops, VIDIOC_S_FREQUENCY, vidioc_s_frequency); +	if (!is_tch) { +		SET_VALID_IOCTL(ops, VIDIOC_G_FREQUENCY, vidioc_g_frequency); +		SET_VALID_IOCTL(ops, VIDIOC_S_FREQUENCY, vidioc_s_frequency); +	}  	SET_VALID_IOCTL(ops, VIDIOC_LOG_STATUS, vidioc_log_status);  #ifdef CONFIG_VIDEO_ADV_DEBUG  	set_bit(_IOC_NR(VIDIOC_DBG_G_CHIP_INFO), valid_ioctls); @@ -586,40 +598,32 @@ static void determine_valid_ioctls(struct video_device *vdev)  	if (ops->vidioc_enum_freq_bands || ops->vidioc_g_tuner || ops->vidioc_g_modulator)  		set_bit(_IOC_NR(VIDIOC_ENUM_FREQ_BANDS), valid_ioctls); -	if (is_vid || is_tch) { -		/* video and metadata specific ioctls */ +	if (is_vid) { +		/* video specific ioctls */  		if ((is_rx && (ops->vidioc_enum_fmt_vid_cap || -			       ops->vidioc_enum_fmt_vid_overlay || -			       ops->vidioc_enum_fmt_meta_cap)) || -		    (is_tx && (ops->vidioc_enum_fmt_vid_out || -			       ops->vidioc_enum_fmt_meta_out))) +			       ops->vidioc_enum_fmt_vid_overlay)) || +		    (is_tx && ops->vidioc_enum_fmt_vid_out))  			set_bit(_IOC_NR(VIDIOC_ENUM_FMT), valid_ioctls);  		if ((is_rx && (ops->vidioc_g_fmt_vid_cap ||  			       ops->vidioc_g_fmt_vid_cap_mplane || -			       ops->vidioc_g_fmt_vid_overlay || -			       ops->vidioc_g_fmt_meta_cap)) || +			       ops->vidioc_g_fmt_vid_overlay)) ||  		    (is_tx && (ops->vidioc_g_fmt_vid_out ||  			       ops->vidioc_g_fmt_vid_out_mplane || -			       ops->vidioc_g_fmt_vid_out_overlay || -			       ops->vidioc_g_fmt_meta_out))) +			       ops->vidioc_g_fmt_vid_out_overlay)))  			 set_bit(_IOC_NR(VIDIOC_G_FMT), valid_ioctls);  		if ((is_rx && (ops->vidioc_s_fmt_vid_cap ||  			       ops->vidioc_s_fmt_vid_cap_mplane || -			       ops->vidioc_s_fmt_vid_overlay || -			       ops->vidioc_s_fmt_meta_cap)) || +			       ops->vidioc_s_fmt_vid_overlay)) ||  		    (is_tx && (ops->vidioc_s_fmt_vid_out ||  			       ops->vidioc_s_fmt_vid_out_mplane || -			       ops->vidioc_s_fmt_vid_out_overlay || -			       ops->vidioc_s_fmt_meta_out))) +			       ops->vidioc_s_fmt_vid_out_overlay)))  			 set_bit(_IOC_NR(VIDIOC_S_FMT), valid_ioctls);  		if ((is_rx && (ops->vidioc_try_fmt_vid_cap ||  			       ops->vidioc_try_fmt_vid_cap_mplane || -			       ops->vidioc_try_fmt_vid_overlay || -			       ops->vidioc_try_fmt_meta_cap)) || +			       ops->vidioc_try_fmt_vid_overlay)) ||  		    (is_tx && (ops->vidioc_try_fmt_vid_out ||  			       ops->vidioc_try_fmt_vid_out_mplane || -			       ops->vidioc_try_fmt_vid_out_overlay || -			       ops->vidioc_try_fmt_meta_out))) +			       ops->vidioc_try_fmt_vid_out_overlay)))  			 set_bit(_IOC_NR(VIDIOC_TRY_FMT), valid_ioctls);  		SET_VALID_IOCTL(ops, VIDIOC_OVERLAY, vidioc_overlay);  		SET_VALID_IOCTL(ops, VIDIOC_G_FBUF, vidioc_g_fbuf); @@ -641,7 +645,21 @@ static void determine_valid_ioctls(struct video_device *vdev)  			set_bit(_IOC_NR(VIDIOC_S_CROP), valid_ioctls);  		SET_VALID_IOCTL(ops, VIDIOC_G_SELECTION, vidioc_g_selection);  		SET_VALID_IOCTL(ops, VIDIOC_S_SELECTION, vidioc_s_selection); -	} else if (is_vbi) { +	} +	if (is_meta && is_rx) { +		/* metadata capture specific ioctls */ +		SET_VALID_IOCTL(ops, VIDIOC_ENUM_FMT, vidioc_enum_fmt_meta_cap); +		SET_VALID_IOCTL(ops, VIDIOC_G_FMT, vidioc_g_fmt_meta_cap); +		SET_VALID_IOCTL(ops, VIDIOC_S_FMT, vidioc_s_fmt_meta_cap); +		SET_VALID_IOCTL(ops, VIDIOC_TRY_FMT, vidioc_try_fmt_meta_cap); +	} else if (is_meta && is_tx) { +		/* metadata output specific ioctls */ +		SET_VALID_IOCTL(ops, VIDIOC_ENUM_FMT, vidioc_enum_fmt_meta_out); +		SET_VALID_IOCTL(ops, VIDIOC_G_FMT, vidioc_g_fmt_meta_out); +		SET_VALID_IOCTL(ops, VIDIOC_S_FMT, vidioc_s_fmt_meta_out); +		SET_VALID_IOCTL(ops, VIDIOC_TRY_FMT, vidioc_try_fmt_meta_out); +	} +	if (is_vbi) {  		/* vbi specific ioctls */  		if ((is_rx && (ops->vidioc_g_fmt_vbi_cap ||  			       ops->vidioc_g_fmt_sliced_vbi_cap)) || @@ -659,30 +677,35 @@ static void determine_valid_ioctls(struct video_device *vdev)  			       ops->vidioc_try_fmt_sliced_vbi_out)))  			set_bit(_IOC_NR(VIDIOC_TRY_FMT), valid_ioctls);  		SET_VALID_IOCTL(ops, VIDIOC_G_SLICED_VBI_CAP, vidioc_g_sliced_vbi_cap); +	} else if (is_tch) { +		/* touch specific ioctls */ +		SET_VALID_IOCTL(ops, VIDIOC_ENUM_FMT, vidioc_enum_fmt_vid_cap); +		SET_VALID_IOCTL(ops, VIDIOC_G_FMT, vidioc_g_fmt_vid_cap); +		SET_VALID_IOCTL(ops, VIDIOC_S_FMT, vidioc_s_fmt_vid_cap); +		SET_VALID_IOCTL(ops, VIDIOC_TRY_FMT, vidioc_try_fmt_vid_cap); +		SET_VALID_IOCTL(ops, VIDIOC_ENUM_FRAMESIZES, vidioc_enum_framesizes); +		SET_VALID_IOCTL(ops, VIDIOC_ENUM_FRAMEINTERVALS, vidioc_enum_frameintervals); +		SET_VALID_IOCTL(ops, VIDIOC_ENUMINPUT, vidioc_enum_input); +		SET_VALID_IOCTL(ops, VIDIOC_G_INPUT, vidioc_g_input); +		SET_VALID_IOCTL(ops, VIDIOC_S_INPUT, vidioc_s_input); +		SET_VALID_IOCTL(ops, VIDIOC_G_PARM, vidioc_g_parm); +		SET_VALID_IOCTL(ops, VIDIOC_S_PARM, vidioc_s_parm);  	} else if (is_sdr && is_rx) {  		/* SDR receiver specific ioctls */ -		if (ops->vidioc_enum_fmt_sdr_cap) -			set_bit(_IOC_NR(VIDIOC_ENUM_FMT), valid_ioctls); -		if (ops->vidioc_g_fmt_sdr_cap) -			set_bit(_IOC_NR(VIDIOC_G_FMT), valid_ioctls); -		if (ops->vidioc_s_fmt_sdr_cap) -			set_bit(_IOC_NR(VIDIOC_S_FMT), valid_ioctls); -		if (ops->vidioc_try_fmt_sdr_cap) -			set_bit(_IOC_NR(VIDIOC_TRY_FMT), valid_ioctls); +		SET_VALID_IOCTL(ops, VIDIOC_ENUM_FMT, vidioc_enum_fmt_sdr_cap); +		SET_VALID_IOCTL(ops, VIDIOC_G_FMT, vidioc_g_fmt_sdr_cap); +		SET_VALID_IOCTL(ops, VIDIOC_S_FMT, vidioc_s_fmt_sdr_cap); +		SET_VALID_IOCTL(ops, VIDIOC_TRY_FMT, vidioc_try_fmt_sdr_cap);  	} else if (is_sdr && is_tx) {  		/* SDR transmitter specific ioctls */ -		if (ops->vidioc_enum_fmt_sdr_out) -			set_bit(_IOC_NR(VIDIOC_ENUM_FMT), valid_ioctls); -		if (ops->vidioc_g_fmt_sdr_out) -			set_bit(_IOC_NR(VIDIOC_G_FMT), valid_ioctls); -		if (ops->vidioc_s_fmt_sdr_out) -			set_bit(_IOC_NR(VIDIOC_S_FMT), valid_ioctls); -		if (ops->vidioc_try_fmt_sdr_out) -			set_bit(_IOC_NR(VIDIOC_TRY_FMT), valid_ioctls); +		SET_VALID_IOCTL(ops, VIDIOC_ENUM_FMT, vidioc_enum_fmt_sdr_out); +		SET_VALID_IOCTL(ops, VIDIOC_G_FMT, vidioc_g_fmt_sdr_out); +		SET_VALID_IOCTL(ops, VIDIOC_S_FMT, vidioc_s_fmt_sdr_out); +		SET_VALID_IOCTL(ops, VIDIOC_TRY_FMT, vidioc_try_fmt_sdr_out);  	} -	if (is_vid || is_vbi || is_sdr || is_tch) { -		/* ioctls valid for video, metadata, vbi or sdr */ +	if (is_vid || is_vbi || is_sdr || is_tch || is_meta) { +		/* ioctls valid for video, vbi, sdr, touch and metadata */  		SET_VALID_IOCTL(ops, VIDIOC_REQBUFS, vidioc_reqbufs);  		SET_VALID_IOCTL(ops, VIDIOC_QUERYBUF, vidioc_querybuf);  		SET_VALID_IOCTL(ops, VIDIOC_QBUF, vidioc_qbuf); @@ -694,8 +717,8 @@ static void determine_valid_ioctls(struct video_device *vdev)  		SET_VALID_IOCTL(ops, VIDIOC_STREAMOFF, vidioc_streamoff);  	} -	if (is_vid || is_vbi || is_tch) { -		/* ioctls valid for video or vbi */ +	if (is_vid || is_vbi || is_meta) { +		/* ioctls valid for video, vbi and metadata */  		if (ops->vidioc_s_std)  			set_bit(_IOC_NR(VIDIOC_ENUMSTD), valid_ioctls);  		SET_VALID_IOCTL(ops, VIDIOC_S_STD, vidioc_s_std); @@ -719,8 +742,7 @@ static void determine_valid_ioctls(struct video_device *vdev)  			SET_VALID_IOCTL(ops, VIDIOC_G_AUDOUT, vidioc_g_audout);  			SET_VALID_IOCTL(ops, VIDIOC_S_AUDOUT, vidioc_s_audout);  		} -		if (ops->vidioc_g_parm || (vdev->vfl_type == VFL_TYPE_GRABBER && -					ops->vidioc_g_std)) +		if (ops->vidioc_g_parm || ops->vidioc_g_std)  			set_bit(_IOC_NR(VIDIOC_G_PARM), valid_ioctls);  		SET_VALID_IOCTL(ops, VIDIOC_S_PARM, vidioc_s_parm);  		SET_VALID_IOCTL(ops, VIDIOC_S_DV_TIMINGS, vidioc_s_dv_timings); @@ -734,7 +756,7 @@ static void determine_valid_ioctls(struct video_device *vdev)  		SET_VALID_IOCTL(ops, VIDIOC_G_MODULATOR, vidioc_g_modulator);  		SET_VALID_IOCTL(ops, VIDIOC_S_MODULATOR, vidioc_s_modulator);  	} -	if (is_rx) { +	if (is_rx && !is_tch) {  		/* receiver only ioctls */  		SET_VALID_IOCTL(ops, VIDIOC_G_TUNER, vidioc_g_tuner);  		SET_VALID_IOCTL(ops, VIDIOC_S_TUNER, vidioc_s_tuner);  |