Răsfoiți Sursa

ALSA: usb-audio: Add keep_iface flag

Introduce a new flag to struct snd_usb_audio for allowing the device
to skip usb_set_interface() calls at changing or closing the stream.
As of this patch, the flag is nowhere set, so it's just a place
holder.  The dynamic switching will be added in the following patch.

A background information for this change:

Dell WD15 dock with Realtek chip gives a very long pause at each time
the driver changes the altset, which eventually happens at every PCM
stream open/close and parameter change.  As the long pause happens in
each usb_set_interface() call, there is nothing we can do as long as
it's called.  The workaround is to reduce calling it as much as
possible, and this flag indicates that behavior.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
Takashi Iwai 7 ani în urmă
părinte
comite
8a463225b1
2 a modificat fișierele cu 13 adăugiri și 7 ștergeri
  1. 10 7
      sound/usb/pcm.c
  2. 3 0
      sound/usb/usbaudio.h

+ 10 - 7
sound/usb/pcm.c

@@ -509,12 +509,14 @@ static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt)
 
 	/* close the old interface */
 	if (subs->interface >= 0 && subs->interface != fmt->iface) {
-		err = usb_set_interface(subs->dev, subs->interface, 0);
-		if (err < 0) {
-			dev_err(&dev->dev,
-				"%d:%d: return to setting 0 failed (%d)\n",
-				fmt->iface, fmt->altsetting, err);
-			return -EIO;
+		if (!subs->stream->chip->keep_iface) {
+			err = usb_set_interface(subs->dev, subs->interface, 0);
+			if (err < 0) {
+				dev_err(&dev->dev,
+					"%d:%d: return to setting 0 failed (%d)\n",
+					fmt->iface, fmt->altsetting, err);
+				return -EIO;
+			}
 		}
 		subs->interface = -1;
 		subs->altset_idx = 0;
@@ -1253,7 +1255,8 @@ static int snd_usb_pcm_close(struct snd_pcm_substream *substream, int direction)
 
 	stop_endpoints(subs, true);
 
-	if (subs->interface >= 0 &&
+	if (!as->chip->keep_iface &&
+	    subs->interface >= 0 &&
 	    !snd_usb_lock_shutdown(subs->stream->chip)) {
 		usb_set_interface(subs->dev, subs->interface, 0);
 		subs->interface = -1;

+ 3 - 0
sound/usb/usbaudio.h

@@ -59,6 +59,9 @@ struct snd_usb_audio {
 
 	int setup;			/* from the 'device_setup' module param */
 	bool autoclock;			/* from the 'autoclock' module param */
+	bool keep_iface;		/* keep interface/altset after closing
+					 * or parameter change
+					 */
 
 	struct usb_host_interface *ctrl_intf;	/* the audio control interface */
 };