diff options
author | Daniel Mack <daniel@caiaq.de> | 2010-02-22 17:49:11 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2010-02-23 02:40:24 -0500 |
commit | 53ee98fe8ac77d00bacc1c814d450d83cbd193d4 (patch) | |
tree | c7f454b89c1032fe964b847048598c0071d88b1d /sound | |
parent | 8fee4aff8c89c229593b76a6ab172a9cad24b412 (diff) |
ALSA: usbaudio: implement basic set of class v2.0 parser
This adds a number of parsers for audio class v2.0. In particular, the
following internals are different and now handled by the code:
* the number of streaming interfaces is now reported by an interface
association descriptor. The old approach using a proprietary
descriptor is deprecated.
* The number of channels per interface is now stored in the AS_GENERAL
descriptor (used to be part of the FORMAT_TYPE descriptor).
* The list of supported sample rates is no longer stored in a variable
length appendix of the format_type descriptor but is retrieved from
the device using a class specific GET_RANGE command.
* Supported sample formats are now reported as 32bit bitmap rather than
a fixed value. For now, this is worked around by choosing just one of
them.
* A devices needs to have at least one CLOCK_SOURCE descriptor which
denotes a clockID that is needed im the class request command.
* Many descriptors (format_type, ...) have changed their layout. Handle
this by casting the descriptors to the appropriate structs.
Signed-off-by: Daniel Mack <daniel@caiaq.de>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-rw-r--r-- | sound/usb/usbaudio.c | 352 | ||||
-rw-r--r-- | sound/usb/usbaudio.h | 3 |
2 files changed, 292 insertions, 63 deletions
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c index f833dea60180..411a6cf43c21 100644 --- a/sound/usb/usbaudio.c +++ b/sound/usb/usbaudio.c | |||
@@ -2422,17 +2422,53 @@ static int is_big_endian_format(struct snd_usb_audio *chip, struct audioformat * | |||
2422 | * @format: the format tag (wFormatTag) | 2422 | * @format: the format tag (wFormatTag) |
2423 | * @fmt: the format type descriptor | 2423 | * @fmt: the format type descriptor |
2424 | */ | 2424 | */ |
2425 | static int parse_audio_format_i_type(struct snd_usb_audio *chip, struct audioformat *fp, | 2425 | static int parse_audio_format_i_type(struct snd_usb_audio *chip, |
2426 | int format, void *fmt_raw) | 2426 | struct audioformat *fp, |
2427 | int format, void *_fmt, | ||
2428 | int protocol) | ||
2427 | { | 2429 | { |
2428 | int pcm_format; | 2430 | int pcm_format, i; |
2429 | int sample_width, sample_bytes; | 2431 | int sample_width, sample_bytes; |
2430 | struct uac_format_type_i_discrete_descriptor *fmt = fmt_raw; | 2432 | |
2433 | switch (protocol) { | ||
2434 | case UAC_VERSION_1: { | ||
2435 | struct uac_format_type_i_discrete_descriptor *fmt = _fmt; | ||
2436 | sample_width = fmt->bBitResolution; | ||
2437 | sample_bytes = fmt->bSubframeSize; | ||
2438 | break; | ||
2439 | } | ||
2440 | |||
2441 | case UAC_VERSION_2: { | ||
2442 | struct uac_format_type_i_ext_descriptor *fmt = _fmt; | ||
2443 | sample_width = fmt->bBitResolution; | ||
2444 | sample_bytes = fmt->bSubslotSize; | ||
2445 | |||
2446 | /* | ||
2447 | * FIXME | ||
2448 | * USB audio class v2 devices specify a bitmap of possible | ||
2449 | * audio formats rather than one fix value. For now, we just | ||
2450 | * pick one of them and report that as the only possible | ||
2451 | * value for this setting. | ||
2452 | * The bit allocation map is in fact compatible to the | ||
2453 | * wFormatTag of the v1 AS streaming descriptors, which is why | ||
2454 | * we can simply map the matrix. | ||
2455 | */ | ||
2456 | |||
2457 | for (i = 0; i < 5; i++) | ||
2458 | if (format & (1UL << i)) { | ||
2459 | format = i + 1; | ||
2460 | break; | ||
2461 | } | ||
2462 | |||
2463 | break; | ||
2464 | } | ||
2465 | |||
2466 | default: | ||
2467 | return -EINVAL; | ||
2468 | } | ||
2431 | 2469 | ||
2432 | /* FIXME: correct endianess and sign? */ | 2470 | /* FIXME: correct endianess and sign? */ |
2433 | pcm_format = -1; | 2471 | pcm_format = -1; |
2434 | sample_width = fmt->bBitResolution; | ||
2435 | sample_bytes = fmt->bSubframeSize; | ||
2436 | 2472 | ||
2437 | switch (format) { | 2473 | switch (format) { |
2438 | case 0: /* some devices don't define this correctly... */ | 2474 | case 0: /* some devices don't define this correctly... */ |
@@ -2446,6 +2482,7 @@ static int parse_audio_format_i_type(struct snd_usb_audio *chip, struct audiofor | |||
2446 | sample_width, sample_bytes); | 2482 | sample_width, sample_bytes); |
2447 | } | 2483 | } |
2448 | /* check the format byte size */ | 2484 | /* check the format byte size */ |
2485 | printk(" XXXXX SAMPLE BYTES %d\n", sample_bytes); | ||
2449 | switch (sample_bytes) { | 2486 | switch (sample_bytes) { |
2450 | case 1: | 2487 | case 1: |
2451 | pcm_format = SNDRV_PCM_FORMAT_S8; | 2488 | pcm_format = SNDRV_PCM_FORMAT_S8; |
@@ -2500,7 +2537,7 @@ static int parse_audio_format_i_type(struct snd_usb_audio *chip, struct audiofor | |||
2500 | 2537 | ||
2501 | /* | 2538 | /* |
2502 | * parse the format descriptor and stores the possible sample rates | 2539 | * parse the format descriptor and stores the possible sample rates |
2503 | * on the audioformat table. | 2540 | * on the audioformat table (audio class v1). |
2504 | * | 2541 | * |
2505 | * @dev: usb device | 2542 | * @dev: usb device |
2506 | * @fp: audioformat record | 2543 | * @fp: audioformat record |
@@ -2508,8 +2545,8 @@ static int parse_audio_format_i_type(struct snd_usb_audio *chip, struct audiofor | |||
2508 | * @offset: the start offset of descriptor pointing the rate type | 2545 | * @offset: the start offset of descriptor pointing the rate type |
2509 | * (7 for type I and II, 8 for type II) | 2546 | * (7 for type I and II, 8 for type II) |
2510 | */ | 2547 | */ |
2511 | static int parse_audio_format_rates(struct snd_usb_audio *chip, struct audioformat *fp, | 2548 | static int parse_audio_format_rates_v1(struct snd_usb_audio *chip, struct audioformat *fp, |
2512 | unsigned char *fmt, int offset) | 2549 | unsigned char *fmt, int offset) |
2513 | { | 2550 | { |
2514 | int nr_rates = fmt[offset]; | 2551 | int nr_rates = fmt[offset]; |
2515 | 2552 | ||
@@ -2565,13 +2602,85 @@ static int parse_audio_format_rates(struct snd_usb_audio *chip, struct audioform | |||
2565 | } | 2602 | } |
2566 | 2603 | ||
2567 | /* | 2604 | /* |
2605 | * parse the format descriptor and stores the possible sample rates | ||
2606 | * on the audioformat table (audio class v2). | ||
2607 | */ | ||
2608 | static int parse_audio_format_rates_v2(struct snd_usb_audio *chip, | ||
2609 | struct audioformat *fp, | ||
2610 | struct usb_host_interface *iface) | ||
2611 | { | ||
2612 | struct usb_device *dev = chip->dev; | ||
2613 | unsigned char tmp[2], *data; | ||
2614 | int i, nr_rates, data_size, ret = 0; | ||
2615 | |||
2616 | /* get the number of sample rates first by only fetching 2 bytes */ | ||
2617 | ret = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), CS_RANGE, | ||
2618 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, | ||
2619 | 0x0100, chip->clock_id << 8, tmp, sizeof(tmp), 1000); | ||
2620 | |||
2621 | if (ret < 0) { | ||
2622 | snd_printk(KERN_ERR "unable to retrieve number of sample rates\n"); | ||
2623 | goto err; | ||
2624 | } | ||
2625 | |||
2626 | nr_rates = (tmp[1] << 8) | tmp[0]; | ||
2627 | data_size = 2 + 12 * nr_rates; | ||
2628 | data = kzalloc(data_size, GFP_KERNEL); | ||
2629 | if (!data) { | ||
2630 | ret = -ENOMEM; | ||
2631 | goto err; | ||
2632 | } | ||
2633 | |||
2634 | /* now get the full information */ | ||
2635 | ret = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), CS_RANGE, | ||
2636 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, | ||
2637 | 0x0100, chip->clock_id << 8, data, data_size, 1000); | ||
2638 | |||
2639 | if (ret < 0) { | ||
2640 | snd_printk(KERN_ERR "unable to retrieve sample rate range\n"); | ||
2641 | ret = -EINVAL; | ||
2642 | goto err_free; | ||
2643 | } | ||
2644 | |||
2645 | fp->rate_table = kmalloc(sizeof(int) * nr_rates, GFP_KERNEL); | ||
2646 | if (!fp->rate_table) { | ||
2647 | ret = -ENOMEM; | ||
2648 | goto err_free; | ||
2649 | } | ||
2650 | |||
2651 | fp->nr_rates = 0; | ||
2652 | fp->rate_min = fp->rate_max = 0; | ||
2653 | |||
2654 | for (i = 0; i < nr_rates; i++) { | ||
2655 | int rate = combine_quad(&data[2 + 12 * i]); | ||
2656 | |||
2657 | fp->rate_table[fp->nr_rates] = rate; | ||
2658 | if (!fp->rate_min || rate < fp->rate_min) | ||
2659 | fp->rate_min = rate; | ||
2660 | if (!fp->rate_max || rate > fp->rate_max) | ||
2661 | fp->rate_max = rate; | ||
2662 | fp->rates |= snd_pcm_rate_to_rate_bit(rate); | ||
2663 | fp->nr_rates++; | ||
2664 | } | ||
2665 | |||
2666 | err_free: | ||
2667 | kfree(data); | ||
2668 | err: | ||
2669 | return ret; | ||
2670 | } | ||
2671 | |||
2672 | /* | ||
2568 | * parse the format type I and III descriptors | 2673 | * parse the format type I and III descriptors |
2569 | */ | 2674 | */ |
2570 | static int parse_audio_format_i(struct snd_usb_audio *chip, struct audioformat *fp, | 2675 | static int parse_audio_format_i(struct snd_usb_audio *chip, |
2571 | int format, void *fmt_raw) | 2676 | struct audioformat *fp, |
2677 | int format, void *_fmt, | ||
2678 | struct usb_host_interface *iface) | ||
2572 | { | 2679 | { |
2573 | int pcm_format; | 2680 | struct usb_interface_descriptor *altsd = get_iface_desc(iface); |
2574 | struct uac_format_type_i_discrete_descriptor *fmt = fmt_raw; | 2681 | struct uac_format_type_i_discrete_descriptor *fmt = _fmt; |
2682 | int protocol = altsd->bInterfaceProtocol; | ||
2683 | int pcm_format, ret; | ||
2575 | 2684 | ||
2576 | if (fmt->bFormatType == USB_FORMAT_TYPE_III) { | 2685 | if (fmt->bFormatType == USB_FORMAT_TYPE_III) { |
2577 | /* FIXME: the format type is really IECxxx | 2686 | /* FIXME: the format type is really IECxxx |
@@ -2591,30 +2700,49 @@ static int parse_audio_format_i(struct snd_usb_audio *chip, struct audioformat * | |||
2591 | pcm_format = SNDRV_PCM_FORMAT_S16_LE; | 2700 | pcm_format = SNDRV_PCM_FORMAT_S16_LE; |
2592 | } | 2701 | } |
2593 | } else { | 2702 | } else { |
2594 | pcm_format = parse_audio_format_i_type(chip, fp, format, fmt); | 2703 | pcm_format = parse_audio_format_i_type(chip, fp, format, fmt, protocol); |
2595 | if (pcm_format < 0) | 2704 | if (pcm_format < 0) |
2596 | return -1; | 2705 | return -1; |
2597 | } | 2706 | } |
2598 | 2707 | ||
2599 | fp->format = pcm_format; | 2708 | fp->format = pcm_format; |
2600 | fp->channels = fmt->bNrChannels; | 2709 | |
2710 | /* gather possible sample rates */ | ||
2711 | /* audio class v1 reports possible sample rates as part of the | ||
2712 | * proprietary class specific descriptor. | ||
2713 | * audio class v2 uses class specific EP0 range requests for that. | ||
2714 | */ | ||
2715 | switch (protocol) { | ||
2716 | case UAC_VERSION_1: | ||
2717 | fp->channels = fmt->bNrChannels; | ||
2718 | ret = parse_audio_format_rates_v1(chip, fp, _fmt, 7); | ||
2719 | break; | ||
2720 | case UAC_VERSION_2: | ||
2721 | /* fp->channels is already set in this case */ | ||
2722 | ret = parse_audio_format_rates_v2(chip, fp, iface); | ||
2723 | break; | ||
2724 | } | ||
2601 | 2725 | ||
2602 | if (fp->channels < 1) { | 2726 | if (fp->channels < 1) { |
2603 | snd_printk(KERN_ERR "%d:%u:%d : invalid channels %d\n", | 2727 | snd_printk(KERN_ERR "%d:%u:%d : invalid channels %d\n", |
2604 | chip->dev->devnum, fp->iface, fp->altsetting, fp->channels); | 2728 | chip->dev->devnum, fp->iface, fp->altsetting, fp->channels); |
2605 | return -1; | 2729 | return -1; |
2606 | } | 2730 | } |
2607 | return parse_audio_format_rates(chip, fp, fmt_raw, 7); | 2731 | |
2732 | return ret; | ||
2608 | } | 2733 | } |
2609 | 2734 | ||
2610 | /* | 2735 | /* |
2611 | * parse the format type II descriptor | 2736 | * parse the format type II descriptor |
2612 | */ | 2737 | */ |
2613 | static int parse_audio_format_ii(struct snd_usb_audio *chip, struct audioformat *fp, | 2738 | static int parse_audio_format_ii(struct snd_usb_audio *chip, |
2614 | int format, void *fmt_raw) | 2739 | struct audioformat *fp, |
2740 | int format, void *_fmt, | ||
2741 | struct usb_host_interface *iface) | ||
2615 | { | 2742 | { |
2616 | int brate, framesize; | 2743 | int brate, framesize, ret; |
2617 | struct uac_format_type_ii_discrete_descriptor *fmt = fmt_raw; | 2744 | struct usb_interface_descriptor *altsd = get_iface_desc(iface); |
2745 | int protocol = altsd->bInterfaceProtocol; | ||
2618 | 2746 | ||
2619 | switch (format) { | 2747 | switch (format) { |
2620 | case USB_AUDIO_FORMAT_AC3: | 2748 | case USB_AUDIO_FORMAT_AC3: |
@@ -2634,35 +2762,50 @@ static int parse_audio_format_ii(struct snd_usb_audio *chip, struct audioformat | |||
2634 | 2762 | ||
2635 | fp->channels = 1; | 2763 | fp->channels = 1; |
2636 | 2764 | ||
2637 | brate = le16_to_cpu(fmt->wMaxBitRate); | 2765 | switch (protocol) { |
2638 | framesize = le16_to_cpu(fmt->wSamplesPerFrame); | 2766 | case UAC_VERSION_1: { |
2639 | snd_printd(KERN_INFO "found format II with max.bitrate = %d, frame size=%d\n", brate, framesize); | 2767 | struct uac_format_type_ii_discrete_descriptor *fmt = _fmt; |
2640 | fp->frame_size = framesize; | 2768 | brate = le16_to_cpu(fmt->wMaxBitRate); |
2641 | return parse_audio_format_rates(chip, fp, fmt_raw, 8); /* fmt[8..] sample rates */ | 2769 | framesize = le16_to_cpu(fmt->wSamplesPerFrame); |
2770 | snd_printd(KERN_INFO "found format II with max.bitrate = %d, frame size=%d\n", brate, framesize); | ||
2771 | fp->frame_size = framesize; | ||
2772 | ret = parse_audio_format_rates_v1(chip, fp, _fmt, 8); /* fmt[8..] sample rates */ | ||
2773 | break; | ||
2774 | } | ||
2775 | case UAC_VERSION_2: { | ||
2776 | struct uac_format_type_ii_ext_descriptor *fmt = _fmt; | ||
2777 | brate = le16_to_cpu(fmt->wMaxBitRate); | ||
2778 | framesize = le16_to_cpu(fmt->wSamplesPerFrame); | ||
2779 | snd_printd(KERN_INFO "found format II with max.bitrate = %d, frame size=%d\n", brate, framesize); | ||
2780 | fp->frame_size = framesize; | ||
2781 | ret = parse_audio_format_rates_v2(chip, fp, iface); | ||
2782 | break; | ||
2783 | } | ||
2784 | } | ||
2785 | |||
2786 | return ret; | ||
2642 | } | 2787 | } |
2643 | 2788 | ||
2644 | static int parse_audio_format(struct snd_usb_audio *chip, struct audioformat *fp, | 2789 | static int parse_audio_format(struct snd_usb_audio *chip, struct audioformat *fp, |
2645 | int format, void *fmt_raw, int stream) | 2790 | int format, unsigned char *fmt, int stream, |
2791 | struct usb_host_interface *iface) | ||
2646 | { | 2792 | { |
2647 | int err; | 2793 | int err; |
2648 | /* we only parse the common header of all format types here, | ||
2649 | * so it is safe to take a type_i struct */ | ||
2650 | struct uac_format_type_i_discrete_descriptor *fmt = fmt_raw; | ||
2651 | 2794 | ||
2652 | switch (fmt->bFormatType) { | 2795 | switch (fmt[3]) { |
2653 | case USB_FORMAT_TYPE_I: | 2796 | case USB_FORMAT_TYPE_I: |
2654 | case USB_FORMAT_TYPE_III: | 2797 | case USB_FORMAT_TYPE_III: |
2655 | err = parse_audio_format_i(chip, fp, format, fmt); | 2798 | err = parse_audio_format_i(chip, fp, format, fmt, iface); |
2656 | break; | 2799 | break; |
2657 | case USB_FORMAT_TYPE_II: | 2800 | case USB_FORMAT_TYPE_II: |
2658 | err = parse_audio_format_ii(chip, fp, format, fmt); | 2801 | err = parse_audio_format_ii(chip, fp, format, fmt, iface); |
2659 | break; | 2802 | break; |
2660 | default: | 2803 | default: |
2661 | snd_printd(KERN_INFO "%d:%u:%d : format type %d is not supported yet\n", | 2804 | snd_printd(KERN_INFO "%d:%u:%d : format type %d is not supported yet\n", |
2662 | chip->dev->devnum, fp->iface, fp->altsetting, fmt->bFormatType); | 2805 | chip->dev->devnum, fp->iface, fp->altsetting, fmt[3]); |
2663 | return -1; | 2806 | return -1; |
2664 | } | 2807 | } |
2665 | fp->fmt_type = fmt->bFormatType; | 2808 | fp->fmt_type = fmt[3]; |
2666 | if (err < 0) | 2809 | if (err < 0) |
2667 | return err; | 2810 | return err; |
2668 | #if 1 | 2811 | #if 1 |
@@ -2673,7 +2816,7 @@ static int parse_audio_format(struct snd_usb_audio *chip, struct audioformat *fp | |||
2673 | if (chip->usb_id == USB_ID(0x041e, 0x3000) || | 2816 | if (chip->usb_id == USB_ID(0x041e, 0x3000) || |
2674 | chip->usb_id == USB_ID(0x041e, 0x3020) || | 2817 | chip->usb_id == USB_ID(0x041e, 0x3020) || |
2675 | chip->usb_id == USB_ID(0x041e, 0x3061)) { | 2818 | chip->usb_id == USB_ID(0x041e, 0x3061)) { |
2676 | if (fmt->bFormatType == USB_FORMAT_TYPE_I && | 2819 | if (fmt[3] == USB_FORMAT_TYPE_I && |
2677 | fp->rates != SNDRV_PCM_RATE_48000 && | 2820 | fp->rates != SNDRV_PCM_RATE_48000 && |
2678 | fp->rates != SNDRV_PCM_RATE_96000) | 2821 | fp->rates != SNDRV_PCM_RATE_96000) |
2679 | return -1; | 2822 | return -1; |
@@ -2702,10 +2845,10 @@ static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) | |||
2702 | struct usb_host_interface *alts; | 2845 | struct usb_host_interface *alts; |
2703 | struct usb_interface_descriptor *altsd; | 2846 | struct usb_interface_descriptor *altsd; |
2704 | int i, altno, err, stream; | 2847 | int i, altno, err, stream; |
2705 | int format; | 2848 | int format = 0, num_channels = 0; |
2706 | struct audioformat *fp = NULL; | 2849 | struct audioformat *fp = NULL; |
2707 | unsigned char *fmt, *csep; | 2850 | unsigned char *fmt, *csep; |
2708 | int num; | 2851 | int num, protocol; |
2709 | 2852 | ||
2710 | dev = chip->dev; | 2853 | dev = chip->dev; |
2711 | 2854 | ||
@@ -2722,10 +2865,9 @@ static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) | |||
2722 | num = 4; | 2865 | num = 4; |
2723 | 2866 | ||
2724 | for (i = 0; i < num; i++) { | 2867 | for (i = 0; i < num; i++) { |
2725 | struct uac_as_header_descriptor_v1 *as; | ||
2726 | |||
2727 | alts = &iface->altsetting[i]; | 2868 | alts = &iface->altsetting[i]; |
2728 | altsd = get_iface_desc(alts); | 2869 | altsd = get_iface_desc(alts); |
2870 | protocol = altsd->bInterfaceProtocol; | ||
2729 | /* skip invalid one */ | 2871 | /* skip invalid one */ |
2730 | if ((altsd->bInterfaceClass != USB_CLASS_AUDIO && | 2872 | if ((altsd->bInterfaceClass != USB_CLASS_AUDIO && |
2731 | altsd->bInterfaceClass != USB_CLASS_VENDOR_SPEC) || | 2873 | altsd->bInterfaceClass != USB_CLASS_VENDOR_SPEC) || |
@@ -2742,7 +2884,7 @@ static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) | |||
2742 | stream = (get_endpoint(alts, 0)->bEndpointAddress & USB_DIR_IN) ? | 2884 | stream = (get_endpoint(alts, 0)->bEndpointAddress & USB_DIR_IN) ? |
2743 | SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK; | 2885 | SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK; |
2744 | altno = altsd->bAlternateSetting; | 2886 | altno = altsd->bAlternateSetting; |
2745 | 2887 | ||
2746 | /* audiophile usb: skip altsets incompatible with device_setup | 2888 | /* audiophile usb: skip altsets incompatible with device_setup |
2747 | */ | 2889 | */ |
2748 | if (chip->usb_id == USB_ID(0x0763, 0x2003) && | 2890 | if (chip->usb_id == USB_ID(0x0763, 0x2003) && |
@@ -2750,21 +2892,54 @@ static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) | |||
2750 | continue; | 2892 | continue; |
2751 | 2893 | ||
2752 | /* get audio formats */ | 2894 | /* get audio formats */ |
2753 | as = snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, AS_GENERAL); | 2895 | switch (protocol) { |
2896 | case UAC_VERSION_1: { | ||
2897 | struct uac_as_header_descriptor_v1 *as = | ||
2898 | snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, AS_GENERAL); | ||
2899 | |||
2900 | if (!as) { | ||
2901 | snd_printk(KERN_ERR "%d:%u:%d : AS_GENERAL descriptor not found\n", | ||
2902 | dev->devnum, iface_no, altno); | ||
2903 | continue; | ||
2904 | } | ||
2754 | 2905 | ||
2755 | if (!as) { | 2906 | if (as->bLength < sizeof(*as)) { |
2756 | snd_printk(KERN_ERR "%d:%u:%d : AS_GENERAL descriptor not found\n", | 2907 | snd_printk(KERN_ERR "%d:%u:%d : invalid AS_GENERAL desc\n", |
2757 | dev->devnum, iface_no, altno); | 2908 | dev->devnum, iface_no, altno); |
2758 | continue; | 2909 | continue; |
2910 | } | ||
2911 | |||
2912 | format = le16_to_cpu(as->wFormatTag); /* remember the format value */ | ||
2913 | break; | ||
2759 | } | 2914 | } |
2760 | 2915 | ||
2761 | if (as->bLength < sizeof(*as)) { | 2916 | case UAC_VERSION_2: { |
2762 | snd_printk(KERN_ERR "%d:%u:%d : invalid AS_GENERAL desc\n", | 2917 | struct uac_as_header_descriptor_v2 *as = |
2763 | dev->devnum, iface_no, altno); | 2918 | snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, AS_GENERAL); |
2764 | continue; | 2919 | |
2920 | if (!as) { | ||
2921 | snd_printk(KERN_ERR "%d:%u:%d : AS_GENERAL descriptor not found\n", | ||
2922 | dev->devnum, iface_no, altno); | ||
2923 | continue; | ||
2924 | } | ||
2925 | |||
2926 | if (as->bLength < sizeof(*as)) { | ||
2927 | snd_printk(KERN_ERR "%d:%u:%d : invalid AS_GENERAL desc\n", | ||
2928 | dev->devnum, iface_no, altno); | ||
2929 | continue; | ||
2930 | } | ||
2931 | |||
2932 | num_channels = as->bNrChannels; | ||
2933 | format = le32_to_cpu(as->bmFormats); | ||
2934 | |||
2935 | break; | ||
2765 | } | 2936 | } |
2766 | 2937 | ||
2767 | format = le16_to_cpu(as->wFormatTag); /* remember the format value */ | 2938 | default: |
2939 | snd_printk(KERN_ERR "%d:%u:%d : unknown interface protocol %04x\n", | ||
2940 | dev->devnum, iface_no, altno, protocol); | ||
2941 | continue; | ||
2942 | } | ||
2768 | 2943 | ||
2769 | /* get format type */ | 2944 | /* get format type */ |
2770 | fmt = snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, FORMAT_TYPE); | 2945 | fmt = snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, FORMAT_TYPE); |
@@ -2773,7 +2948,8 @@ static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) | |||
2773 | dev->devnum, iface_no, altno); | 2948 | dev->devnum, iface_no, altno); |
2774 | continue; | 2949 | continue; |
2775 | } | 2950 | } |
2776 | if (fmt[0] < 8) { | 2951 | if (((protocol == UAC_VERSION_1) && (fmt[0] < 8)) || |
2952 | ((protocol == UAC_VERSION_2) && (fmt[0] != 6))) { | ||
2777 | snd_printk(KERN_ERR "%d:%u:%d : invalid FORMAT_TYPE desc\n", | 2953 | snd_printk(KERN_ERR "%d:%u:%d : invalid FORMAT_TYPE desc\n", |
2778 | dev->devnum, iface_no, altno); | 2954 | dev->devnum, iface_no, altno); |
2779 | continue; | 2955 | continue; |
@@ -2787,6 +2963,7 @@ static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) | |||
2787 | if (fmt[4] == 1 && fmt[5] == 2 && altno == 2 && num == 3 && | 2963 | if (fmt[4] == 1 && fmt[5] == 2 && altno == 2 && num == 3 && |
2788 | fp && fp->altsetting == 1 && fp->channels == 1 && | 2964 | fp && fp->altsetting == 1 && fp->channels == 1 && |
2789 | fp->format == SNDRV_PCM_FORMAT_S16_LE && | 2965 | fp->format == SNDRV_PCM_FORMAT_S16_LE && |
2966 | protocol == UAC_VERSION_1 && | ||
2790 | le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize) == | 2967 | le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize) == |
2791 | fp->maxpacksize * 2) | 2968 | fp->maxpacksize * 2) |
2792 | continue; | 2969 | continue; |
@@ -2815,6 +2992,8 @@ static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) | |||
2815 | fp->ep_attr = get_endpoint(alts, 0)->bmAttributes; | 2992 | fp->ep_attr = get_endpoint(alts, 0)->bmAttributes; |
2816 | fp->datainterval = parse_datainterval(chip, alts); | 2993 | fp->datainterval = parse_datainterval(chip, alts); |
2817 | fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize); | 2994 | fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize); |
2995 | /* num_channels is only set for v2 interfaces */ | ||
2996 | fp->channels = num_channels; | ||
2818 | if (snd_usb_get_speed(dev) == USB_SPEED_HIGH) | 2997 | if (snd_usb_get_speed(dev) == USB_SPEED_HIGH) |
2819 | fp->maxpacksize = (((fp->maxpacksize >> 11) & 3) + 1) | 2998 | fp->maxpacksize = (((fp->maxpacksize >> 11) & 3) + 1) |
2820 | * (fp->maxpacksize & 0x7ff); | 2999 | * (fp->maxpacksize & 0x7ff); |
@@ -2850,7 +3029,7 @@ static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) | |||
2850 | } | 3029 | } |
2851 | 3030 | ||
2852 | /* ok, let's parse further... */ | 3031 | /* ok, let's parse further... */ |
2853 | if (parse_audio_format(chip, fp, format, fmt, stream) < 0) { | 3032 | if (parse_audio_format(chip, fp, format, fmt, stream, alts) < 0) { |
2854 | kfree(fp->rate_table); | 3033 | kfree(fp->rate_table); |
2855 | kfree(fp); | 3034 | kfree(fp); |
2856 | continue; | 3035 | continue; |
@@ -2958,35 +3137,82 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif) | |||
2958 | { | 3137 | { |
2959 | struct usb_device *dev = chip->dev; | 3138 | struct usb_device *dev = chip->dev; |
2960 | struct usb_host_interface *host_iface; | 3139 | struct usb_host_interface *host_iface; |
2961 | struct uac_ac_header_descriptor_v1 *h1; | 3140 | struct usb_interface_descriptor *altsd; |
2962 | void *control_header; | 3141 | void *control_header; |
2963 | int i; | 3142 | int i, protocol; |
2964 | 3143 | ||
2965 | /* find audiocontrol interface */ | 3144 | /* find audiocontrol interface */ |
2966 | host_iface = &usb_ifnum_to_if(dev, ctrlif)->altsetting[0]; | 3145 | host_iface = &usb_ifnum_to_if(dev, ctrlif)->altsetting[0]; |
2967 | control_header = snd_usb_find_csint_desc(host_iface->extra, | 3146 | control_header = snd_usb_find_csint_desc(host_iface->extra, |
2968 | host_iface->extralen, | 3147 | host_iface->extralen, |
2969 | NULL, HEADER); | 3148 | NULL, HEADER); |
3149 | altsd = get_iface_desc(host_iface); | ||
3150 | protocol = altsd->bInterfaceProtocol; | ||
2970 | 3151 | ||
2971 | if (!control_header) { | 3152 | if (!control_header) { |
2972 | snd_printk(KERN_ERR "cannot find HEADER\n"); | 3153 | snd_printk(KERN_ERR "cannot find HEADER\n"); |
2973 | return -EINVAL; | 3154 | return -EINVAL; |
2974 | } | 3155 | } |
2975 | 3156 | ||
2976 | h1 = control_header; | 3157 | switch (protocol) { |
3158 | case UAC_VERSION_1: { | ||
3159 | struct uac_ac_header_descriptor_v1 *h1 = control_header; | ||
2977 | 3160 | ||
2978 | if (!h1->bInCollection) { | 3161 | if (!h1->bInCollection) { |
2979 | snd_printk(KERN_INFO "skipping empty audio interface (v1)\n"); | 3162 | snd_printk(KERN_INFO "skipping empty audio interface (v1)\n"); |
2980 | return -EINVAL; | 3163 | return -EINVAL; |
3164 | } | ||
3165 | |||
3166 | if (h1->bLength < sizeof(*h1) + h1->bInCollection) { | ||
3167 | snd_printk(KERN_ERR "invalid HEADER (v1)\n"); | ||
3168 | return -EINVAL; | ||
3169 | } | ||
3170 | |||
3171 | for (i = 0; i < h1->bInCollection; i++) | ||
3172 | snd_usb_create_stream(chip, ctrlif, h1->baInterfaceNr[i]); | ||
3173 | |||
3174 | break; | ||
2981 | } | 3175 | } |
2982 | 3176 | ||
2983 | if (h1->bLength < sizeof(*h1) + h1->bInCollection) { | 3177 | case UAC_VERSION_2: { |
2984 | snd_printk(KERN_ERR "invalid HEADER (v1)\n"); | 3178 | struct uac_clock_source_descriptor *cs; |
2985 | return -EINVAL; | 3179 | struct usb_interface_assoc_descriptor *assoc = |
3180 | usb_ifnum_to_if(dev, ctrlif)->intf_assoc; | ||
3181 | |||
3182 | if (!assoc) { | ||
3183 | snd_printk(KERN_ERR "Audio class v2 interfaces need an interface association\n"); | ||
3184 | return -EINVAL; | ||
3185 | } | ||
3186 | |||
3187 | /* FIXME: for now, we expect there is at least one clock source | ||
3188 | * descriptor and we always take the first one. | ||
3189 | * We should properly support devices with multiple clock sources, | ||
3190 | * clock selectors and sample rate conversion units. */ | ||
3191 | |||
3192 | cs = snd_usb_find_csint_desc(host_iface->extra, host_iface->extralen, | ||
3193 | NULL, CLOCK_SOURCE); | ||
3194 | |||
3195 | if (!cs) { | ||
3196 | snd_printk(KERN_ERR "CLOCK_SOURCE descriptor not found\n"); | ||
3197 | return -EINVAL; | ||
3198 | } | ||
3199 | |||
3200 | chip->clock_id = cs->bClockID; | ||
3201 | |||
3202 | for (i = 0; i < assoc->bInterfaceCount; i++) { | ||
3203 | int intf = assoc->bFirstInterface + i; | ||
3204 | |||
3205 | if (intf != ctrlif) | ||
3206 | snd_usb_create_stream(chip, ctrlif, intf); | ||
3207 | } | ||
3208 | |||
3209 | break; | ||
2986 | } | 3210 | } |
2987 | 3211 | ||
2988 | for (i = 0; i < h1->bInCollection; i++) | 3212 | default: |
2989 | snd_usb_create_stream(chip, ctrlif, h1->baInterfaceNr[i]); | 3213 | snd_printk(KERN_ERR "unknown protocol version 0x%02x\n", protocol); |
3214 | return -EINVAL; | ||
3215 | } | ||
2990 | 3216 | ||
2991 | return 0; | 3217 | return 0; |
2992 | } | 3218 | } |
diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h index 4f482939e8e8..26daf68631eb 100644 --- a/sound/usb/usbaudio.h +++ b/sound/usb/usbaudio.h | |||
@@ -142,6 +142,9 @@ struct snd_usb_audio { | |||
142 | int num_interfaces; | 142 | int num_interfaces; |
143 | int num_suspended_intf; | 143 | int num_suspended_intf; |
144 | 144 | ||
145 | /* for audio class v2 */ | ||
146 | int clock_id; | ||
147 | |||
145 | struct list_head pcm_list; /* list of pcm streams */ | 148 | struct list_head pcm_list; /* list of pcm streams */ |
146 | int pcm_devs; | 149 | int pcm_devs; |
147 | 150 | ||