From: Pawel Osciak <posciak@xxxxxxxxxxxx> Add support for UVC 1.5 Probe & Commit control. Signed-off-by: Pawel Osciak <posciak@xxxxxxxxxxxx> Signed-off-by: James Hilliard <james.hilliard1@xxxxxxxxx> --- Changes v1 -> v2: - rebase --- drivers/media/usb/uvc/uvc_video.c | 34 +++++++++++++++++++++++++++++++ include/uapi/linux/usb/video.h | 7 +++++++ 2 files changed, 41 insertions(+) diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c index d2eb9066e4dc..127d6428b827 100644 --- a/drivers/media/usb/uvc/uvc_video.c +++ b/drivers/media/usb/uvc/uvc_video.c @@ -256,6 +256,7 @@ static int uvc_get_video_ctrl(struct uvc_streaming *stream, u16 size = uvc_video_ctrl_size(stream); u8 *data; int ret; + unsigned int i; if ((stream->dev->quirks & UVC_QUIRK_PROBE_DEF) && query == UVC_GET_DEF) @@ -327,6 +328,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 @@ -346,6 +367,7 @@ static int uvc_set_video_ctrl(struct uvc_streaming *stream, u16 size = uvc_video_ctrl_size(stream); u8 *data; int ret; + unsigned int i; data = kzalloc(size, GFP_KERNEL); if (data == NULL) @@ -371,6 +393,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 6e8e572c2980..e037d28c29ac 100644 --- a/include/uapi/linux/usb/video.h +++ b/include/uapi/linux/usb/video.h @@ -435,6 +435,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; @@ -452,6 +453,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 */ -- 2.34.1