aboutsummaryrefslogtreecommitdiffstats
path: root/sound/usb/mixer.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/usb/mixer.c')
-rw-r--r--sound/usb/mixer.c74
1 files changed, 73 insertions, 1 deletions
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
index 298070e8f2d4..ed4d89c8b52a 100644
--- a/sound/usb/mixer.c
+++ b/sound/usb/mixer.c
@@ -382,6 +382,8 @@ error:
382 382
383static int get_ctl_value(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret) 383static int get_ctl_value(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret)
384{ 384{
385 validx += cval->idx_off;
386
385 return (cval->mixer->protocol == UAC_VERSION_1) ? 387 return (cval->mixer->protocol == UAC_VERSION_1) ?
386 get_ctl_value_v1(cval, request, validx, value_ret) : 388 get_ctl_value_v1(cval, request, validx, value_ret) :
387 get_ctl_value_v2(cval, request, validx, value_ret); 389 get_ctl_value_v2(cval, request, validx, value_ret);
@@ -432,6 +434,8 @@ int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval,
432 unsigned char buf[2]; 434 unsigned char buf[2];
433 int idx = 0, val_len, err, timeout = 10; 435 int idx = 0, val_len, err, timeout = 10;
434 436
437 validx += cval->idx_off;
438
435 if (cval->mixer->protocol == UAC_VERSION_1) { 439 if (cval->mixer->protocol == UAC_VERSION_1) {
436 val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1; 440 val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1;
437 } else { /* UAC_VERSION_2 */ 441 } else { /* UAC_VERSION_2 */
@@ -719,8 +723,19 @@ static int check_input_term(struct mixer_build *state, int id, struct usb_audio_
719 return 0; 723 return 0;
720 } 724 }
721 case UAC1_PROCESSING_UNIT: 725 case UAC1_PROCESSING_UNIT:
722 case UAC1_EXTENSION_UNIT: { 726 case UAC1_EXTENSION_UNIT:
727 /* UAC2_PROCESSING_UNIT_V2 */
728 /* UAC2_EFFECT_UNIT */ {
723 struct uac_processing_unit_descriptor *d = p1; 729 struct uac_processing_unit_descriptor *d = p1;
730
731 if (state->mixer->protocol == UAC_VERSION_2 &&
732 hdr[2] == UAC2_EFFECT_UNIT) {
733 /* UAC2/UAC1 unit IDs overlap here in an
734 * uncompatible way. Ignore this unit for now.
735 */
736 return 0;
737 }
738
724 if (d->bNrInPins) { 739 if (d->bNrInPins) {
725 id = d->baSourceID[0]; 740 id = d->baSourceID[0];
726 break; /* continue to parse */ 741 break; /* continue to parse */
@@ -791,6 +806,33 @@ static void volume_control_quirks(struct usb_mixer_elem_info *cval,
791 struct snd_kcontrol *kctl) 806 struct snd_kcontrol *kctl)
792{ 807{
793 switch (cval->mixer->chip->usb_id) { 808 switch (cval->mixer->chip->usb_id) {
809 case USB_ID(0x0763, 0x2030): /* M-Audio Fast Track C400 */
810 if (strcmp(kctl->id.name, "Effect Duration") == 0) {
811 cval->min = 0x0000;
812 cval->max = 0xffff;
813 cval->res = 0x00e6;
814 break;
815 }
816 if (strcmp(kctl->id.name, "Effect Volume") == 0 ||
817 strcmp(kctl->id.name, "Effect Feedback Volume") == 0) {
818 cval->min = 0x00;
819 cval->max = 0xff;
820 break;
821 }
822 if (strstr(kctl->id.name, "Effect Return") != NULL) {
823 cval->min = 0xb706;
824 cval->max = 0xff7b;
825 cval->res = 0x0073;
826 break;
827 }
828 if ((strstr(kctl->id.name, "Playback Volume") != NULL) ||
829 (strstr(kctl->id.name, "Effect Send") != NULL)) {
830 cval->min = 0xb5fb; /* -73 dB = 0xb6ff */
831 cval->max = 0xfcfe;
832 cval->res = 0x0073;
833 }
834 break;
835
794 case USB_ID(0x0763, 0x2081): /* M-Audio Fast Track Ultra 8R */ 836 case USB_ID(0x0763, 0x2081): /* M-Audio Fast Track Ultra 8R */
795 case USB_ID(0x0763, 0x2080): /* M-Audio Fast Track Ultra */ 837 case USB_ID(0x0763, 0x2080): /* M-Audio Fast Track Ultra */
796 if (strcmp(kctl->id.name, "Effect Duration") == 0) { 838 if (strcmp(kctl->id.name, "Effect Duration") == 0) {
@@ -1094,6 +1136,32 @@ static size_t append_ctl_name(struct snd_kcontrol *kctl, const char *str)
1094 return strlcat(kctl->id.name, str, sizeof(kctl->id.name)); 1136 return strlcat(kctl->id.name, str, sizeof(kctl->id.name));
1095} 1137}
1096 1138
1139/* A lot of headsets/headphones have a "Speaker" mixer. Make sure we
1140 rename it to "Headphone". We determine if something is a headphone
1141 similar to how udev determines form factor. */
1142static void check_no_speaker_on_headset(struct snd_kcontrol *kctl,
1143 struct snd_card *card)
1144{
1145 const char *names_to_check[] = {
1146 "Headset", "headset", "Headphone", "headphone", NULL};
1147 const char **s;
1148 bool found = 0;
1149
1150 if (strcmp("Speaker", kctl->id.name))
1151 return;
1152
1153 for (s = names_to_check; *s; s++)
1154 if (strstr(card->shortname, *s)) {
1155 found = 1;
1156 break;
1157 }
1158
1159 if (!found)
1160 return;
1161
1162 strlcpy(kctl->id.name, "Headphone", sizeof(kctl->id.name));
1163}
1164
1097static void build_feature_ctl(struct mixer_build *state, void *raw_desc, 1165static void build_feature_ctl(struct mixer_build *state, void *raw_desc,
1098 unsigned int ctl_mask, int control, 1166 unsigned int ctl_mask, int control,
1099 struct usb_audio_term *iterm, int unitid, 1167 struct usb_audio_term *iterm, int unitid,
@@ -1180,6 +1248,10 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc,
1180 len = snprintf(kctl->id.name, sizeof(kctl->id.name), 1248 len = snprintf(kctl->id.name, sizeof(kctl->id.name),
1181 "Feature %d", unitid); 1249 "Feature %d", unitid);
1182 } 1250 }
1251
1252 if (!mapped_name)
1253 check_no_speaker_on_headset(kctl, state->mixer->chip->card);
1254
1183 /* determine the stream direction: 1255 /* determine the stream direction:
1184 * if the connected output is USB stream, then it's likely a 1256 * if the connected output is USB stream, then it's likely a
1185 * capture stream. otherwise it should be playback (hopefully :) 1257 * capture stream. otherwise it should be playback (hopefully :)