ALSA: usb-audio: set the interface format after resume on Dell WD19
[muen/linux.git] / sound / usb / pcm.c
index 9c8930b..96298c7 100644 (file)
@@ -510,11 +510,11 @@ static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt)
        if (WARN_ON(altsd->bAlternateSetting != fmt->altsetting))
                return -EINVAL;
 
-       if (fmt == subs->cur_audiofmt)
+       if (fmt == subs->cur_audiofmt && !subs->need_setup_fmt)
                return 0;
 
        /* close the old interface */
-       if (subs->interface >= 0 && subs->interface != fmt->iface) {
+       if (subs->interface >= 0 && (subs->interface != fmt->iface || subs->need_setup_fmt)) {
                if (!subs->stream->chip->keep_iface) {
                        err = usb_set_interface(subs->dev, subs->interface, 0);
                        if (err < 0) {
@@ -528,6 +528,9 @@ static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt)
                subs->altset_idx = 0;
        }
 
+       if (subs->need_setup_fmt)
+               subs->need_setup_fmt = false;
+
        /* set interface */
        if (iface->cur_altsetting != alts) {
                err = snd_usb_select_mode_quirk(subs, fmt);
@@ -1728,6 +1731,13 @@ static int snd_usb_substream_playback_trigger(struct snd_pcm_substream *substrea
                subs->data_endpoint->retire_data_urb = retire_playback_urb;
                subs->running = 0;
                return 0;
+       case SNDRV_PCM_TRIGGER_SUSPEND:
+               if (subs->stream->chip->setup_fmt_after_resume_quirk) {
+                       stop_endpoints(subs, true);
+                       subs->need_setup_fmt = true;
+                       return 0;
+               }
+               break;
        }
 
        return -EINVAL;
@@ -1760,6 +1770,13 @@ static int snd_usb_substream_capture_trigger(struct snd_pcm_substream *substream
                subs->data_endpoint->retire_data_urb = retire_capture_urb;
                subs->running = 1;
                return 0;
+       case SNDRV_PCM_TRIGGER_SUSPEND:
+               if (subs->stream->chip->setup_fmt_after_resume_quirk) {
+                       stop_endpoints(subs, true);
+                       subs->need_setup_fmt = true;
+                       return 0;
+               }
+               break;
        }
 
        return -EINVAL;