summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorming_qian <ming_qian@realsil.com.cn>2018-05-08 22:13:08 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2018-10-03 17:00:55 -0700
commit67d8e231759fe4ba5fdbae73a94df963816e7652 (patch)
treecd13e1a910bf9c7fbacfb7e1ae35fa0a2147d56a
parent1ddc0781c0ce451805b4ee6a5b7521bf9c49d5aa (diff)
downloadlinux-67d8e231759fe4ba5fdbae73a94df963816e7652.tar.gz
linux-67d8e231759fe4ba5fdbae73a94df963816e7652.tar.bz2
linux-67d8e231759fe4ba5fdbae73a94df963816e7652.zip
media: uvcvideo: Support realtek's UVC 1.5 device
commit f620d1d7afc7db57ab59f35000752840c91f67e7 upstream. media: uvcvideo: Support UVC 1.5 video probe & commit controls The length of UVC 1.5 video control is 48, and it is 34 for UVC 1.1. Change it to 48 for UVC 1.5 device, and the UVC 1.5 device can be recognized. More changes to the driver are needed for full UVC 1.5 compatibility. However, at least the UVC 1.5 Realtek RTS5847/RTS5852 cameras have been reported to work well. [laurent.pinchart@ideasonboard.com: Factor out code to helper function, update size checks] Cc: stable@vger.kernel.org Signed-off-by: ming_qian <ming_qian@realsil.com.cn> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Tested-by: Kai-Heng Feng <kai.heng.feng@canonical.com> Tested-by: Ana Guerrero Lopez <ana.guerrero@collabora.com> Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/media/usb/uvc/uvc_video.c24
1 files changed, 18 insertions, 6 deletions
diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c
index fb86d6af398d..a6d800291883 100644
--- a/drivers/media/usb/uvc/uvc_video.c
+++ b/drivers/media/usb/uvc/uvc_video.c
@@ -163,14 +163,27 @@ static void uvc_fixup_video_ctrl(struct uvc_streaming *stream,
}
}
+static size_t uvc_video_ctrl_size(struct uvc_streaming *stream)
+{
+ /*
+ * Return the size of the video probe and commit controls, which depends
+ * on the protocol version.
+ */
+ 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)
{
+ __u16 size = uvc_video_ctrl_size(stream);
__u8 *data;
- __u16 size;
int ret;
- size = stream->dev->uvc_version >= 0x0110 ? 34 : 26;
if ((stream->dev->quirks & UVC_QUIRK_PROBE_DEF) &&
query == UVC_GET_DEF)
return -EIO;
@@ -225,7 +238,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];
@@ -254,11 +267,10 @@ out:
static int uvc_set_video_ctrl(struct uvc_streaming *stream,
struct uvc_streaming_control *ctrl, int probe)
{
+ __u16 size = uvc_video_ctrl_size(stream);
__u8 *data;
- __u16 size;
int ret;
- size = stream->dev->uvc_version >= 0x0110 ? 34 : 26;
data = kzalloc(size, GFP_KERNEL);
if (data == NULL)
return -ENOMEM;
@@ -275,7 +287,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;