aboutsummaryrefslogtreecommitdiffstats
path: root/sound/usb/endpoint.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/usb/endpoint.c')
-rw-r--r--sound/usb/endpoint.c32
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 */