aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAidan Thornton <makosoft@googlemail.com>2008-04-17 20:40:16 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2008-04-24 13:09:41 -0400
commit579f72e44fb1c991352f44c20b471c3001357f68 (patch)
tree1834a5b1624360955931a7c8bb5a9c000676b6b6
parent7e6388a1b97cca57a1906df6104feb4001721576 (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.c181
-rw-r--r--drivers/media/video/em28xx/em28xx-video.c195
-rw-r--r--drivers/media/video/em28xx/em28xx.h17
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;
53module_param(alt, int, 0644); 53module_param(alt, int, 0644);
54MODULE_PARM_DESC(alt, "alternate setting to use for video endpoint"); 54MODULE_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 */
472static 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 */
500void 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}
534EXPORT_SYMBOL_GPL(em28xx_uninit_isoc);
535
536/*
537 * Allocate URBs and start IRQ
538 */
539int 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}
638EXPORT_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 */
288static inline int em28xx_isoc_copy(struct urb *urb) 288static 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 */
380static 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 */
408static 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 */
446static 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
527static 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
122struct em28xx;
123
122struct em28xx_usb_isoc_ctl { 124struct 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
153struct em28xx_fmt { 159struct em28xx_fmt {
@@ -279,6 +285,12 @@ enum em28xx_dev_state {
279 DEV_MISCONFIGURED = 0x04, 285 DEV_MISCONFIGURED = 0x04,
280}; 286};
281 287
288enum 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);
452int em28xx_outfmt_set_yuv422(struct em28xx *dev); 464int em28xx_outfmt_set_yuv422(struct em28xx *dev);
453int em28xx_resolution_set(struct em28xx *dev); 465int em28xx_resolution_set(struct em28xx *dev);
454int em28xx_set_alternate(struct em28xx *dev); 466int em28xx_set_alternate(struct em28xx *dev);
467int 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);
471void em28xx_uninit_isoc(struct em28xx *dev);
455 472
456/* Provided by em28xx-video.c */ 473/* Provided by em28xx-video.c */
457int em28xx_register_extension(struct em28xx_ops *dev); 474int em28xx_register_extension(struct em28xx_ops *dev);