diff options
-rw-r--r-- | drivers/media/video/em28xx/em28xx-core.c | 62 | ||||
-rw-r--r-- | drivers/media/video/em28xx/em28xx-video.c | 4 | ||||
-rw-r--r-- | drivers/media/video/em28xx/em28xx.h | 2 |
3 files changed, 43 insertions, 25 deletions
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c index 275f1e936304..0966017ca745 100644 --- a/drivers/media/video/em28xx/em28xx-core.c +++ b/drivers/media/video/em28xx/em28xx-core.c | |||
@@ -72,7 +72,8 @@ u32 em28xx_request_buffers(struct em28xx *dev, u32 count) | |||
72 | const size_t imagesize = PAGE_ALIGN(dev->frame_size); /*needs to be page aligned cause the buffers can be mapped individually! */ | 72 | const size_t imagesize = PAGE_ALIGN(dev->frame_size); /*needs to be page aligned cause the buffers can be mapped individually! */ |
73 | void *buff = NULL; | 73 | void *buff = NULL; |
74 | u32 i; | 74 | u32 i; |
75 | em28xx_coredbg("requested %i buffers with size %zi", count, imagesize); | 75 | em28xx_coredbg("requested %i buffers with size %zi\n", |
76 | count, imagesize); | ||
76 | if (count > EM28XX_NUM_FRAMES) | 77 | if (count > EM28XX_NUM_FRAMES) |
77 | count = EM28XX_NUM_FRAMES; | 78 | count = EM28XX_NUM_FRAMES; |
78 | 79 | ||
@@ -676,7 +677,7 @@ static void em28xx_isocIrq(struct urb *urb) | |||
676 | continue; | 677 | continue; |
677 | } | 678 | } |
678 | if (urb->iso_frame_desc[i].actual_length > | 679 | if (urb->iso_frame_desc[i].actual_length > |
679 | dev->max_pkt_size) { | 680 | urb->iso_frame_desc[i].length) { |
680 | em28xx_isocdbg("packet bigger than packet size"); | 681 | em28xx_isocdbg("packet bigger than packet size"); |
681 | continue; | 682 | continue; |
682 | } | 683 | } |
@@ -722,8 +723,11 @@ void em28xx_uninit_isoc(struct em28xx *dev) | |||
722 | for (i = 0; i < EM28XX_NUM_BUFS; i++) { | 723 | for (i = 0; i < EM28XX_NUM_BUFS; i++) { |
723 | if (dev->urb[i]) { | 724 | if (dev->urb[i]) { |
724 | usb_kill_urb(dev->urb[i]); | 725 | usb_kill_urb(dev->urb[i]); |
725 | if (dev->transfer_buffer[i]){ | 726 | if (dev->transfer_buffer[i]) { |
726 | usb_buffer_free(dev->udev,(EM28XX_NUM_PACKETS*dev->max_pkt_size),dev->transfer_buffer[i],dev->urb[i]->transfer_dma); | 727 | usb_buffer_free(dev->udev, |
728 | dev->urb[i]->transfer_buffer_length, | ||
729 | dev->transfer_buffer[i], | ||
730 | dev->urb[i]->transfer_dma); | ||
727 | } | 731 | } |
728 | usb_free_urb(dev->urb[i]); | 732 | usb_free_urb(dev->urb[i]); |
729 | } | 733 | } |
@@ -741,7 +745,10 @@ int em28xx_init_isoc(struct em28xx *dev) | |||
741 | { | 745 | { |
742 | /* change interface to 3 which allows the biggest packet sizes */ | 746 | /* change interface to 3 which allows the biggest packet sizes */ |
743 | int i, errCode; | 747 | int i, errCode; |
744 | const int sb_size = EM28XX_NUM_PACKETS * dev->max_pkt_size; | 748 | int sb_size; |
749 | |||
750 | em28xx_set_alternate(dev); | ||
751 | sb_size = EM28XX_NUM_PACKETS * dev->max_pkt_size; | ||
745 | 752 | ||
746 | /* reset streaming vars */ | 753 | /* reset streaming vars */ |
747 | dev->frame_current = NULL; | 754 | dev->frame_current = NULL; |
@@ -750,7 +757,7 @@ int em28xx_init_isoc(struct em28xx *dev) | |||
750 | /* allocate urbs */ | 757 | /* allocate urbs */ |
751 | for (i = 0; i < EM28XX_NUM_BUFS; i++) { | 758 | for (i = 0; i < EM28XX_NUM_BUFS; i++) { |
752 | struct urb *urb; | 759 | struct urb *urb; |
753 | int j, k; | 760 | int j; |
754 | /* allocate transfer buffer */ | 761 | /* allocate transfer buffer */ |
755 | urb = usb_alloc_urb(EM28XX_NUM_PACKETS, GFP_KERNEL); | 762 | urb = usb_alloc_urb(EM28XX_NUM_PACKETS, GFP_KERNEL); |
756 | if (!urb){ | 763 | if (!urb){ |
@@ -758,7 +765,9 @@ int em28xx_init_isoc(struct em28xx *dev) | |||
758 | em28xx_uninit_isoc(dev); | 765 | em28xx_uninit_isoc(dev); |
759 | return -ENOMEM; | 766 | return -ENOMEM; |
760 | } | 767 | } |
761 | dev->transfer_buffer[i] = usb_buffer_alloc(dev->udev, sb_size, GFP_KERNEL,&urb->transfer_dma); | 768 | dev->transfer_buffer[i] = usb_buffer_alloc(dev->udev, sb_size, |
769 | GFP_KERNEL, | ||
770 | &urb->transfer_dma); | ||
762 | if (!dev->transfer_buffer[i]) { | 771 | if (!dev->transfer_buffer[i]) { |
763 | em28xx_errdev | 772 | em28xx_errdev |
764 | ("unable to allocate %i bytes for transfer buffer %i\n", | 773 | ("unable to allocate %i bytes for transfer buffer %i\n", |
@@ -777,16 +786,16 @@ int em28xx_init_isoc(struct em28xx *dev) | |||
777 | urb->complete = em28xx_isocIrq; | 786 | urb->complete = em28xx_isocIrq; |
778 | urb->number_of_packets = EM28XX_NUM_PACKETS; | 787 | urb->number_of_packets = EM28XX_NUM_PACKETS; |
779 | urb->transfer_buffer_length = sb_size; | 788 | urb->transfer_buffer_length = sb_size; |
780 | for (j = k = 0; j < EM28XX_NUM_PACKETS; | 789 | for (j = 0; j < EM28XX_NUM_PACKETS; j++) { |
781 | j++, k += dev->max_pkt_size) { | 790 | urb->iso_frame_desc[j].offset = j * dev->max_pkt_size; |
782 | urb->iso_frame_desc[j].offset = k; | 791 | urb->iso_frame_desc[j].length = dev->max_pkt_size; |
783 | urb->iso_frame_desc[j].length = | ||
784 | dev->max_pkt_size; | ||
785 | } | 792 | } |
786 | dev->urb[i] = urb; | 793 | dev->urb[i] = urb; |
787 | } | 794 | } |
788 | 795 | ||
789 | /* submit urbs */ | 796 | /* submit urbs */ |
797 | em28xx_coredbg("Submitting %d urbs of %d packets (%d each)\n", | ||
798 | EM28XX_NUM_BUFS, EM28XX_NUM_PACKETS, dev->max_pkt_size); | ||
790 | for (i = 0; i < EM28XX_NUM_BUFS; i++) { | 799 | for (i = 0; i < EM28XX_NUM_BUFS; i++) { |
791 | errCode = usb_submit_urb(dev->urb[i], GFP_KERNEL); | 800 | errCode = usb_submit_urb(dev->urb[i], GFP_KERNEL); |
792 | if (errCode) { | 801 | if (errCode) { |
@@ -803,22 +812,31 @@ int em28xx_init_isoc(struct em28xx *dev) | |||
803 | int em28xx_set_alternate(struct em28xx *dev) | 812 | int em28xx_set_alternate(struct em28xx *dev) |
804 | { | 813 | { |
805 | int errCode, prev_alt = dev->alt; | 814 | int errCode, prev_alt = dev->alt; |
806 | dev->alt = alt; | 815 | int i; |
807 | if (dev->alt == 0) { | 816 | unsigned int min_pkt_size = dev->bytesperline+4; |
808 | int i; | 817 | |
809 | for(i=0;i< dev->num_alt; i++) | 818 | /* When image size is bigger than a ceirtain value, |
810 | if(dev->alt_max_pkt_size[i]>dev->alt_max_pkt_size[dev->alt]) | 819 | the frame size should be increased, otherwise, only |
811 | dev->alt=i; | 820 | green screen will be received. |
812 | } | 821 | */ |
822 | if (dev->frame_size > 720*240*2) | ||
823 | min_pkt_size *= 2; | ||
824 | |||
825 | for (i = 0; i < dev->num_alt; i++) | ||
826 | if (dev->alt_max_pkt_size[i] >= min_pkt_size) | ||
827 | break; | ||
828 | dev->alt = i; | ||
813 | 829 | ||
814 | if (dev->alt != prev_alt) { | 830 | if (dev->alt != prev_alt) { |
831 | em28xx_coredbg("minimum isoc packet size: %u (alt=%d)\n", | ||
832 | min_pkt_size, dev->alt); | ||
815 | dev->max_pkt_size = dev->alt_max_pkt_size[dev->alt]; | 833 | dev->max_pkt_size = dev->alt_max_pkt_size[dev->alt]; |
816 | em28xx_coredbg("setting alternate %d with wMaxPacketSize=%u\n", dev->alt, | 834 | em28xx_coredbg("setting alternate %d with wMaxPacketSize=%u\n", |
817 | dev->max_pkt_size); | 835 | dev->alt, dev->max_pkt_size); |
818 | errCode = usb_set_interface(dev->udev, 0, dev->alt); | 836 | errCode = usb_set_interface(dev->udev, 0, dev->alt); |
819 | if (errCode < 0) { | 837 | if (errCode < 0) { |
820 | em28xx_errdev ("cannot change alternate number to %d (error=%i)\n", | 838 | em28xx_errdev ("cannot change alternate number to %d (error=%i)\n", |
821 | dev->alt, errCode); | 839 | dev->alt, errCode); |
822 | return errCode; | 840 | return errCode; |
823 | } | 841 | } |
824 | } | 842 | } |
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c index eeda3b2faec8..4abe6701a770 100644 --- a/drivers/media/video/em28xx/em28xx-video.c +++ b/drivers/media/video/em28xx/em28xx-video.c | |||
@@ -1352,8 +1352,6 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp) | |||
1352 | filp->private_data = fh; | 1352 | filp->private_data = fh; |
1353 | 1353 | ||
1354 | if (dev->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && dev->users == 0) { | 1354 | if (dev->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && dev->users == 0) { |
1355 | em28xx_set_alternate(dev); | ||
1356 | |||
1357 | dev->width = norm_maxw(dev); | 1355 | dev->width = norm_maxw(dev); |
1358 | dev->height = norm_maxh(dev); | 1356 | dev->height = norm_maxh(dev); |
1359 | dev->frame_size = dev->width * dev->height * 2; | 1357 | dev->frame_size = dev->width * dev->height * 2; |
@@ -1362,6 +1360,7 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp) | |||
1362 | dev->hscale = 0; | 1360 | dev->hscale = 0; |
1363 | dev->vscale = 0; | 1361 | dev->vscale = 0; |
1364 | 1362 | ||
1363 | em28xx_set_alternate(dev); | ||
1365 | em28xx_capture_start(dev, 1); | 1364 | em28xx_capture_start(dev, 1); |
1366 | em28xx_resolution_set(dev); | 1365 | em28xx_resolution_set(dev); |
1367 | 1366 | ||
@@ -2129,6 +2128,7 @@ static int em28xx_usb_probe(struct usb_interface *interface, | |||
2129 | snprintf(dev->name, 29, "em28xx #%d", nr); | 2128 | snprintf(dev->name, 29, "em28xx #%d", nr); |
2130 | dev->devno = nr; | 2129 | dev->devno = nr; |
2131 | dev->model = id->driver_info; | 2130 | dev->model = id->driver_info; |
2131 | dev->alt = -1; | ||
2132 | 2132 | ||
2133 | /* Checks if audio is provided by some interface */ | 2133 | /* Checks if audio is provided by some interface */ |
2134 | for (i = 0; i < udev->config->desc.bNumInterfaces; i++) { | 2134 | for (i = 0; i < udev->config->desc.bNumInterfaces; i++) { |
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h index 813c0af458d3..04e0e48ecabe 100644 --- a/drivers/media/video/em28xx/em28xx.h +++ b/drivers/media/video/em28xx/em28xx.h | |||
@@ -33,7 +33,7 @@ | |||
33 | #define UNSET -1 | 33 | #define UNSET -1 |
34 | 34 | ||
35 | /* maximum number of em28xx boards */ | 35 | /* maximum number of em28xx boards */ |
36 | #define EM28XX_MAXBOARDS 1 /*FIXME: should be bigger */ | 36 | #define EM28XX_MAXBOARDS 4 /*FIXME: should be bigger */ |
37 | 37 | ||
38 | /* maximum number of frames that can be queued */ | 38 | /* maximum number of frames that can be queued */ |
39 | #define EM28XX_NUM_FRAMES 5 | 39 | #define EM28XX_NUM_FRAMES 5 |