From: Pavel Polischouk <pavelvp@inbox.ru>
To: alsa-devel@lists.sourceforge.net
Subject: [PATCH 1/2] M-Audio USB
Date: Fri, 24 Nov 2006 15:26:42 -0500 [thread overview]
Message-ID: <45675582.9060707@inbox.ru> (raw)
[-- Attachment #1: Type: text/plain, Size: 29 bytes --]
Re-send, "hg export" format
[-- Attachment #2: maudio.patch --]
[-- Type: text/plain, Size: 9722 bytes --]
# HG changeset patch
# User Pavel Polischouk <pavelvp@inbox.ru>
# 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
*/
[-- Attachment #3: Type: text/plain, Size: 347 bytes --]
-------------------------------------------------------------------------
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
[-- Attachment #4: Type: text/plain, Size: 161 bytes --]
_______________________________________________
Alsa-devel mailing list
Alsa-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/alsa-devel
next reply other threads:[~2006-11-24 20:26 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-11-24 20:26 Pavel Polischouk [this message]
2006-11-27 11:15 ` [PATCH 1/2] M-Audio USB Takashi Iwai
2006-11-27 11:18 ` Takashi Iwai
2006-12-03 22:42 ` Peter Oehry
2006-12-15 3:10 ` Pavel Polischouk
2006-12-15 8:42 ` RE : " Thibault Le Meur
2006-12-15 9:25 ` Thibault Le Meur
2006-12-03 20:55 ` Thibault Le Meur
2006-12-15 3:36 ` Pavel Polischouk
2006-12-15 8:55 ` RE : " Thibault Le Meur
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=45675582.9060707@inbox.ru \
--to=pavelvp@inbox.ru \
--cc=alsa-devel@lists.sourceforge.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox