Skip to content

Commit

Permalink
ALSA: usb-audio: move implicit fb quirks to separate function
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
eldad authored and tiwai committed Aug 6, 2013
1 parent 71bb64c commit a60945f
Showing 1 changed file with 45 additions and 15 deletions.
60 changes: 45 additions & 15 deletions sound/usb/pcm.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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 ?
Expand Down

0 comments on commit a60945f

Please sign in to comment.