Commit d5a0bf6cc526d326283983bb7935493b722e7063
Committed by
Takashi Iwai
1 parent
014950b013
Exists in
master
and in
7 other branches
ALSA: usb-audio: more control quirks for M-Audio FastTrack devices
Make use of the freshly introduced methods to re-use standard mixer handling and add some controls that are hidden but implemented in a standard conform way on M-Audio's FastTrack devices. Signed-off-by: Daniel Mack <zonque@gmail.com> Original-code-by: Felix Homann <linuxaudio@showlabor.de> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Showing 2 changed files with 72 additions and 2 deletions Side-by-side Diff
sound/usb/mixer_quirks.c
... | ... | @@ -40,6 +40,8 @@ |
40 | 40 | #include "mixer_quirks.h" |
41 | 41 | #include "helper.h" |
42 | 42 | |
43 | +extern struct snd_kcontrol_new *snd_usb_feature_unit_ctl; | |
44 | + | |
43 | 45 | /* |
44 | 46 | * Sound Blaster remote control configuration |
45 | 47 | * |
... | ... | @@ -492,6 +494,69 @@ |
492 | 494 | return err; |
493 | 495 | } |
494 | 496 | |
497 | +/* M-Audio FastTrack Ultra quirks */ | |
498 | + | |
499 | +/* private_free callback */ | |
500 | +static void usb_mixer_elem_free(struct snd_kcontrol *kctl) | |
501 | +{ | |
502 | + kfree(kctl->private_data); | |
503 | + kctl->private_data = NULL; | |
504 | +} | |
505 | + | |
506 | +static int snd_maudio_ftu_create_ctl(struct usb_mixer_interface *mixer, | |
507 | + int in, int out, const char *name) | |
508 | +{ | |
509 | + struct usb_mixer_elem_info *cval; | |
510 | + struct snd_kcontrol *kctl; | |
511 | + | |
512 | + cval = kzalloc(sizeof(*cval), GFP_KERNEL); | |
513 | + if (!cval) | |
514 | + return -ENOMEM; | |
515 | + | |
516 | + cval->id = 5; | |
517 | + cval->mixer = mixer; | |
518 | + cval->val_type = USB_MIXER_S16; | |
519 | + cval->channels = 1; | |
520 | + cval->control = out + 1; | |
521 | + cval->cmask = 1 << in; | |
522 | + | |
523 | + kctl = snd_ctl_new1(snd_usb_feature_unit_ctl, cval); | |
524 | + if (!kctl) { | |
525 | + kfree(cval); | |
526 | + return -ENOMEM; | |
527 | + } | |
528 | + | |
529 | + snprintf(kctl->id.name, sizeof(kctl->id.name), name); | |
530 | + kctl->private_free = usb_mixer_elem_free; | |
531 | + return snd_usb_mixer_add_control(mixer, kctl); | |
532 | +} | |
533 | + | |
534 | +static int snd_maudio_ftu_create_mixer(struct usb_mixer_interface *mixer) | |
535 | +{ | |
536 | + char name[64]; | |
537 | + int in, out, err; | |
538 | + | |
539 | + for (out = 0; out < 8; out++) { | |
540 | + for (in = 0; in < 8; in++) { | |
541 | + snprintf(name, sizeof(name), | |
542 | + "AIn%d - Out%d Capture Volume", in + 1, out + 1); | |
543 | + err = snd_maudio_ftu_create_ctl(mixer, in, out, name); | |
544 | + if (err < 0) | |
545 | + return err; | |
546 | + } | |
547 | + | |
548 | + for (in = 8; in < 16; in++) { | |
549 | + snprintf(name, sizeof(name), | |
550 | + "DIn%d - Out%d Playback Volume", in - 7, out + 1); | |
551 | + err = snd_maudio_ftu_create_ctl(mixer, in, out, name); | |
552 | + if (err < 0) | |
553 | + return err; | |
554 | + } | |
555 | + } | |
556 | + | |
557 | + return 0; | |
558 | +} | |
559 | + | |
495 | 560 | void snd_emuusb_set_samplerate(struct snd_usb_audio *chip, |
496 | 561 | unsigned char samplerate_id) |
497 | 562 | { |
... | ... | @@ -531,6 +596,11 @@ |
531 | 596 | if (!snd_card_proc_new(mixer->chip->card, "audigy2nx", &entry)) |
532 | 597 | snd_info_set_text_ops(entry, mixer, |
533 | 598 | snd_audigy2nx_proc_read); |
599 | + break; | |
600 | + | |
601 | + case USB_ID(0x0763, 0x2080): /* M-Audio Fast Track Ultra */ | |
602 | + case USB_ID(0x0763, 0x2081): /* M-Audio Fast Track Ultra 8R */ | |
603 | + err = snd_maudio_ftu_create_mixer(mixer); | |
534 | 604 | break; |
535 | 605 | |
536 | 606 | case USB_ID(0x0b05, 0x1739): |
sound/usb/quirks-table.h
... | ... | @@ -1988,7 +1988,7 @@ |
1988 | 1988 | .data = & (const struct snd_usb_audio_quirk[]) { |
1989 | 1989 | { |
1990 | 1990 | .ifnum = 0, |
1991 | - .type = QUIRK_IGNORE_INTERFACE | |
1991 | + .type = QUIRK_AUDIO_STANDARD_MIXER, | |
1992 | 1992 | }, |
1993 | 1993 | { |
1994 | 1994 | .ifnum = 1, |
... | ... | @@ -2055,7 +2055,7 @@ |
2055 | 2055 | .data = & (const struct snd_usb_audio_quirk[]) { |
2056 | 2056 | { |
2057 | 2057 | .ifnum = 0, |
2058 | - .type = QUIRK_IGNORE_INTERFACE | |
2058 | + .type = QUIRK_AUDIO_STANDARD_MIXER, | |
2059 | 2059 | }, |
2060 | 2060 | { |
2061 | 2061 | .ifnum = 1, |