From patchwork Thu Oct 12 07:54:17 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Edgar Thier X-Patchwork-Id: 10001205 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 4E70860325 for ; Thu, 12 Oct 2017 07:54:24 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3926C28BF8 for ; Thu, 12 Oct 2017 07:54:24 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2DD8428C13; Thu, 12 Oct 2017 07:54:24 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2A98D28C0C for ; Thu, 12 Oct 2017 07:54:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751542AbdJLHyV (ORCPT ); Thu, 12 Oct 2017 03:54:21 -0400 Received: from out1-smtp.messagingengine.com ([66.111.4.25]:56893 "EHLO out1-smtp.messagingengine.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751410AbdJLHyV (ORCPT ); Thu, 12 Oct 2017 03:54:21 -0400 Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailout.nyi.internal (Postfix) with ESMTP id 840A020DA4; Thu, 12 Oct 2017 03:54:20 -0400 (EDT) Received: from frontend2 ([10.202.2.161]) by compute4.internal (MEProxy); Thu, 12 Oct 2017 03:54:20 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:content-type :date:from:in-reply-to:message-id:mime-version:references :subject:to:x-me-sender:x-me-sender:x-sasl-enc; s=fm1; bh=RepUJq 8mCovHanysLUi5nHoSDoMDfWFtMKhEFnPkCf4=; b=M/RAO4yaO06+6X7jqePPIw vwwN7XJvWsxZjAvWHxID5Z323UHLNSmUbw1DbCNQa2dnALkJS5Cm55u39zLeBDdX L4EdcS0ZFegaUjfQEFOhB4Lho2FuXJuBSNV2rVYiUn4xDxGQMZ8J9Qc4ju5KCp8A POIhmHU7lv9rgHKxyF7lZWE6z+1aol1HyF/bc3xvQHEM272ahsQBXZIQkyVQ+32h lPT/2sbTwcjvXv6GxTNmajXk/UvidByobR2hmlE/LHFhoQnjcLJi1YCUe+wHO+zh zO4FNNjxWkvAAsmhGSzBm9Dt64GxZJCDH6qreH7VpuvFLRLeARSqgykHUi6iQfrw == X-ME-Sender: Received: from [192.168.0.146] (unknown [31.209.95.242]) by mail.messagingengine.com (Postfix) with ESMTPA id EB8AC2479F; Thu, 12 Oct 2017 03:54:19 -0400 (EDT) Subject: Re: [PATCH] uvcvideo: Apply flags from device to actual properties To: Kieran Bingham , Laurent Pinchart Cc: linux-media@vger.kernel.org References: <1516233.pKQSzG3xyp@avalon> <443c86f9-0973-cf52-c0c3-be662a8fee74@ideasonboard.com> <8b32b0f3-e442-6761-ef1c-34ac535080d0@ideasonboard.com> <7342af02-0158-a99e-caf1-6c394842296b@edgarthier.net> <430ebf60-395c-08ff-5500-dedcda91e3b1@ideasonboard.com> From: Edgar Thier Message-ID: <7807bf0a-a0a1-65ad-1a10-3a3234e566e9@edgarthier.net> Date: Thu, 12 Oct 2017 09:54:17 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.3.0 MIME-Version: 1.0 In-Reply-To: <430ebf60-395c-08ff-5500-dedcda91e3b1@ideasonboard.com> Content-Language: en-US Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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 Reviewed-by: Kieran Bingham --- 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 "