All of lore.kernel.org
 help / color / mirror / Atom feed
From: Pavel Polischouk <pavelvp@inbox.ru>
To: alsa-devel@lists.sourceforge.net
Subject: [PATCH 1.0.13 1/2] M-Audio USB
Date: Thu, 23 Nov 2006 23:35:30 -0500	[thread overview]
Message-ID: <45667692.8090600@inbox.ru> (raw)

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. 
This works quite well on Quattro;
Thibault, could you please verify that it works for Audiophile?
- 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.

Part 2 of the patch contains documentation update.

diff -Naur --exclude '*.maudio' --exclude version.h 
alsa-driver-1.0.13.ref/alsa-kernel/usb/usbaudio.c 
alsa-driver-1.0.13/alsa-kernel/usb/usbaudio.c
--- alsa-driver-1.0.13.ref/alsa-kernel/usb/usbaudio.c    2006-09-29 
07:40:38.000000000 -0400
+++ alsa-driver-1.0.13/alsa-kernel/usb/usbaudio.c    2006-11-23 
20:19:33.000000000 -0500
@@ -2339,11 +2339,16 @@
 {
     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;
 }
@@ -2595,8 +2600,12 @@
     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;
@@ -2632,12 +2641,23 @@
             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 */
         fmt = snd_usb_find_csint_desc(alts->extra, alts->extralen, 
NULL, AS_GENERAL);
         if (!fmt) {
@@ -3164,44 +3184,145 @@
     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);
+    snd_printdd(KERN_INFO "resetting to altsetting 0 for interface 
%d\n", iface);
+    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;
+    }
+
     return 0; /* keep this altsetting */
 }
 
@@ -3441,6 +3562,12 @@
             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

             reply	other threads:[~2006-11-24  4:35 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-11-24  4:35 Pavel Polischouk [this message]
2006-11-24 12:11 ` [PATCH 1.0.13 1/2] M-Audio USB Takashi Iwai
2006-11-24 19:49   ` Pavel Polischouk
2006-11-24 20:46     ` Thibault Le Meur
2006-11-24 15:55 ` RE : " Thibault Le Meur
2006-12-03 11:49   ` 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=45667692.8090600@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.