aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@skynet.be>2008-12-28 20:32:29 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2008-12-30 06:40:32 -0500
commitff924203c9e4a5bc218143bc37182851185f4e5f (patch)
tree11ed46e7426ffc00bf016c3b67b26ba26f338c54 /drivers/media
parent538e7a004bf960c96c7e9eb836b59989eb5f5b7f (diff)
V4L/DVB (10104): uvcvideo: Add support for video output devices
Extend the range of supported UVC devices by allowing video output devices matching the following structure: TT_STREAMING -> VC_PROCESSING_UNIT -> VC_EXTENSION_UNIT{0,n} -> OTT_* Video output devices are reported with the V4L2_CAP_VIDEO_OUTPUT capability flag and are subject to the same restrictions as video input devices. Signed-off-by: Laurent Pinchart <laurent.pinchart@skynet.be> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/video/uvc/uvc_driver.c109
-rw-r--r--drivers/media/video/uvc/uvc_queue.c23
-rw-r--r--drivers/media/video/uvc/uvc_v4l2.c81
-rw-r--r--drivers/media/video/uvc/uvc_video.c102
-rw-r--r--drivers/media/video/uvc/uvcvideo.h12
5 files changed, 247 insertions, 80 deletions
diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c
index 18a61928f4f6..89d8bd10a852 100644
--- a/drivers/media/video/uvc/uvc_driver.c
+++ b/drivers/media/video/uvc/uvc_driver.c
@@ -12,8 +12,8 @@
12 */ 12 */
13 13
14/* 14/*
15 * This driver aims to support video input devices compliant with the 'USB 15 * This driver aims to support video input and ouput devices compliant with the
16 * Video Class' specification. 16 * 'USB Video Class' specification.
17 * 17 *
18 * The driver doesn't support the deprecated v4l1 interface. It implements the 18 * The driver doesn't support the deprecated v4l1 interface. It implements the
19 * mmap capture method only, and doesn't do any image format conversion in 19 * mmap capture method only, and doesn't do any image format conversion in
@@ -609,46 +609,55 @@ static int uvc_parse_streaming(struct uvc_device *dev,
609 } 609 }
610 610
611 /* Parse the header descriptor. */ 611 /* Parse the header descriptor. */
612 if (buffer[2] == VS_OUTPUT_HEADER) { 612 switch (buffer[2]) {
613 case VS_OUTPUT_HEADER:
614 streaming->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
615 size = 9;
616 break;
617
618 case VS_INPUT_HEADER:
619 streaming->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
620 size = 13;
621 break;
622
623 default:
613 uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming interface " 624 uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming interface "
614 "%d OUTPUT HEADER descriptor is not supported.\n", 625 "%d HEADER descriptor not found.\n", dev->udev->devnum,
615 dev->udev->devnum, alts->desc.bInterfaceNumber); 626 alts->desc.bInterfaceNumber);
616 goto error; 627 goto error;
617 } else if (buffer[2] == VS_INPUT_HEADER) { 628 }
618 p = buflen >= 5 ? buffer[3] : 0;
619 n = buflen >= 12 ? buffer[12] : 0;
620 629
621 if (buflen < 13 + p*n || buffer[2] != VS_INPUT_HEADER) { 630 p = buflen >= 4 ? buffer[3] : 0;
622 uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming " 631 n = buflen >= size ? buffer[size-1] : 0;
623 "interface %d INPUT HEADER descriptor is " 632
624 "invalid.\n", dev->udev->devnum, 633 if (buflen < size + p*n) {
625 alts->desc.bInterfaceNumber); 634 uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming "
626 goto error; 635 "interface %d HEADER descriptor is invalid.\n",
627 } 636 dev->udev->devnum, alts->desc.bInterfaceNumber);
637 goto error;
638 }
628 639
629 streaming->header.bNumFormats = p; 640 streaming->header.bNumFormats = p;
630 streaming->header.bEndpointAddress = buffer[6]; 641 streaming->header.bEndpointAddress = buffer[6];
642 if (buffer[2] == VS_INPUT_HEADER) {
631 streaming->header.bmInfo = buffer[7]; 643 streaming->header.bmInfo = buffer[7];
632 streaming->header.bTerminalLink = buffer[8]; 644 streaming->header.bTerminalLink = buffer[8];
633 streaming->header.bStillCaptureMethod = buffer[9]; 645 streaming->header.bStillCaptureMethod = buffer[9];
634 streaming->header.bTriggerSupport = buffer[10]; 646 streaming->header.bTriggerSupport = buffer[10];
635 streaming->header.bTriggerUsage = buffer[11]; 647 streaming->header.bTriggerUsage = buffer[11];
636 streaming->header.bControlSize = n;
637
638 streaming->header.bmaControls = kmalloc(p*n, GFP_KERNEL);
639 if (streaming->header.bmaControls == NULL) {
640 ret = -ENOMEM;
641 goto error;
642 }
643
644 memcpy(streaming->header.bmaControls, &buffer[13], p*n);
645 } else { 648 } else {
646 uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming interface " 649 streaming->header.bTerminalLink = buffer[7];
647 "%d HEADER descriptor not found.\n", dev->udev->devnum, 650 }
648 alts->desc.bInterfaceNumber); 651 streaming->header.bControlSize = n;
652
653 streaming->header.bmaControls = kmalloc(p*n, GFP_KERNEL);
654 if (streaming->header.bmaControls == NULL) {
655 ret = -ENOMEM;
649 goto error; 656 goto error;
650 } 657 }
651 658
659 memcpy(streaming->header.bmaControls, &buffer[size], p*n);
660
652 buflen -= buffer[0]; 661 buflen -= buffer[0];
653 buffer += buffer[0]; 662 buffer += buffer[0];
654 663
@@ -1258,6 +1267,26 @@ static int uvc_scan_chain_entity(struct uvc_video_device *video,
1258 list_add_tail(&entity->chain, &video->iterms); 1267 list_add_tail(&entity->chain, &video->iterms);
1259 break; 1268 break;
1260 1269
1270 case TT_STREAMING:
1271 if (uvc_trace_param & UVC_TRACE_PROBE)
1272 printk(" <- IT %d\n", entity->id);
1273
1274 if (!UVC_ENTITY_IS_ITERM(entity)) {
1275 uvc_trace(UVC_TRACE_DESCR, "Unsupported input "
1276 "terminal %u.\n", entity->id);
1277 return -1;
1278 }
1279
1280 if (video->sterm != NULL) {
1281 uvc_trace(UVC_TRACE_DESCR, "Found multiple streaming "
1282 "entities in chain.\n");
1283 return -1;
1284 }
1285
1286 list_add_tail(&entity->chain, &video->iterms);
1287 video->sterm = entity;
1288 break;
1289
1261 default: 1290 default:
1262 uvc_trace(UVC_TRACE_DESCR, "Unsupported entity type " 1291 uvc_trace(UVC_TRACE_DESCR, "Unsupported entity type "
1263 "0x%04x found in chain.\n", UVC_ENTITY_TYPE(entity)); 1292 "0x%04x found in chain.\n", UVC_ENTITY_TYPE(entity));
@@ -1368,6 +1397,10 @@ static int uvc_scan_chain(struct uvc_video_device *video)
1368 1397
1369 entity = video->oterm; 1398 entity = video->oterm;
1370 uvc_trace(UVC_TRACE_PROBE, "Scanning UVC chain: OT %d", entity->id); 1399 uvc_trace(UVC_TRACE_PROBE, "Scanning UVC chain: OT %d", entity->id);
1400
1401 if (UVC_ENTITY_TYPE(entity) == TT_STREAMING)
1402 video->sterm = entity;
1403
1371 id = entity->output.bSourceID; 1404 id = entity->output.bSourceID;
1372 while (id != 0) { 1405 while (id != 0) {
1373 prev = entity; 1406 prev = entity;
@@ -1396,8 +1429,11 @@ static int uvc_scan_chain(struct uvc_video_device *video)
1396 return id; 1429 return id;
1397 } 1430 }
1398 1431
1399 /* Initialize the video buffers queue. */ 1432 if (video->sterm == NULL) {
1400 uvc_queue_init(&video->queue); 1433 uvc_trace(UVC_TRACE_DESCR, "No streaming entity found in "
1434 "chain.\n");
1435 return -1;
1436 }
1401 1437
1402 return 0; 1438 return 0;
1403} 1439}
@@ -1408,7 +1444,8 @@ static int uvc_scan_chain(struct uvc_video_device *video)
1408 * The driver currently supports a single video device per control interface 1444 * The driver currently supports a single video device per control interface
1409 * only. The terminal and units must match the following structure: 1445 * only. The terminal and units must match the following structure:
1410 * 1446 *
1411 * ITT_CAMERA -> VC_PROCESSING_UNIT -> VC_EXTENSION_UNIT{0,n} -> TT_STREAMING 1447 * ITT_* -> VC_PROCESSING_UNIT -> VC_EXTENSION_UNIT{0,n} -> TT_STREAMING
1448 * TT_STREAMING -> VC_PROCESSING_UNIT -> VC_EXTENSION_UNIT{0,n} -> OTT_*
1412 * 1449 *
1413 * The Extension Units, if present, must have a single input pin. The 1450 * The Extension Units, if present, must have a single input pin. The
1414 * Processing Unit and Extension Units can be in any order. Additional 1451 * Processing Unit and Extension Units can be in any order. Additional
@@ -1425,7 +1462,7 @@ static int uvc_register_video(struct uvc_device *dev)
1425 list_for_each_entry(term, &dev->entities, list) { 1462 list_for_each_entry(term, &dev->entities, list) {
1426 struct uvc_streaming *streaming; 1463 struct uvc_streaming *streaming;
1427 1464
1428 if (UVC_ENTITY_TYPE(term) != TT_STREAMING) 1465 if (!UVC_ENTITY_IS_TERM(term) || !UVC_ENTITY_IS_OTERM(term))
1429 continue; 1466 continue;
1430 1467
1431 memset(&dev->video, 0, sizeof dev->video); 1468 memset(&dev->video, 0, sizeof dev->video);
@@ -1438,7 +1475,8 @@ static int uvc_register_video(struct uvc_device *dev)
1438 continue; 1475 continue;
1439 1476
1440 list_for_each_entry(streaming, &dev->streaming, list) { 1477 list_for_each_entry(streaming, &dev->streaming, list) {
1441 if (streaming->header.bTerminalLink == term->id) { 1478 if (streaming->header.bTerminalLink ==
1479 dev->video.sterm->id) {
1442 dev->video.streaming = streaming; 1480 dev->video.streaming = streaming;
1443 found = 1; 1481 found = 1;
1444 break; 1482 break;
@@ -1464,6 +1502,9 @@ static int uvc_register_video(struct uvc_device *dev)
1464 printk(" -> %d).\n", dev->video.oterm->id); 1502 printk(" -> %d).\n", dev->video.oterm->id);
1465 } 1503 }
1466 1504
1505 /* Initialize the video buffers queue. */
1506 uvc_queue_init(&dev->video.queue, dev->video.streaming->type);
1507
1467 /* Initialize the streaming interface with default streaming 1508 /* Initialize the streaming interface with default streaming
1468 * parameters. 1509 * parameters.
1469 */ 1510 */
diff --git a/drivers/media/video/uvc/uvc_queue.c b/drivers/media/video/uvc/uvc_queue.c
index 5646a6a32939..42546342e97d 100644
--- a/drivers/media/video/uvc/uvc_queue.c
+++ b/drivers/media/video/uvc/uvc_queue.c
@@ -79,12 +79,13 @@
79 * 79 *
80 */ 80 */
81 81
82void uvc_queue_init(struct uvc_video_queue *queue) 82void uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type)
83{ 83{
84 mutex_init(&queue->mutex); 84 mutex_init(&queue->mutex);
85 spin_lock_init(&queue->irqlock); 85 spin_lock_init(&queue->irqlock);
86 INIT_LIST_HEAD(&queue->mainqueue); 86 INIT_LIST_HEAD(&queue->mainqueue);
87 INIT_LIST_HEAD(&queue->irqqueue); 87 INIT_LIST_HEAD(&queue->irqqueue);
88 queue->type = type;
88} 89}
89 90
90/* 91/*
@@ -132,7 +133,7 @@ int uvc_alloc_buffers(struct uvc_video_queue *queue, unsigned int nbuffers,
132 queue->buffer[i].buf.index = i; 133 queue->buffer[i].buf.index = i;
133 queue->buffer[i].buf.m.offset = i * bufsize; 134 queue->buffer[i].buf.m.offset = i * bufsize;
134 queue->buffer[i].buf.length = buflength; 135 queue->buffer[i].buf.length = buflength;
135 queue->buffer[i].buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 136 queue->buffer[i].buf.type = queue->type;
136 queue->buffer[i].buf.sequence = 0; 137 queue->buffer[i].buf.sequence = 0;
137 queue->buffer[i].buf.field = V4L2_FIELD_NONE; 138 queue->buffer[i].buf.field = V4L2_FIELD_NONE;
138 queue->buffer[i].buf.memory = V4L2_MEMORY_MMAP; 139 queue->buffer[i].buf.memory = V4L2_MEMORY_MMAP;
@@ -226,7 +227,7 @@ int uvc_queue_buffer(struct uvc_video_queue *queue,
226 227
227 uvc_trace(UVC_TRACE_CAPTURE, "Queuing buffer %u.\n", v4l2_buf->index); 228 uvc_trace(UVC_TRACE_CAPTURE, "Queuing buffer %u.\n", v4l2_buf->index);
228 229
229 if (v4l2_buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || 230 if (v4l2_buf->type != queue->type ||
230 v4l2_buf->memory != V4L2_MEMORY_MMAP) { 231 v4l2_buf->memory != V4L2_MEMORY_MMAP) {
231 uvc_trace(UVC_TRACE_CAPTURE, "[E] Invalid buffer type (%u) " 232 uvc_trace(UVC_TRACE_CAPTURE, "[E] Invalid buffer type (%u) "
232 "and/or memory (%u).\n", v4l2_buf->type, 233 "and/or memory (%u).\n", v4l2_buf->type,
@@ -249,6 +250,13 @@ int uvc_queue_buffer(struct uvc_video_queue *queue,
249 goto done; 250 goto done;
250 } 251 }
251 252
253 if (v4l2_buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
254 v4l2_buf->bytesused > buf->buf.length) {
255 uvc_trace(UVC_TRACE_CAPTURE, "[E] Bytes used out of bounds.\n");
256 ret = -EINVAL;
257 goto done;
258 }
259
252 spin_lock_irqsave(&queue->irqlock, flags); 260 spin_lock_irqsave(&queue->irqlock, flags);
253 if (queue->flags & UVC_QUEUE_DISCONNECTED) { 261 if (queue->flags & UVC_QUEUE_DISCONNECTED) {
254 spin_unlock_irqrestore(&queue->irqlock, flags); 262 spin_unlock_irqrestore(&queue->irqlock, flags);
@@ -256,7 +264,11 @@ int uvc_queue_buffer(struct uvc_video_queue *queue,
256 goto done; 264 goto done;
257 } 265 }
258 buf->state = UVC_BUF_STATE_QUEUED; 266 buf->state = UVC_BUF_STATE_QUEUED;
259 buf->buf.bytesused = 0; 267 if (v4l2_buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
268 buf->buf.bytesused = 0;
269 else
270 buf->buf.bytesused = v4l2_buf->bytesused;
271
260 list_add_tail(&buf->stream, &queue->mainqueue); 272 list_add_tail(&buf->stream, &queue->mainqueue);
261 list_add_tail(&buf->queue, &queue->irqqueue); 273 list_add_tail(&buf->queue, &queue->irqqueue);
262 spin_unlock_irqrestore(&queue->irqlock, flags); 274 spin_unlock_irqrestore(&queue->irqlock, flags);
@@ -289,7 +301,7 @@ int uvc_dequeue_buffer(struct uvc_video_queue *queue,
289 struct uvc_buffer *buf; 301 struct uvc_buffer *buf;
290 int ret = 0; 302 int ret = 0;
291 303
292 if (v4l2_buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || 304 if (v4l2_buf->type != queue->type ||
293 v4l2_buf->memory != V4L2_MEMORY_MMAP) { 305 v4l2_buf->memory != V4L2_MEMORY_MMAP) {
294 uvc_trace(UVC_TRACE_CAPTURE, "[E] Invalid buffer type (%u) " 306 uvc_trace(UVC_TRACE_CAPTURE, "[E] Invalid buffer type (%u) "
295 "and/or memory (%u).\n", v4l2_buf->type, 307 "and/or memory (%u).\n", v4l2_buf->type,
@@ -397,6 +409,7 @@ int uvc_queue_enable(struct uvc_video_queue *queue, int enable)
397 } 409 }
398 queue->sequence = 0; 410 queue->sequence = 0;
399 queue->flags |= UVC_QUEUE_STREAMING; 411 queue->flags |= UVC_QUEUE_STREAMING;
412 queue->buf_used = 0;
400 } else { 413 } else {
401 uvc_queue_cancel(queue, 0); 414 uvc_queue_cancel(queue, 0);
402 INIT_LIST_HEAD(&queue->mainqueue); 415 INIT_LIST_HEAD(&queue->mainqueue);
diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c
index 2e1fd1b2a619..afcc6934559e 100644
--- a/drivers/media/video/uvc/uvc_v4l2.c
+++ b/drivers/media/video/uvc/uvc_v4l2.c
@@ -110,7 +110,7 @@ static int uvc_v4l2_try_format(struct uvc_video_device *video,
110 int ret = 0; 110 int ret = 0;
111 __u8 *fcc; 111 __u8 *fcc;
112 112
113 if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 113 if (fmt->type != video->streaming->type)
114 return -EINVAL; 114 return -EINVAL;
115 115
116 fcc = (__u8 *)&fmt->fmt.pix.pixelformat; 116 fcc = (__u8 *)&fmt->fmt.pix.pixelformat;
@@ -216,7 +216,7 @@ static int uvc_v4l2_get_format(struct uvc_video_device *video,
216 struct uvc_format *format = video->streaming->cur_format; 216 struct uvc_format *format = video->streaming->cur_format;
217 struct uvc_frame *frame = video->streaming->cur_frame; 217 struct uvc_frame *frame = video->streaming->cur_frame;
218 218
219 if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 219 if (fmt->type != video->streaming->type)
220 return -EINVAL; 220 return -EINVAL;
221 221
222 if (format == NULL || frame == NULL) 222 if (format == NULL || frame == NULL)
@@ -242,7 +242,7 @@ static int uvc_v4l2_set_format(struct uvc_video_device *video,
242 struct uvc_frame *frame; 242 struct uvc_frame *frame;
243 int ret; 243 int ret;
244 244
245 if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 245 if (fmt->type != video->streaming->type)
246 return -EINVAL; 246 return -EINVAL;
247 247
248 if (uvc_queue_streaming(&video->queue)) 248 if (uvc_queue_streaming(&video->queue))
@@ -264,7 +264,7 @@ static int uvc_v4l2_get_streamparm(struct uvc_video_device *video,
264{ 264{
265 uint32_t numerator, denominator; 265 uint32_t numerator, denominator;
266 266
267 if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 267 if (parm->type != video->streaming->type)
268 return -EINVAL; 268 return -EINVAL;
269 269
270 numerator = video->streaming->ctrl.dwFrameInterval; 270 numerator = video->streaming->ctrl.dwFrameInterval;
@@ -272,13 +272,21 @@ static int uvc_v4l2_get_streamparm(struct uvc_video_device *video,
272 uvc_simplify_fraction(&numerator, &denominator, 8, 333); 272 uvc_simplify_fraction(&numerator, &denominator, 8, 333);
273 273
274 memset(parm, 0, sizeof *parm); 274 memset(parm, 0, sizeof *parm);
275 parm->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 275 parm->type = video->streaming->type;
276 parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME; 276
277 parm->parm.capture.capturemode = 0; 277 if (video->streaming->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
278 parm->parm.capture.timeperframe.numerator = numerator; 278 parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
279 parm->parm.capture.timeperframe.denominator = denominator; 279 parm->parm.capture.capturemode = 0;
280 parm->parm.capture.extendedmode = 0; 280 parm->parm.capture.timeperframe.numerator = numerator;
281 parm->parm.capture.readbuffers = 0; 281 parm->parm.capture.timeperframe.denominator = denominator;
282 parm->parm.capture.extendedmode = 0;
283 parm->parm.capture.readbuffers = 0;
284 } else {
285 parm->parm.output.capability = V4L2_CAP_TIMEPERFRAME;
286 parm->parm.output.outputmode = 0;
287 parm->parm.output.timeperframe.numerator = numerator;
288 parm->parm.output.timeperframe.denominator = denominator;
289 }
282 290
283 return 0; 291 return 0;
284} 292}
@@ -288,24 +296,27 @@ static int uvc_v4l2_set_streamparm(struct uvc_video_device *video,
288{ 296{
289 struct uvc_frame *frame = video->streaming->cur_frame; 297 struct uvc_frame *frame = video->streaming->cur_frame;
290 struct uvc_streaming_control probe; 298 struct uvc_streaming_control probe;
299 struct v4l2_fract timeperframe;
291 uint32_t interval; 300 uint32_t interval;
292 int ret; 301 int ret;
293 302
294 if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 303 if (parm->type != video->streaming->type)
295 return -EINVAL; 304 return -EINVAL;
296 305
297 if (uvc_queue_streaming(&video->queue)) 306 if (uvc_queue_streaming(&video->queue))
298 return -EBUSY; 307 return -EBUSY;
299 308
309 if (parm->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
310 timeperframe = parm->parm.capture.timeperframe;
311 else
312 timeperframe = parm->parm.output.timeperframe;
313
300 memcpy(&probe, &video->streaming->ctrl, sizeof probe); 314 memcpy(&probe, &video->streaming->ctrl, sizeof probe);
301 interval = uvc_fraction_to_interval( 315 interval = uvc_fraction_to_interval(timeperframe.numerator,
302 parm->parm.capture.timeperframe.numerator, 316 timeperframe.denominator);
303 parm->parm.capture.timeperframe.denominator);
304 317
305 uvc_trace(UVC_TRACE_FORMAT, "Setting frame interval to %u/%u (%u).\n", 318 uvc_trace(UVC_TRACE_FORMAT, "Setting frame interval to %u/%u (%u).\n",
306 parm->parm.capture.timeperframe.numerator, 319 timeperframe.numerator, timeperframe.denominator, interval);
307 parm->parm.capture.timeperframe.denominator,
308 interval);
309 probe.dwFrameInterval = uvc_try_frame_interval(frame, interval); 320 probe.dwFrameInterval = uvc_try_frame_interval(frame, interval);
310 321
311 /* Probe the device with the new settings. */ 322 /* Probe the device with the new settings. */
@@ -315,11 +326,15 @@ static int uvc_v4l2_set_streamparm(struct uvc_video_device *video,
315 memcpy(&video->streaming->ctrl, &probe, sizeof probe); 326 memcpy(&video->streaming->ctrl, &probe, sizeof probe);
316 327
317 /* Return the actual frame period. */ 328 /* Return the actual frame period. */
318 parm->parm.capture.timeperframe.numerator = probe.dwFrameInterval; 329 timeperframe.numerator = probe.dwFrameInterval;
319 parm->parm.capture.timeperframe.denominator = 10000000; 330 timeperframe.denominator = 10000000;
320 uvc_simplify_fraction(&parm->parm.capture.timeperframe.numerator, 331 uvc_simplify_fraction(&timeperframe.numerator,
321 &parm->parm.capture.timeperframe.denominator, 332 &timeperframe.denominator, 8, 333);
322 8, 333); 333
334 if (parm->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
335 parm->parm.capture.timeperframe = timeperframe;
336 else
337 parm->parm.output.timeperframe = timeperframe;
323 338
324 return 0; 339 return 0;
325} 340}
@@ -476,8 +491,12 @@ static int uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
476 strncpy(cap->bus_info, video->dev->udev->bus->bus_name, 491 strncpy(cap->bus_info, video->dev->udev->bus->bus_name,
477 sizeof cap->bus_info); 492 sizeof cap->bus_info);
478 cap->version = DRIVER_VERSION_NUMBER; 493 cap->version = DRIVER_VERSION_NUMBER;
479 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE 494 if (video->streaming->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
480 | V4L2_CAP_STREAMING; 495 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE
496 | V4L2_CAP_STREAMING;
497 else
498 cap->capabilities = V4L2_CAP_VIDEO_OUTPUT
499 | V4L2_CAP_STREAMING;
481 break; 500 break;
482 } 501 }
483 502
@@ -655,7 +674,7 @@ static int uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
655 struct v4l2_fmtdesc *fmt = arg; 674 struct v4l2_fmtdesc *fmt = arg;
656 struct uvc_format *format; 675 struct uvc_format *format;
657 676
658 if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || 677 if (fmt->type != video->streaming->type ||
659 fmt->index >= video->streaming->nformats) 678 fmt->index >= video->streaming->nformats)
660 return -EINVAL; 679 return -EINVAL;
661 680
@@ -794,7 +813,7 @@ static int uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
794 struct v4l2_cropcap *ccap = arg; 813 struct v4l2_cropcap *ccap = arg;
795 struct uvc_frame *frame = video->streaming->cur_frame; 814 struct uvc_frame *frame = video->streaming->cur_frame;
796 815
797 if (ccap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 816 if (ccap->type != video->streaming->type)
798 return -EINVAL; 817 return -EINVAL;
799 818
800 ccap->bounds.left = 0; 819 ccap->bounds.left = 0;
@@ -820,7 +839,7 @@ static int uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
820 unsigned int bufsize = 839 unsigned int bufsize =
821 video->streaming->ctrl.dwMaxVideoFrameSize; 840 video->streaming->ctrl.dwMaxVideoFrameSize;
822 841
823 if (rb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || 842 if (rb->type != video->streaming->type ||
824 rb->memory != V4L2_MEMORY_MMAP) 843 rb->memory != V4L2_MEMORY_MMAP)
825 return -EINVAL; 844 return -EINVAL;
826 845
@@ -840,7 +859,7 @@ static int uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
840 { 859 {
841 struct v4l2_buffer *buf = arg; 860 struct v4l2_buffer *buf = arg;
842 861
843 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 862 if (buf->type != video->streaming->type)
844 return -EINVAL; 863 return -EINVAL;
845 864
846 if (!uvc_has_privileges(handle)) 865 if (!uvc_has_privileges(handle))
@@ -866,7 +885,7 @@ static int uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
866 { 885 {
867 int *type = arg; 886 int *type = arg;
868 887
869 if (*type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 888 if (*type != video->streaming->type)
870 return -EINVAL; 889 return -EINVAL;
871 890
872 if (!uvc_has_privileges(handle)) 891 if (!uvc_has_privileges(handle))
@@ -881,7 +900,7 @@ static int uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
881 { 900 {
882 int *type = arg; 901 int *type = arg;
883 902
884 if (*type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 903 if (*type != video->streaming->type)
885 return -EINVAL; 904 return -EINVAL;
886 905
887 if (!uvc_has_privileges(handle)) 906 if (!uvc_has_privileges(handle))
diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c
index 6d0ac3be8191..e7c31995527f 100644
--- a/drivers/media/video/uvc/uvc_video.c
+++ b/drivers/media/video/uvc/uvc_video.c
@@ -453,6 +453,34 @@ static void uvc_video_decode_end(struct uvc_video_device *video,
453 } 453 }
454} 454}
455 455
456static 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
465static 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
456/* ------------------------------------------------------------------------ 484/* ------------------------------------------------------------------------
457 * URB handling 485 * URB handling
458 */ 486 */
@@ -559,6 +587,48 @@ static void uvc_video_decode_bulk(struct urb *urb,
559 } 587 }
560} 588}
561 589
590static 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
562static void uvc_video_complete(struct urb *urb) 632static void uvc_video_complete(struct urb *urb)
563{ 633{
564 struct uvc_video_device *video = urb->context; 634 struct uvc_video_device *video = urb->context;
@@ -756,7 +826,15 @@ static int uvc_init_video_bulk(struct uvc_video_device *video,
756 if (uvc_alloc_urb_buffers(video, size) < 0) 826 if (uvc_alloc_urb_buffers(video, size) < 0)
757 return -ENOMEM; 827 return -ENOMEM;
758 828
759 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;
760 838
761 for (i = 0; i < UVC_URBS; ++i) { 839 for (i = 0; i < UVC_URBS; ++i) {
762 urb = usb_alloc_urb(0, gfp_flags); 840 urb = usb_alloc_urb(0, gfp_flags);
@@ -977,12 +1055,22 @@ int uvc_video_init(struct uvc_video_device *video)
977 atomic_set(&video->active, 0); 1055 atomic_set(&video->active, 0);
978 1056
979 /* Select the video decoding function */ 1057 /* Select the video decoding function */
980 if (video->dev->quirks & UVC_QUIRK_BUILTIN_ISIGHT) 1058 if (video->streaming->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
981 video->decode = uvc_video_decode_isight; 1059 if (video->dev->quirks & UVC_QUIRK_BUILTIN_ISIGHT)
982 else if (video->streaming->intf->num_altsetting > 1) 1060 video->decode = uvc_video_decode_isight;
983 video->decode = uvc_video_decode_isoc; 1061 else if (video->streaming->intf->num_altsetting > 1)
984 else 1062 video->decode = uvc_video_decode_isoc;
985 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 }
986 1074
987 return 0; 1075 return 0;
988} 1076}
diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h
index 2a5bdacbaf27..731cf7951656 100644
--- a/drivers/media/video/uvc/uvcvideo.h
+++ b/drivers/media/video/uvc/uvcvideo.h
@@ -529,6 +529,7 @@ struct uvc_streaming {
529 __u16 maxpsize; 529 __u16 maxpsize;
530 530
531 struct uvc_streaming_header header; 531 struct uvc_streaming_header header;
532 enum v4l2_buf_type type;
532 533
533 unsigned int nformats; 534 unsigned int nformats;
534 struct uvc_format *format; 535 struct uvc_format *format;
@@ -564,12 +565,15 @@ struct uvc_buffer {
564#define UVC_QUEUE_DROP_INCOMPLETE (1 << 2) 565#define UVC_QUEUE_DROP_INCOMPLETE (1 << 2)
565 566
566struct uvc_video_queue { 567struct uvc_video_queue {
568 enum v4l2_buf_type type;
569
567 void *mem; 570 void *mem;
568 unsigned int flags; 571 unsigned int flags;
569 __u32 sequence; 572 __u32 sequence;
570 573
571 unsigned int count; 574 unsigned int count;
572 unsigned int buf_size; 575 unsigned int buf_size;
576 unsigned int buf_used;
573 struct uvc_buffer buffer[UVC_MAX_VIDEO_BUFFERS]; 577 struct uvc_buffer buffer[UVC_MAX_VIDEO_BUFFERS];
574 struct mutex mutex; /* protects buffers and mainqueue */ 578 struct mutex mutex; /* protects buffers and mainqueue */
575 spinlock_t irqlock; /* protects irqqueue */ 579 spinlock_t irqlock; /* protects irqqueue */
@@ -584,8 +588,9 @@ struct uvc_video_device {
584 atomic_t active; 588 atomic_t active;
585 unsigned int frozen : 1; 589 unsigned int frozen : 1;
586 590
587 struct list_head iterms; 591 struct list_head iterms; /* Input terminals */
588 struct uvc_entity *oterm; 592 struct uvc_entity *oterm; /* Output terminal */
593 struct uvc_entity *sterm; /* USB streaming terminal */
589 struct uvc_entity *processing; 594 struct uvc_entity *processing;
590 struct uvc_entity *selector; 595 struct uvc_entity *selector;
591 struct list_head extensions; 596 struct list_head extensions;
@@ -726,7 +731,8 @@ extern struct uvc_driver uvc_driver;
726extern void uvc_delete(struct kref *kref); 731extern void uvc_delete(struct kref *kref);
727 732
728/* Video buffers queue management. */ 733/* Video buffers queue management. */
729extern void uvc_queue_init(struct uvc_video_queue *queue); 734extern void uvc_queue_init(struct uvc_video_queue *queue,
735 enum v4l2_buf_type type);
730extern int uvc_alloc_buffers(struct uvc_video_queue *queue, 736extern int uvc_alloc_buffers(struct uvc_video_queue *queue,
731 unsigned int nbuffers, unsigned int buflength); 737 unsigned int nbuffers, unsigned int buflength);
732extern int uvc_free_buffers(struct uvc_video_queue *queue); 738extern int uvc_free_buffers(struct uvc_video_queue *queue);