diff options
Diffstat (limited to 'sound/usb/mixer_quirks.c')
-rw-r--r-- | sound/usb/mixer_quirks.c | 472 |
1 files changed, 445 insertions, 27 deletions
diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c index ab125ee0b0f0..41f4b6911920 100644 --- a/sound/usb/mixer_quirks.c +++ b/sound/usb/mixer_quirks.c | |||
@@ -42,6 +42,77 @@ | |||
42 | 42 | ||
43 | extern struct snd_kcontrol_new *snd_usb_feature_unit_ctl; | 43 | extern struct snd_kcontrol_new *snd_usb_feature_unit_ctl; |
44 | 44 | ||
45 | /* private_free callback */ | ||
46 | static void usb_mixer_elem_free(struct snd_kcontrol *kctl) | ||
47 | { | ||
48 | kfree(kctl->private_data); | ||
49 | kctl->private_data = NULL; | ||
50 | } | ||
51 | |||
52 | /* This function allows for the creation of standard UAC controls. | ||
53 | * See the quirks for M-Audio FTUs or Ebox-44. | ||
54 | * If you don't want to set a TLV callback pass NULL. | ||
55 | * | ||
56 | * Since there doesn't seem to be a devices that needs a multichannel | ||
57 | * version, we keep it mono for simplicity. | ||
58 | */ | ||
59 | static int snd_create_std_mono_ctl(struct usb_mixer_interface *mixer, | ||
60 | unsigned int unitid, | ||
61 | unsigned int control, | ||
62 | unsigned int cmask, | ||
63 | int val_type, | ||
64 | const char *name, | ||
65 | snd_kcontrol_tlv_rw_t *tlv_callback) | ||
66 | { | ||
67 | int err; | ||
68 | struct usb_mixer_elem_info *cval; | ||
69 | struct snd_kcontrol *kctl; | ||
70 | |||
71 | cval = kzalloc(sizeof(*cval), GFP_KERNEL); | ||
72 | if (!cval) | ||
73 | return -ENOMEM; | ||
74 | |||
75 | cval->id = unitid; | ||
76 | cval->mixer = mixer; | ||
77 | cval->val_type = val_type; | ||
78 | cval->channels = 1; | ||
79 | cval->control = control; | ||
80 | cval->cmask = cmask; | ||
81 | |||
82 | /* get_min_max() is called only for integer volumes later, | ||
83 | * so provide a short-cut for booleans */ | ||
84 | cval->min = 0; | ||
85 | cval->max = 1; | ||
86 | cval->res = 0; | ||
87 | cval->dBmin = 0; | ||
88 | cval->dBmax = 0; | ||
89 | |||
90 | /* Create control */ | ||
91 | kctl = snd_ctl_new1(snd_usb_feature_unit_ctl, cval); | ||
92 | if (!kctl) { | ||
93 | kfree(cval); | ||
94 | return -ENOMEM; | ||
95 | } | ||
96 | |||
97 | /* Set name */ | ||
98 | snprintf(kctl->id.name, sizeof(kctl->id.name), name); | ||
99 | kctl->private_free = usb_mixer_elem_free; | ||
100 | |||
101 | /* set TLV */ | ||
102 | if (tlv_callback) { | ||
103 | kctl->tlv.c = tlv_callback; | ||
104 | kctl->vd[0].access |= | ||
105 | SNDRV_CTL_ELEM_ACCESS_TLV_READ | | ||
106 | SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK; | ||
107 | } | ||
108 | /* Add control to mixer */ | ||
109 | err = snd_usb_mixer_add_control(mixer, kctl); | ||
110 | if (err < 0) | ||
111 | return err; | ||
112 | |||
113 | return 0; | ||
114 | } | ||
115 | |||
45 | /* | 116 | /* |
46 | * Sound Blaster remote control configuration | 117 | * Sound Blaster remote control configuration |
47 | * | 118 | * |
@@ -495,60 +566,218 @@ static int snd_nativeinstruments_create_mixer(struct usb_mixer_interface *mixer, | |||
495 | } | 566 | } |
496 | 567 | ||
497 | /* M-Audio FastTrack Ultra quirks */ | 568 | /* M-Audio FastTrack Ultra quirks */ |
569 | /* FTU Effect switch */ | ||
570 | struct snd_ftu_eff_switch_priv_val { | ||
571 | struct usb_mixer_interface *mixer; | ||
572 | int cached_value; | ||
573 | int is_cached; | ||
574 | }; | ||
498 | 575 | ||
499 | /* private_free callback */ | 576 | static int snd_ftu_eff_switch_info(struct snd_kcontrol *kcontrol, |
500 | static void usb_mixer_elem_free(struct snd_kcontrol *kctl) | 577 | struct snd_ctl_elem_info *uinfo) |
501 | { | 578 | { |
502 | kfree(kctl->private_data); | 579 | static const char *texts[8] = {"Room 1", |
503 | kctl->private_data = NULL; | 580 | "Room 2", |
581 | "Room 3", | ||
582 | "Hall 1", | ||
583 | "Hall 2", | ||
584 | "Plate", | ||
585 | "Delay", | ||
586 | "Echo" | ||
587 | }; | ||
588 | |||
589 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
590 | uinfo->count = 1; | ||
591 | uinfo->value.enumerated.items = 8; | ||
592 | if (uinfo->value.enumerated.item > 7) | ||
593 | uinfo->value.enumerated.item = 7; | ||
594 | strcpy(uinfo->value.enumerated.name, | ||
595 | texts[uinfo->value.enumerated.item]); | ||
596 | |||
597 | return 0; | ||
504 | } | 598 | } |
505 | 599 | ||
506 | static int snd_maudio_ftu_create_ctl(struct usb_mixer_interface *mixer, | 600 | static int snd_ftu_eff_switch_get(struct snd_kcontrol *kctl, |
507 | int in, int out, const char *name) | 601 | struct snd_ctl_elem_value *ucontrol) |
508 | { | 602 | { |
509 | struct usb_mixer_elem_info *cval; | 603 | struct snd_usb_audio *chip; |
604 | struct usb_mixer_interface *mixer; | ||
605 | struct snd_ftu_eff_switch_priv_val *pval; | ||
606 | int err; | ||
607 | unsigned char value[2]; | ||
608 | |||
609 | const int id = 6; | ||
610 | const int validx = 1; | ||
611 | const int val_len = 2; | ||
612 | |||
613 | value[0] = 0x00; | ||
614 | value[1] = 0x00; | ||
615 | |||
616 | pval = (struct snd_ftu_eff_switch_priv_val *) | ||
617 | kctl->private_value; | ||
618 | |||
619 | if (pval->is_cached) { | ||
620 | ucontrol->value.enumerated.item[0] = pval->cached_value; | ||
621 | return 0; | ||
622 | } | ||
623 | |||
624 | mixer = (struct usb_mixer_interface *) pval->mixer; | ||
625 | if (snd_BUG_ON(!mixer)) | ||
626 | return -EINVAL; | ||
627 | |||
628 | chip = (struct snd_usb_audio *) mixer->chip; | ||
629 | if (snd_BUG_ON(!chip)) | ||
630 | return -EINVAL; | ||
631 | |||
632 | |||
633 | err = snd_usb_ctl_msg(chip->dev, | ||
634 | usb_rcvctrlpipe(chip->dev, 0), UAC_GET_CUR, | ||
635 | USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, | ||
636 | validx << 8, snd_usb_ctrl_intf(chip) | (id << 8), | ||
637 | value, val_len); | ||
638 | if (err < 0) | ||
639 | return err; | ||
640 | |||
641 | ucontrol->value.enumerated.item[0] = value[0]; | ||
642 | pval->cached_value = value[0]; | ||
643 | pval->is_cached = 1; | ||
644 | |||
645 | return 0; | ||
646 | } | ||
647 | |||
648 | static int snd_ftu_eff_switch_put(struct snd_kcontrol *kctl, | ||
649 | struct snd_ctl_elem_value *ucontrol) | ||
650 | { | ||
651 | struct snd_usb_audio *chip; | ||
652 | struct snd_ftu_eff_switch_priv_val *pval; | ||
653 | |||
654 | struct usb_mixer_interface *mixer; | ||
655 | int changed, cur_val, err, new_val; | ||
656 | unsigned char value[2]; | ||
657 | |||
658 | |||
659 | const int id = 6; | ||
660 | const int validx = 1; | ||
661 | const int val_len = 2; | ||
662 | |||
663 | changed = 0; | ||
664 | |||
665 | pval = (struct snd_ftu_eff_switch_priv_val *) | ||
666 | kctl->private_value; | ||
667 | cur_val = pval->cached_value; | ||
668 | new_val = ucontrol->value.enumerated.item[0]; | ||
669 | |||
670 | mixer = (struct usb_mixer_interface *) pval->mixer; | ||
671 | if (snd_BUG_ON(!mixer)) | ||
672 | return -EINVAL; | ||
673 | |||
674 | chip = (struct snd_usb_audio *) mixer->chip; | ||
675 | if (snd_BUG_ON(!chip)) | ||
676 | return -EINVAL; | ||
677 | |||
678 | if (!pval->is_cached) { | ||
679 | /* Read current value */ | ||
680 | err = snd_usb_ctl_msg(chip->dev, | ||
681 | usb_rcvctrlpipe(chip->dev, 0), UAC_GET_CUR, | ||
682 | USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, | ||
683 | validx << 8, snd_usb_ctrl_intf(chip) | (id << 8), | ||
684 | value, val_len); | ||
685 | if (err < 0) | ||
686 | return err; | ||
687 | |||
688 | cur_val = value[0]; | ||
689 | pval->cached_value = cur_val; | ||
690 | pval->is_cached = 1; | ||
691 | } | ||
692 | /* update value if needed */ | ||
693 | if (cur_val != new_val) { | ||
694 | value[0] = new_val; | ||
695 | value[1] = 0; | ||
696 | err = snd_usb_ctl_msg(chip->dev, | ||
697 | usb_sndctrlpipe(chip->dev, 0), UAC_SET_CUR, | ||
698 | USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, | ||
699 | validx << 8, snd_usb_ctrl_intf(chip) | (id << 8), | ||
700 | value, val_len); | ||
701 | if (err < 0) | ||
702 | return err; | ||
703 | |||
704 | pval->cached_value = new_val; | ||
705 | pval->is_cached = 1; | ||
706 | changed = 1; | ||
707 | } | ||
708 | |||
709 | return changed; | ||
710 | } | ||
711 | |||
712 | static int snd_ftu_create_effect_switch(struct usb_mixer_interface *mixer) | ||
713 | { | ||
714 | static struct snd_kcontrol_new template = { | ||
715 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
716 | .name = "Effect Program Switch", | ||
717 | .index = 0, | ||
718 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, | ||
719 | .info = snd_ftu_eff_switch_info, | ||
720 | .get = snd_ftu_eff_switch_get, | ||
721 | .put = snd_ftu_eff_switch_put | ||
722 | }; | ||
723 | |||
724 | int err; | ||
510 | struct snd_kcontrol *kctl; | 725 | struct snd_kcontrol *kctl; |
726 | struct snd_ftu_eff_switch_priv_val *pval; | ||
511 | 727 | ||
512 | cval = kzalloc(sizeof(*cval), GFP_KERNEL); | 728 | pval = kzalloc(sizeof(*pval), GFP_KERNEL); |
513 | if (!cval) | 729 | if (!pval) |
514 | return -ENOMEM; | 730 | return -ENOMEM; |
515 | 731 | ||
516 | cval->id = 5; | 732 | pval->cached_value = 0; |
517 | cval->mixer = mixer; | 733 | pval->is_cached = 0; |
518 | cval->val_type = USB_MIXER_S16; | 734 | pval->mixer = mixer; |
519 | cval->channels = 1; | ||
520 | cval->control = out + 1; | ||
521 | cval->cmask = 1 << in; | ||
522 | 735 | ||
523 | kctl = snd_ctl_new1(snd_usb_feature_unit_ctl, cval); | 736 | template.private_value = (unsigned long) pval; |
737 | kctl = snd_ctl_new1(&template, mixer->chip); | ||
524 | if (!kctl) { | 738 | if (!kctl) { |
525 | kfree(cval); | 739 | kfree(pval); |
526 | return -ENOMEM; | 740 | return -ENOMEM; |
527 | } | 741 | } |
528 | 742 | ||
529 | snprintf(kctl->id.name, sizeof(kctl->id.name), name); | 743 | err = snd_ctl_add(mixer->chip->card, kctl); |
530 | kctl->private_free = usb_mixer_elem_free; | 744 | if (err < 0) |
531 | return snd_usb_mixer_add_control(mixer, kctl); | 745 | return err; |
746 | |||
747 | return 0; | ||
532 | } | 748 | } |
533 | 749 | ||
534 | static int snd_maudio_ftu_create_mixer(struct usb_mixer_interface *mixer) | 750 | /* Create volume controls for FTU devices*/ |
751 | static int snd_ftu_create_volume_ctls(struct usb_mixer_interface *mixer) | ||
535 | { | 752 | { |
536 | char name[64]; | 753 | char name[64]; |
754 | unsigned int control, cmask; | ||
537 | int in, out, err; | 755 | int in, out, err; |
538 | 756 | ||
757 | const unsigned int id = 5; | ||
758 | const int val_type = USB_MIXER_S16; | ||
759 | |||
539 | for (out = 0; out < 8; out++) { | 760 | for (out = 0; out < 8; out++) { |
761 | control = out + 1; | ||
540 | for (in = 0; in < 8; in++) { | 762 | for (in = 0; in < 8; in++) { |
763 | cmask = 1 << in; | ||
541 | snprintf(name, sizeof(name), | 764 | snprintf(name, sizeof(name), |
542 | "AIn%d - Out%d Capture Volume", in + 1, out + 1); | 765 | "AIn%d - Out%d Capture Volume", |
543 | err = snd_maudio_ftu_create_ctl(mixer, in, out, name); | 766 | in + 1, out + 1); |
767 | err = snd_create_std_mono_ctl(mixer, id, control, | ||
768 | cmask, val_type, name, | ||
769 | &snd_usb_mixer_vol_tlv); | ||
544 | if (err < 0) | 770 | if (err < 0) |
545 | return err; | 771 | return err; |
546 | } | 772 | } |
547 | |||
548 | for (in = 8; in < 16; in++) { | 773 | for (in = 8; in < 16; in++) { |
774 | cmask = 1 << in; | ||
549 | snprintf(name, sizeof(name), | 775 | snprintf(name, sizeof(name), |
550 | "DIn%d - Out%d Playback Volume", in - 7, out + 1); | 776 | "DIn%d - Out%d Playback Volume", |
551 | err = snd_maudio_ftu_create_ctl(mixer, in, out, name); | 777 | in - 7, out + 1); |
778 | err = snd_create_std_mono_ctl(mixer, id, control, | ||
779 | cmask, val_type, name, | ||
780 | &snd_usb_mixer_vol_tlv); | ||
552 | if (err < 0) | 781 | if (err < 0) |
553 | return err; | 782 | return err; |
554 | } | 783 | } |
@@ -557,6 +786,191 @@ static int snd_maudio_ftu_create_mixer(struct usb_mixer_interface *mixer) | |||
557 | return 0; | 786 | return 0; |
558 | } | 787 | } |
559 | 788 | ||
789 | /* This control needs a volume quirk, see mixer.c */ | ||
790 | static int snd_ftu_create_effect_volume_ctl(struct usb_mixer_interface *mixer) | ||
791 | { | ||
792 | static const char name[] = "Effect Volume"; | ||
793 | const unsigned int id = 6; | ||
794 | const int val_type = USB_MIXER_U8; | ||
795 | const unsigned int control = 2; | ||
796 | const unsigned int cmask = 0; | ||
797 | |||
798 | return snd_create_std_mono_ctl(mixer, id, control, cmask, val_type, | ||
799 | name, snd_usb_mixer_vol_tlv); | ||
800 | } | ||
801 | |||
802 | /* This control needs a volume quirk, see mixer.c */ | ||
803 | static int snd_ftu_create_effect_duration_ctl(struct usb_mixer_interface *mixer) | ||
804 | { | ||
805 | static const char name[] = "Effect Duration"; | ||
806 | const unsigned int id = 6; | ||
807 | const int val_type = USB_MIXER_S16; | ||
808 | const unsigned int control = 3; | ||
809 | const unsigned int cmask = 0; | ||
810 | |||
811 | return snd_create_std_mono_ctl(mixer, id, control, cmask, val_type, | ||
812 | name, snd_usb_mixer_vol_tlv); | ||
813 | } | ||
814 | |||
815 | /* This control needs a volume quirk, see mixer.c */ | ||
816 | static int snd_ftu_create_effect_feedback_ctl(struct usb_mixer_interface *mixer) | ||
817 | { | ||
818 | static const char name[] = "Effect Feedback Volume"; | ||
819 | const unsigned int id = 6; | ||
820 | const int val_type = USB_MIXER_U8; | ||
821 | const unsigned int control = 4; | ||
822 | const unsigned int cmask = 0; | ||
823 | |||
824 | return snd_create_std_mono_ctl(mixer, id, control, cmask, val_type, | ||
825 | name, NULL); | ||
826 | } | ||
827 | |||
828 | static int snd_ftu_create_effect_return_ctls(struct usb_mixer_interface *mixer) | ||
829 | { | ||
830 | unsigned int cmask; | ||
831 | int err, ch; | ||
832 | char name[48]; | ||
833 | |||
834 | const unsigned int id = 7; | ||
835 | const int val_type = USB_MIXER_S16; | ||
836 | const unsigned int control = 7; | ||
837 | |||
838 | for (ch = 0; ch < 4; ++ch) { | ||
839 | cmask = 1 << ch; | ||
840 | snprintf(name, sizeof(name), | ||
841 | "Effect Return %d Volume", ch + 1); | ||
842 | err = snd_create_std_mono_ctl(mixer, id, control, | ||
843 | cmask, val_type, name, | ||
844 | snd_usb_mixer_vol_tlv); | ||
845 | if (err < 0) | ||
846 | return err; | ||
847 | } | ||
848 | |||
849 | return 0; | ||
850 | } | ||
851 | |||
852 | static int snd_ftu_create_effect_send_ctls(struct usb_mixer_interface *mixer) | ||
853 | { | ||
854 | unsigned int cmask; | ||
855 | int err, ch; | ||
856 | char name[48]; | ||
857 | |||
858 | const unsigned int id = 5; | ||
859 | const int val_type = USB_MIXER_S16; | ||
860 | const unsigned int control = 9; | ||
861 | |||
862 | for (ch = 0; ch < 8; ++ch) { | ||
863 | cmask = 1 << ch; | ||
864 | snprintf(name, sizeof(name), | ||
865 | "Effect Send AIn%d Volume", ch + 1); | ||
866 | err = snd_create_std_mono_ctl(mixer, id, control, cmask, | ||
867 | val_type, name, | ||
868 | snd_usb_mixer_vol_tlv); | ||
869 | if (err < 0) | ||
870 | return err; | ||
871 | } | ||
872 | for (ch = 8; ch < 16; ++ch) { | ||
873 | cmask = 1 << ch; | ||
874 | snprintf(name, sizeof(name), | ||
875 | "Effect Send DIn%d Volume", ch - 7); | ||
876 | err = snd_create_std_mono_ctl(mixer, id, control, cmask, | ||
877 | val_type, name, | ||
878 | snd_usb_mixer_vol_tlv); | ||
879 | if (err < 0) | ||
880 | return err; | ||
881 | } | ||
882 | return 0; | ||
883 | } | ||
884 | |||
885 | static int snd_ftu_create_mixer(struct usb_mixer_interface *mixer) | ||
886 | { | ||
887 | int err; | ||
888 | |||
889 | err = snd_ftu_create_volume_ctls(mixer); | ||
890 | if (err < 0) | ||
891 | return err; | ||
892 | |||
893 | err = snd_ftu_create_effect_switch(mixer); | ||
894 | if (err < 0) | ||
895 | return err; | ||
896 | err = snd_ftu_create_effect_volume_ctl(mixer); | ||
897 | if (err < 0) | ||
898 | return err; | ||
899 | |||
900 | err = snd_ftu_create_effect_duration_ctl(mixer); | ||
901 | if (err < 0) | ||
902 | return err; | ||
903 | |||
904 | err = snd_ftu_create_effect_feedback_ctl(mixer); | ||
905 | if (err < 0) | ||
906 | return err; | ||
907 | |||
908 | err = snd_ftu_create_effect_return_ctls(mixer); | ||
909 | if (err < 0) | ||
910 | return err; | ||
911 | |||
912 | err = snd_ftu_create_effect_send_ctls(mixer); | ||
913 | if (err < 0) | ||
914 | return err; | ||
915 | |||
916 | return 0; | ||
917 | } | ||
918 | |||
919 | |||
920 | /* | ||
921 | * Create mixer for Electrix Ebox-44 | ||
922 | * | ||
923 | * The mixer units from this device are corrupt, and even where they | ||
924 | * are valid they presents mono controls as L and R channels of | ||
925 | * stereo. So we create a good mixer in code. | ||
926 | */ | ||
927 | |||
928 | static int snd_ebox44_create_mixer(struct usb_mixer_interface *mixer) | ||
929 | { | ||
930 | int err; | ||
931 | |||
932 | err = snd_create_std_mono_ctl(mixer, 4, 1, 0x0, USB_MIXER_INV_BOOLEAN, | ||
933 | "Headphone Playback Switch", NULL); | ||
934 | if (err < 0) | ||
935 | return err; | ||
936 | err = snd_create_std_mono_ctl(mixer, 4, 2, 0x1, USB_MIXER_S16, | ||
937 | "Headphone A Mix Playback Volume", NULL); | ||
938 | if (err < 0) | ||
939 | return err; | ||
940 | err = snd_create_std_mono_ctl(mixer, 4, 2, 0x2, USB_MIXER_S16, | ||
941 | "Headphone B Mix Playback Volume", NULL); | ||
942 | if (err < 0) | ||
943 | return err; | ||
944 | |||
945 | err = snd_create_std_mono_ctl(mixer, 7, 1, 0x0, USB_MIXER_INV_BOOLEAN, | ||
946 | "Output Playback Switch", NULL); | ||
947 | if (err < 0) | ||
948 | return err; | ||
949 | err = snd_create_std_mono_ctl(mixer, 7, 2, 0x1, USB_MIXER_S16, | ||
950 | "Output A Playback Volume", NULL); | ||
951 | if (err < 0) | ||
952 | return err; | ||
953 | err = snd_create_std_mono_ctl(mixer, 7, 2, 0x2, USB_MIXER_S16, | ||
954 | "Output B Playback Volume", NULL); | ||
955 | if (err < 0) | ||
956 | return err; | ||
957 | |||
958 | err = snd_create_std_mono_ctl(mixer, 10, 1, 0x0, USB_MIXER_INV_BOOLEAN, | ||
959 | "Input Capture Switch", NULL); | ||
960 | if (err < 0) | ||
961 | return err; | ||
962 | err = snd_create_std_mono_ctl(mixer, 10, 2, 0x1, USB_MIXER_S16, | ||
963 | "Input A Capture Volume", NULL); | ||
964 | if (err < 0) | ||
965 | return err; | ||
966 | err = snd_create_std_mono_ctl(mixer, 10, 2, 0x2, USB_MIXER_S16, | ||
967 | "Input B Capture Volume", NULL); | ||
968 | if (err < 0) | ||
969 | return err; | ||
970 | |||
971 | return 0; | ||
972 | } | ||
973 | |||
560 | void snd_emuusb_set_samplerate(struct snd_usb_audio *chip, | 974 | void snd_emuusb_set_samplerate(struct snd_usb_audio *chip, |
561 | unsigned char samplerate_id) | 975 | unsigned char samplerate_id) |
562 | { | 976 | { |
@@ -600,7 +1014,7 @@ int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer) | |||
600 | 1014 | ||
601 | case USB_ID(0x0763, 0x2080): /* M-Audio Fast Track Ultra */ | 1015 | case USB_ID(0x0763, 0x2080): /* M-Audio Fast Track Ultra */ |
602 | case USB_ID(0x0763, 0x2081): /* M-Audio Fast Track Ultra 8R */ | 1016 | case USB_ID(0x0763, 0x2081): /* M-Audio Fast Track Ultra 8R */ |
603 | err = snd_maudio_ftu_create_mixer(mixer); | 1017 | err = snd_ftu_create_mixer(mixer); |
604 | break; | 1018 | break; |
605 | 1019 | ||
606 | case USB_ID(0x0b05, 0x1739): | 1020 | case USB_ID(0x0b05, 0x1739): |
@@ -619,6 +1033,10 @@ int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer) | |||
619 | snd_nativeinstruments_ta10_mixers, | 1033 | snd_nativeinstruments_ta10_mixers, |
620 | ARRAY_SIZE(snd_nativeinstruments_ta10_mixers)); | 1034 | ARRAY_SIZE(snd_nativeinstruments_ta10_mixers)); |
621 | break; | 1035 | break; |
1036 | |||
1037 | case USB_ID(0x200c, 0x1018): /* Electrix Ebox-44 */ | ||
1038 | err = snd_ebox44_create_mixer(mixer); | ||
1039 | break; | ||
622 | } | 1040 | } |
623 | 1041 | ||
624 | return err; | 1042 | return err; |