Hi,

I was wondering if there are any problems with my latest patch or if it simply 
slipped through.

Regards,

Edgar

On 10/12/2017 09:54 AM, Edgar Thier wrote:
> 
> Use flags the device exposes for UVC controls.
> This allows the device to define which property flags are set.
> 
> Since some cameras offer auto-adjustments for properties (e.g. auto-gain),
> the values of other properties (e.g. gain) can change in the camera.
> Examining the flags ensures that the driver is aware of such properties.
> 
> Signed-off-by: Edgar Thier <i...@edgarthier.net>
> ---
>  drivers/media/usb/uvc/uvc_ctrl.c | 64 
> ++++++++++++++++++++++++++++++----------
>  1 file changed, 49 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/media/usb/uvc/uvc_ctrl.c 
> b/drivers/media/usb/uvc/uvc_ctrl.c
> index 20397aba..8f902a41 100644
> --- a/drivers/media/usb/uvc/uvc_ctrl.c
> +++ b/drivers/media/usb/uvc/uvc_ctrl.c
> @@ -1629,6 +1629,40 @@ static void uvc_ctrl_fixup_xu_info(struct uvc_device 
> *dev,
>       }
>  }
> 
> +/*
> + * Retrieve flags for a given control
> + */
> +static int uvc_ctrl_get_flags(struct uvc_device *dev, const struct 
> uvc_control *ctrl,
> +     const struct uvc_control_info *info)
> +{
> +     u8 *data;
> +     int ret = 0;
> +     int flags = 0;
> +
> +     data = kmalloc(2, GFP_KERNEL);
> +     if (data == NULL)
> +             return -ENOMEM;
> +
> +     ret = uvc_query_ctrl(dev, UVC_GET_INFO, ctrl->entity->id, dev->intfnum,
> +                                              info->selector, data, 1);
> +     if (ret < 0) {
> +             uvc_trace(UVC_TRACE_CONTROL,
> +                               "GET_INFO failed on control %pUl/%u (%d).\n",
> +                               info->entity, info->selector, ret);
> +     } else {
> +             flags = UVC_CTRL_FLAG_GET_MIN | UVC_CTRL_FLAG_GET_MAX
> +                     | UVC_CTRL_FLAG_GET_RES | UVC_CTRL_FLAG_GET_DEF
> +                     | (data[0] & UVC_CONTROL_CAP_GET ?
> +                        UVC_CTRL_FLAG_GET_CUR : 0)
> +                     | (data[0] & UVC_CONTROL_CAP_SET ?
> +                        UVC_CTRL_FLAG_SET_CUR : 0)
> +                     | (data[0] & UVC_CONTROL_CAP_AUTOUPDATE ?
> +                        UVC_CTRL_FLAG_AUTO_UPDATE : 0);
> +     }
> +     kfree(data);
> +     return flags;
> +}
> +
>  /*
>   * Query control information (size and flags) for XU controls.
>   */
> @@ -1636,6 +1670,7 @@ static int uvc_ctrl_fill_xu_info(struct uvc_device *dev,
>       const struct uvc_control *ctrl, struct uvc_control_info *info)
>  {
>       u8 *data;
> +     int flags;
>       int ret;
> 
>       data = kmalloc(2, GFP_KERNEL);
> @@ -1659,24 +1694,15 @@ static int uvc_ctrl_fill_xu_info(struct uvc_device 
> *dev,
> 
>       info->size = le16_to_cpup((__le16 *)data);
> 
> -     /* Query the control information (GET_INFO) */
> -     ret = uvc_query_ctrl(dev, UVC_GET_INFO, ctrl->entity->id, dev->intfnum,
> -                          info->selector, data, 1);
> -     if (ret < 0) {
> +     flags = uvc_ctrl_get_flags(dev, ctrl, info);
> +
> +     if (flags < 0) {
>               uvc_trace(UVC_TRACE_CONTROL,
> -                       "GET_INFO failed on control %pUl/%u (%d).\n",
> -                       info->entity, info->selector, ret);
> +                       "Failed to retrieve flags (%d).\n", ret);
> +             ret = flags;
>               goto done;
>       }
> -
> -     info->flags = UVC_CTRL_FLAG_GET_MIN | UVC_CTRL_FLAG_GET_MAX
> -                 | UVC_CTRL_FLAG_GET_RES | UVC_CTRL_FLAG_GET_DEF
> -                 | (data[0] & UVC_CONTROL_CAP_GET ?
> -                    UVC_CTRL_FLAG_GET_CUR : 0)
> -                 | (data[0] & UVC_CONTROL_CAP_SET ?
> -                    UVC_CTRL_FLAG_SET_CUR : 0)
> -                 | (data[0] & UVC_CONTROL_CAP_AUTOUPDATE ?
> -                    UVC_CTRL_FLAG_AUTO_UPDATE : 0);
> +     info->flags = flags;
> 
>       uvc_ctrl_fixup_xu_info(dev, ctrl, info);
> 
> @@ -1890,6 +1916,7 @@ static int uvc_ctrl_add_info(struct uvc_device *dev, 
> struct uvc_control *ctrl,
>       const struct uvc_control_info *info)
>  {
>       int ret = 0;
> +     int flags = 0;
> 
>       ctrl->info = *info;
>       INIT_LIST_HEAD(&ctrl->info.mappings);
> @@ -1902,6 +1929,13 @@ static int uvc_ctrl_add_info(struct uvc_device *dev, 
> struct uvc_control *ctrl,
>               goto done;
>       }
> 
> +     flags = uvc_ctrl_get_flags(dev, ctrl, info);
> +     if (flags < 0)
> +             uvc_trace(UVC_TRACE_CONTROL,
> +                       "Failed to retrieve flags (%d).\n", ret);
> +     else
> +             ctrl->info.flags = flags;
> +
>       ctrl->initialized = 1;
> 
>       uvc_trace(UVC_TRACE_CONTROL, "Added control %pUl/%u to device %s "
> 

Reply via email to