Re: [PATCH v15 13/19] media: uvcvideo: support V4L2_CTRL_WHICH_MIN/MAX_VAL

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

On 14-Nov-24 8:10 PM, Ricardo Ribalda wrote:
> From: Yunke Cao <yunkec@xxxxxxxxxx>
> 
> Add support for V4L2_CTRL_WHICH_MIN/MAX_VAL in uvc driver.
> It is needed for the V4L2_CID_UVC_REGION_OF_INTEREST_RECT control.
> 
> Signed-off-by: Yunke Cao <yunkec@xxxxxxxxxx>
> Signed-off-by: Ricardo Ribalda <ribalda@xxxxxxxxxxxx>

Thanks, patch looks good to me:

Reviewed-by: Hans de Goede <hdegoede@xxxxxxxxxx>

Regards,

Hans




> ---
>  drivers/media/usb/uvc/uvc_ctrl.c | 96 ++++++++++++++++++++++++++++++++--------
>  drivers/media/usb/uvc/uvc_v4l2.c |  2 +
>  2 files changed, 79 insertions(+), 19 deletions(-)
> 
> diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c
> index b591d7fddc37..0dae5e8c3ca0 100644
> --- a/drivers/media/usb/uvc/uvc_ctrl.c
> +++ b/drivers/media/usb/uvc/uvc_ctrl.c
> @@ -1270,6 +1270,37 @@ static int uvc_query_v4l2_class(struct uvc_video_chain *chain, u32 req_id,
>  	return 0;
>  }
>  
> +static bool uvc_ctrl_is_readable(u32 which, struct uvc_control *ctrl,
> +				 struct uvc_control_mapping *mapping)
> +{
> +	if (which == V4L2_CTRL_WHICH_CUR_VAL)
> +		return !!(ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR);
> +
> +	if (which == V4L2_CTRL_WHICH_DEF_VAL)
> +		return !!(ctrl->info.flags & UVC_CTRL_FLAG_GET_DEF);
> +
> +	/* Types with implicit boundaries. */
> +	switch (mapping->v4l2_type) {
> +	case V4L2_CTRL_TYPE_MENU:
> +	case V4L2_CTRL_TYPE_BOOLEAN:
> +	case V4L2_CTRL_TYPE_BUTTON:
> +		return true;
> +	case V4L2_CTRL_TYPE_BITMASK:
> +		return (ctrl->info.flags & UVC_CTRL_FLAG_GET_RES) ||
> +			(ctrl->info.flags & UVC_CTRL_FLAG_GET_MAX);
> +	default:
> +		break;
> +	}
> +
> +	if (which == V4L2_CTRL_WHICH_MIN_VAL)
> +		return !!(ctrl->info.flags & UVC_CTRL_FLAG_GET_MIN);
> +
> +	if (which == V4L2_CTRL_WHICH_MAX_VAL)
> +		return !!(ctrl->info.flags & UVC_CTRL_FLAG_GET_MAX);
> +
> +	return false;
> +}
> +
>  /*
>   * Check if control @v4l2_id can be accessed by the given control @ioctl
>   * (VIDIOC_G_EXT_CTRLS, VIDIOC_TRY_EXT_CTRLS or VIDIOC_S_EXT_CTRLS).
> @@ -1288,7 +1319,6 @@ int uvc_ctrl_is_accessible(struct uvc_video_chain *chain, u32 v4l2_id,
>  	struct uvc_control *master_ctrl = NULL;
>  	struct uvc_control_mapping *mapping;
>  	struct uvc_control *ctrl;
> -	bool read = ioctl == VIDIOC_G_EXT_CTRLS;
>  	s32 val;
>  	int ret;
>  	int i;
> @@ -1300,10 +1330,10 @@ int uvc_ctrl_is_accessible(struct uvc_video_chain *chain, u32 v4l2_id,
>  	if (!ctrl)
>  		return -EINVAL;
>  
> -	if (!(ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR) && read)
> -		return -EACCES;
> +	if (ioctl == VIDIOC_G_EXT_CTRLS)
> +		return uvc_ctrl_is_readable(ctrls->which, ctrl, mapping);
>  
> -	if (!(ctrl->info.flags & UVC_CTRL_FLAG_SET_CUR) && !read)
> +	if (!(ctrl->info.flags & UVC_CTRL_FLAG_SET_CUR))
>  		return -EACCES;
>  
>  	if (ioctl != VIDIOC_S_EXT_CTRLS || !mapping->master_id)
> @@ -1451,6 +1481,9 @@ static int __uvc_query_v4l2_ctrl(struct uvc_video_chain *chain,
>  		v4l2_ctrl->flags |= V4L2_CTRL_FLAG_WRITE_ONLY;
>  	if (!(ctrl->info.flags & UVC_CTRL_FLAG_SET_CUR))
>  		v4l2_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
> +	if ((ctrl->info.flags & UVC_CTRL_FLAG_GET_MAX) &&
> +	    (ctrl->info.flags & UVC_CTRL_FLAG_GET_MIN))
> +		v4l2_ctrl->flags |= V4L2_CTRL_FLAG_HAS_WHICH_MIN_MAX;
>  
>  	if (mapping->master_id)
>  		__uvc_find_control(ctrl->entity, mapping->master_id,
> @@ -2037,16 +2070,18 @@ static int uvc_mapping_get_xctrl_compound(struct uvc_video_chain *chain,
>  
>  	switch (which) {
>  	case V4L2_CTRL_WHICH_CUR_VAL:
> -		ret = __uvc_ctrl_load_cur(chain, ctrl);
> -		if (ret < 0)
> -			return ret;
>  		id = UVC_CTRL_DATA_CURRENT;
>  		query = UVC_GET_CUR;
>  		break;
> +	case V4L2_CTRL_WHICH_MIN_VAL:
> +		id = UVC_CTRL_DATA_MIN;
> +		query = UVC_GET_MIN;
> +		break;
> +	case V4L2_CTRL_WHICH_MAX_VAL:
> +		id = UVC_CTRL_DATA_MAX;
> +		query = UVC_GET_MAX;
> +		break;
>  	case V4L2_CTRL_WHICH_DEF_VAL:
> -		ret = uvc_ctrl_populate_cache(chain, ctrl);
> -		if (ret < 0)
> -			return ret;
>  		id = UVC_CTRL_DATA_DEF;
>  		query = UVC_GET_DEF;
>  		break;
> @@ -2064,6 +2099,14 @@ static int uvc_mapping_get_xctrl_compound(struct uvc_video_chain *chain,
>  	if (!data)
>  		return -ENOMEM;
>  
> +	if (which == V4L2_CTRL_WHICH_CUR_VAL)
> +		ret = __uvc_ctrl_load_cur(chain, ctrl);
> +	else
> +		ret = uvc_ctrl_populate_cache(chain, ctrl);
> +
> +	if (ret < 0)
> +		return ret;
> +
>  	ret = mapping->get(mapping, query, uvc_ctrl_data(ctrl, id), size, data);
>  	if (ret < 0)
>  		return ret;
> @@ -2076,22 +2119,37 @@ static int uvc_mapping_get_xctrl_std(struct uvc_video_chain *chain,
>  				     struct uvc_control_mapping *mapping,
>  				     u32 which, struct v4l2_ext_control *xctrl)
>  {
> +	struct v4l2_queryctrl qc;
> +	int ret;
> +
>  	switch (which) {
>  	case V4L2_CTRL_WHICH_CUR_VAL:
>  		return __uvc_ctrl_get(chain, ctrl, mapping, &xctrl->value);
>  	case V4L2_CTRL_WHICH_DEF_VAL:
> -		if (!ctrl->cached) {
> -			int ret = uvc_ctrl_populate_cache(chain, ctrl);
> +	case V4L2_CTRL_WHICH_MIN_VAL:
> +	case V4L2_CTRL_WHICH_MAX_VAL:
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
>  
> -			if (ret < 0)
> -				return ret;
> -		}
> -		xctrl->value = uvc_mapping_get_s32(mapping, UVC_GET_DEF,
> -						   uvc_ctrl_data(ctrl, UVC_CTRL_DATA_DEF));
> -		return 0;
> +	ret = __uvc_queryctrl_boundaries(chain, ctrl, mapping, &qc);
> +	if (ret < 0)
> +		return ret;
> +
> +	switch (which) {
> +	case V4L2_CTRL_WHICH_DEF_VAL:
> +		xctrl->value = qc.default_value;
> +		break;
> +	case V4L2_CTRL_WHICH_MIN_VAL:
> +		xctrl->value = qc.minimum;
> +		break;
> +	case V4L2_CTRL_WHICH_MAX_VAL:
> +		xctrl->value = qc.maximum;
> +		break;
>  	}
>  
> -	return -EINVAL;
> +	return 0;
>  }
>  
>  static int uvc_mapping_get_xctrl(struct uvc_video_chain *chain,
> diff --git a/drivers/media/usb/uvc/uvc_v4l2.c b/drivers/media/usb/uvc/uvc_v4l2.c
> index 65dbb53b1e75..7e284770149d 100644
> --- a/drivers/media/usb/uvc/uvc_v4l2.c
> +++ b/drivers/media/usb/uvc/uvc_v4l2.c
> @@ -1087,6 +1087,8 @@ static int uvc_ioctl_g_ext_ctrls(struct file *file, void *fh,
>  	switch (ctrls->which) {
>  	case V4L2_CTRL_WHICH_DEF_VAL:
>  	case V4L2_CTRL_WHICH_CUR_VAL:
> +	case V4L2_CTRL_WHICH_MAX_VAL:
> +	case V4L2_CTRL_WHICH_MIN_VAL:
>  		which = ctrls->which;
>  		break;
>  	default:
> 





[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux