Merge tag 'soc-for-linus-3' of git://git.kernel.org/pub/scm/linux/kernel/git/arm...
[firefly-linux-kernel-4.4.55.git] / sound / usb / endpoint.c
index 21049b882ee6445d47714074fddbcb550cf5eef8..7a444b5501d91d28a4e7e8fb5e044c2b4e7ea41b 100644 (file)
@@ -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 */