aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuillaume Pellerin <yomguy@parisson.com>2011-07-12 12:13:46 -0400
committerTakashi Iwai <tiwai@suse.de>2011-07-12 12:15:45 -0400
commit0f5733b0c883158b13366ae34b5e4bd52a1ac346 (patch)
tree254680d4cb0a258d265ea254eac0d7fcf014d561
parent3101ba035ca9ba92f6cec7fd37348646b7a5cb61 (diff)
ALSA: usb-audio - Add quirks for M-Audio Fast Track Pro and Quattro
This patch gives M-Audio Fast Track Pro and M-Audio Quattro quirks and endpoints to boot and setup those devices with special options (digital inputs and outputs, 24 bits mode, etc...). M-Audio Audiophile quirks are just adapted to match the new global M-Audio parameters. Special configurations can be then loaded through a modprobe conf file. For example, to set the 24 bits mode on the Fast Track Pro add /etc/modprobe.d/fast_track_pro.conf : options snd_usb_audio vid=0x763 pid=0x2012 device_setup=0x08 Here is a list of the possibilities in this example : http://files.parisson.com/debian/fast-track-pro.conf Signed-off-by: Guillaume Pellerin <yomguy@parisson.com> Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r--sound/usb/endpoint.c2
-rw-r--r--sound/usb/quirks.c159
2 files changed, 136 insertions, 25 deletions
diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c
index b0ef9f501896..7c0d21ecd821 100644
--- a/sound/usb/endpoint.c
+++ b/sound/usb/endpoint.c
@@ -408,6 +408,8 @@ int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
408 /* doesn't set the sample rate attribute, but supports it */ 408 /* doesn't set the sample rate attribute, but supports it */
409 fp->attributes |= UAC_EP_CS_ATTR_SAMPLE_RATE; 409 fp->attributes |= UAC_EP_CS_ATTR_SAMPLE_RATE;
410 break; 410 break;
411 case USB_ID(0x0763, 0x2001): /* M-Audio Quattro USB */
412 case USB_ID(0x0763, 0x2012): /* M-Audio Fast Track Pro USB */
411 case USB_ID(0x047f, 0x0ca1): /* plantronics headset */ 413 case USB_ID(0x047f, 0x0ca1): /* plantronics headset */
412 case USB_ID(0x077d, 0x07af): /* Griffin iMic (note that there is 414 case USB_ID(0x077d, 0x07af): /* Griffin iMic (note that there is
413 an older model 77d:223) */ 415 an older model 77d:223) */
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
index 090e1930dfdc..77762c99afbe 100644
--- a/sound/usb/quirks.c
+++ b/sound/usb/quirks.c
@@ -369,6 +369,30 @@ static int snd_usb_audigy2nx_boot_quirk(struct usb_device *dev)
369 return 0; 369 return 0;
370} 370}
371 371
372static int snd_usb_fasttrackpro_boot_quirk(struct usb_device *dev)
373{
374 int err;
375
376 if (dev->actconfig->desc.bConfigurationValue == 1) {
377 snd_printk(KERN_INFO "usb-audio: "
378 "Fast Track Pro switching to config #2\n");
379 /* This function has to be available by the usb core module.
380 * if it is not avialable the boot quirk has to be left out
381 * and the configuration has to be set by udev or hotplug
382 * rules
383 */
384 err = usb_driver_set_configuration(dev, 2);
385 if (err < 0) {
386 snd_printdd("error usb_driver_set_configuration: %d\n",
387 err);
388 return -ENODEV;
389 }
390 } else
391 snd_printk(KERN_INFO "usb-audio: Fast Track Pro config OK\n");
392
393 return 0;
394}
395
372/* 396/*
373 * C-Media CM106/CM106+ have four 16-bit internal registers that are nicely 397 * C-Media CM106/CM106+ have four 16-bit internal registers that are nicely
374 * documented in the device's data sheet. 398 * documented in the device's data sheet.
@@ -471,16 +495,49 @@ static int snd_usb_nativeinstruments_boot_quirk(struct usb_device *dev)
471/* 495/*
472 * Setup quirks 496 * Setup quirks
473 */ 497 */
474#define AUDIOPHILE_SET 0x01 /* if set, parse device_setup */ 498#define MAUDIO_SET 0x01 /* parse device_setup */
475#define AUDIOPHILE_SET_DTS 0x02 /* if set, enable DTS Digital Output */ 499#define MAUDIO_SET_COMPATIBLE 0x80 /* use only "win-compatible" interfaces */
476#define AUDIOPHILE_SET_96K 0x04 /* 48-96KHz rate if set, 8-48KHz otherwise */ 500#define MAUDIO_SET_DTS 0x02 /* enable DTS Digital Output */
477#define AUDIOPHILE_SET_24B 0x08 /* 24bits sample if set, 16bits otherwise */ 501#define MAUDIO_SET_96K 0x04 /* 48-96KHz rate if set, 8-48KHz otherwise */
478#define AUDIOPHILE_SET_DI 0x10 /* if set, enable Digital Input */ 502#define MAUDIO_SET_24B 0x08 /* 24bits sample if set, 16bits otherwise */
479#define AUDIOPHILE_SET_MASK 0x1F /* bit mask for setup value */ 503#define MAUDIO_SET_DI 0x10 /* enable Digital Input */
480#define AUDIOPHILE_SET_24B_48K_DI 0x19 /* value for 24bits+48KHz+Digital Input */ 504#define MAUDIO_SET_MASK 0x1f /* bit mask for setup value */
481#define AUDIOPHILE_SET_24B_48K_NOTDI 0x09 /* value for 24bits+48KHz+No Digital Input */ 505#define MAUDIO_SET_24B_48K_DI 0x19 /* 24bits+48KHz+Digital Input */
482#define AUDIOPHILE_SET_16B_48K_DI 0x11 /* value for 16bits+48KHz+Digital Input */ 506#define MAUDIO_SET_24B_48K_NOTDI 0x09 /* 24bits+48KHz+No Digital Input */
483#define AUDIOPHILE_SET_16B_48K_NOTDI 0x01 /* value for 16bits+48KHz+No Digital Input */ 507#define MAUDIO_SET_16B_48K_DI 0x11 /* 16bits+48KHz+Digital Input */
508#define MAUDIO_SET_16B_48K_NOTDI 0x01 /* 16bits+48KHz+No Digital Input */
509
510static int quattro_skip_setting_quirk(struct snd_usb_audio *chip,
511 int iface, int altno)
512{
513 /* Reset ALL ifaces to 0 altsetting.
514 * Call it for every possible altsetting of every interface.
515 */
516 usb_set_interface(chip->dev, iface, 0);
517 if (chip->setup & MAUDIO_SET) {
518 if (chip->setup & MAUDIO_SET_COMPATIBLE) {
519 if (iface != 1 && iface != 2)
520 return 1; /* skip all interfaces but 1 and 2 */
521 } else {
522 unsigned int mask;
523 if (iface == 1 || iface == 2)
524 return 1; /* skip interfaces 1 and 2 */
525 if ((chip->setup & MAUDIO_SET_96K) && altno != 1)
526 return 1; /* skip this altsetting */
527 mask = chip->setup & MAUDIO_SET_MASK;
528 if (mask == MAUDIO_SET_24B_48K_DI && altno != 2)
529 return 1; /* skip this altsetting */
530 if (mask == MAUDIO_SET_24B_48K_NOTDI && altno != 3)
531 return 1; /* skip this altsetting */
532 if (mask == MAUDIO_SET_16B_48K_NOTDI && altno != 4)
533 return 1; /* skip this altsetting */
534 }
535 }
536 snd_printdd(KERN_INFO
537 "using altsetting %d for interface %d config %d\n",
538 altno, iface, chip->setup);
539 return 0; /* keep this altsetting */
540}
484 541
485static int audiophile_skip_setting_quirk(struct snd_usb_audio *chip, 542static int audiophile_skip_setting_quirk(struct snd_usb_audio *chip,
486 int iface, 543 int iface,
@@ -491,30 +548,65 @@ static int audiophile_skip_setting_quirk(struct snd_usb_audio *chip,
491 */ 548 */
492 usb_set_interface(chip->dev, iface, 0); 549 usb_set_interface(chip->dev, iface, 0);
493 550
494 if (chip->setup & AUDIOPHILE_SET) { 551 if (chip->setup & MAUDIO_SET) {
495 if ((chip->setup & AUDIOPHILE_SET_DTS) 552 unsigned int mask;
496 && altno != 6) 553 if ((chip->setup & MAUDIO_SET_DTS) && altno != 6)
497 return 1; /* skip this altsetting */ 554 return 1; /* skip this altsetting */
498 if ((chip->setup & AUDIOPHILE_SET_96K) 555 if ((chip->setup & MAUDIO_SET_96K) && altno != 1)
499 && altno != 1)
500 return 1; /* skip this altsetting */ 556 return 1; /* skip this altsetting */
501 if ((chip->setup & AUDIOPHILE_SET_MASK) == 557 mask = chip->setup & MAUDIO_SET_MASK;
502 AUDIOPHILE_SET_24B_48K_DI && altno != 2) 558 if (mask == MAUDIO_SET_24B_48K_DI && altno != 2)
503 return 1; /* skip this altsetting */ 559 return 1; /* skip this altsetting */
504 if ((chip->setup & AUDIOPHILE_SET_MASK) == 560 if (mask == MAUDIO_SET_24B_48K_NOTDI && altno != 3)
505 AUDIOPHILE_SET_24B_48K_NOTDI && altno != 3)
506 return 1; /* skip this altsetting */ 561 return 1; /* skip this altsetting */
507 if ((chip->setup & AUDIOPHILE_SET_MASK) == 562 if (mask == MAUDIO_SET_16B_48K_DI && altno != 4)
508 AUDIOPHILE_SET_16B_48K_DI && altno != 4)
509 return 1; /* skip this altsetting */ 563 return 1; /* skip this altsetting */
510 if ((chip->setup & AUDIOPHILE_SET_MASK) == 564 if (mask == MAUDIO_SET_16B_48K_NOTDI && altno != 5)
511 AUDIOPHILE_SET_16B_48K_NOTDI && altno != 5)
512 return 1; /* skip this altsetting */ 565 return 1; /* skip this altsetting */
513 } 566 }
514 567
515 return 0; /* keep this altsetting */ 568 return 0; /* keep this altsetting */
516} 569}
517 570
571
572static int fasttrackpro_skip_setting_quirk(struct snd_usb_audio *chip,
573 int iface, int altno)
574{
575 /* Reset ALL ifaces to 0 altsetting.
576 * Call it for every possible altsetting of every interface.
577 */
578 usb_set_interface(chip->dev, iface, 0);
579
580 /* possible configuration where both inputs and only one output is
581 *used is not supported by the current setup
582 */
583 if (chip->setup & (MAUDIO_SET | MAUDIO_SET_24B)) {
584 if (chip->setup & MAUDIO_SET_96K) {
585 if (altno != 3 && altno != 6)
586 return 1;
587 } else if (chip->setup & MAUDIO_SET_DI) {
588 if (iface == 4)
589 return 1; /* no analog input */
590 if (altno != 2 && altno != 5)
591 return 1; /* enable only altsets 2 and 5 */
592 } else {
593 if (iface == 5)
594 return 1; /* disable digialt input */
595 if (altno != 2 && altno != 5)
596 return 1; /* enalbe only altsets 2 and 5 */
597 }
598 } else {
599 /* keep only 16-Bit mode */
600 if (altno != 1)
601 return 1;
602 }
603
604 snd_printdd(KERN_INFO
605 "using altsetting %d for interface %d config %d\n",
606 altno, iface, chip->setup);
607 return 0; /* keep this altsetting */
608}
609
518int snd_usb_apply_interface_quirk(struct snd_usb_audio *chip, 610int snd_usb_apply_interface_quirk(struct snd_usb_audio *chip,
519 int iface, 611 int iface,
520 int altno) 612 int altno)
@@ -522,6 +614,12 @@ int snd_usb_apply_interface_quirk(struct snd_usb_audio *chip,
522 /* audiophile usb: skip altsets incompatible with device_setup */ 614 /* audiophile usb: skip altsets incompatible with device_setup */
523 if (chip->usb_id == USB_ID(0x0763, 0x2003)) 615 if (chip->usb_id == USB_ID(0x0763, 0x2003))
524 return audiophile_skip_setting_quirk(chip, iface, altno); 616 return audiophile_skip_setting_quirk(chip, iface, altno);
617 /* quattro usb: skip altsets incompatible with device_setup */
618 if (chip->usb_id == USB_ID(0x0763, 0x2001))
619 return quattro_skip_setting_quirk(chip, iface, altno);
620 /* fasttrackpro usb: skip altsets incompatible with device_setup */
621 if (chip->usb_id == USB_ID(0x0763, 0x2012))
622 return fasttrackpro_skip_setting_quirk(chip, iface, altno);
525 623
526 return 0; 624 return 0;
527} 625}
@@ -560,6 +658,8 @@ int snd_usb_apply_boot_quirk(struct usb_device *dev,
560 case USB_ID(0x17cc, 0x1010): /* Traktor Audio 6 */ 658 case USB_ID(0x17cc, 0x1010): /* Traktor Audio 6 */
561 case USB_ID(0x17cc, 0x1020): /* Traktor Audio 10 */ 659 case USB_ID(0x17cc, 0x1020): /* Traktor Audio 10 */
562 return snd_usb_nativeinstruments_boot_quirk(dev); 660 return snd_usb_nativeinstruments_boot_quirk(dev);
661 case USB_ID(0x0763, 0x2012): /* M-Audio Fast Track Pro USB */
662 return snd_usb_fasttrackpro_boot_quirk(dev);
563 } 663 }
564 664
565 return 0; 665 return 0;
@@ -570,15 +670,24 @@ int snd_usb_apply_boot_quirk(struct usb_device *dev,
570 */ 670 */
571int snd_usb_is_big_endian_format(struct snd_usb_audio *chip, struct audioformat *fp) 671int snd_usb_is_big_endian_format(struct snd_usb_audio *chip, struct audioformat *fp)
572{ 672{
673 /* it depends on altsetting wether the device is big-endian or not */
573 switch (chip->usb_id) { 674 switch (chip->usb_id) {
574 case USB_ID(0x0763, 0x2001): /* M-Audio Quattro: captured data only */ 675 case USB_ID(0x0763, 0x2001): /* M-Audio Quattro: captured data only */
575 if (fp->endpoint & USB_DIR_IN) 676 if (fp->altsetting == 2 || fp->altsetting == 3 ||
677 fp->altsetting == 5 || fp->altsetting == 6)
576 return 1; 678 return 1;
577 break; 679 break;
578 case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */ 680 case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */
579 if (chip->setup == 0x00 || 681 if (chip->setup == 0x00 ||
580 fp->altsetting==1 || fp->altsetting==2 || fp->altsetting==3) 682 fp->altsetting == 1 || fp->altsetting == 2 ||
683 fp->altsetting == 3)
684 return 1;
685 break;
686 case USB_ID(0x0763, 0x2012): /* M-Audio Fast Track Pro */
687 if (fp->altsetting == 2 || fp->altsetting == 3 ||
688 fp->altsetting == 5 || fp->altsetting == 6)
581 return 1; 689 return 1;
690 break;
582 } 691 }
583 return 0; 692 return 0;
584} 693}