diff options
Diffstat (limited to 'drivers/media/video/uvc/uvc_video.c')
-rw-r--r-- | drivers/media/video/uvc/uvc_video.c | 214 |
1 files changed, 169 insertions, 45 deletions
diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c index b7bb23820d80..e7c31995527f 100644 --- a/drivers/media/video/uvc/uvc_video.c +++ b/drivers/media/video/uvc/uvc_video.c | |||
@@ -36,15 +36,22 @@ static int __uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit, | |||
36 | { | 36 | { |
37 | __u8 type = USB_TYPE_CLASS | USB_RECIP_INTERFACE; | 37 | __u8 type = USB_TYPE_CLASS | USB_RECIP_INTERFACE; |
38 | unsigned int pipe; | 38 | unsigned int pipe; |
39 | int ret; | ||
40 | 39 | ||
41 | pipe = (query & 0x80) ? usb_rcvctrlpipe(dev->udev, 0) | 40 | pipe = (query & 0x80) ? usb_rcvctrlpipe(dev->udev, 0) |
42 | : usb_sndctrlpipe(dev->udev, 0); | 41 | : usb_sndctrlpipe(dev->udev, 0); |
43 | type |= (query & 0x80) ? USB_DIR_IN : USB_DIR_OUT; | 42 | type |= (query & 0x80) ? USB_DIR_IN : USB_DIR_OUT; |
44 | 43 | ||
45 | ret = usb_control_msg(dev->udev, pipe, query, type, cs << 8, | 44 | return usb_control_msg(dev->udev, pipe, query, type, cs << 8, |
46 | unit << 8 | intfnum, data, size, timeout); | 45 | unit << 8 | intfnum, data, size, timeout); |
46 | } | ||
47 | |||
48 | int uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit, | ||
49 | __u8 intfnum, __u8 cs, void *data, __u16 size) | ||
50 | { | ||
51 | int ret; | ||
47 | 52 | ||
53 | ret = __uvc_query_ctrl(dev, query, unit, intfnum, cs, data, size, | ||
54 | UVC_CTRL_CONTROL_TIMEOUT); | ||
48 | if (ret != size) { | 55 | if (ret != size) { |
49 | uvc_printk(KERN_ERR, "Failed to query (%u) UVC control %u " | 56 | uvc_printk(KERN_ERR, "Failed to query (%u) UVC control %u " |
50 | "(unit %u) : %d (exp. %u).\n", query, cs, unit, ret, | 57 | "(unit %u) : %d (exp. %u).\n", query, cs, unit, ret, |
@@ -55,13 +62,6 @@ static int __uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit, | |||
55 | return 0; | 62 | return 0; |
56 | } | 63 | } |
57 | 64 | ||
58 | int uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit, | ||
59 | __u8 intfnum, __u8 cs, void *data, __u16 size) | ||
60 | { | ||
61 | return __uvc_query_ctrl(dev, query, unit, intfnum, cs, data, size, | ||
62 | UVC_CTRL_CONTROL_TIMEOUT); | ||
63 | } | ||
64 | |||
65 | static void uvc_fixup_buffer_size(struct uvc_video_device *video, | 65 | static void uvc_fixup_buffer_size(struct uvc_video_device *video, |
66 | struct uvc_streaming_control *ctrl) | 66 | struct uvc_streaming_control *ctrl) |
67 | { | 67 | { |
@@ -102,8 +102,36 @@ static int uvc_get_video_ctrl(struct uvc_video_device *video, | |||
102 | ret = __uvc_query_ctrl(video->dev, query, 0, video->streaming->intfnum, | 102 | ret = __uvc_query_ctrl(video->dev, query, 0, video->streaming->intfnum, |
103 | probe ? VS_PROBE_CONTROL : VS_COMMIT_CONTROL, data, size, | 103 | probe ? VS_PROBE_CONTROL : VS_COMMIT_CONTROL, data, size, |
104 | UVC_CTRL_STREAMING_TIMEOUT); | 104 | UVC_CTRL_STREAMING_TIMEOUT); |
105 | if (ret < 0) | 105 | |
106 | if ((query == GET_MIN || query == GET_MAX) && ret == 2) { | ||
107 | /* Some cameras, mostly based on Bison Electronics chipsets, | ||
108 | * answer a GET_MIN or GET_MAX request with the wCompQuality | ||
109 | * field only. | ||
110 | */ | ||
111 | uvc_warn_once(video->dev, UVC_WARN_MINMAX, "UVC non " | ||
112 | "compliance - GET_MIN/MAX(PROBE) incorrectly " | ||
113 | "supported. Enabling workaround.\n"); | ||
114 | memset(ctrl, 0, sizeof ctrl); | ||
115 | ctrl->wCompQuality = le16_to_cpup((__le16 *)data); | ||
116 | ret = 0; | ||
117 | goto out; | ||
118 | } else if (query == GET_DEF && probe == 1) { | ||
119 | /* Many cameras don't support the GET_DEF request on their | ||
120 | * video probe control. Warn once and return, the caller will | ||
121 | * fall back to GET_CUR. | ||
122 | */ | ||
123 | uvc_warn_once(video->dev, UVC_WARN_PROBE_DEF, "UVC non " | ||
124 | "compliance - GET_DEF(PROBE) not supported. " | ||
125 | "Enabling workaround.\n"); | ||
126 | ret = -EIO; | ||
127 | goto out; | ||
128 | } else if (ret != size) { | ||
129 | uvc_printk(KERN_ERR, "Failed to query (%u) UVC %s control : " | ||
130 | "%d (exp. %u).\n", query, probe ? "probe" : "commit", | ||
131 | ret, size); | ||
132 | ret = -EIO; | ||
106 | goto out; | 133 | goto out; |
134 | } | ||
107 | 135 | ||
108 | ctrl->bmHint = le16_to_cpup((__le16 *)&data[0]); | 136 | ctrl->bmHint = le16_to_cpup((__le16 *)&data[0]); |
109 | ctrl->bFormatIndex = data[2]; | 137 | ctrl->bFormatIndex = data[2]; |
@@ -114,14 +142,11 @@ static int uvc_get_video_ctrl(struct uvc_video_device *video, | |||
114 | ctrl->wCompQuality = le16_to_cpup((__le16 *)&data[12]); | 142 | ctrl->wCompQuality = le16_to_cpup((__le16 *)&data[12]); |
115 | ctrl->wCompWindowSize = le16_to_cpup((__le16 *)&data[14]); | 143 | ctrl->wCompWindowSize = le16_to_cpup((__le16 *)&data[14]); |
116 | ctrl->wDelay = le16_to_cpup((__le16 *)&data[16]); | 144 | ctrl->wDelay = le16_to_cpup((__le16 *)&data[16]); |
117 | ctrl->dwMaxVideoFrameSize = | 145 | ctrl->dwMaxVideoFrameSize = get_unaligned_le32(&data[18]); |
118 | le32_to_cpu(get_unaligned((__le32 *)&data[18])); | 146 | ctrl->dwMaxPayloadTransferSize = get_unaligned_le32(&data[22]); |
119 | ctrl->dwMaxPayloadTransferSize = | ||
120 | le32_to_cpu(get_unaligned((__le32 *)&data[22])); | ||
121 | 147 | ||
122 | if (size == 34) { | 148 | if (size == 34) { |
123 | ctrl->dwClockFrequency = | 149 | ctrl->dwClockFrequency = get_unaligned_le32(&data[26]); |
124 | le32_to_cpu(get_unaligned((__le32 *)&data[26])); | ||
125 | ctrl->bmFramingInfo = data[30]; | 150 | ctrl->bmFramingInfo = data[30]; |
126 | ctrl->bPreferedVersion = data[31]; | 151 | ctrl->bPreferedVersion = data[31]; |
127 | ctrl->bMinVersion = data[32]; | 152 | ctrl->bMinVersion = data[32]; |
@@ -138,13 +163,14 @@ static int uvc_get_video_ctrl(struct uvc_video_device *video, | |||
138 | * Try to get the value from the format and frame descriptor. | 163 | * Try to get the value from the format and frame descriptor. |
139 | */ | 164 | */ |
140 | uvc_fixup_buffer_size(video, ctrl); | 165 | uvc_fixup_buffer_size(video, ctrl); |
166 | ret = 0; | ||
141 | 167 | ||
142 | out: | 168 | out: |
143 | kfree(data); | 169 | kfree(data); |
144 | return ret; | 170 | return ret; |
145 | } | 171 | } |
146 | 172 | ||
147 | int uvc_set_video_ctrl(struct uvc_video_device *video, | 173 | static int uvc_set_video_ctrl(struct uvc_video_device *video, |
148 | struct uvc_streaming_control *ctrl, int probe) | 174 | struct uvc_streaming_control *ctrl, int probe) |
149 | { | 175 | { |
150 | __u8 *data; | 176 | __u8 *data; |
@@ -168,14 +194,11 @@ int uvc_set_video_ctrl(struct uvc_video_device *video, | |||
168 | /* Note: Some of the fields below are not required for IN devices (see | 194 | /* Note: Some of the fields below are not required for IN devices (see |
169 | * UVC spec, 4.3.1.1), but we still copy them in case support for OUT | 195 | * UVC spec, 4.3.1.1), but we still copy them in case support for OUT |
170 | * devices is added in the future. */ | 196 | * devices is added in the future. */ |
171 | put_unaligned(cpu_to_le32(ctrl->dwMaxVideoFrameSize), | 197 | put_unaligned_le32(ctrl->dwMaxVideoFrameSize, &data[18]); |
172 | (__le32 *)&data[18]); | 198 | put_unaligned_le32(ctrl->dwMaxPayloadTransferSize, &data[22]); |
173 | put_unaligned(cpu_to_le32(ctrl->dwMaxPayloadTransferSize), | ||
174 | (__le32 *)&data[22]); | ||
175 | 199 | ||
176 | if (size == 34) { | 200 | if (size == 34) { |
177 | put_unaligned(cpu_to_le32(ctrl->dwClockFrequency), | 201 | put_unaligned_le32(ctrl->dwClockFrequency, &data[26]); |
178 | (__le32 *)&data[26]); | ||
179 | data[30] = ctrl->bmFramingInfo; | 202 | data[30] = ctrl->bmFramingInfo; |
180 | data[31] = ctrl->bPreferedVersion; | 203 | data[31] = ctrl->bPreferedVersion; |
181 | data[32] = ctrl->bMinVersion; | 204 | data[32] = ctrl->bMinVersion; |
@@ -186,6 +209,12 @@ int uvc_set_video_ctrl(struct uvc_video_device *video, | |||
186 | video->streaming->intfnum, | 209 | video->streaming->intfnum, |
187 | probe ? VS_PROBE_CONTROL : VS_COMMIT_CONTROL, data, size, | 210 | probe ? VS_PROBE_CONTROL : VS_COMMIT_CONTROL, data, size, |
188 | UVC_CTRL_STREAMING_TIMEOUT); | 211 | UVC_CTRL_STREAMING_TIMEOUT); |
212 | if (ret != size) { | ||
213 | uvc_printk(KERN_ERR, "Failed to set UVC %s control : " | ||
214 | "%d (exp. %u).\n", probe ? "probe" : "commit", | ||
215 | ret, size); | ||
216 | ret = -EIO; | ||
217 | } | ||
189 | 218 | ||
190 | kfree(data); | 219 | kfree(data); |
191 | return ret; | 220 | return ret; |
@@ -252,6 +281,12 @@ done: | |||
252 | return ret; | 281 | return ret; |
253 | } | 282 | } |
254 | 283 | ||
284 | int uvc_commit_video(struct uvc_video_device *video, | ||
285 | struct uvc_streaming_control *probe) | ||
286 | { | ||
287 | return uvc_set_video_ctrl(video, probe, 0); | ||
288 | } | ||
289 | |||
255 | /* ------------------------------------------------------------------------ | 290 | /* ------------------------------------------------------------------------ |
256 | * Video codecs | 291 | * Video codecs |
257 | */ | 292 | */ |
@@ -333,7 +368,7 @@ static int uvc_video_decode_start(struct uvc_video_device *video, | |||
333 | 368 | ||
334 | /* Synchronize to the input stream by waiting for the FID bit to be | 369 | /* Synchronize to the input stream by waiting for the FID bit to be |
335 | * toggled when the the buffer state is not UVC_BUF_STATE_ACTIVE. | 370 | * toggled when the the buffer state is not UVC_BUF_STATE_ACTIVE. |
336 | * queue->last_fid is initialized to -1, so the first isochronous | 371 | * video->last_fid is initialized to -1, so the first isochronous |
337 | * frame will always be in sync. | 372 | * frame will always be in sync. |
338 | * | 373 | * |
339 | * If the device doesn't toggle the FID bit, invert video->last_fid | 374 | * If the device doesn't toggle the FID bit, invert video->last_fid |
@@ -360,7 +395,7 @@ static int uvc_video_decode_start(struct uvc_video_device *video, | |||
360 | * last payload can be lost anyway). We thus must check if the FID has | 395 | * last payload can be lost anyway). We thus must check if the FID has |
361 | * been toggled. | 396 | * been toggled. |
362 | * | 397 | * |
363 | * queue->last_fid is initialized to -1, so the first isochronous | 398 | * video->last_fid is initialized to -1, so the first isochronous |
364 | * frame will never trigger an end of frame detection. | 399 | * frame will never trigger an end of frame detection. |
365 | * | 400 | * |
366 | * Empty buffers (bytesused == 0) don't trigger end of frame detection | 401 | * Empty buffers (bytesused == 0) don't trigger end of frame detection |
@@ -418,6 +453,34 @@ static void uvc_video_decode_end(struct uvc_video_device *video, | |||
418 | } | 453 | } |
419 | } | 454 | } |
420 | 455 | ||
456 | static int uvc_video_encode_header(struct uvc_video_device *video, | ||
457 | struct uvc_buffer *buf, __u8 *data, int len) | ||
458 | { | ||
459 | data[0] = 2; /* Header length */ | ||
460 | data[1] = UVC_STREAM_EOH | UVC_STREAM_EOF | ||
461 | | (video->last_fid & UVC_STREAM_FID); | ||
462 | return 2; | ||
463 | } | ||
464 | |||
465 | static int uvc_video_encode_data(struct uvc_video_device *video, | ||
466 | struct uvc_buffer *buf, __u8 *data, int len) | ||
467 | { | ||
468 | struct uvc_video_queue *queue = &video->queue; | ||
469 | unsigned int nbytes; | ||
470 | void *mem; | ||
471 | |||
472 | /* Copy video data to the URB buffer. */ | ||
473 | mem = queue->mem + buf->buf.m.offset + queue->buf_used; | ||
474 | nbytes = min((unsigned int)len, buf->buf.bytesused - queue->buf_used); | ||
475 | nbytes = min(video->bulk.max_payload_size - video->bulk.payload_size, | ||
476 | nbytes); | ||
477 | memcpy(data, mem, nbytes); | ||
478 | |||
479 | queue->buf_used += nbytes; | ||
480 | |||
481 | return nbytes; | ||
482 | } | ||
483 | |||
421 | /* ------------------------------------------------------------------------ | 484 | /* ------------------------------------------------------------------------ |
422 | * URB handling | 485 | * URB handling |
423 | */ | 486 | */ |
@@ -477,7 +540,7 @@ static void uvc_video_decode_bulk(struct urb *urb, | |||
477 | /* If the URB is the first of its payload, decode and save the | 540 | /* If the URB is the first of its payload, decode and save the |
478 | * header. | 541 | * header. |
479 | */ | 542 | */ |
480 | if (video->bulk.header_size == 0) { | 543 | if (video->bulk.header_size == 0 && !video->bulk.skip_payload) { |
481 | do { | 544 | do { |
482 | ret = uvc_video_decode_start(video, buf, mem, len); | 545 | ret = uvc_video_decode_start(video, buf, mem, len); |
483 | if (ret == -EAGAIN) | 546 | if (ret == -EAGAIN) |
@@ -487,14 +550,13 @@ static void uvc_video_decode_bulk(struct urb *urb, | |||
487 | /* If an error occured skip the rest of the payload. */ | 550 | /* If an error occured skip the rest of the payload. */ |
488 | if (ret < 0 || buf == NULL) { | 551 | if (ret < 0 || buf == NULL) { |
489 | video->bulk.skip_payload = 1; | 552 | video->bulk.skip_payload = 1; |
490 | return; | 553 | } else { |
491 | } | 554 | memcpy(video->bulk.header, mem, ret); |
555 | video->bulk.header_size = ret; | ||
492 | 556 | ||
493 | video->bulk.header_size = ret; | 557 | mem += ret; |
494 | memcpy(video->bulk.header, mem, video->bulk.header_size); | 558 | len -= ret; |
495 | 559 | } | |
496 | mem += ret; | ||
497 | len -= ret; | ||
498 | } | 560 | } |
499 | 561 | ||
500 | /* The buffer queue might have been cancelled while a bulk transfer | 562 | /* The buffer queue might have been cancelled while a bulk transfer |
@@ -525,6 +587,48 @@ static void uvc_video_decode_bulk(struct urb *urb, | |||
525 | } | 587 | } |
526 | } | 588 | } |
527 | 589 | ||
590 | static void uvc_video_encode_bulk(struct urb *urb, | ||
591 | struct uvc_video_device *video, struct uvc_buffer *buf) | ||
592 | { | ||
593 | u8 *mem = urb->transfer_buffer; | ||
594 | int len = video->urb_size, ret; | ||
595 | |||
596 | if (buf == NULL) { | ||
597 | urb->transfer_buffer_length = 0; | ||
598 | return; | ||
599 | } | ||
600 | |||
601 | /* If the URB is the first of its payload, add the header. */ | ||
602 | if (video->bulk.header_size == 0) { | ||
603 | ret = uvc_video_encode_header(video, buf, mem, len); | ||
604 | video->bulk.header_size = ret; | ||
605 | video->bulk.payload_size += ret; | ||
606 | mem += ret; | ||
607 | len -= ret; | ||
608 | } | ||
609 | |||
610 | /* Process video data. */ | ||
611 | ret = uvc_video_encode_data(video, buf, mem, len); | ||
612 | |||
613 | video->bulk.payload_size += ret; | ||
614 | len -= ret; | ||
615 | |||
616 | if (buf->buf.bytesused == video->queue.buf_used || | ||
617 | video->bulk.payload_size == video->bulk.max_payload_size) { | ||
618 | if (buf->buf.bytesused == video->queue.buf_used) { | ||
619 | video->queue.buf_used = 0; | ||
620 | buf->state = UVC_BUF_STATE_DONE; | ||
621 | uvc_queue_next_buffer(&video->queue, buf); | ||
622 | video->last_fid ^= UVC_STREAM_FID; | ||
623 | } | ||
624 | |||
625 | video->bulk.header_size = 0; | ||
626 | video->bulk.payload_size = 0; | ||
627 | } | ||
628 | |||
629 | urb->transfer_buffer_length = video->urb_size - len; | ||
630 | } | ||
631 | |||
528 | static void uvc_video_complete(struct urb *urb) | 632 | static void uvc_video_complete(struct urb *urb) |
529 | { | 633 | { |
530 | struct uvc_video_device *video = urb->context; | 634 | struct uvc_video_device *video = urb->context; |
@@ -722,7 +826,15 @@ static int uvc_init_video_bulk(struct uvc_video_device *video, | |||
722 | if (uvc_alloc_urb_buffers(video, size) < 0) | 826 | if (uvc_alloc_urb_buffers(video, size) < 0) |
723 | return -ENOMEM; | 827 | return -ENOMEM; |
724 | 828 | ||
725 | pipe = usb_rcvbulkpipe(video->dev->udev, ep->desc.bEndpointAddress); | 829 | if (usb_endpoint_dir_in(&ep->desc)) |
830 | pipe = usb_rcvbulkpipe(video->dev->udev, | ||
831 | ep->desc.bEndpointAddress); | ||
832 | else | ||
833 | pipe = usb_sndbulkpipe(video->dev->udev, | ||
834 | ep->desc.bEndpointAddress); | ||
835 | |||
836 | if (video->streaming->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) | ||
837 | size = 0; | ||
726 | 838 | ||
727 | for (i = 0; i < UVC_URBS; ++i) { | 839 | for (i = 0; i < UVC_URBS; ++i) { |
728 | urb = usb_alloc_urb(0, gfp_flags); | 840 | urb = usb_alloc_urb(0, gfp_flags); |
@@ -854,7 +966,7 @@ int uvc_video_resume(struct uvc_video_device *video) | |||
854 | 966 | ||
855 | video->frozen = 0; | 967 | video->frozen = 0; |
856 | 968 | ||
857 | if ((ret = uvc_set_video_ctrl(video, &video->streaming->ctrl, 0)) < 0) { | 969 | if ((ret = uvc_commit_video(video, &video->streaming->ctrl)) < 0) { |
858 | uvc_queue_enable(&video->queue, 0); | 970 | uvc_queue_enable(&video->queue, 0); |
859 | return ret; | 971 | return ret; |
860 | } | 972 | } |
@@ -935,23 +1047,30 @@ int uvc_video_init(struct uvc_video_device *video) | |||
935 | break; | 1047 | break; |
936 | } | 1048 | } |
937 | 1049 | ||
938 | /* Commit the default settings. */ | ||
939 | probe->bFormatIndex = format->index; | 1050 | probe->bFormatIndex = format->index; |
940 | probe->bFrameIndex = frame->bFrameIndex; | 1051 | probe->bFrameIndex = frame->bFrameIndex; |
941 | if ((ret = uvc_set_video_ctrl(video, probe, 0)) < 0) | ||
942 | return ret; | ||
943 | 1052 | ||
944 | video->streaming->cur_format = format; | 1053 | video->streaming->cur_format = format; |
945 | video->streaming->cur_frame = frame; | 1054 | video->streaming->cur_frame = frame; |
946 | atomic_set(&video->active, 0); | 1055 | atomic_set(&video->active, 0); |
947 | 1056 | ||
948 | /* Select the video decoding function */ | 1057 | /* Select the video decoding function */ |
949 | if (video->dev->quirks & UVC_QUIRK_BUILTIN_ISIGHT) | 1058 | if (video->streaming->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { |
950 | video->decode = uvc_video_decode_isight; | 1059 | if (video->dev->quirks & UVC_QUIRK_BUILTIN_ISIGHT) |
951 | else if (video->streaming->intf->num_altsetting > 1) | 1060 | video->decode = uvc_video_decode_isight; |
952 | video->decode = uvc_video_decode_isoc; | 1061 | else if (video->streaming->intf->num_altsetting > 1) |
953 | else | 1062 | video->decode = uvc_video_decode_isoc; |
954 | video->decode = uvc_video_decode_bulk; | 1063 | else |
1064 | video->decode = uvc_video_decode_bulk; | ||
1065 | } else { | ||
1066 | if (video->streaming->intf->num_altsetting == 1) | ||
1067 | video->decode = uvc_video_encode_bulk; | ||
1068 | else { | ||
1069 | uvc_printk(KERN_INFO, "Isochronous endpoints are not " | ||
1070 | "supported for video output devices.\n"); | ||
1071 | return -EINVAL; | ||
1072 | } | ||
1073 | } | ||
955 | 1074 | ||
956 | return 0; | 1075 | return 0; |
957 | } | 1076 | } |
@@ -971,7 +1090,8 @@ int uvc_video_enable(struct uvc_video_device *video, int enable) | |||
971 | return 0; | 1090 | return 0; |
972 | } | 1091 | } |
973 | 1092 | ||
974 | if (video->streaming->cur_format->flags & UVC_FMT_FLAG_COMPRESSED) | 1093 | if ((video->streaming->cur_format->flags & UVC_FMT_FLAG_COMPRESSED) || |
1094 | uvc_no_drop_param) | ||
975 | video->queue.flags &= ~UVC_QUEUE_DROP_INCOMPLETE; | 1095 | video->queue.flags &= ~UVC_QUEUE_DROP_INCOMPLETE; |
976 | else | 1096 | else |
977 | video->queue.flags |= UVC_QUEUE_DROP_INCOMPLETE; | 1097 | video->queue.flags |= UVC_QUEUE_DROP_INCOMPLETE; |
@@ -979,6 +1099,10 @@ int uvc_video_enable(struct uvc_video_device *video, int enable) | |||
979 | if ((ret = uvc_queue_enable(&video->queue, 1)) < 0) | 1099 | if ((ret = uvc_queue_enable(&video->queue, 1)) < 0) |
980 | return ret; | 1100 | return ret; |
981 | 1101 | ||
1102 | /* Commit the streaming parameters. */ | ||
1103 | if ((ret = uvc_commit_video(video, &video->streaming->ctrl)) < 0) | ||
1104 | return ret; | ||
1105 | |||
982 | return uvc_init_video(video, GFP_KERNEL); | 1106 | return uvc_init_video(video, GFP_KERNEL); |
983 | } | 1107 | } |
984 | 1108 | ||