diff options
author | Aidan Thornton <makosoft@googlemail.com> | 2008-04-17 20:40:16 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-04-24 13:09:41 -0400 |
commit | 579f72e44fb1c991352f44c20b471c3001357f68 (patch) | |
tree | 1834a5b1624360955931a7c8bb5a9c000676b6b6 | |
parent | 7e6388a1b97cca57a1906df6104feb4001721576 (diff) |
V4L/DVB (7602): em28xx: generalise URB setup code
Move the URB setup and management code to em28xx-core.c and generalise
it slighlty so that the DVB code can use it.
Signed-off-by: Aidan Thornton <makosoft@googlemail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
-rw-r--r-- | drivers/media/video/em28xx/em28xx-core.c | 181 | ||||
-rw-r--r-- | drivers/media/video/em28xx/em28xx-video.c | 195 | ||||
-rw-r--r-- | drivers/media/video/em28xx/em28xx.h | 17 |
3 files changed, 202 insertions, 191 deletions
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c index 841c7c2c91b3..cb9f721ca280 100644 --- a/drivers/media/video/em28xx/em28xx-core.c +++ b/drivers/media/video/em28xx/em28xx-core.c | |||
@@ -53,6 +53,12 @@ static int alt = EM28XX_PINOUT; | |||
53 | module_param(alt, int, 0644); | 53 | module_param(alt, int, 0644); |
54 | MODULE_PARM_DESC(alt, "alternate setting to use for video endpoint"); | 54 | MODULE_PARM_DESC(alt, "alternate setting to use for video endpoint"); |
55 | 55 | ||
56 | /* FIXME */ | ||
57 | #define em28xx_isocdbg(fmt, arg...) do {\ | ||
58 | if (core_debug) \ | ||
59 | printk(KERN_INFO "%s %s :"fmt, \ | ||
60 | dev->name, __func__ , ##arg); } while (0) | ||
61 | |||
56 | /* | 62 | /* |
57 | * em28xx_read_reg_req() | 63 | * em28xx_read_reg_req() |
58 | * reads data from the usb device specifying bRequest | 64 | * reads data from the usb device specifying bRequest |
@@ -455,3 +461,178 @@ int em28xx_set_alternate(struct em28xx *dev) | |||
455 | } | 461 | } |
456 | return 0; | 462 | return 0; |
457 | } | 463 | } |
464 | |||
465 | /* ------------------------------------------------------------------ | ||
466 | URB control | ||
467 | ------------------------------------------------------------------*/ | ||
468 | |||
469 | /* | ||
470 | * IRQ callback, called by URB callback | ||
471 | */ | ||
472 | static void em28xx_irq_callback(struct urb *urb) | ||
473 | { | ||
474 | struct em28xx_dmaqueue *dma_q = urb->context; | ||
475 | struct em28xx *dev = container_of(dma_q, struct em28xx, vidq); | ||
476 | int rc, i; | ||
477 | |||
478 | /* Copy data from URB */ | ||
479 | spin_lock(&dev->slock); | ||
480 | rc = dev->isoc_ctl.isoc_copy(dev, urb); | ||
481 | spin_unlock(&dev->slock); | ||
482 | |||
483 | /* Reset urb buffers */ | ||
484 | for (i = 0; i < urb->number_of_packets; i++) { | ||
485 | urb->iso_frame_desc[i].status = 0; | ||
486 | urb->iso_frame_desc[i].actual_length = 0; | ||
487 | } | ||
488 | urb->status = 0; | ||
489 | |||
490 | urb->status = usb_submit_urb(urb, GFP_ATOMIC); | ||
491 | if (urb->status) { | ||
492 | em28xx_err("urb resubmit failed (error=%i)\n", | ||
493 | urb->status); | ||
494 | } | ||
495 | } | ||
496 | |||
497 | /* | ||
498 | * Stop and Deallocate URBs | ||
499 | */ | ||
500 | void em28xx_uninit_isoc(struct em28xx *dev) | ||
501 | { | ||
502 | struct urb *urb; | ||
503 | int i; | ||
504 | |||
505 | em28xx_isocdbg("em28xx: called em28xx_uninit_isoc\n"); | ||
506 | |||
507 | dev->isoc_ctl.nfields = -1; | ||
508 | for (i = 0; i < dev->isoc_ctl.num_bufs; i++) { | ||
509 | urb = dev->isoc_ctl.urb[i]; | ||
510 | if (urb) { | ||
511 | usb_kill_urb(urb); | ||
512 | usb_unlink_urb(urb); | ||
513 | if (dev->isoc_ctl.transfer_buffer[i]) { | ||
514 | usb_buffer_free(dev->udev, | ||
515 | urb->transfer_buffer_length, | ||
516 | dev->isoc_ctl.transfer_buffer[i], | ||
517 | urb->transfer_dma); | ||
518 | } | ||
519 | usb_free_urb(urb); | ||
520 | dev->isoc_ctl.urb[i] = NULL; | ||
521 | } | ||
522 | dev->isoc_ctl.transfer_buffer[i] = NULL; | ||
523 | } | ||
524 | |||
525 | kfree(dev->isoc_ctl.urb); | ||
526 | kfree(dev->isoc_ctl.transfer_buffer); | ||
527 | |||
528 | dev->isoc_ctl.urb = NULL; | ||
529 | dev->isoc_ctl.transfer_buffer = NULL; | ||
530 | dev->isoc_ctl.num_bufs = 0; | ||
531 | |||
532 | em28xx_capture_start(dev, 0); | ||
533 | } | ||
534 | EXPORT_SYMBOL_GPL(em28xx_uninit_isoc); | ||
535 | |||
536 | /* | ||
537 | * Allocate URBs and start IRQ | ||
538 | */ | ||
539 | int em28xx_init_isoc(struct em28xx *dev, int max_packets, | ||
540 | int num_bufs, int max_pkt_size, | ||
541 | int (*isoc_copy) (struct em28xx *dev, struct urb *urb), | ||
542 | int cap_type) | ||
543 | { | ||
544 | struct em28xx_dmaqueue *dma_q = &dev->vidq; | ||
545 | int i; | ||
546 | int sb_size, pipe; | ||
547 | struct urb *urb; | ||
548 | int j, k; | ||
549 | int rc; | ||
550 | |||
551 | em28xx_isocdbg("em28xx: called em28xx_prepare_isoc\n"); | ||
552 | |||
553 | /* De-allocates all pending stuff */ | ||
554 | em28xx_uninit_isoc(dev); | ||
555 | |||
556 | dev->isoc_ctl.isoc_copy = isoc_copy; | ||
557 | dev->isoc_ctl.num_bufs = num_bufs; | ||
558 | |||
559 | dev->isoc_ctl.urb = kzalloc(sizeof(void *)*num_bufs, GFP_KERNEL); | ||
560 | if (!dev->isoc_ctl.urb) { | ||
561 | em28xx_errdev("cannot alloc memory for usb buffers\n"); | ||
562 | return -ENOMEM; | ||
563 | } | ||
564 | |||
565 | dev->isoc_ctl.transfer_buffer = kzalloc(sizeof(void *)*num_bufs, | ||
566 | GFP_KERNEL); | ||
567 | if (!dev->isoc_ctl.urb) { | ||
568 | em28xx_errdev("cannot allocate memory for usbtransfer\n"); | ||
569 | kfree(dev->isoc_ctl.urb); | ||
570 | return -ENOMEM; | ||
571 | } | ||
572 | |||
573 | dev->isoc_ctl.max_pkt_size = max_pkt_size; | ||
574 | dev->isoc_ctl.buf = NULL; | ||
575 | |||
576 | sb_size = max_packets * dev->isoc_ctl.max_pkt_size; | ||
577 | |||
578 | /* allocate urbs and transfer buffers */ | ||
579 | for (i = 0; i < dev->isoc_ctl.num_bufs; i++) { | ||
580 | urb = usb_alloc_urb(max_packets, GFP_KERNEL); | ||
581 | if (!urb) { | ||
582 | em28xx_err("cannot alloc isoc_ctl.urb %i\n", i); | ||
583 | em28xx_uninit_isoc(dev); | ||
584 | return -ENOMEM; | ||
585 | } | ||
586 | dev->isoc_ctl.urb[i] = urb; | ||
587 | |||
588 | dev->isoc_ctl.transfer_buffer[i] = usb_buffer_alloc(dev->udev, | ||
589 | sb_size, GFP_KERNEL, &urb->transfer_dma); | ||
590 | if (!dev->isoc_ctl.transfer_buffer[i]) { | ||
591 | em28xx_err("unable to allocate %i bytes for transfer" | ||
592 | " buffer %i%s\n", | ||
593 | sb_size, i, | ||
594 | in_interrupt()?" while in int":""); | ||
595 | em28xx_uninit_isoc(dev); | ||
596 | return -ENOMEM; | ||
597 | } | ||
598 | memset(dev->isoc_ctl.transfer_buffer[i], 0, sb_size); | ||
599 | |||
600 | /* FIXME: this is a hack - should be | ||
601 | 'desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK' | ||
602 | should also be using 'desc.bInterval' | ||
603 | */ | ||
604 | pipe = usb_rcvisocpipe(dev->udev, cap_type == EM28XX_ANALOG_CAPTURE ? 0x82 : 0x84); | ||
605 | usb_fill_int_urb(urb, dev->udev, pipe, | ||
606 | dev->isoc_ctl.transfer_buffer[i], sb_size, | ||
607 | em28xx_irq_callback, dma_q, 1); | ||
608 | |||
609 | urb->number_of_packets = max_packets; | ||
610 | urb->transfer_flags = URB_ISO_ASAP; | ||
611 | |||
612 | k = 0; | ||
613 | for (j = 0; j < max_packets; j++) { | ||
614 | urb->iso_frame_desc[j].offset = k; | ||
615 | urb->iso_frame_desc[j].length = | ||
616 | dev->isoc_ctl.max_pkt_size; | ||
617 | k += dev->isoc_ctl.max_pkt_size; | ||
618 | } | ||
619 | } | ||
620 | |||
621 | init_waitqueue_head(&dma_q->wq); | ||
622 | |||
623 | em28xx_capture_start(dev, cap_type); | ||
624 | |||
625 | /* submit urbs and enables IRQ */ | ||
626 | for (i = 0; i < dev->isoc_ctl.num_bufs; i++) { | ||
627 | rc = usb_submit_urb(dev->isoc_ctl.urb[i], GFP_ATOMIC); | ||
628 | if (rc) { | ||
629 | em28xx_err("submit of urb %i failed (error=%i)\n", i, | ||
630 | rc); | ||
631 | em28xx_uninit_isoc(dev); | ||
632 | return rc; | ||
633 | } | ||
634 | } | ||
635 | |||
636 | return 0; | ||
637 | } | ||
638 | EXPORT_SYMBOL_GPL(em28xx_init_isoc); | ||
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c index 72a7633b6452..1a0b09714af5 100644 --- a/drivers/media/video/em28xx/em28xx-video.c +++ b/drivers/media/video/em28xx/em28xx-video.c | |||
@@ -285,11 +285,10 @@ static inline void get_next_buf(struct em28xx_dmaqueue *dma_q, | |||
285 | /* | 285 | /* |
286 | * Controls the isoc copy of each urb packet | 286 | * Controls the isoc copy of each urb packet |
287 | */ | 287 | */ |
288 | static inline int em28xx_isoc_copy(struct urb *urb) | 288 | static inline int em28xx_isoc_copy(struct em28xx *dev, struct urb *urb) |
289 | { | 289 | { |
290 | struct em28xx_buffer *buf; | 290 | struct em28xx_buffer *buf; |
291 | struct em28xx_dmaqueue *dma_q = urb->context; | 291 | struct em28xx_dmaqueue *dma_q = urb->context; |
292 | struct em28xx *dev = container_of(dma_q, struct em28xx, vidq); | ||
293 | unsigned char *outp = NULL; | 292 | unsigned char *outp = NULL; |
294 | int i, len = 0, rc = 1; | 293 | int i, len = 0, rc = 1; |
295 | unsigned char *p; | 294 | unsigned char *p; |
@@ -371,188 +370,6 @@ static inline int em28xx_isoc_copy(struct urb *urb) | |||
371 | } | 370 | } |
372 | 371 | ||
373 | /* ------------------------------------------------------------------ | 372 | /* ------------------------------------------------------------------ |
374 | URB control | ||
375 | ------------------------------------------------------------------*/ | ||
376 | |||
377 | /* | ||
378 | * IRQ callback, called by URB callback | ||
379 | */ | ||
380 | static void em28xx_irq_callback(struct urb *urb) | ||
381 | { | ||
382 | struct em28xx_dmaqueue *dma_q = urb->context; | ||
383 | struct em28xx *dev = container_of(dma_q, struct em28xx, vidq); | ||
384 | int rc, i; | ||
385 | |||
386 | /* Copy data from URB */ | ||
387 | spin_lock(&dev->slock); | ||
388 | rc = em28xx_isoc_copy(urb); | ||
389 | spin_unlock(&dev->slock); | ||
390 | |||
391 | /* Reset urb buffers */ | ||
392 | for (i = 0; i < urb->number_of_packets; i++) { | ||
393 | urb->iso_frame_desc[i].status = 0; | ||
394 | urb->iso_frame_desc[i].actual_length = 0; | ||
395 | } | ||
396 | urb->status = 0; | ||
397 | |||
398 | urb->status = usb_submit_urb(urb, GFP_ATOMIC); | ||
399 | if (urb->status) { | ||
400 | em28xx_err("urb resubmit failed (error=%i)\n", | ||
401 | urb->status); | ||
402 | } | ||
403 | } | ||
404 | |||
405 | /* | ||
406 | * Stop and Deallocate URBs | ||
407 | */ | ||
408 | static void em28xx_uninit_isoc(struct em28xx *dev) | ||
409 | { | ||
410 | struct urb *urb; | ||
411 | int i; | ||
412 | |||
413 | em28xx_isocdbg("em28xx: called em28xx_uninit_isoc\n"); | ||
414 | |||
415 | dev->isoc_ctl.nfields = -1; | ||
416 | for (i = 0; i < dev->isoc_ctl.num_bufs; i++) { | ||
417 | urb = dev->isoc_ctl.urb[i]; | ||
418 | if (urb) { | ||
419 | usb_kill_urb(urb); | ||
420 | usb_unlink_urb(urb); | ||
421 | if (dev->isoc_ctl.transfer_buffer[i]) { | ||
422 | usb_buffer_free(dev->udev, | ||
423 | urb->transfer_buffer_length, | ||
424 | dev->isoc_ctl.transfer_buffer[i], | ||
425 | urb->transfer_dma); | ||
426 | } | ||
427 | usb_free_urb(urb); | ||
428 | dev->isoc_ctl.urb[i] = NULL; | ||
429 | } | ||
430 | dev->isoc_ctl.transfer_buffer[i] = NULL; | ||
431 | } | ||
432 | |||
433 | kfree(dev->isoc_ctl.urb); | ||
434 | kfree(dev->isoc_ctl.transfer_buffer); | ||
435 | dev->isoc_ctl.urb = NULL; | ||
436 | dev->isoc_ctl.transfer_buffer = NULL; | ||
437 | |||
438 | dev->isoc_ctl.num_bufs = 0; | ||
439 | |||
440 | em28xx_capture_start(dev, 0); | ||
441 | } | ||
442 | |||
443 | /* | ||
444 | * Allocate URBs and start IRQ | ||
445 | */ | ||
446 | static int em28xx_prepare_isoc(struct em28xx *dev, int max_packets, | ||
447 | int num_bufs) | ||
448 | { | ||
449 | struct em28xx_dmaqueue *dma_q = &dev->vidq; | ||
450 | int i; | ||
451 | int sb_size, pipe; | ||
452 | struct urb *urb; | ||
453 | int j, k; | ||
454 | |||
455 | em28xx_isocdbg("em28xx: called em28xx_prepare_isoc\n"); | ||
456 | |||
457 | /* De-allocates all pending stuff */ | ||
458 | em28xx_uninit_isoc(dev); | ||
459 | |||
460 | dev->isoc_ctl.num_bufs = num_bufs; | ||
461 | |||
462 | dev->isoc_ctl.urb = kzalloc(sizeof(void *)*num_bufs, GFP_KERNEL); | ||
463 | if (!dev->isoc_ctl.urb) { | ||
464 | em28xx_errdev("cannot alloc memory for usb buffers\n"); | ||
465 | return -ENOMEM; | ||
466 | } | ||
467 | |||
468 | dev->isoc_ctl.transfer_buffer = kzalloc(sizeof(void *)*num_bufs, | ||
469 | GFP_KERNEL); | ||
470 | if (!dev->isoc_ctl.urb) { | ||
471 | em28xx_errdev("cannot allocate memory for usbtransfer\n"); | ||
472 | kfree(dev->isoc_ctl.urb); | ||
473 | return -ENOMEM; | ||
474 | } | ||
475 | |||
476 | dev->isoc_ctl.max_pkt_size = dev->max_pkt_size; | ||
477 | dev->isoc_ctl.buf = NULL; | ||
478 | |||
479 | sb_size = max_packets * dev->isoc_ctl.max_pkt_size; | ||
480 | |||
481 | /* allocate urbs and transfer buffers */ | ||
482 | for (i = 0; i < dev->isoc_ctl.num_bufs; i++) { | ||
483 | urb = usb_alloc_urb(max_packets, GFP_KERNEL); | ||
484 | if (!urb) { | ||
485 | em28xx_err("cannot alloc isoc_ctl.urb %i\n", i); | ||
486 | em28xx_uninit_isoc(dev); | ||
487 | return -ENOMEM; | ||
488 | } | ||
489 | dev->isoc_ctl.urb[i] = urb; | ||
490 | |||
491 | dev->isoc_ctl.transfer_buffer[i] = usb_buffer_alloc(dev->udev, | ||
492 | sb_size, GFP_KERNEL, &urb->transfer_dma); | ||
493 | if (!dev->isoc_ctl.transfer_buffer[i]) { | ||
494 | em28xx_err("unable to allocate %i bytes for transfer" | ||
495 | " buffer %i%s\n", | ||
496 | sb_size, i, | ||
497 | in_interrupt()?" while in int":""); | ||
498 | em28xx_uninit_isoc(dev); | ||
499 | return -ENOMEM; | ||
500 | } | ||
501 | memset(dev->isoc_ctl.transfer_buffer[i], 0, sb_size); | ||
502 | |||
503 | /* FIXME: this is a hack - should be | ||
504 | 'desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK' | ||
505 | should also be using 'desc.bInterval' | ||
506 | */ | ||
507 | pipe = usb_rcvisocpipe(dev->udev, 0x82); | ||
508 | usb_fill_int_urb(urb, dev->udev, pipe, | ||
509 | dev->isoc_ctl.transfer_buffer[i], sb_size, | ||
510 | em28xx_irq_callback, dma_q, 1); | ||
511 | |||
512 | urb->number_of_packets = max_packets; | ||
513 | urb->transfer_flags = URB_ISO_ASAP; | ||
514 | |||
515 | k = 0; | ||
516 | for (j = 0; j < max_packets; j++) { | ||
517 | urb->iso_frame_desc[j].offset = k; | ||
518 | urb->iso_frame_desc[j].length = | ||
519 | dev->isoc_ctl.max_pkt_size; | ||
520 | k += dev->isoc_ctl.max_pkt_size; | ||
521 | } | ||
522 | } | ||
523 | |||
524 | return 0; | ||
525 | } | ||
526 | |||
527 | static int em28xx_start_thread(struct em28xx_dmaqueue *dma_q) | ||
528 | { | ||
529 | struct em28xx *dev = container_of(dma_q, struct em28xx, vidq); | ||
530 | int i, rc = 0; | ||
531 | |||
532 | em28xx_videodbg("Called em28xx_start_thread\n"); | ||
533 | |||
534 | init_waitqueue_head(&dma_q->wq); | ||
535 | |||
536 | em28xx_capture_start(dev, 1); | ||
537 | |||
538 | /* submit urbs and enables IRQ */ | ||
539 | for (i = 0; i < dev->isoc_ctl.num_bufs; i++) { | ||
540 | rc = usb_submit_urb(dev->isoc_ctl.urb[i], GFP_ATOMIC); | ||
541 | if (rc) { | ||
542 | em28xx_err("submit of urb %i failed (error=%i)\n", i, | ||
543 | rc); | ||
544 | em28xx_uninit_isoc(dev); | ||
545 | return rc; | ||
546 | } | ||
547 | } | ||
548 | |||
549 | if (rc < 0) | ||
550 | return rc; | ||
551 | |||
552 | return 0; | ||
553 | } | ||
554 | |||
555 | /* ------------------------------------------------------------------ | ||
556 | Videobuf operations | 373 | Videobuf operations |
557 | ------------------------------------------------------------------*/ | 374 | ------------------------------------------------------------------*/ |
558 | 375 | ||
@@ -615,7 +432,6 @@ buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, | |||
615 | struct em28xx_fh *fh = vq->priv_data; | 432 | struct em28xx_fh *fh = vq->priv_data; |
616 | struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb); | 433 | struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb); |
617 | struct em28xx *dev = fh->dev; | 434 | struct em28xx *dev = fh->dev; |
618 | struct em28xx_dmaqueue *vidq = &dev->vidq; | ||
619 | int rc = 0, urb_init = 0; | 435 | int rc = 0, urb_init = 0; |
620 | 436 | ||
621 | /* FIXME: It assumes depth = 16 */ | 437 | /* FIXME: It assumes depth = 16 */ |
@@ -639,12 +455,9 @@ buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, | |||
639 | urb_init = 1; | 455 | urb_init = 1; |
640 | 456 | ||
641 | if (urb_init) { | 457 | if (urb_init) { |
642 | rc = em28xx_prepare_isoc(dev, EM28XX_NUM_PACKETS, | 458 | rc = em28xx_init_isoc(dev, EM28XX_NUM_PACKETS, |
643 | EM28XX_NUM_BUFS); | 459 | EM28XX_NUM_BUFS, dev->max_pkt_size, |
644 | if (rc < 0) | 460 | em28xx_isoc_copy, EM28XX_ANALOG_CAPTURE); |
645 | goto fail; | ||
646 | |||
647 | rc = em28xx_start_thread(vidq); | ||
648 | if (rc < 0) | 461 | if (rc < 0) |
649 | goto fail; | 462 | goto fail; |
650 | } | 463 | } |
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h index 3786dd819bbd..151bc57bd08b 100644 --- a/drivers/media/video/em28xx/em28xx.h +++ b/drivers/media/video/em28xx/em28xx.h | |||
@@ -119,6 +119,8 @@ enum em28xx_stream_state { | |||
119 | STREAM_ON, | 119 | STREAM_ON, |
120 | }; | 120 | }; |
121 | 121 | ||
122 | struct em28xx; | ||
123 | |||
122 | struct em28xx_usb_isoc_ctl { | 124 | struct em28xx_usb_isoc_ctl { |
123 | /* max packet size of isoc transaction */ | 125 | /* max packet size of isoc transaction */ |
124 | int max_pkt_size; | 126 | int max_pkt_size; |
@@ -148,6 +150,10 @@ struct em28xx_usb_isoc_ctl { | |||
148 | 150 | ||
149 | /* Stores the number of received fields */ | 151 | /* Stores the number of received fields */ |
150 | int nfields; | 152 | int nfields; |
153 | |||
154 | /* isoc urb callback */ | ||
155 | int (*isoc_copy) (struct em28xx *dev, struct urb *urb); | ||
156 | |||
151 | }; | 157 | }; |
152 | 158 | ||
153 | struct em28xx_fmt { | 159 | struct em28xx_fmt { |
@@ -279,6 +285,12 @@ enum em28xx_dev_state { | |||
279 | DEV_MISCONFIGURED = 0x04, | 285 | DEV_MISCONFIGURED = 0x04, |
280 | }; | 286 | }; |
281 | 287 | ||
288 | enum em28xx_capture_mode { | ||
289 | EM28XX_CAPTURE_OFF = 0, | ||
290 | EM28XX_ANALOG_CAPTURE, | ||
291 | EM28XX_DIGITAL_CAPTURE, | ||
292 | }; | ||
293 | |||
282 | #define EM28XX_AUDIO_BUFS 5 | 294 | #define EM28XX_AUDIO_BUFS 5 |
283 | #define EM28XX_NUM_AUDIO_PACKETS 64 | 295 | #define EM28XX_NUM_AUDIO_PACKETS 64 |
284 | #define EM28XX_AUDIO_MAX_PACKET_SIZE 196 /* static value */ | 296 | #define EM28XX_AUDIO_MAX_PACKET_SIZE 196 /* static value */ |
@@ -452,6 +464,11 @@ int em28xx_capture_start(struct em28xx *dev, int start); | |||
452 | int em28xx_outfmt_set_yuv422(struct em28xx *dev); | 464 | int em28xx_outfmt_set_yuv422(struct em28xx *dev); |
453 | int em28xx_resolution_set(struct em28xx *dev); | 465 | int em28xx_resolution_set(struct em28xx *dev); |
454 | int em28xx_set_alternate(struct em28xx *dev); | 466 | int em28xx_set_alternate(struct em28xx *dev); |
467 | int em28xx_init_isoc(struct em28xx *dev, int max_packets, | ||
468 | int num_bufs, int max_pkt_size, | ||
469 | int (*isoc_copy) (struct em28xx *dev, struct urb *urb), | ||
470 | int cap_type); | ||
471 | void em28xx_uninit_isoc(struct em28xx *dev); | ||
455 | 472 | ||
456 | /* Provided by em28xx-video.c */ | 473 | /* Provided by em28xx-video.c */ |
457 | int em28xx_register_extension(struct em28xx_ops *dev); | 474 | int em28xx_register_extension(struct em28xx_ops *dev); |