Created
July 7, 2012 04:06
-
-
Save Apsu/3064557 to your computer and use it in GitHub Desktop.
M-Audio FastTrack Pro 48/96kHz 24-bit kernel patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- original/linux-2.6.38.4/sound/usb/quirks.c 2011-04-21 16:34:46.000000000 -0500 | |
+++ new/linux-2.6.38.4/sound/usb/quirks.c 2011-04-23 20:32:19.486586452 -0500 | |
@@ -427,16 +427,17 @@ | |
/* | |
* 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 chip_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 audiophile_skip_setting_quirk(struct snd_usb_audio *chip, | |
int iface, | |
@@ -447,38 +448,137 @@ | |
*/ | |
usb_set_interface(chip->dev, iface, 0); | |
- if (chip->setup & AUDIOPHILE_SET) { | |
- if ((chip->setup & AUDIOPHILE_SET_DTS) | |
+ if (chip->setup & MAUDIO_SET) { | |
+ if ((chip->setup & MAUDIO_SET_DTS) | |
&& altno != 6) | |
return 1; /* skip this altsetting */ | |
- if ((chip->setup & AUDIOPHILE_SET_96K) | |
+ if ((chip->setup & MAUDIO_SET_96K) | |
&& altno != 1) | |
return 1; /* skip this altsetting */ | |
- if ((chip->setup & AUDIOPHILE_SET_MASK) == | |
- AUDIOPHILE_SET_24B_48K_DI && altno != 2) | |
+ if ((chip->setup & MAUDIO_SET_MASK) == | |
+ MAUDIO_SET_24B_48K_DI && altno != 2) | |
return 1; /* skip this altsetting */ | |
- if ((chip->setup & AUDIOPHILE_SET_MASK) == | |
- AUDIOPHILE_SET_24B_48K_NOTDI && altno != 3) | |
+ if ((chip->setup & MAUDIO_SET_MASK) == | |
+ MAUDIO_SET_24B_48K_NOTDI && altno != 3) | |
return 1; /* skip this altsetting */ | |
- if ((chip->setup & AUDIOPHILE_SET_MASK) == | |
- AUDIOPHILE_SET_16B_48K_DI && altno != 4) | |
+ if ((chip->setup & MAUDIO_SET_MASK) == | |
+ MAUDIO_SET_16B_48K_DI && altno != 4) | |
return 1; /* skip this altsetting */ | |
- if ((chip->setup & AUDIOPHILE_SET_MASK) == | |
- AUDIOPHILE_SET_16B_48K_NOTDI && altno != 5) | |
+ if ((chip->setup & MAUDIO_SET_MASK) == | |
+ MAUDIO_SET_16B_48K_NOTDI && altno != 5) | |
return 1; /* skip this altsetting */ | |
} | |
return 0; /* keep this altsetting */ | |
} | |
+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 (chip->setup & MAUDIO_SET) { | |
+ if ((chip->setup & 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 ((chip->setup & MAUDIO_SET_96K) | |
+ && altno != 1) | |
+ return 1; /* skip this altsetting */ | |
+ if ((chip->setup & MAUDIO_SET_MASK) == | |
+ MAUDIO_SET_24B_48K_DI && altno != 2) | |
+ return 1; /* skip this altsetting */ | |
+ if ((chip->setup & MAUDIO_SET_MASK) == | |
+ MAUDIO_SET_24B_48K_NOTDI && altno != 3) | |
+ return 1; /* skip this altsetting */ | |
+ if ((chip->setup & MAUDIO_SET_MASK) == | |
+ MAUDIO_SET_16B_48K_NOTDI && altno != 4) | |
+ return 1; /* skip this altsetting */ | |
+ } | |
+ } | |
+ snd_printk(KERN_INFO "using altsetting %d for interface %d config %d\n", altno, iface, chip->setup); | |
+ 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 (chip->setup & (MAUDIO_SET | MAUDIO_SET_24B)) { | |
+ if(chip->setup & MAUDIO_SET_96K){ | |
+ if((altno != 3) && (altno != 6)) | |
+ return 1; | |
+ } else if(chip->setup & 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 digital input */ | |
+ | |
+ if((altno != 2) && (altno != 5)) | |
+ return 1; /* enable only altsets 2 and 5 */ | |
+ } | |
+ } else { | |
+ /* keep only 16-Bit mode */ | |
+ if(altno !=1) | |
+ return 1; | |
+ } | |
+ | |
+ snd_printk(KERN_INFO "using altsetting %d for interface %d config %d\n", altno, iface, chip->setup); | |
+ return 0; /* keep this altsetting */ | |
+} | |
+ | |
+ | |
+static int snd_usb_fasttrackpro_boot_quirk(struct usb_device *dev, struct usb_interface *intf) | |
+{ | |
+ int err; | |
+ | |
+ if(dev->actconfig->desc.bConfigurationValue==1) { | |
+ if(intf->num_altsetting==1) { | |
+ snd_printk(KERN_INFO "Switching to config #2\n"); | |
+ /* This function has to be available by the usb core module. | |
+ if it is not available 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_printk("error usb_driver_set_configuration: %d\n", err); | |
+ return -ENODEV; | |
+ } | |
+ } | |
+ } else { | |
+ snd_printk(KERN_INFO "Fast Track Pro config OK\n"); | |
+ } | |
+ | |
+ return 0; | |
+} | |
+ | |
int snd_usb_apply_interface_quirk(struct snd_usb_audio *chip, | |
int iface, | |
int altno) | |
{ | |
- /* audiophile usb: skip altsets incompatible with device_setup */ | |
+ /* m-audio usb devices: skip altsets incompatible with chip-setup */ | |
if (chip->usb_id == USB_ID(0x0763, 0x2003)) | |
return audiophile_skip_setting_quirk(chip, iface, altno); | |
+ if (chip->usb_id == USB_ID(0x0763, 0x2001)) | |
+ return quattro_skip_setting_quirk(chip, iface, altno); | |
+ | |
+ if (chip->usb_id == USB_ID(0x0763, 0x2012)) | |
+ return fasttrackpro_skip_setting_quirk(chip, iface, altno); | |
+ | |
return 0; | |
} | |
@@ -510,6 +610,10 @@ | |
if (id == USB_ID(0x133e, 0x0815)) | |
return snd_usb_accessmusic_boot_quirk(dev); | |
+ /* M-Audio Fast Track Pro */ | |
+ if (id == USB_ID(0x0763, 0x2012)) | |
+ return snd_usb_fasttrackpro_boot_quirk(dev, intf); | |
+ | |
return 0; | |
} | |
@@ -519,14 +623,23 @@ | |
int snd_usb_is_big_endian_format(struct snd_usb_audio *chip, struct audioformat *fp) | |
{ | |
switch (chip->usb_id) { | |
- case USB_ID(0x0763, 0x2001): /* M-Audio Quattro: captured data only */ | |
- if (fp->endpoint & USB_DIR_IN) | |
+ case USB_ID(0x0763, 0x2001): /* M-Audio Quattro: captured data only */ | |
+ /* 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; | |
+ case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */ | |
+ if (chip->setup == 0x00 || | |
+ fp->altsetting==1 || fp->altsetting==2 || fp->altsetting==3) | |
return 1; | |
- break; | |
- case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */ | |
- if (chip->setup == 0x00 || | |
- fp->altsetting==1 || fp->altsetting==2 || fp->altsetting==3) | |
+ break; | |
+ 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; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment