diff options
Diffstat (limited to 'sound/usb/stream.c')
-rw-r--r-- | sound/usb/stream.c | 395 |
1 files changed, 330 insertions, 65 deletions
diff --git a/sound/usb/stream.c b/sound/usb/stream.c index d1776e5517ff..6a8f5843334e 100644 --- a/sound/usb/stream.c +++ b/sound/usb/stream.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/usb.h> | 20 | #include <linux/usb.h> |
21 | #include <linux/usb/audio.h> | 21 | #include <linux/usb/audio.h> |
22 | #include <linux/usb/audio-v2.h> | 22 | #include <linux/usb/audio-v2.h> |
23 | #include <linux/usb/audio-v3.h> | ||
23 | 24 | ||
24 | #include <sound/core.h> | 25 | #include <sound/core.h> |
25 | #include <sound/pcm.h> | 26 | #include <sound/pcm.h> |
@@ -311,6 +312,153 @@ static struct snd_pcm_chmap_elem *convert_chmap(int channels, unsigned int bits, | |||
311 | return chmap; | 312 | return chmap; |
312 | } | 313 | } |
313 | 314 | ||
315 | /* UAC3 device stores channels information in Cluster Descriptors */ | ||
316 | static struct | ||
317 | snd_pcm_chmap_elem *convert_chmap_v3(struct uac3_cluster_header_descriptor | ||
318 | *cluster) | ||
319 | { | ||
320 | unsigned int channels = cluster->bNrChannels; | ||
321 | struct snd_pcm_chmap_elem *chmap; | ||
322 | void *p = cluster; | ||
323 | int len, c; | ||
324 | |||
325 | if (channels > ARRAY_SIZE(chmap->map)) | ||
326 | return NULL; | ||
327 | |||
328 | chmap = kzalloc(sizeof(*chmap), GFP_KERNEL); | ||
329 | if (!chmap) | ||
330 | return NULL; | ||
331 | |||
332 | len = le16_to_cpu(cluster->wLength); | ||
333 | c = 0; | ||
334 | p += sizeof(struct uac3_cluster_header_descriptor); | ||
335 | |||
336 | while (((p - (void *)cluster) < len) && (c < channels)) { | ||
337 | struct uac3_cluster_segment_descriptor *cs_desc = p; | ||
338 | u16 cs_len; | ||
339 | u8 cs_type; | ||
340 | |||
341 | cs_len = le16_to_cpu(cs_desc->wLength); | ||
342 | cs_type = cs_desc->bSegmentType; | ||
343 | |||
344 | if (cs_type == UAC3_CHANNEL_INFORMATION) { | ||
345 | struct uac3_cluster_information_segment_descriptor *is = p; | ||
346 | unsigned char map; | ||
347 | |||
348 | /* | ||
349 | * TODO: this conversion is not complete, update it | ||
350 | * after adding UAC3 values to asound.h | ||
351 | */ | ||
352 | switch (is->bChPurpose) { | ||
353 | case UAC3_CH_MONO: | ||
354 | map = SNDRV_CHMAP_MONO; | ||
355 | break; | ||
356 | case UAC3_CH_LEFT: | ||
357 | case UAC3_CH_FRONT_LEFT: | ||
358 | case UAC3_CH_HEADPHONE_LEFT: | ||
359 | map = SNDRV_CHMAP_FL; | ||
360 | break; | ||
361 | case UAC3_CH_RIGHT: | ||
362 | case UAC3_CH_FRONT_RIGHT: | ||
363 | case UAC3_CH_HEADPHONE_RIGHT: | ||
364 | map = SNDRV_CHMAP_FR; | ||
365 | break; | ||
366 | case UAC3_CH_FRONT_CENTER: | ||
367 | map = SNDRV_CHMAP_FC; | ||
368 | break; | ||
369 | case UAC3_CH_FRONT_LEFT_OF_CENTER: | ||
370 | map = SNDRV_CHMAP_FLC; | ||
371 | break; | ||
372 | case UAC3_CH_FRONT_RIGHT_OF_CENTER: | ||
373 | map = SNDRV_CHMAP_FRC; | ||
374 | break; | ||
375 | case UAC3_CH_SIDE_LEFT: | ||
376 | map = SNDRV_CHMAP_SL; | ||
377 | break; | ||
378 | case UAC3_CH_SIDE_RIGHT: | ||
379 | map = SNDRV_CHMAP_SR; | ||
380 | break; | ||
381 | case UAC3_CH_BACK_LEFT: | ||
382 | map = SNDRV_CHMAP_RL; | ||
383 | break; | ||
384 | case UAC3_CH_BACK_RIGHT: | ||
385 | map = SNDRV_CHMAP_RR; | ||
386 | break; | ||
387 | case UAC3_CH_BACK_CENTER: | ||
388 | map = SNDRV_CHMAP_RC; | ||
389 | break; | ||
390 | case UAC3_CH_BACK_LEFT_OF_CENTER: | ||
391 | map = SNDRV_CHMAP_RLC; | ||
392 | break; | ||
393 | case UAC3_CH_BACK_RIGHT_OF_CENTER: | ||
394 | map = SNDRV_CHMAP_RRC; | ||
395 | break; | ||
396 | case UAC3_CH_TOP_CENTER: | ||
397 | map = SNDRV_CHMAP_TC; | ||
398 | break; | ||
399 | case UAC3_CH_TOP_FRONT_LEFT: | ||
400 | map = SNDRV_CHMAP_TFL; | ||
401 | break; | ||
402 | case UAC3_CH_TOP_FRONT_RIGHT: | ||
403 | map = SNDRV_CHMAP_TFR; | ||
404 | break; | ||
405 | case UAC3_CH_TOP_FRONT_CENTER: | ||
406 | map = SNDRV_CHMAP_TFC; | ||
407 | break; | ||
408 | case UAC3_CH_TOP_FRONT_LOC: | ||
409 | map = SNDRV_CHMAP_TFLC; | ||
410 | break; | ||
411 | case UAC3_CH_TOP_FRONT_ROC: | ||
412 | map = SNDRV_CHMAP_TFRC; | ||
413 | break; | ||
414 | case UAC3_CH_TOP_SIDE_LEFT: | ||
415 | map = SNDRV_CHMAP_TSL; | ||
416 | break; | ||
417 | case UAC3_CH_TOP_SIDE_RIGHT: | ||
418 | map = SNDRV_CHMAP_TSR; | ||
419 | break; | ||
420 | case UAC3_CH_TOP_BACK_LEFT: | ||
421 | map = SNDRV_CHMAP_TRL; | ||
422 | break; | ||
423 | case UAC3_CH_TOP_BACK_RIGHT: | ||
424 | map = SNDRV_CHMAP_TRR; | ||
425 | break; | ||
426 | case UAC3_CH_TOP_BACK_CENTER: | ||
427 | map = SNDRV_CHMAP_TRC; | ||
428 | break; | ||
429 | case UAC3_CH_BOTTOM_CENTER: | ||
430 | map = SNDRV_CHMAP_BC; | ||
431 | break; | ||
432 | case UAC3_CH_LOW_FREQUENCY_EFFECTS: | ||
433 | map = SNDRV_CHMAP_LFE; | ||
434 | break; | ||
435 | case UAC3_CH_LFE_LEFT: | ||
436 | map = SNDRV_CHMAP_LLFE; | ||
437 | break; | ||
438 | case UAC3_CH_LFE_RIGHT: | ||
439 | map = SNDRV_CHMAP_RLFE; | ||
440 | break; | ||
441 | case UAC3_CH_RELATIONSHIP_UNDEFINED: | ||
442 | default: | ||
443 | map = SNDRV_CHMAP_UNKNOWN; | ||
444 | break; | ||
445 | } | ||
446 | chmap->map[c++] = map; | ||
447 | } | ||
448 | p += cs_len; | ||
449 | } | ||
450 | |||
451 | if (channels < c) | ||
452 | pr_err("%s: channel number mismatch\n", __func__); | ||
453 | |||
454 | chmap->channels = channels; | ||
455 | |||
456 | for (; c < channels; c++) | ||
457 | chmap->map[c] = SNDRV_CHMAP_UNKNOWN; | ||
458 | |||
459 | return chmap; | ||
460 | } | ||
461 | |||
314 | /* | 462 | /* |
315 | * add this endpoint to the chip instance. | 463 | * add this endpoint to the chip instance. |
316 | * if a stream with the same endpoint already exists, append to it. | 464 | * if a stream with the same endpoint already exists, append to it. |
@@ -461,10 +609,11 @@ snd_usb_find_input_terminal_descriptor(struct usb_host_interface *ctrl_iface, | |||
461 | return NULL; | 609 | return NULL; |
462 | } | 610 | } |
463 | 611 | ||
464 | static struct uac2_output_terminal_descriptor * | 612 | static void * |
465 | snd_usb_find_output_terminal_descriptor(struct usb_host_interface *ctrl_iface, | 613 | snd_usb_find_output_terminal_descriptor(struct usb_host_interface *ctrl_iface, |
466 | int terminal_id) | 614 | int terminal_id) |
467 | { | 615 | { |
616 | /* OK to use with both UAC2 and UAC3 */ | ||
468 | struct uac2_output_terminal_descriptor *term = NULL; | 617 | struct uac2_output_terminal_descriptor *term = NULL; |
469 | 618 | ||
470 | while ((term = snd_usb_find_csint_desc(ctrl_iface->extra, | 619 | while ((term = snd_usb_find_csint_desc(ctrl_iface->extra, |
@@ -484,10 +633,12 @@ int snd_usb_parse_audio_interface(struct snd_usb_audio *chip, int iface_no) | |||
484 | struct usb_host_interface *alts; | 633 | struct usb_host_interface *alts; |
485 | struct usb_interface_descriptor *altsd; | 634 | struct usb_interface_descriptor *altsd; |
486 | int i, altno, err, stream; | 635 | int i, altno, err, stream; |
487 | unsigned int format = 0, num_channels = 0; | 636 | u64 format = 0; |
637 | unsigned int num_channels = 0; | ||
488 | struct audioformat *fp = NULL; | 638 | struct audioformat *fp = NULL; |
489 | int num, protocol, clock = 0; | 639 | int num, protocol, clock = 0; |
490 | struct uac_format_type_i_continuous_descriptor *fmt; | 640 | struct uac_format_type_i_continuous_descriptor *fmt = NULL; |
641 | struct snd_pcm_chmap_elem *chmap_v3 = NULL; | ||
491 | unsigned int chconfig; | 642 | unsigned int chconfig; |
492 | 643 | ||
493 | dev = chip->dev; | 644 | dev = chip->dev; |
@@ -624,38 +775,158 @@ int snd_usb_parse_audio_interface(struct snd_usb_audio *chip, int iface_no) | |||
624 | iface_no, altno, as->bTerminalLink); | 775 | iface_no, altno, as->bTerminalLink); |
625 | continue; | 776 | continue; |
626 | } | 777 | } |
627 | } | ||
628 | 778 | ||
629 | /* get format type */ | 779 | case UAC_VERSION_3: { |
630 | fmt = snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_FORMAT_TYPE); | 780 | struct uac3_input_terminal_descriptor *input_term; |
631 | if (!fmt) { | 781 | struct uac3_output_terminal_descriptor *output_term; |
782 | struct uac3_as_header_descriptor *as; | ||
783 | struct uac3_cluster_header_descriptor *cluster; | ||
784 | struct uac3_hc_descriptor_header hc_header; | ||
785 | u16 cluster_id, wLength; | ||
786 | |||
787 | as = snd_usb_find_csint_desc(alts->extra, | ||
788 | alts->extralen, | ||
789 | NULL, UAC_AS_GENERAL); | ||
790 | |||
791 | if (!as) { | ||
792 | dev_err(&dev->dev, | ||
793 | "%u:%d : UAC_AS_GENERAL descriptor not found\n", | ||
794 | iface_no, altno); | ||
795 | continue; | ||
796 | } | ||
797 | |||
798 | if (as->bLength < sizeof(*as)) { | ||
799 | dev_err(&dev->dev, | ||
800 | "%u:%d : invalid UAC_AS_GENERAL desc\n", | ||
801 | iface_no, altno); | ||
802 | continue; | ||
803 | } | ||
804 | |||
805 | cluster_id = le16_to_cpu(as->wClusterDescrID); | ||
806 | if (!cluster_id) { | ||
807 | dev_err(&dev->dev, | ||
808 | "%u:%d : no cluster descriptor\n", | ||
809 | iface_no, altno); | ||
810 | continue; | ||
811 | } | ||
812 | |||
813 | /* | ||
814 | * Get number of channels and channel map through | ||
815 | * High Capability Cluster Descriptor | ||
816 | * | ||
817 | * First step: get High Capability header and | ||
818 | * read size of Cluster Descriptor | ||
819 | */ | ||
820 | err = snd_usb_ctl_msg(chip->dev, | ||
821 | usb_rcvctrlpipe(chip->dev, 0), | ||
822 | UAC3_CS_REQ_HIGH_CAPABILITY_DESCRIPTOR, | ||
823 | USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, | ||
824 | cluster_id, | ||
825 | snd_usb_ctrl_intf(chip), | ||
826 | &hc_header, sizeof(hc_header)); | ||
827 | if (err < 0) | ||
828 | return err; | ||
829 | else if (err != sizeof(hc_header)) { | ||
830 | dev_err(&dev->dev, | ||
831 | "%u:%d : can't get High Capability descriptor\n", | ||
832 | iface_no, altno); | ||
833 | return -EIO; | ||
834 | } | ||
835 | |||
836 | /* | ||
837 | * Second step: allocate needed amount of memory | ||
838 | * and request Cluster Descriptor | ||
839 | */ | ||
840 | wLength = le16_to_cpu(hc_header.wLength); | ||
841 | cluster = kzalloc(wLength, GFP_KERNEL); | ||
842 | if (!cluster) | ||
843 | return -ENOMEM; | ||
844 | err = snd_usb_ctl_msg(chip->dev, | ||
845 | usb_rcvctrlpipe(chip->dev, 0), | ||
846 | UAC3_CS_REQ_HIGH_CAPABILITY_DESCRIPTOR, | ||
847 | USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, | ||
848 | cluster_id, | ||
849 | snd_usb_ctrl_intf(chip), | ||
850 | cluster, wLength); | ||
851 | if (err < 0) { | ||
852 | kfree(cluster); | ||
853 | return err; | ||
854 | } else if (err != wLength) { | ||
855 | dev_err(&dev->dev, | ||
856 | "%u:%d : can't get Cluster Descriptor\n", | ||
857 | iface_no, altno); | ||
858 | kfree(cluster); | ||
859 | return -EIO; | ||
860 | } | ||
861 | |||
862 | num_channels = cluster->bNrChannels; | ||
863 | chmap_v3 = convert_chmap_v3(cluster); | ||
864 | |||
865 | kfree(cluster); | ||
866 | |||
867 | format = le64_to_cpu(as->bmFormats); | ||
868 | |||
869 | /* lookup the terminal associated to this interface | ||
870 | * to extract the clock */ | ||
871 | input_term = snd_usb_find_input_terminal_descriptor( | ||
872 | chip->ctrl_intf, | ||
873 | as->bTerminalLink); | ||
874 | |||
875 | if (input_term) { | ||
876 | clock = input_term->bCSourceID; | ||
877 | break; | ||
878 | } | ||
879 | |||
880 | output_term = snd_usb_find_output_terminal_descriptor(chip->ctrl_intf, | ||
881 | as->bTerminalLink); | ||
882 | if (output_term) { | ||
883 | clock = output_term->bCSourceID; | ||
884 | break; | ||
885 | } | ||
886 | |||
632 | dev_err(&dev->dev, | 887 | dev_err(&dev->dev, |
633 | "%u:%d : no UAC_FORMAT_TYPE desc\n", | 888 | "%u:%d : bogus bTerminalLink %d\n", |
634 | iface_no, altno); | 889 | iface_no, altno, as->bTerminalLink); |
635 | continue; | 890 | continue; |
636 | } | 891 | } |
637 | if (((protocol == UAC_VERSION_1) && (fmt->bLength < 8)) || | ||
638 | ((protocol == UAC_VERSION_2) && (fmt->bLength < 6))) { | ||
639 | dev_err(&dev->dev, | ||
640 | "%u:%d : invalid UAC_FORMAT_TYPE desc\n", | ||
641 | iface_no, altno); | ||
642 | continue; | ||
643 | } | 892 | } |
644 | 893 | ||
645 | /* | 894 | if (protocol == UAC_VERSION_1 || protocol == UAC_VERSION_2) { |
646 | * Blue Microphones workaround: The last altsetting is identical | 895 | /* get format type */ |
647 | * with the previous one, except for a larger packet size, but | 896 | fmt = snd_usb_find_csint_desc(alts->extra, |
648 | * is actually a mislabeled two-channel setting; ignore it. | 897 | alts->extralen, |
649 | */ | 898 | NULL, UAC_FORMAT_TYPE); |
650 | if (fmt->bNrChannels == 1 && | 899 | if (!fmt) { |
651 | fmt->bSubframeSize == 2 && | 900 | dev_err(&dev->dev, |
652 | altno == 2 && num == 3 && | 901 | "%u:%d : no UAC_FORMAT_TYPE desc\n", |
653 | fp && fp->altsetting == 1 && fp->channels == 1 && | 902 | iface_no, altno); |
654 | fp->formats == SNDRV_PCM_FMTBIT_S16_LE && | 903 | continue; |
655 | protocol == UAC_VERSION_1 && | 904 | } |
656 | le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize) == | 905 | if (((protocol == UAC_VERSION_1) && (fmt->bLength < 8)) |
906 | || ((protocol == UAC_VERSION_2) && | ||
907 | (fmt->bLength < 6))) { | ||
908 | dev_err(&dev->dev, | ||
909 | "%u:%d : invalid UAC_FORMAT_TYPE desc\n", | ||
910 | iface_no, altno); | ||
911 | continue; | ||
912 | } | ||
913 | |||
914 | /* | ||
915 | * Blue Microphones workaround: The last altsetting is | ||
916 | * identical with the previous one, except for a larger | ||
917 | * packet size, but is actually a mislabeled two-channel | ||
918 | * setting; ignore it. | ||
919 | */ | ||
920 | if (fmt->bNrChannels == 1 && | ||
921 | fmt->bSubframeSize == 2 && | ||
922 | altno == 2 && num == 3 && | ||
923 | fp && fp->altsetting == 1 && fp->channels == 1 && | ||
924 | fp->formats == SNDRV_PCM_FMTBIT_S16_LE && | ||
925 | protocol == UAC_VERSION_1 && | ||
926 | le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize) == | ||
657 | fp->maxpacksize * 2) | 927 | fp->maxpacksize * 2) |
658 | continue; | 928 | continue; |
929 | } | ||
659 | 930 | ||
660 | fp = kzalloc(sizeof(*fp), GFP_KERNEL); | 931 | fp = kzalloc(sizeof(*fp), GFP_KERNEL); |
661 | if (!fp) | 932 | if (!fp) |
@@ -678,48 +949,42 @@ int snd_usb_parse_audio_interface(struct snd_usb_audio *chip, int iface_no) | |||
678 | INIT_LIST_HEAD(&fp->list); | 949 | INIT_LIST_HEAD(&fp->list); |
679 | 950 | ||
680 | /* some quirks for attributes here */ | 951 | /* some quirks for attributes here */ |
681 | 952 | snd_usb_audioformat_attributes_quirk(chip, fp, stream); | |
682 | switch (chip->usb_id) { | ||
683 | case USB_ID(0x0a92, 0x0053): /* AudioTrak Optoplay */ | ||
684 | /* Optoplay sets the sample rate attribute although | ||
685 | * it seems not supporting it in fact. | ||
686 | */ | ||
687 | fp->attributes &= ~UAC_EP_CS_ATTR_SAMPLE_RATE; | ||
688 | break; | ||
689 | case USB_ID(0x041e, 0x3020): /* Creative SB Audigy 2 NX */ | ||
690 | case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */ | ||
691 | /* doesn't set the sample rate attribute, but supports it */ | ||
692 | fp->attributes |= UAC_EP_CS_ATTR_SAMPLE_RATE; | ||
693 | break; | ||
694 | case USB_ID(0x0763, 0x2001): /* M-Audio Quattro USB */ | ||
695 | case USB_ID(0x0763, 0x2012): /* M-Audio Fast Track Pro USB */ | ||
696 | case USB_ID(0x047f, 0x0ca1): /* plantronics headset */ | ||
697 | case USB_ID(0x077d, 0x07af): /* Griffin iMic (note that there is | ||
698 | an older model 77d:223) */ | ||
699 | /* | ||
700 | * plantronics headset and Griffin iMic have set adaptive-in | ||
701 | * although it's really not... | ||
702 | */ | ||
703 | fp->ep_attr &= ~USB_ENDPOINT_SYNCTYPE; | ||
704 | if (stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
705 | fp->ep_attr |= USB_ENDPOINT_SYNC_ADAPTIVE; | ||
706 | else | ||
707 | fp->ep_attr |= USB_ENDPOINT_SYNC_SYNC; | ||
708 | break; | ||
709 | } | ||
710 | 953 | ||
711 | /* ok, let's parse further... */ | 954 | /* ok, let's parse further... */ |
712 | if (snd_usb_parse_audio_format(chip, fp, format, fmt, stream) < 0) { | 955 | if (protocol == UAC_VERSION_1 || protocol == UAC_VERSION_2) { |
713 | kfree(fp->rate_table); | 956 | if (snd_usb_parse_audio_format(chip, fp, format, |
714 | kfree(fp); | 957 | fmt, stream) < 0) { |
715 | fp = NULL; | 958 | kfree(fp->rate_table); |
716 | continue; | 959 | kfree(fp); |
960 | fp = NULL; | ||
961 | continue; | ||
962 | } | ||
963 | } else { | ||
964 | struct uac3_as_header_descriptor *as; | ||
965 | |||
966 | as = snd_usb_find_csint_desc(alts->extra, | ||
967 | alts->extralen, | ||
968 | NULL, UAC_AS_GENERAL); | ||
969 | |||
970 | if (snd_usb_parse_audio_format_v3(chip, fp, as, | ||
971 | stream) < 0) { | ||
972 | kfree(fp->rate_table); | ||
973 | kfree(fp); | ||
974 | fp = NULL; | ||
975 | continue; | ||
976 | } | ||
717 | } | 977 | } |
718 | 978 | ||
719 | /* Create chmap */ | 979 | /* Create chmap */ |
720 | if (fp->channels != num_channels) | 980 | if (fp->channels != num_channels) |
721 | chconfig = 0; | 981 | chconfig = 0; |
722 | fp->chmap = convert_chmap(fp->channels, chconfig, protocol); | 982 | |
983 | if (protocol == UAC_VERSION_3) | ||
984 | fp->chmap = chmap_v3; | ||
985 | else | ||
986 | fp->chmap = convert_chmap(fp->channels, chconfig, | ||
987 | protocol); | ||
723 | 988 | ||
724 | dev_dbg(&dev->dev, "%u:%d: add audio endpoint %#x\n", iface_no, altno, fp->endpoint); | 989 | dev_dbg(&dev->dev, "%u:%d: add audio endpoint %#x\n", iface_no, altno, fp->endpoint); |
725 | err = snd_usb_add_audio_stream(chip, stream, fp); | 990 | err = snd_usb_add_audio_stream(chip, stream, fp); |