diff options
author | Guillaume Pellerin <yomguy@parisson.com> | 2011-07-12 12:13:46 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2011-07-12 12:15:45 -0400 |
commit | 0f5733b0c883158b13366ae34b5e4bd52a1ac346 (patch) | |
tree | 254680d4cb0a258d265ea254eac0d7fcf014d561 /sound | |
parent | 3101ba035ca9ba92f6cec7fd37348646b7a5cb61 (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>
Diffstat (limited to 'sound')
-rw-r--r-- | sound/usb/endpoint.c | 2 | ||||
-rw-r--r-- | sound/usb/quirks.c | 159 |
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 | ||
372 | static 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 | |||
510 | static 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 | ||
485 | static int audiophile_skip_setting_quirk(struct snd_usb_audio *chip, | 542 | static 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 | |||
572 | static 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 | |||
518 | int snd_usb_apply_interface_quirk(struct snd_usb_audio *chip, | 610 | int 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 | */ |
571 | int snd_usb_is_big_endian_format(struct snd_usb_audio *chip, struct audioformat *fp) | 671 | int 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 | } |