diff options
Diffstat (limited to 'sound/usb/endpoint.c')
-rw-r--r-- | sound/usb/endpoint.c | 21 |
1 files changed, 17 insertions, 4 deletions
diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c index 4f856771216b..533919a28856 100644 --- a/sound/usb/endpoint.c +++ b/sound/usb/endpoint.c @@ -240,6 +240,11 @@ static void retire_inbound_urb(struct snd_usb_endpoint *ep, call_retire_callback(ep, urb); } +static inline bool has_tx_length_quirk(struct snd_usb_audio *chip) +{ + return chip->quirk_flags & QUIRK_FLAG_TX_LENGTH; +} + static void prepare_silent_urb(struct snd_usb_endpoint *ep, struct snd_urb_ctx *ctx) { @@ -250,7 +255,7 @@ static void prepare_silent_urb(struct snd_usb_endpoint *ep, int i; /* For tx_length_quirk, put packet length at start of packet */ - if (ep->chip->tx_length_quirk) + if (has_tx_length_quirk(ep->chip)) extra = sizeof(packet_length); for (i = 0; i < ctx->packets; ++i) { @@ -803,7 +808,8 @@ static int endpoint_set_interface(struct snd_usb_audio *chip, return err; } - snd_usb_set_interface_quirk(chip); + if (chip->quirk_flags & QUIRK_FLAG_IFACE_DELAY) + msleep(50); return 0; } @@ -952,7 +958,7 @@ static int data_ep_set_params(struct snd_usb_endpoint *ep) unsigned int max_urbs, i; const struct audioformat *fmt = ep->cur_audiofmt; int frame_bits = ep->cur_frame_bytes * 8; - int tx_length_quirk = (chip->tx_length_quirk && + int tx_length_quirk = (has_tx_length_quirk(chip) && usb_pipeout(ep->pipe)); usb_audio_dbg(chip, "Setting params for data EP 0x%x, pipe 0x%x\n", @@ -1126,6 +1132,10 @@ static int data_ep_set_params(struct snd_usb_endpoint *ep) INIT_LIST_HEAD(&u->ready_list); } + /* total buffer bytes of all URBs plus the next queue; + * referred in pcm.c + */ + ep->nominal_queue_size = maxsize * urb_packs * (ep->nurbs + 1); return 0; out_of_memory: @@ -1287,6 +1297,9 @@ int snd_usb_endpoint_configure(struct snd_usb_audio *chip, * to be set up before parameter setups */ iface_first = ep->cur_audiofmt->protocol == UAC_VERSION_1; + /* Workaround for devices that require the interface setup at first like UAC1 */ + if (chip->quirk_flags & QUIRK_FLAG_SET_IFACE_FIRST) + iface_first = true; if (iface_first) { err = endpoint_set_interface(chip, ep, true); if (err < 0) @@ -1377,7 +1390,7 @@ int snd_usb_endpoint_start(struct snd_usb_endpoint *ep) goto __error; if (snd_usb_endpoint_implicit_feedback_sink(ep) && - !ep->chip->playback_first) { + !(ep->chip->quirk_flags & QUIRK_FLAG_PLAYBACK_FIRST)) { for (i = 0; i < ep->nurbs; i++) { struct snd_urb_ctx *ctx = ep->urb + i; list_add_tail(&ctx->ready_list, &ep->ready_playback_urbs); |