summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEldad Zack <eldad@fogrefinery.com>2013-08-03 12:50:18 +0400
committerTakashi Iwai <tiwai@suse.de>2013-08-06 12:49:21 +0400
commita60945fd08e45fceca9e3525d70e080f7ad60a4e (patch)
tree5b78766c192fa0700bf2e78ef99f40875706b474
parent71bb64c56d787a221752b1de034fe8c07c737f5c (diff)
downloadlinux-a60945fd08e45fceca9e3525d70e080f7ad60a4e.tar.xz
ALSA: usb-audio: move implicit fb quirks to separate function
Separate setting implicit feedback quirks from setting a sync endpoint (which may also be explicit feedback or async). Signed-off-by: Eldad Zack <eldad@fogrefinery.com> Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r--sound/usb/pcm.c60
1 files changed, 45 insertions, 15 deletions
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c
index e24ce7d58d83..0016f28039f2 100644
--- a/sound/usb/pcm.c
+++ b/sound/usb/pcm.c
@@ -327,24 +327,16 @@ static int search_roland_implicit_fb(struct usb_device *dev, int ifnum,
return 0;
}
-
-static int set_sync_endpoint(struct snd_usb_substream *subs,
- struct audioformat *fmt,
- struct usb_device *dev,
- struct usb_host_interface *alts,
- struct usb_interface_descriptor *altsd)
+static int set_sync_ep_implicit_fb_quirk(struct snd_usb_substream *subs,
+ struct usb_device *dev,
+ struct usb_interface_descriptor *altsd,
+ unsigned int attr)
{
+ struct usb_host_interface *alts;
struct usb_interface *iface;
int is_playback = subs->direction == SNDRV_PCM_STREAM_PLAYBACK;
- unsigned int ep, attr;
int implicit_fb = 0;
-
- /* we need a sync pipe in async OUT or adaptive IN mode */
- /* check the number of EP, since some devices have broken
- * descriptors which fool us. if it has only one EP,
- * assume it as adaptive-out or sync-in.
- */
- attr = fmt->ep_attr & USB_ENDPOINT_SYNCTYPE;
+ unsigned int ep;
switch (subs->stream->chip->usb_id) {
case USB_ID(0x0763, 0x2030): /* M-Audio Fast Track C400 */
@@ -388,6 +380,45 @@ static int set_sync_endpoint(struct snd_usb_substream *subs,
goto add_sync_ep;
}
+ /* No quirk */
+ return 0;
+
+add_sync_ep:
+ subs->sync_endpoint = snd_usb_add_endpoint(subs->stream->chip,
+ alts, ep, !subs->direction,
+ implicit_fb ?
+ SND_USB_ENDPOINT_TYPE_DATA :
+ SND_USB_ENDPOINT_TYPE_SYNC);
+ if (!subs->sync_endpoint)
+ return -EINVAL;
+
+ subs->data_endpoint->sync_master = subs->sync_endpoint;
+
+ return 0;
+}
+
+static int set_sync_endpoint(struct snd_usb_substream *subs,
+ struct audioformat *fmt,
+ struct usb_device *dev,
+ struct usb_host_interface *alts,
+ struct usb_interface_descriptor *altsd)
+{
+ int is_playback = subs->direction == SNDRV_PCM_STREAM_PLAYBACK;
+ unsigned int ep, attr;
+ int implicit_fb = 0;
+ int err;
+
+ /* we need a sync pipe in async OUT or adaptive IN mode */
+ /* check the number of EP, since some devices have broken
+ * descriptors which fool us. if it has only one EP,
+ * assume it as adaptive-out or sync-in.
+ */
+ attr = fmt->ep_attr & USB_ENDPOINT_SYNCTYPE;
+
+ err = set_sync_ep_implicit_fb_quirk(subs, dev, altsd, attr);
+ if (err < 0)
+ return err;
+
if (((is_playback && attr == USB_ENDPOINT_SYNC_ASYNC) ||
(!is_playback && attr == USB_ENDPOINT_SYNC_ADAPTIVE)) &&
altsd->bNumEndpoints >= 2) {
@@ -420,7 +451,6 @@ static int set_sync_endpoint(struct snd_usb_substream *subs,
implicit_fb = (get_endpoint(alts, 1)->bmAttributes & USB_ENDPOINT_USAGE_MASK)
== USB_ENDPOINT_USAGE_IMPLICIT_FB;
-add_sync_ep:
subs->sync_endpoint = snd_usb_add_endpoint(subs->stream->chip,
alts, ep, !subs->direction,
implicit_fb ?