diff options
Diffstat (limited to 'sound/usb/endpoint.c')
-rw-r--r-- | sound/usb/endpoint.c | 32 |
1 files changed, 19 insertions, 13 deletions
diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c index 21049b882ee6..7a444b5501d9 100644 --- a/sound/usb/endpoint.c +++ b/sound/usb/endpoint.c @@ -128,7 +128,7 @@ static const char *usb_error_string(int err) * Determine whether an endpoint is driven by an implicit feedback * data endpoint source. */ -int snd_usb_endpoint_implict_feedback_sink(struct snd_usb_endpoint *ep) +int snd_usb_endpoint_implicit_feedback_sink(struct snd_usb_endpoint *ep) { return ep->sync_master && ep->sync_master->type == SND_USB_ENDPOINT_TYPE_DATA && @@ -363,7 +363,7 @@ static void snd_complete_urb(struct urb *urb) if (unlikely(!test_bit(EP_FLAG_RUNNING, &ep->flags))) goto exit_clear; - if (snd_usb_endpoint_implict_feedback_sink(ep)) { + if (snd_usb_endpoint_implicit_feedback_sink(ep)) { unsigned long flags; spin_lock_irqsave(&ep->lock, flags); @@ -415,14 +415,12 @@ struct snd_usb_endpoint *snd_usb_add_endpoint(struct snd_usb_audio *chip, struct usb_host_interface *alts, int ep_num, int direction, int type) { - struct list_head *p; struct snd_usb_endpoint *ep; int is_playback = direction == SNDRV_PCM_STREAM_PLAYBACK; mutex_lock(&chip->mutex); - list_for_each(p, &chip->ep_list) { - ep = list_entry(p, struct snd_usb_endpoint, list); + list_for_each_entry(ep, &chip->ep_list, list) { if (ep->ep_num == ep_num && ep->iface == alts->desc.bInterfaceNumber && ep->alt_idx == alts->desc.bAlternateSetting) { @@ -580,6 +578,15 @@ static int data_ep_set_params(struct snd_usb_endpoint *ep, int is_playback = usb_pipeout(ep->pipe); int frame_bits = snd_pcm_format_physical_width(pcm_format) * channels; + if (pcm_format == SNDRV_PCM_FORMAT_DSD_U16_LE && fmt->dsd_dop) { + /* + * When operating in DSD DOP mode, the size of a sample frame + * in hardware differs from the actual physical format width + * because we need to make room for the DOP markers. + */ + frame_bits += channels << 3; + } + ep->datainterval = fmt->datainterval; ep->stride = frame_bits >> 3; ep->silence_value = pcm_format == SNDRV_PCM_FORMAT_U8 ? 0x80 : 0; @@ -607,7 +614,7 @@ static int data_ep_set_params(struct snd_usb_endpoint *ep, else packs_per_ms = 1; - if (is_playback && !snd_usb_endpoint_implict_feedback_sink(ep)) { + if (is_playback && !snd_usb_endpoint_implicit_feedback_sink(ep)) { urb_packs = max(ep->chip->nrpacks, 1); urb_packs = min(urb_packs, (unsigned int) MAX_PACKS); } else { @@ -616,11 +623,11 @@ static int data_ep_set_params(struct snd_usb_endpoint *ep, urb_packs *= packs_per_ms; - if (sync_ep && !snd_usb_endpoint_implict_feedback_sink(ep)) + if (sync_ep && !snd_usb_endpoint_implicit_feedback_sink(ep)) urb_packs = min(urb_packs, 1U << sync_ep->syncinterval); /* decide how many packets to be used */ - if (is_playback && !snd_usb_endpoint_implict_feedback_sink(ep)) { + if (is_playback && !snd_usb_endpoint_implicit_feedback_sink(ep)) { unsigned int minsize, maxpacks; /* determine how small a packet can be */ minsize = (ep->freqn >> (16 - ep->datainterval)) @@ -677,7 +684,7 @@ static int data_ep_set_params(struct snd_usb_endpoint *ep, if (!u->urb->transfer_buffer) goto out_of_memory; u->urb->pipe = ep->pipe; - u->urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP; + u->urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP; u->urb->interval = 1 << ep->datainterval; u->urb->context = u; u->urb->complete = snd_complete_urb; @@ -716,8 +723,7 @@ static int sync_ep_set_params(struct snd_usb_endpoint *ep, u->urb->transfer_dma = ep->sync_dma + i * 4; u->urb->transfer_buffer_length = 4; u->urb->pipe = ep->pipe; - u->urb->transfer_flags = URB_ISO_ASAP | - URB_NO_TRANSFER_DMA_MAP; + u->urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP; u->urb->number_of_packets = 1; u->urb->interval = 1 << ep->syncinterval; u->urb->context = u; @@ -847,7 +853,7 @@ int snd_usb_endpoint_start(struct snd_usb_endpoint *ep, bool can_sleep) set_bit(EP_FLAG_RUNNING, &ep->flags); - if (snd_usb_endpoint_implict_feedback_sink(ep)) { + if (snd_usb_endpoint_implicit_feedback_sink(ep)) { 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); @@ -990,7 +996,7 @@ void snd_usb_handle_sync_urb(struct snd_usb_endpoint *ep, * and add it to the list of pending urbs. queue_pending_output_urbs() * will take care of them later. */ - if (snd_usb_endpoint_implict_feedback_sink(ep) && + if (snd_usb_endpoint_implicit_feedback_sink(ep) && ep->use_count != 0) { /* implicit feedback case */ |