[PATCH] [UBUNTU:sound/usb/] Fix analog capture by adding device_setup parameter (affects notably M-Audio Audiophile)

crimsun at fungus.sh.nu crimsun at fungus.sh.nu
Tue Oct 10 08:02:39 UTC 2006


From dd356cf385fcf7ddcb7541870bbeaba8a4bbad98 Mon Sep 17 00:00:00 2001
From: Daniel T. Chen <crimsun at garnish.localdomain>
Date: Tue, 10 Oct 2006 03:55:31 -0400
Subject: [PATCH] [UBUNTU:sound/usb/] Fix analog capture by adding device_setup parameter (affects notably M-Audio Audiophile)

UpstreamStatus: Added in upstream alsa-kernel hg changeset:
		4249e5ffdb3f [http://hg-mirror.alsa-project.org/alsa-kernel?cmd=changeset;node=4249e5ffdb3fdf345b6fe34a04fde2268312a871;style=raw]

This patch from Thibault LE MEUR <Thibault.LeMeur at supelec.fr> adds
a "device_setup" module parameter and a specific quirk to correctly
initialise the audiophile usb device, which fixes distorted sound
on the analog capture port of the M-Audio Audiophile. Backward
compatibility is achieved by simply omitting the new parameter.

This commit is suitable for both Dapper and Edgy linux-source but
is targeted toward Dapper (typedef adjustment is necessary for
Edgy).

Signed-off-by: Daniel T Chen <crimsun at ubuntu.com>
---
 sound/usb/usbaudio.c |   53 +++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 52 insertions(+), 1 deletions(-)

diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
index c0b78ce..6e74244 100644
--- a/sound/usb/usbaudio.c
+++ b/sound/usb/usbaudio.c
@@ -69,6 +69,7 @@ static int vid[SNDRV_CARDS] = { [0 ... (
 static int pid[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = -1 }; /* Product ID for this card */
 static int nrpacks = 8;		/* max. number of packets per urb */
 static int async_unlink = 1;
+static int device_setup[SNDRV_CARDS]; /* device parameter for this card*/
 
 module_param_array(index, int, NULL, 0444);
 MODULE_PARM_DESC(index, "Index value for the USB audio adapter.");
@@ -84,6 +85,8 @@ module_param(nrpacks, int, 0644);
 MODULE_PARM_DESC(nrpacks, "Max. number of packets per URB.");
 module_param(async_unlink, bool, 0444);
 MODULE_PARM_DESC(async_unlink, "Use async unlink mode.");
+module_param_array(device_setup, int, NULL, 0444);
+MODULE_PARM_DESC(device_setup, "Specific device setup (if needed).");
 
 
 /*
@@ -2594,6 +2597,9 @@ #endif
 	return 0;
 }
 
+static int audiophile_skip_setting_quirk(snd_usb_audio_t *chip,
+					 int iface, int altno);
+
 static int parse_audio_endpoints(snd_usb_audio_t *chip, int iface_no)
 {
 	struct usb_device *dev;
@@ -2628,6 +2634,12 @@ static int parse_audio_endpoints(snd_usb
 		stream = (get_endpoint(alts, 0)->bEndpointAddress & USB_DIR_IN) ?
 			SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
 		altno = altsd->bAlternateSetting;
+	
+		/* 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;
 
 		/* get audio formats */
 		fmt = snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, AS_GENERAL);
@@ -2723,7 +2735,7 @@ static int parse_audio_endpoints(snd_usb
 			continue;
 		}
 
-		snd_printdd(KERN_INFO "%d:%u:%d: add audio endpoint 0x%x\n", dev->devnum, iface_no, i, fp->endpoint);
+		snd_printdd(KERN_INFO "%d:%u:%d: add audio endpoint 0x%x\n", dev->devnum, iface_no, altno, fp->endpoint);
 		err = add_audio_endpoint(chip, stream, fp);
 		if (err < 0) {
 			kfree(fp->rate_table);
@@ -3131,6 +3143,45 @@ static int snd_usb_audigy2nx_boot_quirk(
 	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 */
+
+static int audiophile_skip_setting_quirk(snd_usb_audio_t *chip,
+					 int iface, int altno)
+{
+	if (device_setup[chip->index] & AUDIOPHILE_SET) {
+		if ((device_setup[chip->index] & AUDIOPHILE_SET_DTS)
+		    && altno != 6)
+			return 1; /* skip this altsetting */
+		if ((device_setup[chip->index] & AUDIOPHILE_SET_96K)
+		    && altno != 1)
+			return 1; /* skip this altsetting */
+		if ((device_setup[chip->index] & AUDIOPHILE_SET_MASK) ==
+		    AUDIOPHILE_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)
+			return 1; /* skip this altsetting */
+		if ((device_setup[chip->index] & AUDIOPHILE_SET_MASK) ==
+		    AUDIOPHILE_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)
+			return 1; /* skip this altsetting */
+	}	
+	return 0; /* keep this altsetting */
+}
 
 /*
  * audio-interface quirks
-- 
1.4.1


-- 
Daniel T. Chen            crimsun at ubuntu.com
GPG key:  0xC88ABDA3
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
URL: <https://lists.ubuntu.com/archives/kernel-team/attachments/20061010/fc82356f/attachment.sig>


More information about the kernel-team mailing list