From patchwork Fri Aug 30 02:17:04 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pawel Osciak X-Patchwork-Id: 19975 X-Patchwork-Delegate: laurent.pinchart@ideasonboard.com Received: from mail.tu-berlin.de ([130.149.7.33]) by www.linuxtv.org with esmtp (Exim 4.72) (envelope-from ) id 1VFEHY-0006b0-DS; Fri, 30 Aug 2013 04:17:52 +0200 X-tubIT-Incoming-IP: 209.132.180.67 Received: from vger.kernel.org ([209.132.180.67]) by mail.tu-berlin.de (exim-4.72/mailfrontend-6) with esmtp id 1VFEHW-0007f4-4U; Fri, 30 Aug 2013 04:17:52 +0200 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754227Ab3H3CRk (ORCPT + 1 other); Thu, 29 Aug 2013 22:17:40 -0400 Received: from mail-pa0-f41.google.com ([209.85.220.41]:33503 "EHLO mail-pa0-f41.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751807Ab3H3CRg (ORCPT ); Thu, 29 Aug 2013 22:17:36 -0400 Received: by mail-pa0-f41.google.com with SMTP id bj1so1696083pad.0 for ; Thu, 29 Aug 2013 19:17:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=IpoNQxzkK1/CtPNDFNoi4+QnPCxQyqn0fKamKYe7ffo=; b=Y43kT2v7KIBAZK45IhDaVfEPsg1e4bt6cqnqoA4OJ+b/QflrqmArC3g4xGqGuZWys7 a9rSLTqQmfNSOSPyWaeAbd/FuGcmrZaaYUrhARjpeXOaQLEUWMxyBG/rn6lZ3curCjjn pCswQNALJqFxeiBdg+XGt1XzQCx5R/011GR+E= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=IpoNQxzkK1/CtPNDFNoi4+QnPCxQyqn0fKamKYe7ffo=; b=lUCrTA4PeBSSKzrxoApUG4YfRXmMZPH30EOGII2PfevgBfku/JY33l1hLChbz11ph7 MOwBv6AtdCi8vhhgexXEFL5PhjXa+LEq14N20xY8u8VLjQ4Dls/wFkFNWArjjYZhLh/F k+48GgazHShAp9I8oDxV31L4NL9uG+lKd1DJ1AQ+mdjufvE7KUSlrZeF+W2VBy3xoOHz T8lRFcZSWZKRzzIf3gxPYO3NiQYqq/PGBxDKH0S9NEsJu4PiTuqZSgMtVr7CIB9pBWm9 XksH1+qNqswxNaZ2E9Wgxlr6eoDB+hGFNTeyMH31EKJl2qZq+lpn5tuO6RjDVTDBCbPz SXlA== X-Gm-Message-State: ALoCoQmtk9kbSoAJt+Gr1vsH7VwmkOX+p5uqzA7LrKkIGxvZkNcY9IKAySP6PfNfKyxFn2l2/fXa X-Received: by 10.68.233.134 with SMTP id tw6mr7096682pbc.9.1377829056124; Thu, 29 Aug 2013 19:17:36 -0700 (PDT) Received: from kawagoe.tok.corp.google.com (kawagoe.tok.corp.google.com [172.30.88.114]) by mx.google.com with ESMTPSA id ye1sm27935254pab.19.1969.12.31.16.00.00 (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 29 Aug 2013 19:17:35 -0700 (PDT) From: Pawel Osciak To: linux-media@vger.kernel.org Cc: laurent.pinchart@ideasonboard.com, Pawel Osciak Subject: [PATCH v1 05/19] uvcvideo: Add support for UVC1.5 P&C control. Date: Fri, 30 Aug 2013 11:17:04 +0900 Message-Id: <1377829038-4726-6-git-send-email-posciak@chromium.org> X-Mailer: git-send-email 1.8.4 In-Reply-To: <1377829038-4726-1-git-send-email-posciak@chromium.org> References: <1377829038-4726-1-git-send-email-posciak@chromium.org> Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-PMX-Version: 6.0.0.2142326, Antispam-Engine: 2.7.2.2107409, Antispam-Data: 2013.8.30.20624 X-PMX-Spam: Gauge=IIIIIIII, Probability=8%, Report=' MULTIPLE_RCPTS 0.1, HTML_00_01 0.05, HTML_00_10 0.05, BODY_SIZE_4000_4999 0, BODY_SIZE_5000_LESS 0, BODY_SIZE_7000_LESS 0, DKIM_SIGNATURE 0, URI_ENDS_IN_HTML 0, __ANY_URI 0, __CP_MEDIA_BODY 0, __CP_URI_IN_BODY 0, __HAS_FROM 0, __HAS_MSGID 0, __HAS_X_MAILER 0, __HAS_X_MAILING_LIST 0, __IN_REP_TO 0, __MIME_TEXT_ONLY 0, __MULTIPLE_RCPTS_CC_X2 0, __SANE_MSGID 0, __TO_MALFORMED_2 0, __TO_NO_NAME 0, __URI_NO_WWW 0, __URI_NS , __YOUTUBE_RCVD 0' Add support for UVC 1.5 Probe & Commit control. Signed-off-by: Pawel Osciak --- drivers/media/usb/uvc/uvc_video.c | 52 ++++++++++++++++++++++++++++++++++++--- include/uapi/linux/usb/video.h | 7 ++++++ 2 files changed, 55 insertions(+), 4 deletions(-) diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c index 1198989..b4ebccd 100644 --- a/drivers/media/usb/uvc/uvc_video.c +++ b/drivers/media/usb/uvc/uvc_video.c @@ -168,14 +168,25 @@ static void uvc_fixup_video_ctrl(struct uvc_streaming *stream, } } +int uvc_get_probe_ctrl_size(struct uvc_streaming *stream) +{ + if (stream->dev->uvc_version < 0x0110) + return 26; + else if (stream->dev->uvc_version < 0x0150) + return 34; + else + return 48; +} + static int uvc_get_video_ctrl(struct uvc_streaming *stream, struct uvc_streaming_control *ctrl, int probe, __u8 query) { __u8 *data; __u16 size; int ret; + int i; - size = stream->dev->uvc_version >= 0x0110 ? 34 : 26; + size = uvc_get_probe_ctrl_size(stream); if ((stream->dev->quirks & UVC_QUIRK_PROBE_DEF) && query == UVC_GET_DEF) return -EIO; @@ -230,7 +241,7 @@ static int uvc_get_video_ctrl(struct uvc_streaming *stream, ctrl->dwMaxVideoFrameSize = get_unaligned_le32(&data[18]); ctrl->dwMaxPayloadTransferSize = get_unaligned_le32(&data[22]); - if (size == 34) { + if (size >= 34) { ctrl->dwClockFrequency = get_unaligned_le32(&data[26]); ctrl->bmFramingInfo = data[30]; ctrl->bPreferedVersion = data[31]; @@ -244,6 +255,26 @@ static int uvc_get_video_ctrl(struct uvc_streaming *stream, ctrl->bMaxVersion = 0; } + if (size >= 48) { + ctrl->bUsage = data[34]; + ctrl->bBitDepthLuma = data[35]; + ctrl->bmSetting = data[36]; + ctrl->bMaxNumberOfRefFramesPlus1 = data[37]; + ctrl->bmRateControlModes = get_unaligned_le16(&data[38]); + for (i = 0; i < ARRAY_SIZE(ctrl->bmLayoutPerStream); ++i) { + ctrl->bmLayoutPerStream[i] = + get_unaligned_le16(&data[40 + i * 2]); + } + } else { + ctrl->bUsage = 0; + ctrl->bBitDepthLuma = 0; + ctrl->bmSetting = 0; + ctrl->bMaxNumberOfRefFramesPlus1 = 0; + ctrl->bmRateControlModes = 0; + for (i = 0; i < ARRAY_SIZE(ctrl->bmLayoutPerStream); ++i) + ctrl->bmLayoutPerStream[i] = 0; + } + /* Some broken devices return null or wrong dwMaxVideoFrameSize and * dwMaxPayloadTransferSize fields. Try to get the value from the * format and frame descriptors. @@ -262,8 +293,9 @@ static int uvc_set_video_ctrl(struct uvc_streaming *stream, __u8 *data; __u16 size; int ret; + int i; - size = stream->dev->uvc_version >= 0x0110 ? 34 : 26; + size = uvc_get_probe_ctrl_size(stream); data = kzalloc(size, GFP_KERNEL); if (data == NULL) return -ENOMEM; @@ -280,7 +312,7 @@ static int uvc_set_video_ctrl(struct uvc_streaming *stream, put_unaligned_le32(ctrl->dwMaxVideoFrameSize, &data[18]); put_unaligned_le32(ctrl->dwMaxPayloadTransferSize, &data[22]); - if (size == 34) { + if (size >= 34) { put_unaligned_le32(ctrl->dwClockFrequency, &data[26]); data[30] = ctrl->bmFramingInfo; data[31] = ctrl->bPreferedVersion; @@ -288,6 +320,18 @@ static int uvc_set_video_ctrl(struct uvc_streaming *stream, data[33] = ctrl->bMaxVersion; } + if (size >= 48) { + data[34] = ctrl->bUsage; + data[35] = ctrl->bBitDepthLuma; + data[36] = ctrl->bmSetting; + data[37] = ctrl->bMaxNumberOfRefFramesPlus1; + *(__le16 *)&data[38] = cpu_to_le16(ctrl->bmRateControlModes); + for (i = 0; i < ARRAY_SIZE(ctrl->bmLayoutPerStream); ++i) { + *(__le16 *)&data[40 + i * 2] = + cpu_to_le16(ctrl->bmLayoutPerStream[i]); + } + } + ret = __uvc_query_ctrl(stream->dev, UVC_SET_CUR, 0, stream->intfnum, probe ? UVC_VS_PROBE_CONTROL : UVC_VS_COMMIT_CONTROL, data, size, uvc_timeout_param); diff --git a/include/uapi/linux/usb/video.h b/include/uapi/linux/usb/video.h index 3b3b95e..331c071 100644 --- a/include/uapi/linux/usb/video.h +++ b/include/uapi/linux/usb/video.h @@ -432,6 +432,7 @@ struct uvc_color_matching_descriptor { #define UVC_DT_COLOR_MATCHING_SIZE 6 /* 4.3.1.1. Video Probe and Commit Controls */ +#define UVC_NUM_SIMULCAST_STREAMS 4 struct uvc_streaming_control { __u16 bmHint; __u8 bFormatIndex; @@ -449,6 +450,12 @@ struct uvc_streaming_control { __u8 bPreferedVersion; __u8 bMinVersion; __u8 bMaxVersion; + __u8 bUsage; + __u8 bBitDepthLuma; + __u8 bmSetting; + __u8 bMaxNumberOfRefFramesPlus1; + __u16 bmRateControlModes; + __u16 bmLayoutPerStream[UVC_NUM_SIMULCAST_STREAMS]; } __attribute__((__packed__)); /* Uncompressed Payload - 3.1.1. Uncompressed Video Format Descriptor */