diff options
Diffstat (limited to 'sound/usb/mixer.c')
-rw-r--r-- | sound/usb/mixer.c | 511 |
1 files changed, 375 insertions, 136 deletions
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index 06b22624ab7a..301ad61ed426 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c | |||
@@ -51,6 +51,7 @@ | |||
51 | #include <linux/usb.h> | 51 | #include <linux/usb.h> |
52 | #include <linux/usb/audio.h> | 52 | #include <linux/usb/audio.h> |
53 | #include <linux/usb/audio-v2.h> | 53 | #include <linux/usb/audio-v2.h> |
54 | #include <linux/usb/audio-v3.h> | ||
54 | 55 | ||
55 | #include <sound/core.h> | 56 | #include <sound/core.h> |
56 | #include <sound/control.h> | 57 | #include <sound/control.h> |
@@ -189,7 +190,7 @@ static void *find_audio_control_unit(struct mixer_build *state, | |||
189 | USB_DT_CS_INTERFACE)) != NULL) { | 190 | USB_DT_CS_INTERFACE)) != NULL) { |
190 | if (hdr->bLength >= 4 && | 191 | if (hdr->bLength >= 4 && |
191 | hdr->bDescriptorSubtype >= UAC_INPUT_TERMINAL && | 192 | hdr->bDescriptorSubtype >= UAC_INPUT_TERMINAL && |
192 | hdr->bDescriptorSubtype <= UAC2_SAMPLE_RATE_CONVERTER && | 193 | hdr->bDescriptorSubtype <= UAC3_SAMPLE_RATE_CONVERTER && |
193 | hdr->bUnitID == unit) | 194 | hdr->bUnitID == unit) |
194 | return hdr; | 195 | return hdr; |
195 | } | 196 | } |
@@ -468,9 +469,10 @@ int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval, | |||
468 | 469 | ||
469 | validx += cval->idx_off; | 470 | validx += cval->idx_off; |
470 | 471 | ||
472 | |||
471 | if (cval->head.mixer->protocol == UAC_VERSION_1) { | 473 | if (cval->head.mixer->protocol == UAC_VERSION_1) { |
472 | val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1; | 474 | val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1; |
473 | } else { /* UAC_VERSION_2 */ | 475 | } else { /* UAC_VERSION_2/3 */ |
474 | val_len = uac2_ctl_value_size(cval->val_type); | 476 | val_len = uac2_ctl_value_size(cval->val_type); |
475 | 477 | ||
476 | /* FIXME */ | 478 | /* FIXME */ |
@@ -723,6 +725,7 @@ static int get_term_name(struct mixer_build *state, struct usb_audio_term *iterm | |||
723 | static int check_input_term(struct mixer_build *state, int id, | 725 | static int check_input_term(struct mixer_build *state, int id, |
724 | struct usb_audio_term *term) | 726 | struct usb_audio_term *term) |
725 | { | 727 | { |
728 | int protocol = state->mixer->protocol; | ||
726 | int err; | 729 | int err; |
727 | void *p1; | 730 | void *p1; |
728 | 731 | ||
@@ -730,16 +733,104 @@ static int check_input_term(struct mixer_build *state, int id, | |||
730 | while ((p1 = find_audio_control_unit(state, id)) != NULL) { | 733 | while ((p1 = find_audio_control_unit(state, id)) != NULL) { |
731 | unsigned char *hdr = p1; | 734 | unsigned char *hdr = p1; |
732 | term->id = id; | 735 | term->id = id; |
733 | switch (hdr[2]) { | 736 | |
734 | case UAC_INPUT_TERMINAL: | 737 | if (protocol == UAC_VERSION_1 || protocol == UAC_VERSION_2) { |
735 | if (state->mixer->protocol == UAC_VERSION_1) { | 738 | switch (hdr[2]) { |
736 | struct uac_input_terminal_descriptor *d = p1; | 739 | case UAC_INPUT_TERMINAL: |
737 | term->type = le16_to_cpu(d->wTerminalType); | 740 | if (protocol == UAC_VERSION_1) { |
738 | term->channels = d->bNrChannels; | 741 | struct uac_input_terminal_descriptor *d = p1; |
739 | term->chconfig = le16_to_cpu(d->wChannelConfig); | 742 | |
740 | term->name = d->iTerminal; | 743 | term->type = le16_to_cpu(d->wTerminalType); |
741 | } else { /* UAC_VERSION_2 */ | 744 | term->channels = d->bNrChannels; |
742 | struct uac2_input_terminal_descriptor *d = p1; | 745 | term->chconfig = le16_to_cpu(d->wChannelConfig); |
746 | term->name = d->iTerminal; | ||
747 | } else { /* UAC_VERSION_2 */ | ||
748 | struct uac2_input_terminal_descriptor *d = p1; | ||
749 | |||
750 | /* call recursively to verify that the | ||
751 | * referenced clock entity is valid */ | ||
752 | err = check_input_term(state, d->bCSourceID, term); | ||
753 | if (err < 0) | ||
754 | return err; | ||
755 | |||
756 | /* save input term properties after recursion, | ||
757 | * to ensure they are not overriden by the | ||
758 | * recursion calls */ | ||
759 | term->id = id; | ||
760 | term->type = le16_to_cpu(d->wTerminalType); | ||
761 | term->channels = d->bNrChannels; | ||
762 | term->chconfig = le32_to_cpu(d->bmChannelConfig); | ||
763 | term->name = d->iTerminal; | ||
764 | } | ||
765 | return 0; | ||
766 | case UAC_FEATURE_UNIT: { | ||
767 | /* the header is the same for v1 and v2 */ | ||
768 | struct uac_feature_unit_descriptor *d = p1; | ||
769 | |||
770 | id = d->bSourceID; | ||
771 | break; /* continue to parse */ | ||
772 | } | ||
773 | case UAC_MIXER_UNIT: { | ||
774 | struct uac_mixer_unit_descriptor *d = p1; | ||
775 | |||
776 | term->type = d->bDescriptorSubtype << 16; /* virtual type */ | ||
777 | term->channels = uac_mixer_unit_bNrChannels(d); | ||
778 | term->chconfig = uac_mixer_unit_wChannelConfig(d, protocol); | ||
779 | term->name = uac_mixer_unit_iMixer(d); | ||
780 | return 0; | ||
781 | } | ||
782 | case UAC_SELECTOR_UNIT: | ||
783 | case UAC2_CLOCK_SELECTOR: { | ||
784 | struct uac_selector_unit_descriptor *d = p1; | ||
785 | /* call recursively to retrieve the channel info */ | ||
786 | err = check_input_term(state, d->baSourceID[0], term); | ||
787 | if (err < 0) | ||
788 | return err; | ||
789 | term->type = d->bDescriptorSubtype << 16; /* virtual type */ | ||
790 | term->id = id; | ||
791 | term->name = uac_selector_unit_iSelector(d); | ||
792 | return 0; | ||
793 | } | ||
794 | case UAC1_PROCESSING_UNIT: | ||
795 | case UAC1_EXTENSION_UNIT: | ||
796 | /* UAC2_PROCESSING_UNIT_V2 */ | ||
797 | /* UAC2_EFFECT_UNIT */ | ||
798 | case UAC2_EXTENSION_UNIT_V2: { | ||
799 | struct uac_processing_unit_descriptor *d = p1; | ||
800 | |||
801 | if (protocol == UAC_VERSION_2 && | ||
802 | hdr[2] == UAC2_EFFECT_UNIT) { | ||
803 | /* UAC2/UAC1 unit IDs overlap here in an | ||
804 | * uncompatible way. Ignore this unit for now. | ||
805 | */ | ||
806 | return 0; | ||
807 | } | ||
808 | |||
809 | if (d->bNrInPins) { | ||
810 | id = d->baSourceID[0]; | ||
811 | break; /* continue to parse */ | ||
812 | } | ||
813 | term->type = d->bDescriptorSubtype << 16; /* virtual type */ | ||
814 | term->channels = uac_processing_unit_bNrChannels(d); | ||
815 | term->chconfig = uac_processing_unit_wChannelConfig(d, protocol); | ||
816 | term->name = uac_processing_unit_iProcessing(d, protocol); | ||
817 | return 0; | ||
818 | } | ||
819 | case UAC2_CLOCK_SOURCE: { | ||
820 | struct uac_clock_source_descriptor *d = p1; | ||
821 | |||
822 | term->type = d->bDescriptorSubtype << 16; /* virtual type */ | ||
823 | term->id = id; | ||
824 | term->name = d->iClockSource; | ||
825 | return 0; | ||
826 | } | ||
827 | default: | ||
828 | return -ENODEV; | ||
829 | } | ||
830 | } else { /* UAC_VERSION_3 */ | ||
831 | switch (hdr[2]) { | ||
832 | case UAC_INPUT_TERMINAL: { | ||
833 | struct uac3_input_terminal_descriptor *d = p1; | ||
743 | 834 | ||
744 | /* call recursively to verify that the | 835 | /* call recursively to verify that the |
745 | * referenced clock entity is valid */ | 836 | * referenced clock entity is valid */ |
@@ -752,71 +843,31 @@ static int check_input_term(struct mixer_build *state, int id, | |||
752 | * recursion calls */ | 843 | * recursion calls */ |
753 | term->id = id; | 844 | term->id = id; |
754 | term->type = le16_to_cpu(d->wTerminalType); | 845 | term->type = le16_to_cpu(d->wTerminalType); |
755 | term->channels = d->bNrChannels; | 846 | |
756 | term->chconfig = le32_to_cpu(d->bmChannelConfig); | 847 | /* REVISIT: UAC3 IT doesn't have channels/cfg */ |
757 | term->name = d->iTerminal; | 848 | term->channels = 0; |
758 | } | 849 | term->chconfig = 0; |
759 | return 0; | 850 | |
760 | case UAC_FEATURE_UNIT: { | 851 | term->name = le16_to_cpu(d->wTerminalDescrStr); |
761 | /* the header is the same for v1 and v2 */ | ||
762 | struct uac_feature_unit_descriptor *d = p1; | ||
763 | id = d->bSourceID; | ||
764 | break; /* continue to parse */ | ||
765 | } | ||
766 | case UAC_MIXER_UNIT: { | ||
767 | struct uac_mixer_unit_descriptor *d = p1; | ||
768 | term->type = d->bDescriptorSubtype << 16; /* virtual type */ | ||
769 | term->channels = uac_mixer_unit_bNrChannels(d); | ||
770 | term->chconfig = uac_mixer_unit_wChannelConfig(d, state->mixer->protocol); | ||
771 | term->name = uac_mixer_unit_iMixer(d); | ||
772 | return 0; | ||
773 | } | ||
774 | case UAC_SELECTOR_UNIT: | ||
775 | case UAC2_CLOCK_SELECTOR: { | ||
776 | struct uac_selector_unit_descriptor *d = p1; | ||
777 | /* call recursively to retrieve the channel info */ | ||
778 | err = check_input_term(state, d->baSourceID[0], term); | ||
779 | if (err < 0) | ||
780 | return err; | ||
781 | term->type = d->bDescriptorSubtype << 16; /* virtual type */ | ||
782 | term->id = id; | ||
783 | term->name = uac_selector_unit_iSelector(d); | ||
784 | return 0; | ||
785 | } | ||
786 | case UAC1_PROCESSING_UNIT: | ||
787 | case UAC1_EXTENSION_UNIT: | ||
788 | /* UAC2_PROCESSING_UNIT_V2 */ | ||
789 | /* UAC2_EFFECT_UNIT */ | ||
790 | case UAC2_EXTENSION_UNIT_V2: { | ||
791 | struct uac_processing_unit_descriptor *d = p1; | ||
792 | |||
793 | if (state->mixer->protocol == UAC_VERSION_2 && | ||
794 | hdr[2] == UAC2_EFFECT_UNIT) { | ||
795 | /* UAC2/UAC1 unit IDs overlap here in an | ||
796 | * uncompatible way. Ignore this unit for now. | ||
797 | */ | ||
798 | return 0; | 852 | return 0; |
799 | } | 853 | } |
854 | case UAC3_FEATURE_UNIT: { | ||
855 | struct uac3_feature_unit_descriptor *d = p1; | ||
800 | 856 | ||
801 | if (d->bNrInPins) { | 857 | id = d->bSourceID; |
802 | id = d->baSourceID[0]; | ||
803 | break; /* continue to parse */ | 858 | break; /* continue to parse */ |
804 | } | 859 | } |
805 | term->type = d->bDescriptorSubtype << 16; /* virtual type */ | 860 | case UAC3_CLOCK_SOURCE: { |
806 | term->channels = uac_processing_unit_bNrChannels(d); | 861 | struct uac3_clock_source_descriptor *d = p1; |
807 | term->chconfig = uac_processing_unit_wChannelConfig(d, state->mixer->protocol); | 862 | |
808 | term->name = uac_processing_unit_iProcessing(d, state->mixer->protocol); | 863 | term->type = d->bDescriptorSubtype << 16; /* virtual type */ |
809 | return 0; | 864 | term->id = id; |
810 | } | 865 | term->name = le16_to_cpu(d->wClockSourceStr); |
811 | case UAC2_CLOCK_SOURCE: { | 866 | return 0; |
812 | struct uac_clock_source_descriptor *d = p1; | 867 | } |
813 | term->type = d->bDescriptorSubtype << 16; /* virtual type */ | 868 | default: |
814 | term->id = id; | 869 | return -ENODEV; |
815 | term->name = d->iClockSource; | 870 | } |
816 | return 0; | ||
817 | } | ||
818 | default: | ||
819 | return -ENODEV; | ||
820 | } | 871 | } |
821 | } | 872 | } |
822 | return -ENODEV; | 873 | return -ENODEV; |
@@ -828,26 +879,27 @@ static int check_input_term(struct mixer_build *state, int id, | |||
828 | 879 | ||
829 | /* feature unit control information */ | 880 | /* feature unit control information */ |
830 | struct usb_feature_control_info { | 881 | struct usb_feature_control_info { |
882 | int control; | ||
831 | const char *name; | 883 | const char *name; |
832 | int type; /* data type for uac1 */ | 884 | int type; /* data type for uac1 */ |
833 | int type_uac2; /* data type for uac2 if different from uac1, else -1 */ | 885 | int type_uac2; /* data type for uac2 if different from uac1, else -1 */ |
834 | }; | 886 | }; |
835 | 887 | ||
836 | static struct usb_feature_control_info audio_feature_info[] = { | 888 | static struct usb_feature_control_info audio_feature_info[] = { |
837 | { "Mute", USB_MIXER_INV_BOOLEAN, -1 }, | 889 | { UAC_FU_MUTE, "Mute", USB_MIXER_INV_BOOLEAN, -1 }, |
838 | { "Volume", USB_MIXER_S16, -1 }, | 890 | { UAC_FU_VOLUME, "Volume", USB_MIXER_S16, -1 }, |
839 | { "Tone Control - Bass", USB_MIXER_S8, -1 }, | 891 | { UAC_FU_BASS, "Tone Control - Bass", USB_MIXER_S8, -1 }, |
840 | { "Tone Control - Mid", USB_MIXER_S8, -1 }, | 892 | { UAC_FU_MID, "Tone Control - Mid", USB_MIXER_S8, -1 }, |
841 | { "Tone Control - Treble", USB_MIXER_S8, -1 }, | 893 | { UAC_FU_TREBLE, "Tone Control - Treble", USB_MIXER_S8, -1 }, |
842 | { "Graphic Equalizer", USB_MIXER_S8, -1 }, /* FIXME: not implemeted yet */ | 894 | { UAC_FU_GRAPHIC_EQUALIZER, "Graphic Equalizer", USB_MIXER_S8, -1 }, /* FIXME: not implemented yet */ |
843 | { "Auto Gain Control", USB_MIXER_BOOLEAN, -1 }, | 895 | { UAC_FU_AUTOMATIC_GAIN, "Auto Gain Control", USB_MIXER_BOOLEAN, -1 }, |
844 | { "Delay Control", USB_MIXER_U16, USB_MIXER_U32 }, | 896 | { UAC_FU_DELAY, "Delay Control", USB_MIXER_U16, USB_MIXER_U32 }, |
845 | { "Bass Boost", USB_MIXER_BOOLEAN, -1 }, | 897 | { UAC_FU_BASS_BOOST, "Bass Boost", USB_MIXER_BOOLEAN, -1 }, |
846 | { "Loudness", USB_MIXER_BOOLEAN, -1 }, | 898 | { UAC_FU_LOUDNESS, "Loudness", USB_MIXER_BOOLEAN, -1 }, |
847 | /* UAC2 specific */ | 899 | /* UAC2 specific */ |
848 | { "Input Gain Control", USB_MIXER_S16, -1 }, | 900 | { UAC2_FU_INPUT_GAIN, "Input Gain Control", USB_MIXER_S16, -1 }, |
849 | { "Input Gain Pad Control", USB_MIXER_S16, -1 }, | 901 | { UAC2_FU_INPUT_GAIN_PAD, "Input Gain Pad Control", USB_MIXER_S16, -1 }, |
850 | { "Phase Inverter Control", USB_MIXER_BOOLEAN, -1 }, | 902 | { UAC2_FU_PHASE_INVERTER, "Phase Inverter Control", USB_MIXER_BOOLEAN, -1 }, |
851 | }; | 903 | }; |
852 | 904 | ||
853 | /* private_free callback */ | 905 | /* private_free callback */ |
@@ -1183,6 +1235,21 @@ static int mixer_ctl_feature_put(struct snd_kcontrol *kcontrol, | |||
1183 | return changed; | 1235 | return changed; |
1184 | } | 1236 | } |
1185 | 1237 | ||
1238 | /* get the boolean value from the master channel of a UAC control */ | ||
1239 | static int mixer_ctl_master_bool_get(struct snd_kcontrol *kcontrol, | ||
1240 | struct snd_ctl_elem_value *ucontrol) | ||
1241 | { | ||
1242 | struct usb_mixer_elem_info *cval = kcontrol->private_data; | ||
1243 | int val, err; | ||
1244 | |||
1245 | err = snd_usb_get_cur_mix_value(cval, 0, 0, &val); | ||
1246 | if (err < 0) | ||
1247 | return filter_error(cval, err); | ||
1248 | val = (val != 0); | ||
1249 | ucontrol->value.integer.value[0] = val; | ||
1250 | return 0; | ||
1251 | } | ||
1252 | |||
1186 | static struct snd_kcontrol_new usb_feature_unit_ctl = { | 1253 | static struct snd_kcontrol_new usb_feature_unit_ctl = { |
1187 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 1254 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
1188 | .name = "", /* will be filled later manually */ | 1255 | .name = "", /* will be filled later manually */ |
@@ -1201,6 +1268,19 @@ static const struct snd_kcontrol_new usb_feature_unit_ctl_ro = { | |||
1201 | }; | 1268 | }; |
1202 | 1269 | ||
1203 | /* | 1270 | /* |
1271 | * A control which shows the boolean value from reading a UAC control on | ||
1272 | * the master channel. | ||
1273 | */ | ||
1274 | static struct snd_kcontrol_new usb_bool_master_control_ctl_ro = { | ||
1275 | .iface = SNDRV_CTL_ELEM_IFACE_CARD, | ||
1276 | .name = "", /* will be filled later manually */ | ||
1277 | .access = SNDRV_CTL_ELEM_ACCESS_READ, | ||
1278 | .info = snd_ctl_boolean_mono_info, | ||
1279 | .get = mixer_ctl_master_bool_get, | ||
1280 | .put = NULL, | ||
1281 | }; | ||
1282 | |||
1283 | /* | ||
1204 | * This symbol is exported in order to allow the mixer quirks to | 1284 | * This symbol is exported in order to allow the mixer quirks to |
1205 | * hook up to the standard feature unit control mechanism | 1285 | * hook up to the standard feature unit control mechanism |
1206 | */ | 1286 | */ |
@@ -1242,6 +1322,17 @@ static void check_no_speaker_on_headset(struct snd_kcontrol *kctl, | |||
1242 | strlcpy(kctl->id.name, "Headphone", sizeof(kctl->id.name)); | 1322 | strlcpy(kctl->id.name, "Headphone", sizeof(kctl->id.name)); |
1243 | } | 1323 | } |
1244 | 1324 | ||
1325 | static struct usb_feature_control_info *get_feature_control_info(int control) | ||
1326 | { | ||
1327 | int i; | ||
1328 | |||
1329 | for (i = 0; i < ARRAY_SIZE(audio_feature_info); ++i) { | ||
1330 | if (audio_feature_info[i].control == control) | ||
1331 | return &audio_feature_info[i]; | ||
1332 | } | ||
1333 | return NULL; | ||
1334 | } | ||
1335 | |||
1245 | static void build_feature_ctl(struct mixer_build *state, void *raw_desc, | 1336 | static void build_feature_ctl(struct mixer_build *state, void *raw_desc, |
1246 | unsigned int ctl_mask, int control, | 1337 | unsigned int ctl_mask, int control, |
1247 | struct usb_audio_term *iterm, int unitid, | 1338 | struct usb_audio_term *iterm, int unitid, |
@@ -1257,8 +1348,6 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc, | |||
1257 | const struct usbmix_name_map *map; | 1348 | const struct usbmix_name_map *map; |
1258 | unsigned int range; | 1349 | unsigned int range; |
1259 | 1350 | ||
1260 | control++; /* change from zero-based to 1-based value */ | ||
1261 | |||
1262 | if (control == UAC_FU_GRAPHIC_EQUALIZER) { | 1351 | if (control == UAC_FU_GRAPHIC_EQUALIZER) { |
1263 | /* FIXME: not supported yet */ | 1352 | /* FIXME: not supported yet */ |
1264 | return; | 1353 | return; |
@@ -1274,7 +1363,12 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc, | |||
1274 | snd_usb_mixer_elem_init_std(&cval->head, state->mixer, unitid); | 1363 | snd_usb_mixer_elem_init_std(&cval->head, state->mixer, unitid); |
1275 | cval->control = control; | 1364 | cval->control = control; |
1276 | cval->cmask = ctl_mask; | 1365 | cval->cmask = ctl_mask; |
1277 | ctl_info = &audio_feature_info[control-1]; | 1366 | |
1367 | ctl_info = get_feature_control_info(control); | ||
1368 | if (!ctl_info) { | ||
1369 | kfree(cval); | ||
1370 | return; | ||
1371 | } | ||
1278 | if (state->mixer->protocol == UAC_VERSION_1) | 1372 | if (state->mixer->protocol == UAC_VERSION_1) |
1279 | cval->val_type = ctl_info->type; | 1373 | cval->val_type = ctl_info->type; |
1280 | else /* UAC_VERSION_2 */ | 1374 | else /* UAC_VERSION_2 */ |
@@ -1400,6 +1494,60 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc, | |||
1400 | snd_usb_mixer_add_control(&cval->head, kctl); | 1494 | snd_usb_mixer_add_control(&cval->head, kctl); |
1401 | } | 1495 | } |
1402 | 1496 | ||
1497 | static void get_connector_control_name(struct mixer_build *state, | ||
1498 | struct usb_audio_term *term, | ||
1499 | bool is_input, char *name, int name_size) | ||
1500 | { | ||
1501 | int name_len = get_term_name(state, term, name, name_size, 0); | ||
1502 | |||
1503 | if (name_len == 0) | ||
1504 | strlcpy(name, "Unknown", name_size); | ||
1505 | |||
1506 | /* | ||
1507 | * sound/core/ctljack.c has a convention of naming jack controls | ||
1508 | * by ending in " Jack". Make it slightly more useful by | ||
1509 | * indicating Input or Output after the terminal name. | ||
1510 | */ | ||
1511 | if (is_input) | ||
1512 | strlcat(name, " - Input Jack", name_size); | ||
1513 | else | ||
1514 | strlcat(name, " - Output Jack", name_size); | ||
1515 | } | ||
1516 | |||
1517 | /* Build a mixer control for a UAC connector control (jack-detect) */ | ||
1518 | static void build_connector_control(struct mixer_build *state, | ||
1519 | struct usb_audio_term *term, bool is_input) | ||
1520 | { | ||
1521 | struct snd_kcontrol *kctl; | ||
1522 | struct usb_mixer_elem_info *cval; | ||
1523 | |||
1524 | cval = kzalloc(sizeof(*cval), GFP_KERNEL); | ||
1525 | if (!cval) | ||
1526 | return; | ||
1527 | snd_usb_mixer_elem_init_std(&cval->head, state->mixer, term->id); | ||
1528 | /* | ||
1529 | * The first byte from reading the UAC2_TE_CONNECTOR control returns the | ||
1530 | * number of channels connected. This boolean ctl will simply report | ||
1531 | * if any channels are connected or not. | ||
1532 | * (Audio20_final.pdf Table 5-10: Connector Control CUR Parameter Block) | ||
1533 | */ | ||
1534 | cval->control = UAC2_TE_CONNECTOR; | ||
1535 | cval->val_type = USB_MIXER_BOOLEAN; | ||
1536 | cval->channels = 1; /* report true if any channel is connected */ | ||
1537 | cval->min = 0; | ||
1538 | cval->max = 1; | ||
1539 | kctl = snd_ctl_new1(&usb_bool_master_control_ctl_ro, cval); | ||
1540 | if (!kctl) { | ||
1541 | usb_audio_err(state->chip, "cannot malloc kcontrol\n"); | ||
1542 | kfree(cval); | ||
1543 | return; | ||
1544 | } | ||
1545 | get_connector_control_name(state, term, is_input, kctl->id.name, | ||
1546 | sizeof(kctl->id.name)); | ||
1547 | kctl->private_free = snd_usb_mixer_elem_free; | ||
1548 | snd_usb_mixer_add_control(&cval->head, kctl); | ||
1549 | } | ||
1550 | |||
1403 | static int parse_clock_source_unit(struct mixer_build *state, int unitid, | 1551 | static int parse_clock_source_unit(struct mixer_build *state, int unitid, |
1404 | void *_ftr) | 1552 | void *_ftr) |
1405 | { | 1553 | { |
@@ -1423,8 +1571,8 @@ static int parse_clock_source_unit(struct mixer_build *state, int unitid, | |||
1423 | * The only property of this unit we are interested in is the | 1571 | * The only property of this unit we are interested in is the |
1424 | * clock source validity. If that isn't readable, just bail out. | 1572 | * clock source validity. If that isn't readable, just bail out. |
1425 | */ | 1573 | */ |
1426 | if (!uac2_control_is_readable(hdr->bmControls, | 1574 | if (!uac_v2v3_control_is_readable(hdr->bmControls, |
1427 | ilog2(UAC2_CS_CONTROL_CLOCK_VALID))) | 1575 | UAC2_CS_CONTROL_CLOCK_VALID)) |
1428 | return 0; | 1576 | return 0; |
1429 | 1577 | ||
1430 | cval = kzalloc(sizeof(*cval), GFP_KERNEL); | 1578 | cval = kzalloc(sizeof(*cval), GFP_KERNEL); |
@@ -1439,13 +1587,9 @@ static int parse_clock_source_unit(struct mixer_build *state, int unitid, | |||
1439 | cval->val_type = USB_MIXER_BOOLEAN; | 1587 | cval->val_type = USB_MIXER_BOOLEAN; |
1440 | cval->control = UAC2_CS_CONTROL_CLOCK_VALID; | 1588 | cval->control = UAC2_CS_CONTROL_CLOCK_VALID; |
1441 | 1589 | ||
1442 | if (uac2_control_is_writeable(hdr->bmControls, | 1590 | cval->master_readonly = 1; |
1443 | ilog2(UAC2_CS_CONTROL_CLOCK_VALID))) | 1591 | /* From UAC2 5.2.5.1.2 "Only the get request is supported." */ |
1444 | kctl = snd_ctl_new1(&usb_feature_unit_ctl, cval); | 1592 | kctl = snd_ctl_new1(&usb_bool_master_control_ctl_ro, cval); |
1445 | else { | ||
1446 | cval->master_readonly = 1; | ||
1447 | kctl = snd_ctl_new1(&usb_feature_unit_ctl_ro, cval); | ||
1448 | } | ||
1449 | 1593 | ||
1450 | if (!kctl) { | 1594 | if (!kctl) { |
1451 | kfree(cval); | 1595 | kfree(cval); |
@@ -1502,7 +1646,7 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, | |||
1502 | unitid); | 1646 | unitid); |
1503 | return -EINVAL; | 1647 | return -EINVAL; |
1504 | } | 1648 | } |
1505 | } else { | 1649 | } else if (state->mixer->protocol == UAC_VERSION_2) { |
1506 | struct uac2_feature_unit_descriptor *ftr = _ftr; | 1650 | struct uac2_feature_unit_descriptor *ftr = _ftr; |
1507 | if (hdr->bLength < 6) { | 1651 | if (hdr->bLength < 6) { |
1508 | usb_audio_err(state->chip, | 1652 | usb_audio_err(state->chip, |
@@ -1519,6 +1663,24 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, | |||
1519 | unitid); | 1663 | unitid); |
1520 | return -EINVAL; | 1664 | return -EINVAL; |
1521 | } | 1665 | } |
1666 | } else { /* UAC_VERSION_3 */ | ||
1667 | struct uac3_feature_unit_descriptor *ftr = _ftr; | ||
1668 | |||
1669 | if (hdr->bLength < 7) { | ||
1670 | usb_audio_err(state->chip, | ||
1671 | "unit %u: invalid UAC3_FEATURE_UNIT descriptor\n", | ||
1672 | unitid); | ||
1673 | return -EINVAL; | ||
1674 | } | ||
1675 | csize = 4; | ||
1676 | channels = (ftr->bLength - 7) / 4 - 1; | ||
1677 | bmaControls = ftr->bmaControls; | ||
1678 | if (hdr->bLength < 7 + csize) { | ||
1679 | usb_audio_err(state->chip, | ||
1680 | "unit %u: invalid UAC3_FEATURE_UNIT descriptor\n", | ||
1681 | unitid); | ||
1682 | return -EINVAL; | ||
1683 | } | ||
1522 | } | 1684 | } |
1523 | 1685 | ||
1524 | /* parse the source unit */ | 1686 | /* parse the source unit */ |
@@ -1556,6 +1718,8 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, | |||
1556 | /* check all control types */ | 1718 | /* check all control types */ |
1557 | for (i = 0; i < 10; i++) { | 1719 | for (i = 0; i < 10; i++) { |
1558 | unsigned int ch_bits = 0; | 1720 | unsigned int ch_bits = 0; |
1721 | int control = audio_feature_info[i].control; | ||
1722 | |||
1559 | for (j = 0; j < channels; j++) { | 1723 | for (j = 0; j < channels; j++) { |
1560 | unsigned int mask; | 1724 | unsigned int mask; |
1561 | 1725 | ||
@@ -1571,25 +1735,26 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, | |||
1571 | * (for ease of programming). | 1735 | * (for ease of programming). |
1572 | */ | 1736 | */ |
1573 | if (ch_bits & 1) | 1737 | if (ch_bits & 1) |
1574 | build_feature_ctl(state, _ftr, ch_bits, i, | 1738 | build_feature_ctl(state, _ftr, ch_bits, control, |
1575 | &iterm, unitid, 0); | 1739 | &iterm, unitid, 0); |
1576 | if (master_bits & (1 << i)) | 1740 | if (master_bits & (1 << i)) |
1577 | build_feature_ctl(state, _ftr, 0, i, &iterm, | 1741 | build_feature_ctl(state, _ftr, 0, control, |
1578 | unitid, 0); | 1742 | &iterm, unitid, 0); |
1579 | } | 1743 | } |
1580 | } else { /* UAC_VERSION_2 */ | 1744 | } else { /* UAC_VERSION_2/3 */ |
1581 | for (i = 0; i < ARRAY_SIZE(audio_feature_info); i++) { | 1745 | for (i = 0; i < ARRAY_SIZE(audio_feature_info); i++) { |
1582 | unsigned int ch_bits = 0; | 1746 | unsigned int ch_bits = 0; |
1583 | unsigned int ch_read_only = 0; | 1747 | unsigned int ch_read_only = 0; |
1748 | int control = audio_feature_info[i].control; | ||
1584 | 1749 | ||
1585 | for (j = 0; j < channels; j++) { | 1750 | for (j = 0; j < channels; j++) { |
1586 | unsigned int mask; | 1751 | unsigned int mask; |
1587 | 1752 | ||
1588 | mask = snd_usb_combine_bytes(bmaControls + | 1753 | mask = snd_usb_combine_bytes(bmaControls + |
1589 | csize * (j+1), csize); | 1754 | csize * (j+1), csize); |
1590 | if (uac2_control_is_readable(mask, i)) { | 1755 | if (uac_v2v3_control_is_readable(mask, control)) { |
1591 | ch_bits |= (1 << j); | 1756 | ch_bits |= (1 << j); |
1592 | if (!uac2_control_is_writeable(mask, i)) | 1757 | if (!uac_v2v3_control_is_writeable(mask, control)) |
1593 | ch_read_only |= (1 << j); | 1758 | ch_read_only |= (1 << j); |
1594 | } | 1759 | } |
1595 | } | 1760 | } |
@@ -1608,11 +1773,12 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, | |||
1608 | * (for ease of programming). | 1773 | * (for ease of programming). |
1609 | */ | 1774 | */ |
1610 | if (ch_bits & 1) | 1775 | if (ch_bits & 1) |
1611 | build_feature_ctl(state, _ftr, ch_bits, i, | 1776 | build_feature_ctl(state, _ftr, ch_bits, control, |
1612 | &iterm, unitid, ch_read_only); | 1777 | &iterm, unitid, ch_read_only); |
1613 | if (uac2_control_is_readable(master_bits, i)) | 1778 | if (uac_v2v3_control_is_readable(master_bits, control)) |
1614 | build_feature_ctl(state, _ftr, 0, i, &iterm, unitid, | 1779 | build_feature_ctl(state, _ftr, 0, i, &iterm, unitid, |
1615 | !uac2_control_is_writeable(master_bits, i)); | 1780 | !uac_v2v3_control_is_writeable(master_bits, |
1781 | control)); | ||
1616 | } | 1782 | } |
1617 | } | 1783 | } |
1618 | 1784 | ||
@@ -1684,6 +1850,23 @@ static void build_mixer_unit_ctl(struct mixer_build *state, | |||
1684 | snd_usb_mixer_add_control(&cval->head, kctl); | 1850 | snd_usb_mixer_add_control(&cval->head, kctl); |
1685 | } | 1851 | } |
1686 | 1852 | ||
1853 | static int parse_audio_input_terminal(struct mixer_build *state, int unitid, | ||
1854 | void *raw_desc) | ||
1855 | { | ||
1856 | struct usb_audio_term iterm; | ||
1857 | struct uac2_input_terminal_descriptor *d = raw_desc; | ||
1858 | |||
1859 | check_input_term(state, d->bTerminalID, &iterm); | ||
1860 | if (state->mixer->protocol == UAC_VERSION_2) { | ||
1861 | /* Check for jack detection. */ | ||
1862 | if (uac_v2v3_control_is_readable(d->bmControls, | ||
1863 | UAC2_TE_CONNECTOR)) { | ||
1864 | build_connector_control(state, &iterm, true); | ||
1865 | } | ||
1866 | } | ||
1867 | return 0; | ||
1868 | } | ||
1869 | |||
1687 | /* | 1870 | /* |
1688 | * parse a mixer unit | 1871 | * parse a mixer unit |
1689 | */ | 1872 | */ |
@@ -2220,6 +2403,7 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, | |||
2220 | static int parse_audio_unit(struct mixer_build *state, int unitid) | 2403 | static int parse_audio_unit(struct mixer_build *state, int unitid) |
2221 | { | 2404 | { |
2222 | unsigned char *p1; | 2405 | unsigned char *p1; |
2406 | int protocol = state->mixer->protocol; | ||
2223 | 2407 | ||
2224 | if (test_and_set_bit(unitid, state->unitbitmap)) | 2408 | if (test_and_set_bit(unitid, state->unitbitmap)) |
2225 | return 0; /* the unit already visited */ | 2409 | return 0; /* the unit already visited */ |
@@ -2230,36 +2414,61 @@ static int parse_audio_unit(struct mixer_build *state, int unitid) | |||
2230 | return -EINVAL; | 2414 | return -EINVAL; |
2231 | } | 2415 | } |
2232 | 2416 | ||
2233 | switch (p1[2]) { | 2417 | if (protocol == UAC_VERSION_1 || protocol == UAC_VERSION_2) { |
2234 | case UAC_INPUT_TERMINAL: | 2418 | switch (p1[2]) { |
2235 | return 0; /* NOP */ | 2419 | case UAC_INPUT_TERMINAL: |
2236 | case UAC_MIXER_UNIT: | 2420 | return parse_audio_input_terminal(state, unitid, p1); |
2237 | return parse_audio_mixer_unit(state, unitid, p1); | 2421 | case UAC_MIXER_UNIT: |
2238 | case UAC2_CLOCK_SOURCE: | 2422 | return parse_audio_mixer_unit(state, unitid, p1); |
2239 | return parse_clock_source_unit(state, unitid, p1); | 2423 | case UAC2_CLOCK_SOURCE: |
2240 | case UAC_SELECTOR_UNIT: | 2424 | return parse_clock_source_unit(state, unitid, p1); |
2241 | case UAC2_CLOCK_SELECTOR: | 2425 | case UAC_SELECTOR_UNIT: |
2242 | return parse_audio_selector_unit(state, unitid, p1); | 2426 | case UAC2_CLOCK_SELECTOR: |
2243 | case UAC_FEATURE_UNIT: | 2427 | return parse_audio_selector_unit(state, unitid, p1); |
2244 | return parse_audio_feature_unit(state, unitid, p1); | 2428 | case UAC_FEATURE_UNIT: |
2245 | case UAC1_PROCESSING_UNIT: | 2429 | return parse_audio_feature_unit(state, unitid, p1); |
2246 | /* UAC2_EFFECT_UNIT has the same value */ | 2430 | case UAC1_PROCESSING_UNIT: |
2247 | if (state->mixer->protocol == UAC_VERSION_1) | 2431 | /* UAC2_EFFECT_UNIT has the same value */ |
2248 | return parse_audio_processing_unit(state, unitid, p1); | 2432 | if (protocol == UAC_VERSION_1) |
2249 | else | 2433 | return parse_audio_processing_unit(state, unitid, p1); |
2250 | return 0; /* FIXME - effect units not implemented yet */ | 2434 | else |
2251 | case UAC1_EXTENSION_UNIT: | 2435 | return 0; /* FIXME - effect units not implemented yet */ |
2252 | /* UAC2_PROCESSING_UNIT_V2 has the same value */ | 2436 | case UAC1_EXTENSION_UNIT: |
2253 | if (state->mixer->protocol == UAC_VERSION_1) | 2437 | /* UAC2_PROCESSING_UNIT_V2 has the same value */ |
2438 | if (protocol == UAC_VERSION_1) | ||
2439 | return parse_audio_extension_unit(state, unitid, p1); | ||
2440 | else /* UAC_VERSION_2 */ | ||
2441 | return parse_audio_processing_unit(state, unitid, p1); | ||
2442 | case UAC2_EXTENSION_UNIT_V2: | ||
2254 | return parse_audio_extension_unit(state, unitid, p1); | 2443 | return parse_audio_extension_unit(state, unitid, p1); |
2255 | else /* UAC_VERSION_2 */ | 2444 | default: |
2445 | usb_audio_err(state->chip, | ||
2446 | "unit %u: unexpected type 0x%02x\n", unitid, p1[2]); | ||
2447 | return -EINVAL; | ||
2448 | } | ||
2449 | } else { /* UAC_VERSION_3 */ | ||
2450 | switch (p1[2]) { | ||
2451 | case UAC_INPUT_TERMINAL: | ||
2452 | return 0; /* NOP */ | ||
2453 | case UAC3_MIXER_UNIT: | ||
2454 | return parse_audio_mixer_unit(state, unitid, p1); | ||
2455 | case UAC3_CLOCK_SOURCE: | ||
2456 | return parse_clock_source_unit(state, unitid, p1); | ||
2457 | case UAC3_CLOCK_SELECTOR: | ||
2458 | return parse_audio_selector_unit(state, unitid, p1); | ||
2459 | case UAC3_FEATURE_UNIT: | ||
2460 | return parse_audio_feature_unit(state, unitid, p1); | ||
2461 | case UAC3_EFFECT_UNIT: | ||
2462 | return 0; /* FIXME - effect units not implemented yet */ | ||
2463 | case UAC3_PROCESSING_UNIT: | ||
2256 | return parse_audio_processing_unit(state, unitid, p1); | 2464 | return parse_audio_processing_unit(state, unitid, p1); |
2257 | case UAC2_EXTENSION_UNIT_V2: | 2465 | case UAC3_EXTENSION_UNIT: |
2258 | return parse_audio_extension_unit(state, unitid, p1); | 2466 | return parse_audio_extension_unit(state, unitid, p1); |
2259 | default: | 2467 | default: |
2260 | usb_audio_err(state->chip, | 2468 | usb_audio_err(state->chip, |
2261 | "unit %u: unexpected type 0x%02x\n", unitid, p1[2]); | 2469 | "unit %u: unexpected type 0x%02x\n", unitid, p1[2]); |
2262 | return -EINVAL; | 2470 | return -EINVAL; |
2471 | } | ||
2263 | } | 2472 | } |
2264 | } | 2473 | } |
2265 | 2474 | ||
@@ -2330,7 +2539,7 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer) | |||
2330 | err = parse_audio_unit(&state, desc->bSourceID); | 2539 | err = parse_audio_unit(&state, desc->bSourceID); |
2331 | if (err < 0 && err != -EINVAL) | 2540 | if (err < 0 && err != -EINVAL) |
2332 | return err; | 2541 | return err; |
2333 | } else { /* UAC_VERSION_2 */ | 2542 | } else if (mixer->protocol == UAC_VERSION_2) { |
2334 | struct uac2_output_terminal_descriptor *desc = p; | 2543 | struct uac2_output_terminal_descriptor *desc = p; |
2335 | 2544 | ||
2336 | if (desc->bLength < sizeof(*desc)) | 2545 | if (desc->bLength < sizeof(*desc)) |
@@ -2351,6 +2560,33 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer) | |||
2351 | err = parse_audio_unit(&state, desc->bCSourceID); | 2560 | err = parse_audio_unit(&state, desc->bCSourceID); |
2352 | if (err < 0 && err != -EINVAL) | 2561 | if (err < 0 && err != -EINVAL) |
2353 | return err; | 2562 | return err; |
2563 | |||
2564 | if (uac_v2v3_control_is_readable(desc->bmControls, | ||
2565 | UAC2_TE_CONNECTOR)) { | ||
2566 | build_connector_control(&state, &state.oterm, | ||
2567 | false); | ||
2568 | } | ||
2569 | } else { /* UAC_VERSION_3 */ | ||
2570 | struct uac3_output_terminal_descriptor *desc = p; | ||
2571 | |||
2572 | if (desc->bLength < sizeof(*desc)) | ||
2573 | continue; /* invalid descriptor? */ | ||
2574 | /* mark terminal ID as visited */ | ||
2575 | set_bit(desc->bTerminalID, state.unitbitmap); | ||
2576 | state.oterm.id = desc->bTerminalID; | ||
2577 | state.oterm.type = le16_to_cpu(desc->wTerminalType); | ||
2578 | state.oterm.name = le16_to_cpu(desc->wTerminalDescrStr); | ||
2579 | err = parse_audio_unit(&state, desc->bSourceID); | ||
2580 | if (err < 0 && err != -EINVAL) | ||
2581 | return err; | ||
2582 | |||
2583 | /* | ||
2584 | * For UAC3, use the same approach to also add the | ||
2585 | * clock selectors | ||
2586 | */ | ||
2587 | err = parse_audio_unit(&state, desc->bCSourceID); | ||
2588 | if (err < 0 && err != -EINVAL) | ||
2589 | return err; | ||
2354 | } | 2590 | } |
2355 | } | 2591 | } |
2356 | 2592 | ||
@@ -2597,6 +2833,9 @@ int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif, | |||
2597 | case UAC_VERSION_2: | 2833 | case UAC_VERSION_2: |
2598 | mixer->protocol = UAC_VERSION_2; | 2834 | mixer->protocol = UAC_VERSION_2; |
2599 | break; | 2835 | break; |
2836 | case UAC_VERSION_3: | ||
2837 | mixer->protocol = UAC_VERSION_3; | ||
2838 | break; | ||
2600 | } | 2839 | } |
2601 | 2840 | ||
2602 | if ((err = snd_usb_mixer_controls(mixer)) < 0 || | 2841 | if ((err = snd_usb_mixer_controls(mixer)) < 0 || |