aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/em28xx
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/em28xx')
-rw-r--r--drivers/media/video/em28xx/em28xx-core.c62
-rw-r--r--drivers/media/video/em28xx/em28xx-video.c4
-rw-r--r--drivers/media/video/em28xx/em28xx.h2
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)
803int em28xx_set_alternate(struct em28xx *dev) 812int 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