~ubuntu-branches/ubuntu/precise/alsa-driver/precise

« back to all changes in this revision

Viewing changes to alsa-kernel/usb/endpoint.c

  • Committer: Bazaar Package Importer
  • Author(s): Luke Yelavich
  • Date: 2011-02-21 18:06:40 UTC
  • mfrom: (1.1.15 upstream)
  • Revision ID: james.westby@ubuntu.com-20110221180640-a8p2yxtvgf7xbxub
Tags: 1.0.24+dfsg-0ubuntu1
* New upstream release
* Refreshed patches:
  - distinguish_kernel_makefile_and_source_dirs.patch
  - debian_dfsg_configure.patch
* debian/control: Update Vcs-bzr field to point to new branch location

Show diffs side-by-side

added added

removed removed

Lines of Context:
33
33
#include "pcm.h"
34
34
#include "helper.h"
35
35
#include "format.h"
 
36
#include "clock.h"
36
37
 
37
38
/*
38
39
 * free a substream
149
150
        return 0;
150
151
}
151
152
 
 
153
static int parse_uac_endpoint_attributes(struct snd_usb_audio *chip,
 
154
                                         struct usb_host_interface *alts,
 
155
                                         int protocol, int iface_no)
 
156
{
 
157
        /* parsed with a v1 header here. that's ok as we only look at the
 
158
         * header first which is the same for both versions */
 
159
        struct uac_iso_endpoint_descriptor *csep;
 
160
        struct usb_interface_descriptor *altsd = get_iface_desc(alts);
 
161
        int attributes = 0;
 
162
 
 
163
        csep = snd_usb_find_desc(alts->endpoint[0].extra, alts->endpoint[0].extralen, NULL, USB_DT_CS_ENDPOINT);
 
164
 
 
165
        /* Creamware Noah has this descriptor after the 2nd endpoint */
 
166
        if (!csep && altsd->bNumEndpoints >= 2)
 
167
                csep = snd_usb_find_desc(alts->endpoint[1].extra, alts->endpoint[1].extralen, NULL, USB_DT_CS_ENDPOINT);
 
168
 
 
169
        if (!csep || csep->bLength < 7 ||
 
170
            csep->bDescriptorSubtype != UAC_EP_GENERAL) {
 
171
                snd_printk(KERN_WARNING "%d:%u:%d : no or invalid"
 
172
                           " class specific endpoint descriptor\n",
 
173
                           chip->dev->devnum, iface_no,
 
174
                           altsd->bAlternateSetting);
 
175
                return 0;
 
176
        }
 
177
 
 
178
        if (protocol == UAC_VERSION_1) {
 
179
                attributes = csep->bmAttributes;
 
180
        } else {
 
181
                struct uac2_iso_endpoint_descriptor *csep2 =
 
182
                        (struct uac2_iso_endpoint_descriptor *) csep;
 
183
 
 
184
                attributes = csep->bmAttributes & UAC_EP_CS_ATTR_FILL_MAX;
 
185
 
 
186
                /* emulate the endpoint attributes of a v1 device */
 
187
                if (csep2->bmControls & UAC2_CONTROL_PITCH)
 
188
                        attributes |= UAC_EP_CS_ATTR_PITCH_CONTROL;
 
189
        }
 
190
 
 
191
        return attributes;
 
192
}
 
193
 
 
194
static struct uac2_input_terminal_descriptor *
 
195
        snd_usb_find_input_terminal_descriptor(struct usb_host_interface *ctrl_iface,
 
196
                                               int terminal_id)
 
197
{
 
198
        struct uac2_input_terminal_descriptor *term = NULL;
 
199
 
 
200
        while ((term = snd_usb_find_csint_desc(ctrl_iface->extra,
 
201
                                               ctrl_iface->extralen,
 
202
                                               term, UAC_INPUT_TERMINAL))) {
 
203
                if (term->bTerminalID == terminal_id)
 
204
                        return term;
 
205
        }
 
206
 
 
207
        return NULL;
 
208
}
 
209
 
 
210
static struct uac2_output_terminal_descriptor *
 
211
        snd_usb_find_output_terminal_descriptor(struct usb_host_interface *ctrl_iface,
 
212
                                                int terminal_id)
 
213
{
 
214
        struct uac2_output_terminal_descriptor *term = NULL;
 
215
 
 
216
        while ((term = snd_usb_find_csint_desc(ctrl_iface->extra,
 
217
                                               ctrl_iface->extralen,
 
218
                                               term, UAC_OUTPUT_TERMINAL))) {
 
219
                if (term->bTerminalID == terminal_id)
 
220
                        return term;
 
221
        }
 
222
 
 
223
        return NULL;
 
224
}
 
225
 
152
226
int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
153
227
{
154
228
        struct usb_device *dev;
158
232
        int i, altno, err, stream;
159
233
        int format = 0, num_channels = 0;
160
234
        struct audioformat *fp = NULL;
161
 
        unsigned char *fmt, *csep;
162
 
        int num, protocol;
 
235
        int num, protocol, clock = 0;
 
236
        struct uac_format_type_i_continuous_descriptor *fmt;
163
237
 
164
238
        dev = chip->dev;
165
239
 
201
275
 
202
276
                /* get audio formats */
203
277
                switch (protocol) {
 
278
                default:
 
279
                        snd_printdd(KERN_WARNING "%d:%u:%d: unknown interface protocol %#02x, assuming v1\n",
 
280
                                    dev->devnum, iface_no, altno, protocol);
 
281
                        protocol = UAC_VERSION_1;
 
282
                        /* fall through */
 
283
 
204
284
                case UAC_VERSION_1: {
205
 
                        struct uac_as_header_descriptor_v1 *as =
 
285
                        struct uac1_as_header_descriptor *as =
206
286
                                snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_AS_GENERAL);
207
287
 
208
288
                        if (!as) {
222
302
                }
223
303
 
224
304
                case UAC_VERSION_2: {
225
 
                        struct uac_as_header_descriptor_v2 *as =
 
305
                        struct uac2_input_terminal_descriptor *input_term;
 
306
                        struct uac2_output_terminal_descriptor *output_term;
 
307
                        struct uac2_as_header_descriptor *as =
226
308
                                snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_AS_GENERAL);
227
309
 
228
310
                        if (!as) {
240
322
                        num_channels = as->bNrChannels;
241
323
                        format = le32_to_cpu(as->bmFormats);
242
324
 
243
 
                        break;
244
 
                }
245
 
 
246
 
                default:
247
 
                        snd_printk(KERN_ERR "%d:%u:%d : unknown interface protocol %04x\n",
248
 
                                   dev->devnum, iface_no, altno, protocol);
 
325
                        /* lookup the terminal associated to this interface
 
326
                         * to extract the clock */
 
327
                        input_term = snd_usb_find_input_terminal_descriptor(chip->ctrl_intf,
 
328
                                                                            as->bTerminalLink);
 
329
                        if (input_term) {
 
330
                                clock = input_term->bCSourceID;
 
331
                                break;
 
332
                        }
 
333
 
 
334
                        output_term = snd_usb_find_output_terminal_descriptor(chip->ctrl_intf,
 
335
                                                                              as->bTerminalLink);
 
336
                        if (output_term) {
 
337
                                clock = output_term->bCSourceID;
 
338
                                break;
 
339
                        }
 
340
 
 
341
                        snd_printk(KERN_ERR "%d:%u:%d : bogus bTerminalLink %d\n",
 
342
                                   dev->devnum, iface_no, altno, as->bTerminalLink);
249
343
                        continue;
250
344
                }
 
345
                }
251
346
 
252
347
                /* get format type */
253
348
                fmt = snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_FORMAT_TYPE);
256
351
                                   dev->devnum, iface_no, altno);
257
352
                        continue;
258
353
                }
259
 
                if (((protocol == UAC_VERSION_1) && (fmt[0] < 8)) ||
260
 
                    ((protocol == UAC_VERSION_2) && (fmt[0] != 6))) {
 
354
                if (((protocol == UAC_VERSION_1) && (fmt->bLength < 8)) ||
 
355
                    ((protocol == UAC_VERSION_2) && (fmt->bLength != 6))) {
261
356
                        snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_FORMAT_TYPE desc\n",
262
357
                                   dev->devnum, iface_no, altno);
263
358
                        continue;
268
363
                 * with the previous one, except for a larger packet size, but
269
364
                 * is actually a mislabeled two-channel setting; ignore it.
270
365
                 */
271
 
                if (fmt[4] == 1 && fmt[5] == 2 && altno == 2 && num == 3 &&
 
366
                if (fmt->bNrChannels == 1 &&
 
367
                    fmt->bSubframeSize == 2 &&
 
368
                    altno == 2 && num == 3 &&
272
369
                    fp && fp->altsetting == 1 && fp->channels == 1 &&
273
370
                    fp->formats == SNDRV_PCM_FMTBIT_S16_LE &&
274
371
                    protocol == UAC_VERSION_1 &&
276
373
                                                        fp->maxpacksize * 2)
277
374
                        continue;
278
375
 
279
 
                csep = snd_usb_find_desc(alts->endpoint[0].extra, alts->endpoint[0].extralen, NULL, USB_DT_CS_ENDPOINT);
280
 
                /* Creamware Noah has this descriptor after the 2nd endpoint */
281
 
                if (!csep && altsd->bNumEndpoints >= 2)
282
 
                        csep = snd_usb_find_desc(alts->endpoint[1].extra, alts->endpoint[1].extralen, NULL, USB_DT_CS_ENDPOINT);
283
 
                if (!csep || csep[0] < 7 || csep[2] != UAC_EP_GENERAL) {
284
 
                        snd_printk(KERN_WARNING "%d:%u:%d : no or invalid"
285
 
                                   " class specific endpoint descriptor\n",
286
 
                                   dev->devnum, iface_no, altno);
287
 
                        csep = NULL;
288
 
                }
289
 
 
290
376
                fp = kzalloc(sizeof(*fp), GFP_KERNEL);
291
377
                if (! fp) {
292
378
                        snd_printk(KERN_ERR "cannot malloc\n");
305
391
                if (snd_usb_get_speed(dev) == USB_SPEED_HIGH)
306
392
                        fp->maxpacksize = (((fp->maxpacksize >> 11) & 3) + 1)
307
393
                                        * (fp->maxpacksize & 0x7ff);
308
 
                fp->attributes = csep ? csep[3] : 0;
 
394
                fp->attributes = parse_uac_endpoint_attributes(chip, alts, protocol, iface_no);
 
395
                fp->clock = clock;
309
396
 
310
397
                /* some quirks for attributes here */
311
398
 
318
405
                        break;
319
406
                case USB_ID(0x041e, 0x3020): /* Creative SB Audigy 2 NX */
320
407
                case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */
321
 
                case USB_ID(0x0763, 0x2080): /* M-Audio Fast Track Ultra 8 */
322
 
                case USB_ID(0x0763, 0x2081): /* M-Audio Fast Track Ultra 8R */
323
408
                        /* doesn't set the sample rate attribute, but supports it */
324
409
                        fp->attributes |= UAC_EP_CS_ATTR_SAMPLE_RATE;
325
410
                        break;
342
427
                if (snd_usb_parse_audio_format(chip, fp, format, fmt, stream, alts) < 0) {
343
428
                        kfree(fp->rate_table);
344
429
                        kfree(fp);
 
430
                        fp = NULL;
345
431
                        continue;
346
432
                }
347
433