aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <m.chehab@samsung.com>2014-01-10 03:43:09 -0500
committerMauro Carvalho Chehab <m.chehab@samsung.com>2014-01-12 08:56:53 -0500
commitd2849fa59d79dea7a6deeef13cc3efaafab3bf63 (patch)
tree68d481b5af521a448f9611910f56444829aac29c
parentd845fb3ae5b97bda8810f450030c061b49a0b91b (diff)
[media] em28xx-audio: use bInterval on em28xx-audio
Just filling urb->interval with 1 is wrong, and causes a different behaviour with xHCI. With EHCI, the URB size is typically 192 bytes. However, as xHCI specifies intervals in microframes, the URB size becomes too short (24 bytes). With this patch, the interval will be properly initialized, and the device will behave the same if connected into a xHCI or an EHCI device port. Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
-rw-r--r--drivers/media/usb/em28xx/em28xx-audio.c39
1 files changed, 38 insertions, 1 deletions
diff --git a/drivers/media/usb/em28xx/em28xx-audio.c b/drivers/media/usb/em28xx/em28xx-audio.c
index 30ee389a07f0..8e6f04873422 100644
--- a/drivers/media/usb/em28xx/em28xx-audio.c
+++ b/drivers/media/usb/em28xx/em28xx-audio.c
@@ -620,10 +620,13 @@ static int em28xx_audio_init(struct em28xx *dev)
620 struct em28xx_audio *adev = &dev->adev; 620 struct em28xx_audio *adev = &dev->adev;
621 struct snd_pcm *pcm; 621 struct snd_pcm *pcm;
622 struct snd_card *card; 622 struct snd_card *card;
623 struct usb_interface *intf;
624 struct usb_endpoint_descriptor *e, *ep = NULL;
623 static int devnr; 625 static int devnr;
624 int err, i; 626 int err, i;
625 const int sb_size = EM28XX_NUM_AUDIO_PACKETS * 627 const int sb_size = EM28XX_NUM_AUDIO_PACKETS *
626 EM28XX_AUDIO_MAX_PACKET_SIZE; 628 EM28XX_AUDIO_MAX_PACKET_SIZE;
629 u8 alt;
627 630
628 if (!dev->has_alsa_audio || dev->audio_ifnum < 0) { 631 if (!dev->has_alsa_audio || dev->audio_ifnum < 0) {
629 /* This device does not support the extension (in this case 632 /* This device does not support the extension (in this case
@@ -679,6 +682,34 @@ static int em28xx_audio_init(struct em28xx *dev)
679 em28xx_cvol_new(card, dev, "Surround", AC97_SURROUND_MASTER); 682 em28xx_cvol_new(card, dev, "Surround", AC97_SURROUND_MASTER);
680 } 683 }
681 684
685 if (dev->audio_ifnum)
686 alt = 1;
687 else
688 alt = 7;
689
690 intf = usb_ifnum_to_if(dev->udev, dev->audio_ifnum);
691
692 if (intf->num_altsetting <= alt) {
693 em28xx_errdev("alt %d doesn't exist on interface %d\n",
694 dev->audio_ifnum, alt);
695 return -ENODEV;
696 }
697
698 for (i = 0; i < intf->altsetting[alt].desc.bNumEndpoints; i++) {
699 e = &intf->altsetting[alt].endpoint[i].desc;
700 if (!usb_endpoint_dir_in(e))
701 continue;
702 if (e->bEndpointAddress == EM28XX_EP_AUDIO) {
703 ep = e;
704 break;
705 }
706 }
707
708 if (!ep) {
709 em28xx_errdev("Couldn't find an audio endpoint");
710 return -ENODEV;
711 }
712
682 /* Alloc URB and transfer buffers */ 713 /* Alloc URB and transfer buffers */
683 for (i = 0; i < EM28XX_AUDIO_BUFS; i++) { 714 for (i = 0; i < EM28XX_AUDIO_BUFS; i++) {
684 struct urb *urb; 715 struct urb *urb;
@@ -707,11 +738,17 @@ static int em28xx_audio_init(struct em28xx *dev)
707 urb->pipe = usb_rcvisocpipe(dev->udev, EM28XX_EP_AUDIO); 738 urb->pipe = usb_rcvisocpipe(dev->udev, EM28XX_EP_AUDIO);
708 urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP; 739 urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
709 urb->transfer_buffer = dev->adev.transfer_buffer[i]; 740 urb->transfer_buffer = dev->adev.transfer_buffer[i];
710 urb->interval = 1; 741 urb->interval = 1 << (ep->bInterval - 1);
711 urb->complete = em28xx_audio_isocirq; 742 urb->complete = em28xx_audio_isocirq;
712 urb->number_of_packets = EM28XX_NUM_AUDIO_PACKETS; 743 urb->number_of_packets = EM28XX_NUM_AUDIO_PACKETS;
713 urb->transfer_buffer_length = sb_size; 744 urb->transfer_buffer_length = sb_size;
714 745
746 if (!i)
747 dprintk("Will use ep 0x%02x on intf %d alt %d interval = %d (rcv isoc pipe: 0x%08x)\n",
748 EM28XX_EP_AUDIO, dev->audio_ifnum, alt,
749 urb->interval,
750 urb->pipe);
751
715 for (j = k = 0; j < EM28XX_NUM_AUDIO_PACKETS; 752 for (j = k = 0; j < EM28XX_NUM_AUDIO_PACKETS;
716 j++, k += EM28XX_AUDIO_MAX_PACKET_SIZE) { 753 j++, k += EM28XX_AUDIO_MAX_PACKET_SIZE) {
717 urb->iso_frame_desc[j].offset = k; 754 urb->iso_frame_desc[j].offset = k;