[alsa-devel] usbaudio: Support for USB audio v2.0 devices
Hi,
I've been working on support for USB devices compliant to audio class v2.0 and would like to share what I got.
First problem is that they literally changed every single descriptor type by adding or removing fields or changing their width, respectively. Even worse, some enum values were dropped and reassigned so their numerical value has a different meaning now.
My first step was to clean up most of the existing descriptor parsers by moving away from anonymous byte array access to real structs so we can see which fields we're actually dereferencing.
In a second step, I added definitions for the replacement descriptors and use them at appropriate places. The bInterfaceProtocol field must always be set correctly of course, otherwise we'll parse garbage.
Other things that have changed from v1.0 to v2.0 are:
* The number of streaming interfaces is now reported by a standard interface association descriptor. The old approach using a proprietary descriptor extension 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 as a fixed value. For now, this is worked around by choosing just one of them. Eventually, the code should propagate the full ability of the device.
* A devices needs to have at least one CLOCK_SOURCE descriptor which denotes a clockID that is needed as argument to the class request command. If can have more than one though and the host driver is in charge to choose the right one. There are also new types for clock selectors and sample rate converters that a device might report. This is all unsupported at the moment. We only parse the first CLOCK_SOURCE and take this one.
* Many descriptors (format_type, ...) have changed their layout. Handle this by casting the descriptors to the appropriate structs.
With the following patches applied, a v2.0 device is recognized and reported as ALSA device. I can even hear at least some kind of music, but the sample rate setting does not yet seem to be correct.
Also, the existing mixer code does not work at all for v2.0 devices. This will be quite some work to support that and I fear the whole thing must be reimplemented for v2.0 specifically. For now, I worked around that by not parsing them at all but bailing out very early.
However, I would like to make sure the changes I made so far won't cause any regression for v1.0 devices, and so it would be good to see them applied as a preliminary support. I'll continue working on this and send more updates along.
Let me know what you think.
Thanks, Daniel
In preparation of support for v2.0 audio class, introduce structs to describe the fields that are actually parsed by the descriptor decoders.
Also, factor out code from usb_create_streams(). This makes it easier to adopt the new iteration logic needed for v2.0.
Signed-off-by: Daniel Mack daniel@caiaq.de --- sound/usb/usbaudio.c | 194 ++++++++++++++++++++++++++++++-------------------- sound/usb/usbaudio.h | 83 +++++++++++++++++++++ sound/usb/usbmixer.c | 37 +++++----- 3 files changed, 218 insertions(+), 96 deletions(-)
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c index 4208b44..8925879 100644 --- a/sound/usb/usbaudio.c +++ b/sound/usb/usbaudio.c @@ -2421,15 +2421,17 @@ static int is_big_endian_format(struct snd_usb_audio *chip, struct audioformat * * @fmt: the format type descriptor */ static int parse_audio_format_i_type(struct snd_usb_audio *chip, struct audioformat *fp, - int format, unsigned char *fmt) + int format, void *fmt_raw) { int pcm_format; int sample_width, sample_bytes; + struct usb_format_type_i *fmt = fmt_raw;
/* FIXME: correct endianess and sign? */ pcm_format = -1; - sample_width = fmt[6]; - sample_bytes = fmt[5]; + sample_width = fmt->bBitResolution; + sample_bytes = fmt->bSubframeSize; + switch (format) { case 0: /* some devices don't define this correctly... */ snd_printdd(KERN_INFO "%d:%u:%d : format type 0 is detected, processed as PCM\n", @@ -2442,7 +2444,7 @@ static int parse_audio_format_i_type(struct snd_usb_audio *chip, struct audiofor sample_width, sample_bytes); } /* check the format byte size */ - switch (fmt[5]) { + switch (sample_bytes) { case 1: pcm_format = SNDRV_PCM_FORMAT_S8; break; @@ -2463,8 +2465,8 @@ static int parse_audio_format_i_type(struct snd_usb_audio *chip, struct audiofor break; default: snd_printk(KERN_INFO "%d:%u:%d : unsupported sample bitwidth %d in %d bytes\n", - chip->dev->devnum, fp->iface, - fp->altsetting, sample_width, sample_bytes); + chip->dev->devnum, fp->iface, fp->altsetting, + sample_width, sample_bytes); break; } break; @@ -2564,11 +2566,12 @@ static int parse_audio_format_rates(struct snd_usb_audio *chip, struct audioform * parse the format type I and III descriptors */ static int parse_audio_format_i(struct snd_usb_audio *chip, struct audioformat *fp, - int format, unsigned char *fmt) + int format, void *fmt_raw) { int pcm_format; + struct usb_format_type_i *fmt = fmt_raw;
- if (fmt[3] == USB_FORMAT_TYPE_III) { + if (fmt->bFormatType == USB_FORMAT_TYPE_III) { /* FIXME: the format type is really IECxxx * but we give normal PCM format to get the existing * apps working... @@ -2590,23 +2593,27 @@ static int parse_audio_format_i(struct snd_usb_audio *chip, struct audioformat * if (pcm_format < 0) return -1; } + fp->format = pcm_format; - fp->channels = fmt[4]; + fp->channels = fmt->bNrChannels; + if (fp->channels < 1) { snd_printk(KERN_ERR "%d:%u:%d : invalid channels %d\n", chip->dev->devnum, fp->iface, fp->altsetting, fp->channels); return -1; } - return parse_audio_format_rates(chip, fp, fmt, 7); + return parse_audio_format_rates(chip, fp, fmt_raw, 7); }
/* - * prase the format type II descriptor + * parse the format type II descriptor */ static int parse_audio_format_ii(struct snd_usb_audio *chip, struct audioformat *fp, - int format, unsigned char *fmt) + int format, void *fmt_raw) { int brate, framesize; + struct usb_format_type_ii *fmt = fmt_raw; + switch (format) { case USB_AUDIO_FORMAT_AC3: /* FIXME: there is no AC3 format defined yet */ @@ -2622,20 +2629,25 @@ static int parse_audio_format_ii(struct snd_usb_audio *chip, struct audioformat fp->format = SNDRV_PCM_FORMAT_MPEG; break; } + fp->channels = 1; - brate = combine_word(&fmt[4]); /* fmt[4,5] : wMaxBitRate (in kbps) */ - framesize = combine_word(&fmt[6]); /* fmt[6,7]: wSamplesPerFrame */ + + brate = le16_to_cpu(fmt->wMaxBitRate); + framesize = le16_to_cpu(fmt->wSamplesPerFrame); snd_printd(KERN_INFO "found format II with max.bitrate = %d, frame size=%d\n", brate, framesize); fp->frame_size = framesize; - return parse_audio_format_rates(chip, fp, fmt, 8); /* fmt[8..] sample rates */ + return parse_audio_format_rates(chip, fp, fmt_raw, 8); /* fmt[8..] sample rates */ }
static int parse_audio_format(struct snd_usb_audio *chip, struct audioformat *fp, - int format, unsigned char *fmt, int stream) + int format, void *fmt_raw, int stream) { int err; + /* we only parse the common header of all format types here, + * so it is safe to take a type_i struct */ + struct usb_format_type_i *fmt = fmt_raw;
- switch (fmt[3]) { + switch (fmt->bFormatType) { case USB_FORMAT_TYPE_I: case USB_FORMAT_TYPE_III: err = parse_audio_format_i(chip, fp, format, fmt); @@ -2645,10 +2657,10 @@ static int parse_audio_format(struct snd_usb_audio *chip, struct audioformat *fp break; default: snd_printd(KERN_INFO "%d:%u:%d : format type %d is not supported yet\n", - chip->dev->devnum, fp->iface, fp->altsetting, fmt[3]); + chip->dev->devnum, fp->iface, fp->altsetting, fmt->bFormatType); return -1; } - fp->fmt_type = fmt[3]; + fp->fmt_type = fmt->bFormatType; if (err < 0) return err; #if 1 @@ -2659,7 +2671,7 @@ static int parse_audio_format(struct snd_usb_audio *chip, struct audioformat *fp if (chip->usb_id == USB_ID(0x041e, 0x3000) || chip->usb_id == USB_ID(0x041e, 0x3020) || chip->usb_id == USB_ID(0x041e, 0x3061)) { - if (fmt[3] == USB_FORMAT_TYPE_I && + if (fmt->bFormatType == USB_FORMAT_TYPE_I && fp->rates != SNDRV_PCM_RATE_48000 && fp->rates != SNDRV_PCM_RATE_96000) return -1; @@ -2708,6 +2720,8 @@ static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) num = 4;
for (i = 0; i < num; i++) { + struct usb_as_interface_v1 *as; + alts = &iface->altsetting[i]; altsd = get_iface_desc(alts); /* skip invalid one */ @@ -2734,20 +2748,21 @@ static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) continue;
/* get audio formats */ - fmt = snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, AS_GENERAL); - if (!fmt) { + as = snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, AS_GENERAL); + + if (!as) { snd_printk(KERN_ERR "%d:%u:%d : AS_GENERAL descriptor not found\n", dev->devnum, iface_no, altno); continue; }
- if (fmt[0] < 7) { + if (as->bLength < sizeof(*as)) { snd_printk(KERN_ERR "%d:%u:%d : invalid AS_GENERAL desc\n", dev->devnum, iface_no, altno); continue; }
- format = (fmt[6] << 8) | fmt[5]; /* remember the format value */ + format = le16_to_cpu(as->wFormatTag); /* remember the format value */
/* get format type */ fmt = snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, FORMAT_TYPE); @@ -2875,6 +2890,65 @@ static void snd_usb_stream_disconnect(struct list_head *head) } }
+static int snd_usb_create_stream(struct snd_usb_audio *chip, int ctrlif, int interface) +{ + struct usb_device *dev = chip->dev; + struct usb_host_interface *alts; + struct usb_interface_descriptor *altsd; + struct usb_interface *iface = usb_ifnum_to_if(dev, interface); + + if (!iface) { + snd_printk(KERN_ERR "%d:%u:%d : does not exist\n", + dev->devnum, ctrlif, interface); + return -EINVAL; + } + + if (usb_interface_claimed(iface)) { + snd_printdd(KERN_INFO "%d:%d:%d: skipping, already claimed\n", + dev->devnum, ctrlif, interface); + return -EINVAL; + } + + alts = &iface->altsetting[0]; + altsd = get_iface_desc(alts); + if ((altsd->bInterfaceClass == USB_CLASS_AUDIO || + altsd->bInterfaceClass == USB_CLASS_VENDOR_SPEC) && + altsd->bInterfaceSubClass == USB_SUBCLASS_MIDI_STREAMING) { + int err = snd_usbmidi_create(chip->card, iface, + &chip->midi_list, NULL); + if (err < 0) { + snd_printk(KERN_ERR "%d:%u:%d: cannot create sequencer device\n", + dev->devnum, ctrlif, interface); + return -EINVAL; + } + usb_driver_claim_interface(&usb_audio_driver, iface, (void *)-1L); + + return 0; + } + + if ((altsd->bInterfaceClass != USB_CLASS_AUDIO && + altsd->bInterfaceClass != USB_CLASS_VENDOR_SPEC) || + altsd->bInterfaceSubClass != USB_SUBCLASS_AUDIO_STREAMING) { + snd_printdd(KERN_ERR "%d:%u:%d: skipping non-supported interface %d\n", + dev->devnum, ctrlif, interface, altsd->bInterfaceClass); + /* skip non-supported classes */ + return -EINVAL; + } + + if (snd_usb_get_speed(dev) == USB_SPEED_LOW) { + snd_printk(KERN_ERR "low speed audio streaming not supported\n"); + return -EINVAL; + } + + if (! parse_audio_endpoints(chip, interface)) { + usb_set_interface(dev, interface, 0); /* reset the current interface */ + usb_driver_claim_interface(&usb_audio_driver, iface, (void *)-1L); + return -EINVAL; + } + + return 0; +} + /* * parse audio control descriptor and create pcm/midi streams */ @@ -2882,69 +2956,36 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif) { struct usb_device *dev = chip->dev; struct usb_host_interface *host_iface; - struct usb_interface *iface; - unsigned char *p1; - int i, j; + struct usb_ac_intf_header_v1 *h1; + void *control_header; + int i;
/* find audiocontrol interface */ host_iface = &usb_ifnum_to_if(dev, ctrlif)->altsetting[0]; - if (!(p1 = snd_usb_find_csint_desc(host_iface->extra, host_iface->extralen, NULL, HEADER))) { + control_header = snd_usb_find_csint_desc(host_iface->extra, + host_iface->extralen, + NULL, HEADER); + + if (!control_header) { snd_printk(KERN_ERR "cannot find HEADER\n"); return -EINVAL; } - if (! p1[7] || p1[0] < 8 + p1[7]) { - snd_printk(KERN_ERR "invalid HEADER\n"); + + h1 = control_header; + + if (!h1->bInCollection) { + snd_printk(KERN_INFO "skipping empty audio interface (v1)\n"); return -EINVAL; }
- /* - * parse all USB audio streaming interfaces - */ - for (i = 0; i < p1[7]; i++) { - struct usb_host_interface *alts; - struct usb_interface_descriptor *altsd; - j = p1[8 + i]; - iface = usb_ifnum_to_if(dev, j); - if (!iface) { - snd_printk(KERN_ERR "%d:%u:%d : does not exist\n", - dev->devnum, ctrlif, j); - continue; - } - if (usb_interface_claimed(iface)) { - snd_printdd(KERN_INFO "%d:%d:%d: skipping, already claimed\n", dev->devnum, ctrlif, j); - continue; - } - alts = &iface->altsetting[0]; - altsd = get_iface_desc(alts); - if ((altsd->bInterfaceClass == USB_CLASS_AUDIO || - altsd->bInterfaceClass == USB_CLASS_VENDOR_SPEC) && - altsd->bInterfaceSubClass == USB_SUBCLASS_MIDI_STREAMING) { - int err = snd_usbmidi_create(chip->card, iface, - &chip->midi_list, NULL); - if (err < 0) { - snd_printk(KERN_ERR "%d:%u:%d: cannot create sequencer device\n", dev->devnum, ctrlif, j); - continue; - } - usb_driver_claim_interface(&usb_audio_driver, iface, (void *)-1L); - continue; - } - if ((altsd->bInterfaceClass != USB_CLASS_AUDIO && - altsd->bInterfaceClass != USB_CLASS_VENDOR_SPEC) || - altsd->bInterfaceSubClass != USB_SUBCLASS_AUDIO_STREAMING) { - snd_printdd(KERN_ERR "%d:%u:%d: skipping non-supported interface %d\n", dev->devnum, ctrlif, j, altsd->bInterfaceClass); - /* skip non-supported classes */ - continue; - } - if (snd_usb_get_speed(dev) == USB_SPEED_LOW) { - snd_printk(KERN_ERR "low speed audio streaming not supported\n"); - continue; - } - if (! parse_audio_endpoints(chip, j)) { - usb_set_interface(dev, j, 0); /* reset the current interface */ - usb_driver_claim_interface(&usb_audio_driver, iface, (void *)-1L); - } + if (h1->bLength < sizeof(*h1) + h1->bInCollection) { + snd_printk(KERN_ERR "invalid HEADER (v1)\n"); + return -EINVAL; }
+ for (i = 0; i < h1->bInCollection; i++) + snd_usb_create_stream(chip, ctrlif, h1->baInterfaceNr[i]); + return 0; }
@@ -3581,7 +3622,6 @@ static void *snd_usb_audio_probe(struct usb_device *dev, ifnum = get_iface_desc(alts)->bInterfaceNumber; id = USB_ID(le16_to_cpu(dev->descriptor.idVendor), le16_to_cpu(dev->descriptor.idProduct)); - if (quirk && quirk->ifnum >= 0 && ifnum != quirk->ifnum) goto __err_val;
diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h index 9d8cea4..c466ccc 100644 --- a/sound/usb/usbaudio.h +++ b/sound/usb/usbaudio.h @@ -117,6 +117,89 @@ #define USB_ID_PRODUCT(id) ((u16)(id))
/* + * class-specific AC header descriptors + */ + +struct usb_ac_intf_header_v1 { + __u8 bLength; + __u8 bDescriptorType; + __u8 bDescriptorSubtype; + __u16 bcdADC; + __u16 wTotalLength; + __u8 bInCollection; + __u8 baInterfaceNr[0]; +} __attribute__((packed)); + +/* + * class specific format type descriptors + */ + +struct usb_format_type_i { + __u8 bLength; + __u8 bDescriptorType; + __u8 bDescriptorSubtype; + __u8 bFormatType; + __u8 bNrChannels; + __u8 bSubframeSize; + __u8 bBitResolution; + __u8 bSamFreqType; + __u8 samplerates[0]; +} __attribute__((packed)); + +struct usb_format_type_ii { + __u8 bLength; + __u8 bDescriptorType; + __u8 bDescriptorSubtype; + __u8 bFormatType; + __u16 wMaxBitRate; + __u16 wSamplesPerFrame; + __u8 bSamFreqType; + __u8 samplerates[0]; +} __attribute__((packed)); + +/* + * class specific AS interface descriptors + */ + +struct usb_as_interface_v1 { + __u8 bLength; + __u8 bDescriptorType; + __u8 bDescriptorSubtype; + __u8 bTerminalLink; + __u8 bDelay; + __u16 wFormatTag; +} __attribute__((packed)); + +/* + * class specific feature unit descriptors + */ + +struct usb_feature_unit_descriptor { + __u8 bLength; + __u8 bDescriptorType; + __u8 bDescriptorSubtype; + __u8 bUnitID; + __u8 bSourceID; + __u8 bControlSize; + __u8 controls[0]; /* variable length */ +} __attribute__((packed)); + +/* + * class specific terminal types + */ + +struct usb_output_terminal_v1 { + __u8 bLength; + __u8 bDescriptorType; + __u8 bDescriptorSubtype; + __u8 bTerminalID; + __u16 wTerminalType; + __u8 bAssocTerminal; + __u8 bSourceID; + __u8 iTerminal; +} __attribute__((packed)); + +/* */
struct snd_usb_audio { diff --git a/sound/usb/usbmixer.c b/sound/usb/usbmixer.c index dd0c1d7..93d3339 100644 --- a/sound/usb/usbmixer.c +++ b/sound/usb/usbmixer.c @@ -278,7 +278,6 @@ static void *find_audio_control_unit(struct mixer_build *state, unsigned char un { unsigned char *p;
- p = NULL; while ((p = snd_usb_find_desc(state->buffer, state->buflen, p, USB_DT_CS_INTERFACE)) != NULL) { if (p[0] >= 4 && p[2] >= INPUT_TERMINAL && p[2] <= EXTENSION_UNIT && p[3] == unit) @@ -1083,29 +1082,30 @@ static void build_feature_ctl(struct mixer_build *state, unsigned char *desc, * * most of controlls are defined here. */ -static int parse_audio_feature_unit(struct mixer_build *state, int unitid, unsigned char *ftr) +static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void *_ftr) { int channels, i, j; struct usb_audio_term iterm; unsigned int master_bits, first_ch_bits; int err, csize; + struct usb_feature_unit_descriptor *ftr = _ftr;
- if (ftr[0] < 7 || ! (csize = ftr[5]) || ftr[0] < 7 + csize) { + if (ftr->bLength < 7 || ! (csize = ftr->bControlSize) || ftr->bLength < 7 + csize) { snd_printk(KERN_ERR "usbaudio: unit %u: invalid FEATURE_UNIT descriptor\n", unitid); return -EINVAL; }
/* parse the source unit */ - if ((err = parse_audio_unit(state, ftr[4])) < 0) + if ((err = parse_audio_unit(state, ftr->bSourceID)) < 0) return err;
/* determine the input source type and name */ - if (check_input_term(state, ftr[4], &iterm) < 0) + if (check_input_term(state, ftr->bSourceID, &iterm) < 0) return -EINVAL;
- channels = (ftr[0] - 7) / csize - 1; + channels = (ftr->bLength - 7) / csize - 1;
- master_bits = snd_usb_combine_bytes(ftr + 6, csize); + master_bits = snd_usb_combine_bytes(ftr->controls, csize); /* master configuration quirks */ switch (state->chip->usb_id) { case USB_ID(0x08bb, 0x2702): @@ -1116,21 +1116,21 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, unsig break; } if (channels > 0) - first_ch_bits = snd_usb_combine_bytes(ftr + 6 + csize, csize); + first_ch_bits = snd_usb_combine_bytes(ftr->controls + csize, csize); else first_ch_bits = 0; /* check all control types */ for (i = 0; i < 10; i++) { unsigned int ch_bits = 0; for (j = 0; j < channels; j++) { - unsigned int mask = snd_usb_combine_bytes(ftr + 6 + csize * (j+1), csize); + unsigned int mask = snd_usb_combine_bytes(ftr->controls + csize * (j+1), csize); if (mask & (1 << i)) ch_bits |= (1 << j); } if (ch_bits & 1) /* the first channel must be set (for ease of programming) */ - build_feature_ctl(state, ftr, ch_bits, i, &iterm, unitid); + build_feature_ctl(state, _ftr, ch_bits, i, &iterm, unitid); if (master_bits & (1 << i)) - build_feature_ctl(state, ftr, 0, i, &iterm, unitid); + build_feature_ctl(state, _ftr, 0, i, &iterm, unitid); }
return 0; @@ -1777,7 +1777,7 @@ static int snd_usb_mixer_dev_free(struct snd_device *device) */ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer) { - unsigned char *desc; + struct usb_output_terminal_v1 *desc; struct mixer_build state; int err; const struct usbmix_ctl_map *map; @@ -1800,15 +1800,14 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer) } }
- desc = NULL; while ((desc = snd_usb_find_csint_desc(hostif->extra, hostif->extralen, desc, OUTPUT_TERMINAL)) != NULL) { - if (desc[0] < 9) + if (desc->bLength < 9) continue; /* invalid descriptor? */ - set_bit(desc[3], state.unitbitmap); /* mark terminal ID as visited */ - state.oterm.id = desc[3]; - state.oterm.type = combine_word(&desc[4]); - state.oterm.name = desc[8]; - err = parse_audio_unit(&state, desc[7]); + set_bit(desc->bTerminalID, state.unitbitmap); /* mark terminal ID as visited */ + state.oterm.id = desc->bTerminalID; + state.oterm.type = le16_to_cpu(desc->wTerminalType); + state.oterm.name = desc->iTerminal; + err = parse_audio_unit(&state, desc->bSourceID); if (err < 0) return err; }
This patch adds some definitions for audio class v2.
Unfortunately, the UNIT types PROCESSING_UNIT and EXTENSION_UNIT have different numerical representations in both standards, so there is need for a _V1 add-on now. usbmixer.c is changed accordingly.
Signed-off-by: Daniel Mack daniel@caiaq.de --- sound/usb/usbaudio.h | 114 +++++++++++++++++++++++++++++++++++++++++++++----- sound/usb/usbmixer.c | 14 +++--- 2 files changed, 110 insertions(+), 18 deletions(-)
diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h index c466ccc..d08f347 100644 --- a/sound/usb/usbaudio.h +++ b/sound/usb/usbaudio.h @@ -30,14 +30,26 @@ #define USB_SUBCLASS_MIDI_STREAMING 0x03 #define USB_SUBCLASS_VENDOR_SPEC 0xff
+#define USB_AC_VERSION_1 0x00 +#define USB_AC_VERSION_2 0x20 + #define HEADER 0x01 #define INPUT_TERMINAL 0x02 #define OUTPUT_TERMINAL 0x03 #define MIXER_UNIT 0x04 #define SELECTOR_UNIT 0x05 #define FEATURE_UNIT 0x06 -#define PROCESSING_UNIT 0x07 -#define EXTENSION_UNIT 0x08 +#define PROCESSING_UNIT_V1 0x07 +#define EXTENSION_UNIT_V1 0x08 + +/* audio class v2 */ +#define EFFECT_UNIT 0x07 +#define PROCESSING_UNIT_V2 0x08 +#define EXTENSION_UNIT_V2 0x09 +#define CLOCK_SOURCE 0x0a +#define CLOCK_SELECTOR 0x0b +#define CLOCK_MULTIPLIER 0x0c +#define SAMPLE_RATE_CONVERTER 0x0d
#define AS_GENERAL 0x01 #define FORMAT_TYPE 0x02 @@ -60,7 +72,7 @@ #define EP_CS_ATTR_PITCH_CONTROL 0x02 #define EP_CS_ATTR_FILL_MAX 0x80
-/* Audio Class specific Request Codes */ +/* Audio Class specific Request Codes (v1) */
#define SET_CUR 0x01 #define GET_CUR 0x81 @@ -74,6 +86,10 @@ #define GET_MEM 0x85 #define GET_STAT 0xff
+/* Audio Class specific Request Codes (v2) */ +#define CS_CUR 0x01 +#define CS_RANGE 0x02 + /* Terminal Control Selectors */
#define COPY_PROTECT_CONTROL 0x01 @@ -87,6 +103,9 @@ #define USB_FORMAT_TYPE_I 0x01 #define USB_FORMAT_TYPE_II 0x02 #define USB_FORMAT_TYPE_III 0x03 +#define USB_EXT_FORMAT_TYPE_I 0x81 +#define USB_EXT_FORMAT_TYPE_II 0x82 +#define USB_EXT_FORMAT_TYPE_III 0x83
/* type I */ #define USB_AUDIO_FORMAT_PCM 0x01 @@ -131,6 +150,47 @@ struct usb_ac_intf_header_v1 { } __attribute__((packed));
/* + * class specific AS interface descriptors + */ + +struct usb_as_interface_v1 { + __u8 bLength; + __u8 bDescriptorType; + __u8 bDescriptorSubtype; + __u8 bTerminalLink; + __u8 bDelay; + __u16 wFormatTag; +} __attribute__((packed)); + +struct usb_as_interface_v2 { + __u8 bLength; + __u8 bDescriptorType; + __u8 bDescriptorSubtype; + __u8 bTerminalLink; + __u8 bmControls; + __u8 bFormatType; + __u32 bmFormats; + __u8 bNrChannels; + __u32 bmChannelConfig; + __u8 iChannelNames; +} __attribute__((packed)); + +/* + * class specific clock source descriptor (v2) + */ + +struct usb_clock_source_descriptor { + __u8 bLength; + __u8 bDescriptorType; + __u8 bDescriptorSubtype; + __u8 bClockID; + __u8 bmAttributes; + __u8 bmControls; + __u8 bAssocTerminal; + __u8 iClockSource; +} __attribute__((packed)); + +/* * class specific format type descriptors */
@@ -146,6 +206,18 @@ struct usb_format_type_i { __u8 samplerates[0]; } __attribute__((packed));
+struct usb_format_type_i_ext { + __u8 bLength; + __u8 bDescriptorType; + __u8 bDescriptorSubtype; + __u8 bSubslotSize; + __u8 bFormatType; + __u8 bBitResolution; + __u8 bHeaderLength; + __u8 bControlSize; + __u8 bSideBandProtocol; +} __attribute__((packed)); + struct usb_format_type_ii { __u8 bLength; __u8 bDescriptorType; @@ -157,17 +229,15 @@ struct usb_format_type_ii { __u8 samplerates[0]; } __attribute__((packed));
-/* - * class specific AS interface descriptors - */ - -struct usb_as_interface_v1 { +struct usb_format_type_ii_ext { __u8 bLength; __u8 bDescriptorType; __u8 bDescriptorSubtype; - __u8 bTerminalLink; - __u8 bDelay; - __u16 wFormatTag; + __u8 bFormatType; + __u16 wMaxBitRate; + __u16 wSamplesPerFrame; + __u8 bHeaderLength; + __u8 bSideBandProtocol; } __attribute__((packed));
/* @@ -184,6 +254,15 @@ struct usb_feature_unit_descriptor { __u8 controls[0]; /* variable length */ } __attribute__((packed));
+struct usb_feature_unit_descriptor_v2 { + __u8 bLength; + __u8 bDescriptorType; + __u8 bDescriptorSubtype; + __u8 bUnitID; + __u8 bSourceID; + __u32 bmaControls[0]; +} __attribute__((packed)); + /* * class specific terminal types */ @@ -199,6 +278,19 @@ struct usb_output_terminal_v1 { __u8 iTerminal; } __attribute__((packed));
+struct usb_output_terminal_v2 { + __u8 bLength; + __u8 bDescriptorType; + __u8 bDescriptorSubtype; + __u8 bTerminalID; + __u16 wTerminalType; + __u8 bAssocTerminal; + __u8 bSourceID; + __u8 bCSourceID; + __u16 bmControls; + __u8 iTerminal; +} __attribute__((packed)); + /* */
diff --git a/sound/usb/usbmixer.c b/sound/usb/usbmixer.c index 93d3339..2bfc446 100644 --- a/sound/usb/usbmixer.c +++ b/sound/usb/usbmixer.c @@ -280,7 +280,7 @@ static void *find_audio_control_unit(struct mixer_build *state, unsigned char un
while ((p = snd_usb_find_desc(state->buffer, state->buflen, p, USB_DT_CS_INTERFACE)) != NULL) { - if (p[0] >= 4 && p[2] >= INPUT_TERMINAL && p[2] <= EXTENSION_UNIT && p[3] == unit) + if (p[0] >= 4 && p[2] >= INPUT_TERMINAL && p[2] <= EXTENSION_UNIT_V1 && p[3] == unit) return p; } return NULL; @@ -601,9 +601,9 @@ static int get_term_name(struct mixer_build *state, struct usb_audio_term *iterm switch (iterm->type >> 16) { case SELECTOR_UNIT: strcpy(name, "Selector"); return 8; - case PROCESSING_UNIT: + case PROCESSING_UNIT_V1: strcpy(name, "Process Unit"); return 12; - case EXTENSION_UNIT: + case EXTENSION_UNIT_V1: strcpy(name, "Ext Unit"); return 8; case MIXER_UNIT: strcpy(name, "Mixer"); return 5; @@ -667,8 +667,8 @@ static int check_input_term(struct mixer_build *state, int id, struct usb_audio_ term->id = id; term->name = p1[9 + p1[0] - 1]; return 0; - case PROCESSING_UNIT: - case EXTENSION_UNIT: + case PROCESSING_UNIT_V1: + case EXTENSION_UNIT_V1: if (p1[6] == 1) { id = p1[7]; break; /* continue to parse */ @@ -1741,9 +1741,9 @@ static int parse_audio_unit(struct mixer_build *state, int unitid) return parse_audio_selector_unit(state, unitid, p1); case FEATURE_UNIT: return parse_audio_feature_unit(state, unitid, p1); - case PROCESSING_UNIT: + case PROCESSING_UNIT_V1: return parse_audio_processing_unit(state, unitid, p1); - case EXTENSION_UNIT: + case EXTENSION_UNIT_V1: return parse_audio_extension_unit(state, unitid, p1); default: snd_printk(KERN_ERR "usbaudio: unit %u: unexpected type 0x%02x\n", unitid, p1[2]);
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 --- sound/usb/usbaudio.c | 342 +++++++++++++++++++++++++++++++++++++++++--------- sound/usb/usbaudio.h | 3 + 2 files changed, 288 insertions(+), 57 deletions(-)
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c index 8925879..4fd0ef7 100644 --- a/sound/usb/usbaudio.c +++ b/sound/usb/usbaudio.c @@ -2412,7 +2412,7 @@ static int is_big_endian_format(struct snd_usb_audio *chip, struct audioformat * }
/* - * parse the audio format type I descriptor + * parse the audio format type I descriptor (audio class v1) * and returns the corresponding pcm format * * @dev: usb device @@ -2420,17 +2420,53 @@ static int is_big_endian_format(struct snd_usb_audio *chip, struct audioformat * * @format: the format tag (wFormatTag) * @fmt: the format type descriptor */ -static int parse_audio_format_i_type(struct snd_usb_audio *chip, struct audioformat *fp, - int format, void *fmt_raw) +static int parse_audio_format_i_type(struct snd_usb_audio *chip, + struct audioformat *fp, + int format, void *fmt_raw, + int protocol) { - int pcm_format; + int pcm_format, i; int sample_width, sample_bytes; - struct usb_format_type_i *fmt = fmt_raw; + + switch (protocol) { + case USB_AC_VERSION_1: { + struct usb_format_type_i *fmt = fmt_raw; + sample_width = fmt->bBitResolution; + sample_bytes = fmt->bSubframeSize; + break; + } + + case USB_AC_VERSION_2: { + struct usb_format_type_i_ext *fmt = fmt_raw; + sample_width = fmt->bBitResolution; + sample_bytes = fmt->bSubslotSize; + + /* + * FIXME + * USB audio class v2 devices specify a bitmap of possible + * audio formats rather than one fix value. For now, we just + * pick one of them and report that as the only possible + * value for this setting. + * The bit allocation map is in fact compatible to the + * wFormatTag of the v1 AS streaming descriptors, which is why + * we can simply map the matrix. + */ + + for (i = 0; i < 5; i++) + if (format & (1UL << i)) { + format = i + 1; + break; + } + + break; + } + + default: + return -EINVAL; + }
/* FIXME: correct endianess and sign? */ pcm_format = -1; - sample_width = fmt->bBitResolution; - sample_bytes = fmt->bSubframeSize;
switch (format) { case 0: /* some devices don't define this correctly... */ @@ -2498,7 +2534,7 @@ static int parse_audio_format_i_type(struct snd_usb_audio *chip, struct audiofor
/* * parse the format descriptor and stores the possible sample rates - * on the audioformat table. + * on the audioformat table (audio class v1). * * @dev: usb device * @fp: audioformat record @@ -2506,8 +2542,8 @@ static int parse_audio_format_i_type(struct snd_usb_audio *chip, struct audiofor * @offset: the start offset of descriptor pointing the rate type * (7 for type I and II, 8 for type II) */ -static int parse_audio_format_rates(struct snd_usb_audio *chip, struct audioformat *fp, - unsigned char *fmt, int offset) +static int parse_audio_format_rates_v1(struct snd_usb_audio *chip, struct audioformat *fp, + unsigned char *fmt, int offset) { int nr_rates = fmt[offset];
@@ -2563,13 +2599,85 @@ static int parse_audio_format_rates(struct snd_usb_audio *chip, struct audioform }
/* - * parse the format type I and III descriptors + * parse the format descriptor and stores the possible sample rates + * on the audioformat table (audio class v2). + */ +static int parse_audio_format_rates_v2(struct snd_usb_audio *chip, + struct audioformat *fp, + struct usb_host_interface *iface) +{ + struct usb_device *dev = chip->dev; + unsigned char tmp[2], *data; + int i, nr_rates, data_size, ret = 0; + + /* get the number of sample rates first by only fetching 2 bytes */ + ret = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), CS_RANGE, + USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, + 0x0100, chip->clock_id << 8, tmp, sizeof(tmp), 1000); + + if (ret < 0) { + snd_printk(KERN_ERR "unable to retrieve number of sample rates\n"); + goto err; + } + + nr_rates = (tmp[1] << 8) | tmp[0]; + data_size = 2 + 12 * nr_rates; + data = kzalloc(data_size, GFP_KERNEL); + if (!data) { + ret = -ENOMEM; + goto err; + } + + /* now get the full information */ + ret = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), CS_RANGE, + USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, + 0x0100, chip->clock_id << 8, data, data_size, 1000); + + if (ret < 0) { + snd_printk(KERN_ERR "unable to retrieve sample rate range\n"); + ret = -EINVAL; + goto err_free; + } + + fp->rate_table = kmalloc(sizeof(int) * nr_rates, GFP_KERNEL); + if (!fp->rate_table) { + ret = -ENOMEM; + goto err_free; + } + + fp->nr_rates = 0; + fp->rate_min = fp->rate_max = 0; + + for (i = 0; i < nr_rates; i++) { + int rate = combine_quad(&data[2 + 12 * i]); + + fp->rate_table[fp->nr_rates] = rate; + if (!fp->rate_min || rate < fp->rate_min) + fp->rate_min = rate; + if (!fp->rate_max || rate > fp->rate_max) + fp->rate_max = rate; + fp->rates |= snd_pcm_rate_to_rate_bit(rate); + fp->nr_rates++; + } + +err_free: + kfree(data); +err: + return ret; +} + +/* + * parse the format type I and III descriptors (audio class v1) */ -static int parse_audio_format_i(struct snd_usb_audio *chip, struct audioformat *fp, - int format, void *fmt_raw) +static int parse_audio_format_i(struct snd_usb_audio *chip, + struct audioformat *fp, + int format, void *fmt_raw, + struct usb_host_interface *iface) { - int pcm_format; + struct usb_interface_descriptor *altsd = get_iface_desc(iface); struct usb_format_type_i *fmt = fmt_raw; + int protocol = altsd->bInterfaceProtocol; + int pcm_format, ret;
if (fmt->bFormatType == USB_FORMAT_TYPE_III) { /* FIXME: the format type is really IECxxx @@ -2589,30 +2697,49 @@ static int parse_audio_format_i(struct snd_usb_audio *chip, struct audioformat * pcm_format = SNDRV_PCM_FORMAT_S16_LE; } } else { - pcm_format = parse_audio_format_i_type(chip, fp, format, fmt); + pcm_format = parse_audio_format_i_type(chip, fp, format, fmt, protocol); if (pcm_format < 0) return -1; }
fp->format = pcm_format; - fp->channels = fmt->bNrChannels; + + /* gather possible sample rates */ + /* audio class v1 reports possible sample rates as part of the + * proprietary class specific descriptor. + * audio class v2 uses class specific EP0 range requests for that. + */ + switch (protocol) { + case USB_AC_VERSION_1: + fp->channels = fmt->bNrChannels; + ret = parse_audio_format_rates_v1(chip, fp, fmt_raw, 7); + break; + case USB_AC_VERSION_2: + /* fp->channels is already set in this case */ + ret = parse_audio_format_rates_v2(chip, fp, iface); + break; + }
if (fp->channels < 1) { snd_printk(KERN_ERR "%d:%u:%d : invalid channels %d\n", chip->dev->devnum, fp->iface, fp->altsetting, fp->channels); return -1; } - return parse_audio_format_rates(chip, fp, fmt_raw, 7); + + return ret; }
/* - * parse the format type II descriptor + * parse the format type II descriptor (audio class v1) */ -static int parse_audio_format_ii(struct snd_usb_audio *chip, struct audioformat *fp, - int format, void *fmt_raw) +static int parse_audio_format_ii(struct snd_usb_audio *chip, + struct audioformat *fp, + int format, void *fmt_raw, + struct usb_host_interface *iface) { - int brate, framesize; - struct usb_format_type_ii *fmt = fmt_raw; + int brate, framesize, ret; + struct usb_interface_descriptor *altsd = get_iface_desc(iface); + int protocol = altsd->bInterfaceProtocol;
switch (format) { case USB_AUDIO_FORMAT_AC3: @@ -2632,15 +2759,33 @@ static int parse_audio_format_ii(struct snd_usb_audio *chip, struct audioformat
fp->channels = 1;
- brate = le16_to_cpu(fmt->wMaxBitRate); - framesize = le16_to_cpu(fmt->wSamplesPerFrame); - snd_printd(KERN_INFO "found format II with max.bitrate = %d, frame size=%d\n", brate, framesize); - fp->frame_size = framesize; - return parse_audio_format_rates(chip, fp, fmt_raw, 8); /* fmt[8..] sample rates */ + switch (protocol) { + case USB_AC_VERSION_1: { + struct usb_format_type_ii *fmt = fmt_raw; + brate = le16_to_cpu(fmt->wMaxBitRate); + framesize = le16_to_cpu(fmt->wSamplesPerFrame); + snd_printd(KERN_INFO "found format II with max.bitrate = %d, frame size=%d\n", brate, framesize); + fp->frame_size = framesize; + ret = parse_audio_format_rates_v1(chip, fp, fmt_raw, 8); /* fmt[8..] sample rates */ + break; + } + case USB_AC_VERSION_2: { + struct usb_format_type_ii_ext *fmt = fmt_raw; + brate = le16_to_cpu(fmt->wMaxBitRate); + framesize = le16_to_cpu(fmt->wSamplesPerFrame); + snd_printd(KERN_INFO "found format II with max.bitrate = %d, frame size=%d\n", brate, framesize); + fp->frame_size = framesize; + ret = parse_audio_format_rates_v2(chip, fp, iface); + break; + } + } + + return ret; }
static int parse_audio_format(struct snd_usb_audio *chip, struct audioformat *fp, - int format, void *fmt_raw, int stream) + int format, void *fmt_raw, int stream, + struct usb_host_interface *iface) { int err; /* we only parse the common header of all format types here, @@ -2650,10 +2795,10 @@ static int parse_audio_format(struct snd_usb_audio *chip, struct audioformat *fp switch (fmt->bFormatType) { case USB_FORMAT_TYPE_I: case USB_FORMAT_TYPE_III: - err = parse_audio_format_i(chip, fp, format, fmt); + err = parse_audio_format_i(chip, fp, format, fmt, iface); break; case USB_FORMAT_TYPE_II: - err = parse_audio_format_ii(chip, fp, format, fmt); + err = parse_audio_format_ii(chip, fp, format, fmt, iface); break; default: snd_printd(KERN_INFO "%d:%u:%d : format type %d is not supported yet\n", @@ -2700,10 +2845,10 @@ static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) struct usb_host_interface *alts; struct usb_interface_descriptor *altsd; int i, altno, err, stream; - int format; + int format = 0, num_channels = 0; struct audioformat *fp = NULL; unsigned char *fmt, *csep; - int num; + int num, protocol;
dev = chip->dev;
@@ -2720,10 +2865,9 @@ static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) num = 4;
for (i = 0; i < num; i++) { - struct usb_as_interface_v1 *as; - alts = &iface->altsetting[i]; altsd = get_iface_desc(alts); + protocol = altsd->bInterfaceProtocol; /* skip invalid one */ if ((altsd->bInterfaceClass != USB_CLASS_AUDIO && altsd->bInterfaceClass != USB_CLASS_VENDOR_SPEC) || @@ -2748,21 +2892,54 @@ static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) continue;
/* get audio formats */ - as = snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, AS_GENERAL); + switch (protocol) { + case USB_AC_VERSION_1: { + struct usb_as_interface_v1 *as = + snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, AS_GENERAL); + + if (!as) { + snd_printk(KERN_ERR "%d:%u:%d : AS_GENERAL descriptor not found\n", + dev->devnum, iface_no, altno); + continue; + }
- if (!as) { - snd_printk(KERN_ERR "%d:%u:%d : AS_GENERAL descriptor not found\n", - dev->devnum, iface_no, altno); - continue; + if (as->bLength < sizeof(*as)) { + snd_printk(KERN_ERR "%d:%u:%d : invalid AS_GENERAL desc\n", + dev->devnum, iface_no, altno); + continue; + } + + format = le16_to_cpu(as->wFormatTag); /* remember the format value */ + break; }
- if (as->bLength < sizeof(*as)) { - snd_printk(KERN_ERR "%d:%u:%d : invalid AS_GENERAL desc\n", - dev->devnum, iface_no, altno); - continue; + case USB_AC_VERSION_2: { + struct usb_as_interface_v2 *as = + snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, AS_GENERAL); + + if (!as) { + snd_printk(KERN_ERR "%d:%u:%d : AS_GENERAL descriptor not found\n", + dev->devnum, iface_no, altno); + continue; + } + + if (as->bLength < sizeof(*as)) { + snd_printk(KERN_ERR "%d:%u:%d : invalid AS_GENERAL desc\n", + dev->devnum, iface_no, altno); + continue; + } + + num_channels = as->bNrChannels; + format = le32_to_cpu(as->bmFormats); + + break; }
- format = le16_to_cpu(as->wFormatTag); /* remember the format value */ + default: + snd_printk(KERN_ERR "%d:%u:%d : unknown interface protocol %04x\n", + dev->devnum, iface_no, altno, protocol); + continue; + }
/* get format type */ fmt = snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, FORMAT_TYPE); @@ -2771,7 +2948,8 @@ static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) dev->devnum, iface_no, altno); continue; } - if (fmt[0] < 8) { + if (((protocol == USB_AC_VERSION_1) && (fmt[0] < 8)) || + ((protocol == USB_AC_VERSION_2) && (fmt[0] < 6))) { snd_printk(KERN_ERR "%d:%u:%d : invalid FORMAT_TYPE desc\n", dev->devnum, iface_no, altno); continue; @@ -2785,6 +2963,7 @@ static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) if (fmt[4] == 1 && fmt[5] == 2 && altno == 2 && num == 3 && fp && fp->altsetting == 1 && fp->channels == 1 && fp->format == SNDRV_PCM_FORMAT_S16_LE && + protocol == USB_AC_VERSION_1 && le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize) == fp->maxpacksize * 2) continue; @@ -2813,6 +2992,8 @@ static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) fp->ep_attr = get_endpoint(alts, 0)->bmAttributes; fp->datainterval = parse_datainterval(chip, alts); fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize); + /* num_channels is only set for v2 interfaces */ + fp->channels = num_channels; if (snd_usb_get_speed(dev) == USB_SPEED_HIGH) fp->maxpacksize = (((fp->maxpacksize >> 11) & 3) + 1) * (fp->maxpacksize & 0x7ff); @@ -2848,7 +3029,7 @@ static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) }
/* ok, let's parse further... */ - if (parse_audio_format(chip, fp, format, fmt, stream) < 0) { + if (parse_audio_format(chip, fp, format, fmt, stream, alts) < 0) { kfree(fp->rate_table); kfree(fp); continue; @@ -2956,35 +3137,82 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif) { struct usb_device *dev = chip->dev; struct usb_host_interface *host_iface; - struct usb_ac_intf_header_v1 *h1; + struct usb_interface_descriptor *altsd; void *control_header; - int i; + int i, protocol;
/* find audiocontrol interface */ host_iface = &usb_ifnum_to_if(dev, ctrlif)->altsetting[0]; control_header = snd_usb_find_csint_desc(host_iface->extra, host_iface->extralen, NULL, HEADER); + altsd = get_iface_desc(host_iface); + protocol = altsd->bInterfaceProtocol;
if (!control_header) { snd_printk(KERN_ERR "cannot find HEADER\n"); return -EINVAL; }
- h1 = control_header; + switch (protocol) { + case USB_AC_VERSION_1: { + struct usb_ac_intf_header_v1 *h1 = control_header;
- if (!h1->bInCollection) { - snd_printk(KERN_INFO "skipping empty audio interface (v1)\n"); - return -EINVAL; + if (!h1->bInCollection) { + snd_printk(KERN_INFO "skipping empty audio interface (v1)\n"); + return -EINVAL; + } + + if (h1->bLength < sizeof(*h1) + h1->bInCollection) { + snd_printk(KERN_ERR "invalid HEADER (v1)\n"); + return -EINVAL; + } + + for (i = 0; i < h1->bInCollection; i++) + snd_usb_create_stream(chip, ctrlif, h1->baInterfaceNr[i]); + + break; }
- if (h1->bLength < sizeof(*h1) + h1->bInCollection) { - snd_printk(KERN_ERR "invalid HEADER (v1)\n"); - return -EINVAL; + case USB_AC_VERSION_2: { + struct usb_clock_source_descriptor *cs; + struct usb_interface_assoc_descriptor *assoc = + usb_ifnum_to_if(dev, ctrlif)->intf_assoc; + + if (!assoc) { + snd_printk(KERN_ERR "Audio class v2 interfaces need an interface association\n"); + return -EINVAL; + } + + /* FIXME: for now, we expect there is at least one clock source + * descriptor and we always take the first one. + * We should properly support devices with multiple clock sources, + * clock selectors and sample rate conversion units. */ + + cs = snd_usb_find_csint_desc(host_iface->extra, host_iface->extralen, + NULL, CLOCK_SOURCE); + + if (!cs) { + snd_printk(KERN_ERR "CLOCK_SOURCE descriptor not found\n"); + return -EINVAL; + } + + chip->clock_id = cs->bClockID; + + for (i = 0; i < assoc->bInterfaceCount; i++) { + int intf = assoc->bFirstInterface + i; + + if (intf != ctrlif) + snd_usb_create_stream(chip, ctrlif, intf); + } + + break; }
- for (i = 0; i < h1->bInCollection; i++) - snd_usb_create_stream(chip, ctrlif, h1->baInterfaceNr[i]); + default: + snd_printk(KERN_ERR "unknown protocol version 0x%02x\n", protocol); + return -EINVAL; + }
return 0; } diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h index d08f347..d1f5ca7 100644 --- a/sound/usb/usbaudio.h +++ b/sound/usb/usbaudio.h @@ -304,6 +304,9 @@ struct snd_usb_audio { int num_interfaces; int num_suspended_intf;
+ /* for audio class v2 */ + int clock_id; + struct list_head pcm_list; /* list of pcm streams */ int pcm_devs;
This is just a quick hack that needs to be removed once the new units defined by the audio class v2.0 standard are supported.
However, it allows using these devices for now, without mixer support.
Signed-off-by: Daniel Mack daniel@caiaq.de --- sound/usb/usbmixer.c | 13 ++++++++++++- 1 files changed, 12 insertions(+), 1 deletions(-)
diff --git a/sound/usb/usbmixer.c b/sound/usb/usbmixer.c index 2bfc446..79ce3f4 100644 --- a/sound/usb/usbmixer.c +++ b/sound/usb/usbmixer.c @@ -2209,7 +2209,8 @@ int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif, .dev_free = snd_usb_mixer_dev_free }; struct usb_mixer_interface *mixer; - int err; + struct usb_host_interface *host_iface; + int err, protocol;
strcpy(chip->card->mixername, "USB Mixer");
@@ -2225,6 +2226,16 @@ int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif, return -ENOMEM; }
+ host_iface = &usb_ifnum_to_if(chip->dev, ctrlif)->altsetting[0]; + protocol = host_iface->desc.bInterfaceProtocol; + + /* FIXME! */ + if (protocol != USB_AC_VERSION_1) { + snd_printk(KERN_WARNING "mixer interface protocol 0x%02x not yet supported\n", + protocol); + return 0; + } + if ((err = snd_usb_mixer_controls(mixer)) < 0 || (err = snd_usb_mixer_status_create(mixer)) < 0) goto _error;
Daniel Mack wrote:
I've been working on support for USB devices compliant to audio class v2.0 and would like to share what I got.
Great!
Just out of curiousity: what device are you testing this with?
My first step was to clean up most of the existing descriptor parsers by moving away from anonymous byte array access to real structs so we can see which fields we're actually dereferencing.
Please use the structures in <linux/usb/audio.h>.
- Supported sample formats are now reported as 32bit bitmap rather than as a fixed value. For now, this is worked around by choosing just one of them.
I'll write a patch to change struct audioformat to use a bitmask.
Let me know what you think.
Haven't tested yet, but the patches look fine.
Regards, Clemens
On Mon, Feb 22, 2010 at 06:40:39PM +0100, Clemens Ladisch wrote:
Daniel Mack wrote:
I've been working on support for USB devices compliant to audio class v2.0 and would like to share what I got.
Great!
Just out of curiousity: what device are you testing this with?
An XMOS eval kit. I have OSX/CoreAudio as reference which seems to have a more or less complete support.
My first step was to clean up most of the existing descriptor parsers by moving away from anonymous byte array access to real structs so we can see which fields we're actually dereferencing.
Please use the structures in <linux/usb/audio.h>.
Gna. Haven't seen that before. Why are they there if no code actually uses them?
I'll rework my patches then.
Thanks, Daniel
On 22/2/2010 6:28 μμ, Daniel Mack wrote:
Hi,
I've been working on support for USB devices compliant to audio class v2.0 and would like to share what I got.
First problem is that they literally changed every single descriptor type by adding or removing fields or changing their width, respectively. Even worse, some enum values were dropped and reassigned so their numerical value has a different meaning now.
My first step was to clean up most of the existing descriptor parsers by moving away from anonymous byte array access to real structs so we can see which fields we're actually dereferencing.
In a second step, I added definitions for the replacement descriptors and use them at appropriate places. The bInterfaceProtocol field must always be set correctly of course, otherwise we'll parse garbage.
Other things that have changed from v1.0 to v2.0 are:
The number of streaming interfaces is now reported by a standard interface association descriptor. The old approach using a proprietary descriptor extension 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 as a fixed value. For now, this is worked around by choosing just one of them. Eventually, the code should propagate the full ability of the device.
A devices needs to have at least one CLOCK_SOURCE descriptor which denotes a clockID that is needed as argument to the class request command. If can have more than one though and the host driver is in charge to choose the right one. There are also new types for clock selectors and sample rate converters that a device might report. This is all unsupported at the moment. We only parse the first CLOCK_SOURCE and take this one.
Many descriptors (format_type, ...) have changed their layout. Handle this by casting the descriptors to the appropriate structs.
With the following patches applied, a v2.0 device is recognized and reported as ALSA device. I can even hear at least some kind of music, but the sample rate setting does not yet seem to be correct.
Also, the existing mixer code does not work at all for v2.0 devices. This will be quite some work to support that and I fear the whole thing must be reimplemented for v2.0 specifically. For now, I worked around that by not parsing them at all but bailing out very early.
However, I would like to make sure the changes I made so far won't cause any regression for v1.0 devices, and so it would be good to see them applied as a preliminary support. I'll continue working on this and send more updates along.
Let me know what you think.
Thanks, Daniel
Thanks to all involved for working on usb audio v2.
Last night I installed the 20100226 snapshot. I did a little testing with my XMOS board using toslink out into may DAC. I tried various files ranging 16bit/44110kHz-24bit/192000kHz. The 44110 files had quite a bit of static, the higher bitrate files were better. As you stated the sampling rate is not correct and be verified by looking at the flashing LEDs on the XMOS board. They should flash faster as sampling rate increase. In this case no change was observed.
Thanks, Nikos
On Tue, Mar 02, 2010 at 11:13:04AM +0200, adelias wrote:
Thanks to all involved for working on usb audio v2.
Last night I installed the 20100226 snapshot. I did a little testing with my XMOS board using toslink out into may DAC. I tried various files ranging 16bit/44110kHz-24bit/192000kHz. The 44110 files had quite a bit of static, the higher bitrate files were better. As you stated the sampling rate is not correct and be verified by looking at the flashing LEDs on the XMOS board. They should flash faster as sampling rate increase. In this case no change was observed.
Yes - this is all do be done. The sample rate setting is done with a different type of class request, which also addresses the interface now, unlike v1 devices which send that to the endpoint. But that's just one out of many differences that need to be addressed, and it's still a long way to go. I'm on it :)
Daniel
On 2/3/2010 8:35 μμ, Daniel Mack wrote:
On Tue, Mar 02, 2010 at 11:13:04AM +0200, adelias wrote:
Thanks to all involved for working on usb audio v2.
Last night I installed the 20100226 snapshot. I did a little testing with my XMOS board using toslink out into may DAC. I tried various files ranging 16bit/44110kHz-24bit/192000kHz. The 44110 files had quite a bit of static, the higher bitrate files were better. As you stated the sampling rate is not correct and be verified by looking at the flashing LEDs on the XMOS board. They should flash faster as sampling rate increase. In this case no change was observed.
Yes - this is all do be done. The sample rate setting is done with a different type of class request, which also addresses the interface now, unlike v1 devices which send that to the endpoint. But that's just one out of many differences that need to be addressed, and it's still a long way to go. I'm on it :)
Daniel
I upgraded alsa to 1.0.23. The XMOS device is working great with the exception of some mild clicks here and there. Is this a known issue or might it be a problem with my specific configuration?
27.04.2010 17:23, adelias пишет:
On 2/3/2010 8:35 μμ, Daniel Mack wrote:
On Tue, Mar 02, 2010 at 11:13:04AM +0200, adelias wrote:
Thanks to all involved for working on usb audio v2.
Last night I installed the 20100226 snapshot. I did a little testing with my XMOS board using toslink out into may DAC. I tried various files ranging 16bit/44110kHz-24bit/192000kHz. The 44110 files had quite a bit of static, the higher bitrate files were better. As you stated the sampling rate is not correct and be verified by looking at the flashing LEDs on the XMOS board. They should flash faster as sampling rate increase. In this case no change was observed.
Yes - this is all do be done. The sample rate setting is done with a different type of class request, which also addresses the interface now, unlike v1 devices which send that to the endpoint. But that's just one out of many differences that need to be addressed, and it's still a long way to go. I'm on it :)
Daniel
I upgraded alsa to 1.0.23. The XMOS device is working great with the exception of some mild clicks here and there. Is this a known issue or might it be a problem with my specific configuration?
Alsa-devel mailing list Alsa-devel@alsa-project.org http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
Perhaps I should've posted my problem in this thread earlier. Here's the summary: Creative X-Fi Notebook stopped working after upgrading from 1.0.22.1 to 1.0.23 (worked just fine before). dmesg gives the following:
usb 8-2: new full speed USB device using uhci_hcd and address 2 usb 8-2: New USB device found, idVendor=041e, idProduct=30d2 usb 8-2: New USB device strings: Mfr=1, Product=2, SerialNumber=0 usb 8-2: Product: SB X-Fi Notebook usb 8-2: Manufacturer: Creative Technology Ltd usb 8-2: configuration #1 chosen from 1 choice input: Creative Technology Ltd SB X-Fi Notebook as /devices/pci0000:00/0000:00:1d.2/usb8/8-2/8-2:1.3/input/input11 generic-usb 0003:041E:30D2.0002: input,hidraw1: USB HID v1.11 Device [Creative Technology Ltd SB X-Fi Notebook] on usb-0000:00:1d.2-2/input3 input: Creative Technology Ltd SB X-Fi Notebook as /devices/pci0000:00/0000:00:1d.2/usb8/8-2/8-2:1.4/input/input12 generic-usb 0003:041E:30D2.0003: input,hidraw2: USB HID v1.11 Keyboard [Creative Technology Ltd SB X-Fi Notebook] on usb-0000:00:1d.2-2/input4 ALSA pcm.c:174: 2:1:1: endpoint lacks sample rate attribute bit, cannot set. ALSA pcm.c:174: 2:2:1: endpoint lacks sample rate attribute bit, cannot set.
Additionally, modprobe never exits after connecting the device using 100% CPU and disrupting system's work.
On Tue, Apr 27, 2010 at 05:31:35PM +0400, The Source wrote:
Perhaps I should've posted my problem in this thread earlier. Here's the summary: Creative X-Fi Notebook stopped working after upgrading from 1.0.22.1 to 1.0.23 (worked just fine before). dmesg gives the following:
usb 8-2: new full speed USB device using uhci_hcd and address 2 usb 8-2: New USB device found, idVendor=041e, idProduct=30d2 usb 8-2: New USB device strings: Mfr=1, Product=2, SerialNumber=0 usb 8-2: Product: SB X-Fi Notebook usb 8-2: Manufacturer: Creative Technology Ltd usb 8-2: configuration #1 chosen from 1 choice input: Creative Technology Ltd SB X-Fi Notebook as /devices/pci0000:00/0000:00:1d.2/usb8/8-2/8-2:1.3/input/input11 generic-usb 0003:041E:30D2.0002: input,hidraw1: USB HID v1.11 Device [Creative Technology Ltd SB X-Fi Notebook] on usb-0000:00:1d.2-2/input3 input: Creative Technology Ltd SB X-Fi Notebook as /devices/pci0000:00/0000:00:1d.2/usb8/8-2/8-2:1.4/input/input12 generic-usb 0003:041E:30D2.0003: input,hidraw2: USB HID v1.11 Keyboard [Creative Technology Ltd SB X-Fi Notebook] on usb-0000:00:1d.2-2/input4 ALSA pcm.c:174: 2:1:1: endpoint lacks sample rate attribute bit, cannot set. ALSA pcm.c:174: 2:2:1: endpoint lacks sample rate attribute bit, cannot set.
And you say this is a regression from earlier versions? Would you be able to bisect this problem?
Daniel
27.04.2010 18:07, Daniel Mack пишет:
On Tue, Apr 27, 2010 at 05:31:35PM +0400, The Source wrote:
Perhaps I should've posted my problem in this thread earlier. Here's the summary: Creative X-Fi Notebook stopped working after upgrading from 1.0.22.1 to 1.0.23 (worked just fine before). dmesg gives the following:
usb 8-2: new full speed USB device using uhci_hcd and address 2 usb 8-2: New USB device found, idVendor=041e, idProduct=30d2 usb 8-2: New USB device strings: Mfr=1, Product=2, SerialNumber=0 usb 8-2: Product: SB X-Fi Notebook usb 8-2: Manufacturer: Creative Technology Ltd usb 8-2: configuration #1 chosen from 1 choice input: Creative Technology Ltd SB X-Fi Notebook as /devices/pci0000:00/0000:00:1d.2/usb8/8-2/8-2:1.3/input/input11 generic-usb 0003:041E:30D2.0002: input,hidraw1: USB HID v1.11 Device [Creative Technology Ltd SB X-Fi Notebook] on usb-0000:00:1d.2-2/input3 input: Creative Technology Ltd SB X-Fi Notebook as /devices/pci0000:00/0000:00:1d.2/usb8/8-2/8-2:1.4/input/input12 generic-usb 0003:041E:30D2.0003: input,hidraw2: USB HID v1.11 Keyboard [Creative Technology Ltd SB X-Fi Notebook] on usb-0000:00:1d.2-2/input4 ALSA pcm.c:174: 2:1:1: endpoint lacks sample rate attribute bit, cannot set. ALSA pcm.c:174: 2:2:1: endpoint lacks sample rate attribute bit, cannot set.
And you say this is a regression from earlier versions? Would you be able to bisect this problem?
Daniel
Gladly, if you just tell me how :)
On Tue, Apr 27, 2010 at 07:29:52PM +0400, The Source wrote:
27.04.2010 18:07, Daniel Mack пишет:
On Tue, Apr 27, 2010 at 05:31:35PM +0400, The Source wrote:
Perhaps I should've posted my problem in this thread earlier. Here's the summary: Creative X-Fi Notebook stopped working after upgrading from 1.0.22.1 to 1.0.23 (worked just fine before). dmesg gives the following:
usb 8-2: new full speed USB device using uhci_hcd and address 2 usb 8-2: New USB device found, idVendor=041e, idProduct=30d2 usb 8-2: New USB device strings: Mfr=1, Product=2, SerialNumber=0 usb 8-2: Product: SB X-Fi Notebook usb 8-2: Manufacturer: Creative Technology Ltd usb 8-2: configuration #1 chosen from 1 choice input: Creative Technology Ltd SB X-Fi Notebook as /devices/pci0000:00/0000:00:1d.2/usb8/8-2/8-2:1.3/input/input11 generic-usb 0003:041E:30D2.0002: input,hidraw1: USB HID v1.11 Device [Creative Technology Ltd SB X-Fi Notebook] on usb-0000:00:1d.2-2/input3 input: Creative Technology Ltd SB X-Fi Notebook as /devices/pci0000:00/0000:00:1d.2/usb8/8-2/8-2:1.4/input/input12 generic-usb 0003:041E:30D2.0003: input,hidraw2: USB HID v1.11 Keyboard [Creative Technology Ltd SB X-Fi Notebook] on usb-0000:00:1d.2-2/input4 ALSA pcm.c:174: 2:1:1: endpoint lacks sample rate attribute bit, cannot set. ALSA pcm.c:174: 2:2:1: endpoint lacks sample rate attribute bit, cannot set.
And you say this is a regression from earlier versions? Would you be able to bisect this problem?
Daniel
Gladly, if you just tell me how :)
You would check out the latest mainline sources:
$ git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git $ cd linux-2.6
Then create a branch and merge the latest ALSA patches:
$ git checkout -b alsa $ git pull git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6.git
Then build and install the kernel and verify it still shows the error. Start the bisect and mark the current revision as 'bad':
$ git bisect start $ git bisect bad
Assuming that v2.6.34-rc5 (before the merge) still works, you would mark this as 'good':
$ git bisect good v2.6.34-rc5
git will now iterate you thru the changes and drop you off at chosen points. Just compile the tree you get, and tell git whether this is a good or bad one:
$ git bisect good or $ git bisect bad
Then recompile and test again After some steps, it will tell you which commit precisely broke it.
HTH, Daniel
27.04.2010 19:43, Daniel Mack пишет:
On Tue, Apr 27, 2010 at 07:29:52PM +0400, The Source wrote:
27.04.2010 18:07, Daniel Mack пишет:
On Tue, Apr 27, 2010 at 05:31:35PM +0400, The Source wrote:
Perhaps I should've posted my problem in this thread earlier. Here's the summary: Creative X-Fi Notebook stopped working after upgrading from 1.0.22.1 to 1.0.23 (worked just fine before). dmesg gives the following:
usb 8-2: new full speed USB device using uhci_hcd and address 2 usb 8-2: New USB device found, idVendor=041e, idProduct=30d2 usb 8-2: New USB device strings: Mfr=1, Product=2, SerialNumber=0 usb 8-2: Product: SB X-Fi Notebook usb 8-2: Manufacturer: Creative Technology Ltd usb 8-2: configuration #1 chosen from 1 choice input: Creative Technology Ltd SB X-Fi Notebook as /devices/pci0000:00/0000:00:1d.2/usb8/8-2/8-2:1.3/input/input11 generic-usb 0003:041E:30D2.0002: input,hidraw1: USB HID v1.11 Device [Creative Technology Ltd SB X-Fi Notebook] on usb-0000:00:1d.2-2/input3 input: Creative Technology Ltd SB X-Fi Notebook as /devices/pci0000:00/0000:00:1d.2/usb8/8-2/8-2:1.4/input/input12 generic-usb 0003:041E:30D2.0003: input,hidraw2: USB HID v1.11 Keyboard [Creative Technology Ltd SB X-Fi Notebook] on usb-0000:00:1d.2-2/input4 ALSA pcm.c:174: 2:1:1: endpoint lacks sample rate attribute bit, cannot set. ALSA pcm.c:174: 2:2:1: endpoint lacks sample rate attribute bit, cannot set.
And you say this is a regression from earlier versions? Would you be able to bisect this problem?
Daniel
Gladly, if you just tell me how :)
You would check out the latest mainline sources:
$ git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git $ cd linux-2.6
Then create a branch and merge the latest ALSA patches:
$ git checkout -b alsa $ git pull git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6.git
Then build and install the kernel and verify it still shows the error. Start the bisect and mark the current revision as 'bad':
$ git bisect start $ git bisect bad
Assuming that v2.6.34-rc5 (before the merge) still works, you would mark this as 'good':
$ git bisect good v2.6.34-rc5
git will now iterate you thru the changes and drop you off at chosen points. Just compile the tree you get, and tell git whether this is a good or bad one:
$ git bisect good or $ git bisect bad
Then recompile and test again After some steps, it will tell you which commit precisely broke it.
HTH, Daniel
I'll try that. But is there any way to do this just with alsa and not with entire kernel? Compiling kernel is a loooong process.
On Tue, Apr 27, 2010 at 09:27:15PM +0400, The Source wrote:
27.04.2010 19:43, Daniel Mack пишет:
You would check out the latest mainline sources:
$ git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git $ cd linux-2.6
Then create a branch and merge the latest ALSA patches:
$ git checkout -b alsa $ git pull git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6.git
Then build and install the kernel and verify it still shows the error. Start the bisect and mark the current revision as 'bad':
$ git bisect start $ git bisect bad
Assuming that v2.6.34-rc5 (before the merge) still works, you would mark this as 'good':
$ git bisect good v2.6.34-rc5
git will now iterate you thru the changes and drop you off at chosen points. Just compile the tree you get, and tell git whether this is a good or bad one:
$ git bisect good or $ git bisect bad
Then recompile and test again After some steps, it will tell you which commit precisely broke it.
HTH, Daniel
I'll try that. But is there any way to do this just with alsa and not with entire kernel? Compiling kernel is a loooong process.
The description above won't touch much things outside the ALSA tree during the bisect, so it shouldn't take long to compile.
Thanks for helping, Daniel
27.04.2010 21:33, Daniel Mack пишет:
On Tue, Apr 27, 2010 at 09:27:15PM +0400, The Source wrote:
27.04.2010 19:43, Daniel Mack пишет:
You would check out the latest mainline sources:
$ git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git $ cd linux-2.6
Then create a branch and merge the latest ALSA patches:
$ git checkout -b alsa $ git pull git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6.git
Then build and install the kernel and verify it still shows the error. Start the bisect and mark the current revision as 'bad':
$ git bisect start $ git bisect bad
Assuming that v2.6.34-rc5 (before the merge) still works, you would mark this as 'good':
$ git bisect good v2.6.34-rc5
git will now iterate you thru the changes and drop you off at chosen points. Just compile the tree you get, and tell git whether this is a good or bad one:
$ git bisect good or $ git bisect bad
Then recompile and test again After some steps, it will tell you which commit precisely broke it.
HTH, Daniel
I'll try that. But is there any way to do this just with alsa and not with entire kernel? Compiling kernel is a loooong process.
The description above won't touch much things outside the ALSA tree during the bisect, so it shouldn't take long to compile.
Thanks for helping, Daniel
I'm sorry, but after 2 or 3 steps (of ~10) I got kernel that doesn't even boot properly (2.6.34-rc4, something with sata is broken) so I can't test my card with this kernel. Should I mark current version as bad and continue or something else can be done?
On Sun, May 02, 2010 at 08:56:18PM +0400, The Source wrote:
27.04.2010 21:33, Daniel Mack пишет:
On Tue, Apr 27, 2010 at 09:27:15PM +0400, The Source wrote:
27.04.2010 19:43, Daniel Mack пишет:
You would check out the latest mainline sources:
$ git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git $ cd linux-2.6
Then create a branch and merge the latest ALSA patches:
$ git checkout -b alsa $ git pull git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6.git
Then build and install the kernel and verify it still shows the error. Start the bisect and mark the current revision as 'bad':
$ git bisect start $ git bisect bad
Assuming that v2.6.34-rc5 (before the merge) still works, you would mark this as 'good':
$ git bisect good v2.6.34-rc5
git will now iterate you thru the changes and drop you off at chosen points. Just compile the tree you get, and tell git whether this is a good or bad one:
$ git bisect good or $ git bisect bad
Then recompile and test again After some steps, it will tell you which commit precisely broke it.
HTH, Daniel
I'll try that. But is there any way to do this just with alsa and not with entire kernel? Compiling kernel is a loooong process.
The description above won't touch much things outside the ALSA tree during the bisect, so it shouldn't take long to compile.
Thanks for helping, Daniel
I'm sorry, but after 2 or 3 steps (of ~10) I got kernel that doesn't even boot properly (2.6.34-rc4, something with sata is broken) so I can't test my card with this kernel. Should I mark current version as bad and continue or something else can be done?
Hmm, so you say you can't boot a vanilla (unmodified) 2.6.34-rc4? Is your problem fixed in the current git HEAD? The bisect procedure I described shouldn't touch anything else than sound code, so SATA should be unaffected. Anyway, you can skip unbootable or uncompilable versions with
$ git bisect skip
HTH, Daniel
04.05.2010 00:55, Daniel Mack пишет:
On Sun, May 02, 2010 at 08:56:18PM +0400, The Source wrote:
27.04.2010 21:33, Daniel Mack пишет:
On Tue, Apr 27, 2010 at 09:27:15PM +0400, The Source wrote:
27.04.2010 19:43, Daniel Mack пишет:
You would check out the latest mainline sources:
$ git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git $ cd linux-2.6
Then create a branch and merge the latest ALSA patches:
$ git checkout -b alsa $ git pull git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6.git
Then build and install the kernel and verify it still shows the error. Start the bisect and mark the current revision as 'bad':
$ git bisect start $ git bisect bad
Assuming that v2.6.34-rc5 (before the merge) still works, you would mark this as 'good':
$ git bisect good v2.6.34-rc5
git will now iterate you thru the changes and drop you off at chosen points. Just compile the tree you get, and tell git whether this is a good or bad one:
$ git bisect good or $ git bisect bad
Then recompile and test again After some steps, it will tell you which commit precisely broke it.
HTH, Daniel
I'll try that. But is there any way to do this just with alsa and not with entire kernel? Compiling kernel is a loooong process.
The description above won't touch much things outside the ALSA tree during the bisect, so it shouldn't take long to compile.
Thanks for helping, Daniel
I'm sorry, but after 2 or 3 steps (of ~10) I got kernel that doesn't even boot properly (2.6.34-rc4, something with sata is broken) so I can't test my card with this kernel. Should I mark current version as bad and continue or something else can be done?
Hmm, so you say you can't boot a vanilla (unmodified) 2.6.34-rc4? Is your problem fixed in the current git HEAD? The bisect procedure I described shouldn't touch anything else than sound code, so SATA should be unaffected. Anyway, you can skip unbootable or uncompilable versions with
$ git bisect skip
HTH, Daniel
Bisect results:
23caaf19b11eda7054348452e1618d4512a86907 is the first bad commit commit 23caaf19b11eda7054348452e1618d4512a86907 Author: Daniel Mack daniel@caiaq.de Date: Thu Mar 11 21:13:25 2010 +0100
ALSA: usb-mixer: Add support for Audio Class v2.0
USB Audio Class v2.0 compliant devices have different descriptors and a different way of setting/getting min/max/res/cur properties. This patch adds support for them.
Signed-off-by: Daniel Mack daniel@caiaq.de Cc: Clemens Ladisch clemens@ladisch.de Signed-off-by: Takashi Iwai tiwai@suse.de
:040000 040000 db0691095b20f0872c9042e6498ce40693d69241 7cd9e29352fd45e50968b4a17891d1c3225aaba9 M include :040000 040000 981c7c69fc8695281929677ebccf3bdae5ef41de c5bec5c3954278601ec4b29226f4671333262f04 M sound
On Fri, May 07, 2010 at 05:19:24PM +0400, The Source wrote:
Bisect results:
23caaf19b11eda7054348452e1618d4512a86907 is the first bad commit commit 23caaf19b11eda7054348452e1618d4512a86907 Author: Daniel Mack daniel@caiaq.de Date: Thu Mar 11 21:13:25 2010 +0100
Thanks a lot! I'll have a close look again where I might have broken anything. I'll let you know.
Daniel
ALSA: usb-mixer: Add support for Audio Class v2.0 USB Audio Class v2.0 compliant devices have different descriptors and a different way of setting/getting min/max/res/cur properties. This patch adds support for them. Signed-off-by: Daniel Mack <daniel@caiaq.de> Cc: Clemens Ladisch <clemens@ladisch.de> Signed-off-by: Takashi Iwai <tiwai@suse.de>
:040000 040000 db0691095b20f0872c9042e6498ce40693d69241 7cd9e29352fd45e50968b4a17891d1c3225aaba9 M include :040000 040000 981c7c69fc8695281929677ebccf3bdae5ef41de c5bec5c3954278601ec4b29226f4671333262f04 M sound
On Fri, May 07, 2010 at 05:19:24PM +0400, The Source wrote:
Bisect results:
23caaf19b11eda7054348452e1618d4512a86907 is the first bad commit commit 23caaf19b11eda7054348452e1618d4512a86907 Author: Daniel Mack daniel@caiaq.de Date: Thu Mar 11 21:13:25 2010 +0100
ALSA: usb-mixer: Add support for Audio Class v2.0 USB Audio Class v2.0 compliant devices have different descriptors and a different way of setting/getting min/max/res/cur properties. This patch adds support for them. Signed-off-by: Daniel Mack <daniel@caiaq.de> Cc: Clemens Ladisch <clemens@ladisch.de> Signed-off-by: Takashi Iwai <tiwai@suse.de>
I've found two changes in this commit that are obviously wrong. Could you try the patch below please?
Sorry for the trouble.
Daniel
diff --git a/include/linux/usb/audio.h b/include/linux/usb/audio.h index 905a87c..57f2055 100644 --- a/include/linux/usb/audio.h +++ b/include/linux/usb/audio.h @@ -244,7 +244,7 @@ struct uac_selector_unit_descriptor { static inline __u8 uac_selector_unit_iSelector(struct uac_selector_unit_descriptor *desc) { __u8 *raw = (__u8 *) desc; - return raw[desc->bLength - 1]; + return raw[9 + desc->bLength - 1]; }
/* 4.3.2.5 Feature Unit Descriptor */ diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index 21613fe..fa0fb77 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c @@ -656,7 +656,7 @@ static int check_input_term(struct mixer_build *state, int id, struct usb_audio_ case UAC_FEATURE_UNIT: { /* the header is the same for v1 and v2 */ struct uac_feature_unit_descriptor *d = p1; - id = d->bUnitID; + id = d->bSourceID; break; /* continue to parse */ } case UAC_MIXER_UNIT: {
08.05.2010 00:12, Daniel Mack пишет:
On Fri, May 07, 2010 at 05:19:24PM +0400, The Source wrote:
Bisect results:
23caaf19b11eda7054348452e1618d4512a86907 is the first bad commit commit 23caaf19b11eda7054348452e1618d4512a86907 Author: Daniel Mackdaniel@caiaq.de Date: Thu Mar 11 21:13:25 2010 +0100
ALSA: usb-mixer: Add support for Audio Class v2.0 USB Audio Class v2.0 compliant devices have different descriptors and a different way of setting/getting min/max/res/cur properties. This patch adds support for them. Signed-off-by: Daniel Mack<daniel@caiaq.de> Cc: Clemens Ladisch<clemens@ladisch.de> Signed-off-by: Takashi Iwai<tiwai@suse.de>
I've found two changes in this commit that are obviously wrong. Could you try the patch below please?
Sorry for the trouble.
Daniel
diff --git a/include/linux/usb/audio.h b/include/linux/usb/audio.h index 905a87c..57f2055 100644 --- a/include/linux/usb/audio.h +++ b/include/linux/usb/audio.h @@ -244,7 +244,7 @@ struct uac_selector_unit_descriptor { static inline __u8 uac_selector_unit_iSelector(struct uac_selector_unit_descriptor *desc) { __u8 *raw = (__u8 *) desc;
- return raw[desc->bLength - 1];
return raw[9 + desc->bLength - 1]; }
/* 4.3.2.5 Feature Unit Descriptor */
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index 21613fe..fa0fb77 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c @@ -656,7 +656,7 @@ static int check_input_term(struct mixer_build *state, int id, struct usb_audio_ case UAC_FEATURE_UNIT: { /* the header is the same for v1 and v2 */ struct uac_feature_unit_descriptor *d = p1;
id = d->bUnitID;
} case UAC_MIXER_UNIT: {id = d->bSourceID; break; /* continue to parse */
Can you create a patch against 1.0.23 alsa-driver package? It would be much easier (and faster) to test, thank you.
On Sat, May 08, 2010 at 01:32:49AM +0400, The Source wrote:
Can you create a patch against 1.0.23 alsa-driver package? It would be much easier (and faster) to test, thank you.
Is it really? The patch I sent should apply cleanly to a checkout of Linus' master + Takashi's sound-2.6.git, just like the tree you used for bisecting. This is also usually a much better way to keep up-to-date, and patches against ALSA releases are rather uncommon.
Daniel
08.05.2010 00:12, Daniel Mack пишет:
On Fri, May 07, 2010 at 05:19:24PM +0400, The Source wrote:
Bisect results:
23caaf19b11eda7054348452e1618d4512a86907 is the first bad commit commit 23caaf19b11eda7054348452e1618d4512a86907 Author: Daniel Mackdaniel@caiaq.de Date: Thu Mar 11 21:13:25 2010 +0100
ALSA: usb-mixer: Add support for Audio Class v2.0 USB Audio Class v2.0 compliant devices have different descriptors and a different way of setting/getting min/max/res/cur properties. This patch adds support for them. Signed-off-by: Daniel Mack<daniel@caiaq.de> Cc: Clemens Ladisch<clemens@ladisch.de> Signed-off-by: Takashi Iwai<tiwai@suse.de>
I've found two changes in this commit that are obviously wrong. Could you try the patch below please?
Sorry for the trouble.
Daniel
diff --git a/include/linux/usb/audio.h b/include/linux/usb/audio.h index 905a87c..57f2055 100644 --- a/include/linux/usb/audio.h +++ b/include/linux/usb/audio.h @@ -244,7 +244,7 @@ struct uac_selector_unit_descriptor { static inline __u8 uac_selector_unit_iSelector(struct uac_selector_unit_descriptor *desc) { __u8 *raw = (__u8 *) desc;
- return raw[desc->bLength - 1];
return raw[9 + desc->bLength - 1]; }
/* 4.3.2.5 Feature Unit Descriptor */
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index 21613fe..fa0fb77 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c @@ -656,7 +656,7 @@ static int check_input_term(struct mixer_build *state, int id, struct usb_audio_ case UAC_FEATURE_UNIT: { /* the header is the same for v1 and v2 */ struct uac_feature_unit_descriptor *d = p1;
id = d->bUnitID;
} case UAC_MIXER_UNIT: {id = d->bSourceID; break; /* continue to parse */
The patch did it (applied to latest git, or so I think - I used 'git bisect reset' to return to latest), now the card works properly (both playback and record), thank you very much.
On Sat, May 08, 2010 at 11:26:03AM +0400, The Source wrote:
08.05.2010 00:12, Daniel Mack пишет:
On Fri, May 07, 2010 at 05:19:24PM +0400, The Source wrote:
Bisect results:
23caaf19b11eda7054348452e1618d4512a86907 is the first bad commit commit 23caaf19b11eda7054348452e1618d4512a86907 Author: Daniel Mackdaniel@caiaq.de Date: Thu Mar 11 21:13:25 2010 +0100
ALSA: usb-mixer: Add support for Audio Class v2.0 USB Audio Class v2.0 compliant devices have different descriptors and a different way of setting/getting min/max/res/cur properties. This patch adds support for them. Signed-off-by: Daniel Mack<daniel@caiaq.de> Cc: Clemens Ladisch<clemens@ladisch.de> Signed-off-by: Takashi Iwai<tiwai@suse.de>
I've found two changes in this commit that are obviously wrong. Could you try the patch below please?
Sorry for the trouble.
Daniel
diff --git a/include/linux/usb/audio.h b/include/linux/usb/audio.h index 905a87c..57f2055 100644 --- a/include/linux/usb/audio.h +++ b/include/linux/usb/audio.h @@ -244,7 +244,7 @@ struct uac_selector_unit_descriptor { static inline __u8 uac_selector_unit_iSelector(struct uac_selector_unit_descriptor *desc) { __u8 *raw = (__u8 *) desc;
- return raw[desc->bLength - 1];
- return raw[9 + desc->bLength - 1];
}
/* 4.3.2.5 Feature Unit Descriptor */ diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index 21613fe..fa0fb77 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c @@ -656,7 +656,7 @@ static int check_input_term(struct mixer_build *state, int id, struct usb_audio_ case UAC_FEATURE_UNIT: { /* the header is the same for v1 and v2 */ struct uac_feature_unit_descriptor *d = p1;
id = d->bUnitID;
} case UAC_MIXER_UNIT: {id = d->bSourceID; break; /* continue to parse */
The patch did it (applied to latest git, or so I think - I used 'git bisect reset' to return to latest), now the card works properly (both playback and record), thank you very much.
Thank you for helping - much appreciated!
Daniel
Commit 23caaf19b ("ALSA: usb-mixer: Add support for Audio Class v2.0") broke support for Class1 devices due to two faulty changes. This patch fixes it.
Signed-off-by: Daniel Mack daniel@caiaq.de Reported-and-Tested-by: The Source thesourcehim@gmail.com Cc: Takashi Iwai tiwai@suse.de Cc: Clemens Ladisch clemens@ladisch.de --- include/linux/usb/audio.h | 2 +- sound/usb/mixer.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/include/linux/usb/audio.h b/include/linux/usb/audio.h index 905a87c..57f2055 100644 --- a/include/linux/usb/audio.h +++ b/include/linux/usb/audio.h @@ -244,7 +244,7 @@ struct uac_selector_unit_descriptor { static inline __u8 uac_selector_unit_iSelector(struct uac_selector_unit_descriptor *desc) { __u8 *raw = (__u8 *) desc; - return raw[desc->bLength - 1]; + return raw[9 + desc->bLength - 1]; }
/* 4.3.2.5 Feature Unit Descriptor */ diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index 21613fe..fa0fb77 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c @@ -656,7 +656,7 @@ static int check_input_term(struct mixer_build *state, int id, struct usb_audio_ case UAC_FEATURE_UNIT: { /* the header is the same for v1 and v2 */ struct uac_feature_unit_descriptor *d = p1; - id = d->bUnitID; + id = d->bSourceID; break; /* continue to parse */ } case UAC_MIXER_UNIT: {
At Sat, 8 May 2010 11:24:56 +0200, Daniel Mack wrote:
Commit 23caaf19b ("ALSA: usb-mixer: Add support for Audio Class v2.0") broke support for Class1 devices due to two faulty changes. This patch fixes it.
Signed-off-by: Daniel Mack daniel@caiaq.de Reported-and-Tested-by: The Source thesourcehim@gmail.com Cc: Takashi Iwai tiwai@suse.de Cc: Clemens Ladisch clemens@ladisch.de
Applied now. Thanks.
Takashi
include/linux/usb/audio.h | 2 +- sound/usb/mixer.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/include/linux/usb/audio.h b/include/linux/usb/audio.h index 905a87c..57f2055 100644 --- a/include/linux/usb/audio.h +++ b/include/linux/usb/audio.h @@ -244,7 +244,7 @@ struct uac_selector_unit_descriptor { static inline __u8 uac_selector_unit_iSelector(struct uac_selector_unit_descriptor *desc) { __u8 *raw = (__u8 *) desc;
- return raw[desc->bLength - 1];
- return raw[9 + desc->bLength - 1];
}
/* 4.3.2.5 Feature Unit Descriptor */ diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index 21613fe..fa0fb77 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c @@ -656,7 +656,7 @@ static int check_input_term(struct mixer_build *state, int id, struct usb_audio_ case UAC_FEATURE_UNIT: { /* the header is the same for v1 and v2 */ struct uac_feature_unit_descriptor *d = p1;
id = d->bUnitID;
} case UAC_MIXER_UNIT: {id = d->bSourceID; break; /* continue to parse */
-- 1.7.1
On Tue, Apr 27, 2010 at 04:23:48PM +0300, adelias wrote:
On 2/3/2010 8:35 μμ, Daniel Mack wrote:
On Tue, Mar 02, 2010 at 11:13:04AM +0200, adelias wrote:
Thanks to all involved for working on usb audio v2.
Last night I installed the 20100226 snapshot. I did a little testing with my XMOS board using toslink out into may DAC. I tried various files ranging 16bit/44110kHz-24bit/192000kHz. The 44110 files had quite a bit of static, the higher bitrate files were better. As you stated the sampling rate is not correct and be verified by looking at the flashing LEDs on the XMOS board. They should flash faster as sampling rate increase. In this case no change was observed.
Yes - this is all do be done. The sample rate setting is done with a different type of class request, which also addresses the interface now, unlike v1 devices which send that to the endpoint. But that's just one out of many differences that need to be addressed, and it's still a long way to go. I'm on it :)
Daniel
I upgraded alsa to 1.0.23. The XMOS device is working great with the exception of some mild clicks here and there. Is this a known issue or might it be a problem with my specific configuration?
What specific configuration are you testing with? As you have such an evaluation kit, I believe you're also provided with the XMOS development platform - which firmware did you install to the board?
Daniel
On 27/4/2010 5:06 μμ, Daniel Mack wrote:
On Tue, Apr 27, 2010 at 04:23:48PM +0300, adelias wrote:
On 2/3/2010 8:35 μμ, Daniel Mack wrote:
On Tue, Mar 02, 2010 at 11:13:04AM +0200, adelias wrote:
Thanks to all involved for working on usb audio v2.
Last night I installed the 20100226 snapshot. I did a little testing with my XMOS board using toslink out into may DAC. I tried various files ranging 16bit/44110kHz-24bit/192000kHz. The 44110 files had quite a bit of static, the higher bitrate files were better. As you stated the sampling rate is not correct and be verified by looking at the flashing LEDs on the XMOS board. They should flash faster as sampling rate increase. In this case no change was observed.
Yes - this is all do be done. The sample rate setting is done with a different type of class request, which also addresses the interface now, unlike v1 devices which send that to the endpoint. But that's just one out of many differences that need to be addressed, and it's still a long way to go. I'm on it :)
Daniel
I upgraded alsa to 1.0.23. The XMOS device is working great with the exception of some mild clicks here and there. Is this a known issue or might it be a problem with my specific configuration?
What specific configuration are you testing with? As you have such an evaluation kit, I believe you're also provided with the XMOS development platform - which firmware did you install to the board?
Daniel
Firmware is on 1v2. I'm not getting clicks on OSX 10.6.2 or Windows 7 with the ASIO driver.
On Mon, May 03, 2010 at 03:49:05PM +0300, adelias wrote:
On 27/4/2010 5:06 μμ, Daniel Mack wrote:
What specific configuration are you testing with? As you have such an evaluation kit, I believe you're also provided with the XMOS development platform - which firmware did you install to the board?
Daniel
Firmware is on 1v2. I'm not getting clicks on OSX 10.6.2 or Windows 7 with the ASIO driver.
Well, at least for OS X 10.6.2, there are problems in the class driver. Do some long-time measurements with inputs and outputs to meet them.
I would also suggest to try a newer firmware, 1v2 is rather old. If you still happen to have problems, let me know and I'll have another look.
Ironically, things don't work for me anymore currently with the Linux master git + sound-2.6. I'm getting XActErrors all over the place, but that's most probably not related to the driver itself but some regression in the Linux USB stack I believe. Could you try that as well?
Thanks, Daniel
On 4/5/2010 1:48 μμ, Daniel Mack wrote:
On Mon, May 03, 2010 at 03:49:05PM +0300, adelias wrote:
On 27/4/2010 5:06 μμ, Daniel Mack wrote:
What specific configuration are you testing with? As you have such an evaluation kit, I believe you're also provided with the XMOS development platform - which firmware did you install to the board?
Daniel
Firmware is on 1v2. I'm not getting clicks on OSX 10.6.2 or Windows 7 with the ASIO driver.
Well, at least for OS X 10.6.2, there are problems in the class driver. Do some long-time measurements with inputs and outputs to meet them.
I would also suggest to try a newer firmware, 1v2 is rather old. If you still happen to have problems, let me know and I'll have another look.
Ironically, things don't work for me anymore currently with the Linux master git + sound-2.6. I'm getting XActErrors all over the place, but that's most probably not related to the driver itself but some regression in the Linux USB stack I believe. Could you try that as well?
Thanks, Daniel
After upgrading XMOS firmware to 1v5, although the board is recognized, it no longer functions with alsa. Also needs to be reset before it is recognized in Windows.
On Tue, May 18, 2010 at 10:07:57AM +0300, adelias wrote:
On 4/5/2010 1:48 μμ, Daniel Mack wrote:
On Mon, May 03, 2010 at 03:49:05PM +0300, adelias wrote:
On 27/4/2010 5:06 μμ, Daniel Mack wrote:
What specific configuration are you testing with? As you have such an evaluation kit, I believe you're also provided with the XMOS development platform - which firmware did you install to the board?
Daniel
Firmware is on 1v2. I'm not getting clicks on OSX 10.6.2 or Windows 7 with the ASIO driver.
Well, at least for OS X 10.6.2, there are problems in the class driver. Do some long-time measurements with inputs and outputs to meet them.
I would also suggest to try a newer firmware, 1v2 is rather old. If you still happen to have problems, let me know and I'll have another look.
Ironically, things don't work for me anymore currently with the Linux master git + sound-2.6. I'm getting XActErrors all over the place, but that's most probably not related to the driver itself but some regression in the Linux USB stack I believe. Could you try that as well?
Thanks, Daniel
After upgrading XMOS firmware to 1v5, although the board is recognized, it no longer functions with alsa. Also needs to be reset before it is recognized in Windows.
Jup. I believe this is a firmware bug though, but I need to investigate again. Just to make sure you're seeing the same kind of error, could you send me your dmesg output that is produced when the device is plugged in?
Thanks, Daniel
On 18/5/2010 10:40 πμ, Daniel Mack wrote:
On Tue, May 18, 2010 at 10:07:57AM +0300, adelias wrote:
On 4/5/2010 1:48 μμ, Daniel Mack wrote:
On Mon, May 03, 2010 at 03:49:05PM +0300, adelias wrote:
On 27/4/2010 5:06 μμ, Daniel Mack wrote:
What specific configuration are you testing with? As you have such an evaluation kit, I believe you're also provided with the XMOS development platform - which firmware did you install to the board?
Daniel
Firmware is on 1v2. I'm not getting clicks on OSX 10.6.2 or Windows 7 with the ASIO driver.
Well, at least for OS X 10.6.2, there are problems in the class driver. Do some long-time measurements with inputs and outputs to meet them.
I would also suggest to try a newer firmware, 1v2 is rather old. If you still happen to have problems, let me know and I'll have another look.
Ironically, things don't work for me anymore currently with the Linux master git + sound-2.6. I'm getting XActErrors all over the place, but that's most probably not related to the driver itself but some regression in the Linux USB stack I believe. Could you try that as well?
Thanks, Daniel
After upgrading XMOS firmware to 1v5, although the board is recognized, it no longer functions with alsa. Also needs to be reset before it is recognized in Windows.
Jup. I believe this is a firmware bug though, but I need to investigate again. Just to make sure you're seeing the same kind of error, could you send me your dmesg output that is produced when the device is plugged in?
Thanks, Daniel
Sorry but I have already downgraded the firmware to 1v45 and will be testing with it this afternoon. Might there be anything of value in /var/log/messages?
On Tue, May 18, 2010 at 10:07:57AM +0300, adelias wrote:
On 4/5/2010 1:48 μμ, Daniel Mack wrote:
On Mon, May 03, 2010 at 03:49:05PM +0300, adelias wrote:
On 27/4/2010 5:06 μμ, Daniel Mack wrote:
What specific configuration are you testing with? As you have such an evaluation kit, I believe you're also provided with the XMOS development platform - which firmware did you install to the board?
Daniel
Firmware is on 1v2. I'm not getting clicks on OSX 10.6.2 or Windows 7 with the ASIO driver.
Well, at least for OS X 10.6.2, there are problems in the class driver. Do some long-time measurements with inputs and outputs to meet them.
I would also suggest to try a newer firmware, 1v2 is rather old. If you still happen to have problems, let me know and I'll have another look.
Ironically, things don't work for me anymore currently with the Linux master git + sound-2.6. I'm getting XActErrors all over the place, but that's most probably not related to the driver itself but some regression in the Linux USB stack I believe. Could you try that as well?
Thanks, Daniel
After upgrading XMOS firmware to 1v5, although the board is recognized, it no longer functions with alsa. Also needs to be reset before it is recognized in Windows.
I fixed this problem now - see my latest email to Takashi. The patch will likely be merged in a few days, but you could also give it a try by applying it manually (see below).
And I would still appreciate some testing feedback :)
Daniel
participants (5)
-
adelias
-
Clemens Ladisch
-
Daniel Mack
-
Takashi Iwai
-
The Source