--- sound/usb/pcm.c | 14 ++++++++++---- 1 files changed, 10 insertions(+), 4 deletions(-)
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c index af21d38..e88abfa 100644 --- a/sound/usb/pcm.c +++ b/sound/usb/pcm.c @@ -312,9 +312,12 @@ static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt) if (((is_playback && attr == USB_ENDPOINT_SYNC_ASYNC) || (! is_playback && attr == USB_ENDPOINT_SYNC_ADAPTIVE)) && altsd->bNumEndpoints >= 2) { + int implicit_fb = (get_endpoint(alts, 1)->bmAttributes & USB_ENDPOINT_USAGE_MASK) + == USB_ENDPOINT_USAGE_IMPLICIT_FB; switch (subs->stream->chip->usb_id) { case USB_ID(0x0763, 0x2080): /* M-Audio FastTrack Ultra */ case USB_ID(0x0763, 0x2081): + implicit_fb = 1; ep = 0x81; iface = usb_ifnum_to_if(dev, 2); alts = &iface->altsetting[1]; @@ -327,7 +330,8 @@ static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt) the audio fields in the endpoint descriptors */ if ((get_endpoint(alts, 1)->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != 0x01 || (get_endpoint(alts, 1)->bLength >= USB_DT_ENDPOINT_AUDIO_SIZE && - get_endpoint(alts, 1)->bSynchAddress != 0)) { + get_endpoint(alts, 1)->bSynchAddress != 0 && + !implicit_fb)) { snd_printk(KERN_ERR "%d:%d:%d : invalid synch pipe\n", dev->devnum, fmt->iface, fmt->altsetting); return -EINVAL; @@ -335,7 +339,8 @@ static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt) ep = get_endpoint(alts, 1)->bEndpointAddress; if (get_endpoint(alts, 0)->bLength >= USB_DT_ENDPOINT_AUDIO_SIZE && (( is_playback && ep != (unsigned int)(get_endpoint(alts, 0)->bSynchAddress | USB_DIR_IN)) || - (!is_playback && ep != (unsigned int)(get_endpoint(alts, 0)->bSynchAddress & ~USB_DIR_IN)))) { + (!is_playback && ep != (unsigned int)(get_endpoint(alts, 0)->bSynchAddress & ~USB_DIR_IN)) || + ( is_playback && !implicit_fb))) { snd_printk(KERN_ERR "%d:%d:%d : invalid synch pipe\n", dev->devnum, fmt->iface, fmt->altsetting); return -EINVAL; @@ -343,8 +348,9 @@ static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt) add_sync_ep: subs->sync_endpoint = snd_usb_add_endpoint(subs->stream->chip, alts, ep, !subs->direction, - SND_USB_ENDPOINT_TYPE_SYNC); - + implicit_fb ? + SND_USB_ENDPOINT_TYPE_DATA : + SND_USB_ENDPOINT_TYPE_SYNC); if (!subs->sync_endpoint) return -EINVAL;