[PATCH 1/2] M-Audio USB

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Re-send, "hg export" format

# HG changeset patch
# User Pavel Polischouk <pavelvp@xxxxxxxx>
# Date 1164392350 18000
# Node ID d447f5a178f0d40ec98c4cde2e3d6e4d012a7f65
# Parent  6f81f7397f82b392e40c582e48a02a7c1cbd7c3e
This patch adds the following capabilities to usbaudio.c:
- Merges support for M-Audio FastTrack USB
- Adds proper support for M-Audio Quattro USB
- Adds hot-reload support for all Audiophile, FastTrack and Quattro.
- FastTrack "select configuration #2" quirk is present but #ifdef'd out
pending inclusion of "usb_driver_set_configuration" function in mainline
kernel. This quirk could possibly be handled in user space anyway.

diff -r 6f81f7397f82 -r d447f5a178f0 usb/usbaudio.c
--- a/usb/usbaudio.c	Fri Nov 24 11:50:29 2006 -0500
+++ b/usb/usbaudio.c	Fri Nov 24 13:19:10 2006 -0500
@@ -2346,11 +2346,16 @@ static int is_big_endian_format(struct s
 {
 	switch (chip->usb_id) {
 	case USB_ID(0x0763, 0x2001): /* M-Audio Quattro: captured data only */
-		if (fp->endpoint & USB_DIR_IN)
-			return 1;
-		break;
 	case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */
 		return 1;
+
+ 	case USB_ID(0x0763, 0x2012): /* M-Audio Fast Track Pro */
+ 		/* it depends on altsetting wether the device is big-endian or not */
+ 		if(fp->altsetting==2 || fp->altsetting==3 ||
+ 		   fp->altsetting==5 || fp->altsetting==6)
+ 			return 1;
+ 		break;
+
 	}
 	return 0;
 }
@@ -2608,8 +2613,12 @@ static int parse_audio_format(struct snd
 	return 0;
 }
 
+static int quattro_skip_setting_quirk(struct snd_usb_audio *chip,
+					 int iface, int altno);
 static int audiophile_skip_setting_quirk(struct snd_usb_audio *chip,
 					 int iface, int altno);
+static int fasttrackpro_skip_setting_quirk(struct snd_usb_audio *chip,
+ int iface, int altno);
 static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
 {
 	struct usb_device *dev;
@@ -2645,10 +2654,21 @@ static int parse_audio_endpoints(struct 
 			SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
 		altno = altsd->bAlternateSetting;
 	
+		/* quattro usb: skip altsets incompatible with device_setup
+		 */
+		if (chip->usb_id == USB_ID(0x0763, 0x2001) && 
+		    quattro_skip_setting_quirk(chip, iface_no, altno))
+			continue;
+
 		/* audiophile usb: skip altsets incompatible with device_setup
 		 */
 		if (chip->usb_id == USB_ID(0x0763, 0x2003) && 
 		    audiophile_skip_setting_quirk(chip, iface_no, altno))
+			continue;
+
+		/* M-Audio Fast Track Pro: skip alsets incompatible with device_setup */
+		if (chip->usb_id == USB_ID(0x0763, 0x2012) &&
+		    fasttrackpro_skip_setting_quirk(chip, iface_no, altno))
 			continue;
 
 		/* get audio formats */
@@ -3175,44 +3195,140 @@ static int snd_usb_cm106_boot_quirk(stru
 	return snd_usb_cm106_write_int_reg(dev, 2, 0x8004);
 }
 
+static int snd_usb_fasttrackpro_boot_quirk(struct usb_device *dev, int ifnum)
+{
+#if 0
+    int err;
+
+    if(dev->actconfig->desc.bConfigurationValue==1) {
+	if(ifnum==0) {
+	    snd_printk(KERN_INFO "Switching to config #2\n");
+	    /* This function has to be available by the usb core module.
+	       if it is not avialable the boot quirk has to be left out and the
+	       configuration has to be set by udev or hotplug rules */
+	    err=usb_driver_set_configuration(dev,2);
+	    if(err < 0) {
+		snd_printdd("error usb_driver_set_configuration: %d\n", err);
+		return -ENODEV;
+	    }
+	}
+    } else {
+	snd_printk(KERN_INFO "Fast Track Pro config OK\n");
+    }
+#endif
+
+    return 0;
+}
 
 /*
  * Setup quirks
  */
-#define AUDIOPHILE_SET			0x01 /* if set, parse device_setup */
-#define AUDIOPHILE_SET_DTS              0x02 /* if set, enable DTS Digital Output */
-#define AUDIOPHILE_SET_96K              0x04 /* 48-96KHz rate if set, 8-48KHz otherwise */
-#define AUDIOPHILE_SET_24B		0x08 /* 24bits sample if set, 16bits otherwise */
-#define AUDIOPHILE_SET_DI		0x10 /* if set, enable Digital Input */
-#define AUDIOPHILE_SET_MASK		0x1F /* bit mask for setup value */
-#define AUDIOPHILE_SET_24B_48K_DI	0x19 /* value for 24bits+48KHz+Digital Input */
-#define AUDIOPHILE_SET_24B_48K_NOTDI	0x09 /* value for 24bits+48KHz+No Digital Input */
-#define AUDIOPHILE_SET_16B_48K_DI	0x11 /* value for 16bits+48KHz+Digital Input */
-#define AUDIOPHILE_SET_16B_48K_NOTDI	0x01 /* value for 16bits+48KHz+No Digital Input */
-
+#define MAUDIO_SET			0x01 /* if set, parse device_setup */
+#define MAUDIO_SET_COMPATIBLE		0x80 /* if set, use only "win-compatible" interfaces */
+#define MAUDIO_SET_DTS              0x02 /* if set, enable DTS Digital Output */
+#define MAUDIO_SET_96K              0x04 /* 48-96KHz rate if set, 8-48KHz otherwise */
+#define MAUDIO_SET_24B		0x08 /* 24bits sample if set, 16bits otherwise */
+#define MAUDIO_SET_DI		0x10 /* if set, enable Digital Input */
+#define MAUDIO_SET_MASK		0x1F /* bit mask for setup value */
+#define MAUDIO_SET_24B_48K_DI	0x19 /* value for 24bits+48KHz+Digital Input */
+#define MAUDIO_SET_24B_48K_NOTDI	0x09 /* value for 24bits+48KHz+No Digital Input */
+#define MAUDIO_SET_16B_48K_DI	0x11 /* value for 16bits+48KHz+Digital Input */
+#define MAUDIO_SET_16B_48K_NOTDI	0x01 /* value for 16bits+48KHz+No Digital Input */
+
+static int quattro_skip_setting_quirk(struct snd_usb_audio *chip,
+					 int iface, int altno)
+{
+	/* Reset ALL ifaces to 0 altsetting. 
+	   Call it for every possible altsetting of every interface. */
+	usb_set_interface(chip->dev, iface, 0); 
+	if (device_setup[chip->index] & MAUDIO_SET) {
+		if ((device_setup[chip->index] & MAUDIO_SET_COMPATIBLE)) {
+			if((iface != 1) && (iface != 2)) 
+				return 1; /* skip all interfaces but 1 and 2 */
+		} else {
+			if ((iface == 1) || (iface == 2))
+				return 1; /* skip interfaces 1 and 2 */
+			if ((device_setup[chip->index] & MAUDIO_SET_96K)
+			    && altno != 1)
+				return 1; /* skip this altsetting */
+			if ((device_setup[chip->index] & MAUDIO_SET_MASK) ==
+			    MAUDIO_SET_24B_48K_DI && altno != 2)
+				return 1; /* skip this altsetting */
+			if ((device_setup[chip->index] & MAUDIO_SET_MASK) ==
+			    MAUDIO_SET_24B_48K_NOTDI && altno != 3)
+				return 1; /* skip this altsetting */
+			if ((device_setup[chip->index] & MAUDIO_SET_MASK) ==
+			    MAUDIO_SET_16B_48K_NOTDI && altno != 4)
+				return 1; /* skip this altsetting */
+		}
+	}	
+	snd_printdd(KERN_INFO "using altsetting %d for interface %d config %d\n", altno, iface, device_setup[chip->index]);
+	return 0; /* keep this altsetting */
+}
 static int audiophile_skip_setting_quirk(struct snd_usb_audio *chip,
 					 int iface, int altno)
 {
-	if (device_setup[chip->index] & AUDIOPHILE_SET) {
-		if ((device_setup[chip->index] & AUDIOPHILE_SET_DTS)
+	/* Reset ALL ifaces to 0 altsetting. 
+	   Call it for every possible altsetting of every interface. */
+	usb_set_interface(chip->dev, iface, 0); 
+	if (device_setup[chip->index] & MAUDIO_SET) {
+		if ((device_setup[chip->index] & MAUDIO_SET_DTS)
 		    && altno != 6)
 			return 1; /* skip this altsetting */
-		if ((device_setup[chip->index] & AUDIOPHILE_SET_96K)
+		if ((device_setup[chip->index] & MAUDIO_SET_96K)
 		    && altno != 1)
 			return 1; /* skip this altsetting */
-		if ((device_setup[chip->index] & AUDIOPHILE_SET_MASK) ==
-		    AUDIOPHILE_SET_24B_48K_DI && altno != 2)
+		if ((device_setup[chip->index] & MAUDIO_SET_MASK) ==
+		    MAUDIO_SET_24B_48K_DI && altno != 2)
 			return 1; /* skip this altsetting */
-		if ((device_setup[chip->index] & AUDIOPHILE_SET_MASK) ==
-		    AUDIOPHILE_SET_24B_48K_NOTDI && altno != 3)
+		if ((device_setup[chip->index] & MAUDIO_SET_MASK) ==
+		    MAUDIO_SET_24B_48K_NOTDI && altno != 3)
 			return 1; /* skip this altsetting */
-		if ((device_setup[chip->index] & AUDIOPHILE_SET_MASK) ==
-		    AUDIOPHILE_SET_16B_48K_DI && altno != 4)
+		if ((device_setup[chip->index] & MAUDIO_SET_MASK) ==
+		    MAUDIO_SET_16B_48K_DI && altno != 4)
 			return 1; /* skip this altsetting */
-		if ((device_setup[chip->index] & AUDIOPHILE_SET_MASK) ==
-		    AUDIOPHILE_SET_16B_48K_NOTDI && altno != 5)
+		if ((device_setup[chip->index] & MAUDIO_SET_MASK) ==
+		    MAUDIO_SET_16B_48K_NOTDI && altno != 5)
 			return 1; /* skip this altsetting */
 	}	
+	snd_printdd(KERN_INFO "using altsetting %d for interface %d config %d\n", altno, iface, device_setup[chip->index]);
+	return 0; /* keep this altsetting */
+}
+
+static int fasttrackpro_skip_setting_quirk(struct snd_usb_audio *chip,
+		int iface, int altno)
+{
+
+	/* Reset ALL ifaces to 0 altsetting. 
+           Call it for every possible altsetting of every interface. */
+	usb_set_interface(chip->dev, iface, 0); 
+	/* possible configuration where both inputs and only one output is
+	   used is not supported by the current setup */
+
+	if (device_setup[chip->index] & (MAUDIO_SET | MAUDIO_SET_24B)) {
+		if(device_setup[chip->index] & MAUDIO_SET_96K){
+			if((altno != 3) && (altno != 6))
+				return 1;
+		} else if(device_setup[chip->index] & MAUDIO_SET_DI){
+			if(iface == 4)
+				return 1; /* no analog input */
+
+			if((altno != 2) && (altno != 5))
+				return 1; /* enable only altsets 2 and 5 */
+		} else {
+			if(iface == 5)
+				return 1; /* disable digialt input */
+
+			if((altno != 2) && (altno != 5))
+				return 1; /* enalbe only altsets 2 and 5 */
+		}
+	} else {
+		/* keep only 16-Bit mode */
+		if(altno !=1)
+			return 1;
+	}
+
+	snd_printdd(KERN_INFO "using altsetting %d for interface %d config %d\n", altno, iface, device_setup[chip->index]);
 	return 0; /* keep this altsetting */
 }
 
@@ -3452,6 +3568,12 @@ static void *snd_usb_audio_probe(struct 
 			goto __err_val;
 	}
 
+	/* M-Audio Fast Track Pro */
+	if (id == USB_ID(0x0763, 0x2012)) {
+		if (snd_usb_fasttrackpro_boot_quirk(dev, ifnum) < 0)
+			goto __err_val;
+	}
+
 	/*
 	 * found a config.  now register to ALSA
 	 */

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Alsa-devel mailing list
Alsa-devel@xxxxxxxxxxxxxxxxxxxxx
https://lists.sourceforge.net/lists/listinfo/alsa-devel

[Index of Archives]     [ALSA User]     [Linux Audio Users]     [Kernel Archive]     [Asterisk PBX]     [Photo Sharing]     [Linux Sound]     [Video 4 Linux]     [Gimp]     [Yosemite News]

  Powered by Linux