diff options
Diffstat (limited to 'sound/usb')
-rw-r--r-- | sound/usb/usbaudio.c | 93 |
1 files changed, 31 insertions, 62 deletions
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c index e1a648d7ffff..a5e97d081c3b 100644 --- a/sound/usb/usbaudio.c +++ b/sound/usb/usbaudio.c | |||
@@ -177,7 +177,7 @@ struct snd_usb_substream { | |||
177 | unsigned int nurbs; /* # urbs */ | 177 | unsigned int nurbs; /* # urbs */ |
178 | snd_urb_ctx_t dataurb[MAX_URBS]; /* data urb table */ | 178 | snd_urb_ctx_t dataurb[MAX_URBS]; /* data urb table */ |
179 | snd_urb_ctx_t syncurb[SYNC_URBS]; /* sync urb table */ | 179 | snd_urb_ctx_t syncurb[SYNC_URBS]; /* sync urb table */ |
180 | char syncbuf[SYNC_URBS * MAX_PACKS * 4]; /* sync buffer; it's so small - let's get static */ | 180 | char syncbuf[SYNC_URBS * 4]; /* sync buffer; it's so small - let's get static */ |
181 | char *tmpbuf; /* temporary buffer for playback */ | 181 | char *tmpbuf; /* temporary buffer for playback */ |
182 | 182 | ||
183 | u64 formats; /* format bitmasks (all or'ed) */ | 183 | u64 formats; /* format bitmasks (all or'ed) */ |
@@ -251,17 +251,13 @@ static int prepare_capture_sync_urb(snd_usb_substream_t *subs, | |||
251 | { | 251 | { |
252 | unsigned char *cp = urb->transfer_buffer; | 252 | unsigned char *cp = urb->transfer_buffer; |
253 | snd_urb_ctx_t *ctx = (snd_urb_ctx_t *)urb->context; | 253 | snd_urb_ctx_t *ctx = (snd_urb_ctx_t *)urb->context; |
254 | int i, offs; | ||
255 | 254 | ||
256 | urb->number_of_packets = ctx->packets; | ||
257 | urb->dev = ctx->subs->dev; /* we need to set this at each time */ | 255 | urb->dev = ctx->subs->dev; /* we need to set this at each time */ |
258 | for (i = offs = 0; i < urb->number_of_packets; i++, offs += 4, cp += 4) { | 256 | urb->iso_frame_desc[0].length = 3; |
259 | urb->iso_frame_desc[i].length = 3; | 257 | urb->iso_frame_desc[0].offset = 0; |
260 | urb->iso_frame_desc[i].offset = offs; | 258 | cp[0] = subs->freqn >> 2; |
261 | cp[0] = subs->freqn >> 2; | 259 | cp[1] = subs->freqn >> 10; |
262 | cp[1] = subs->freqn >> 10; | 260 | cp[2] = subs->freqn >> 18; |
263 | cp[2] = subs->freqn >> 18; | ||
264 | } | ||
265 | return 0; | 261 | return 0; |
266 | } | 262 | } |
267 | 263 | ||
@@ -277,18 +273,14 @@ static int prepare_capture_sync_urb_hs(snd_usb_substream_t *subs, | |||
277 | { | 273 | { |
278 | unsigned char *cp = urb->transfer_buffer; | 274 | unsigned char *cp = urb->transfer_buffer; |
279 | snd_urb_ctx_t *ctx = (snd_urb_ctx_t *)urb->context; | 275 | snd_urb_ctx_t *ctx = (snd_urb_ctx_t *)urb->context; |
280 | int i, offs; | ||
281 | 276 | ||
282 | urb->number_of_packets = ctx->packets; | ||
283 | urb->dev = ctx->subs->dev; /* we need to set this at each time */ | 277 | urb->dev = ctx->subs->dev; /* we need to set this at each time */ |
284 | for (i = offs = 0; i < urb->number_of_packets; i++, offs += 4, cp += 4) { | 278 | urb->iso_frame_desc[0].length = 4; |
285 | urb->iso_frame_desc[i].length = 4; | 279 | urb->iso_frame_desc[0].offset = 0; |
286 | urb->iso_frame_desc[i].offset = offs; | 280 | cp[0] = subs->freqn; |
287 | cp[0] = subs->freqn; | 281 | cp[1] = subs->freqn >> 8; |
288 | cp[1] = subs->freqn >> 8; | 282 | cp[2] = subs->freqn >> 16; |
289 | cp[2] = subs->freqn >> 16; | 283 | cp[3] = subs->freqn >> 24; |
290 | cp[3] = subs->freqn >> 24; | ||
291 | } | ||
292 | return 0; | 284 | return 0; |
293 | } | 285 | } |
294 | 286 | ||
@@ -418,15 +410,11 @@ static int prepare_playback_sync_urb(snd_usb_substream_t *subs, | |||
418 | snd_pcm_runtime_t *runtime, | 410 | snd_pcm_runtime_t *runtime, |
419 | struct urb *urb) | 411 | struct urb *urb) |
420 | { | 412 | { |
421 | int i, offs; | ||
422 | snd_urb_ctx_t *ctx = (snd_urb_ctx_t *)urb->context; | 413 | snd_urb_ctx_t *ctx = (snd_urb_ctx_t *)urb->context; |
423 | 414 | ||
424 | urb->number_of_packets = ctx->packets; | ||
425 | urb->dev = ctx->subs->dev; /* we need to set this at each time */ | 415 | urb->dev = ctx->subs->dev; /* we need to set this at each time */ |
426 | for (i = offs = 0; i < urb->number_of_packets; i++, offs += 4) { | 416 | urb->iso_frame_desc[0].length = 3; |
427 | urb->iso_frame_desc[i].length = 3; | 417 | urb->iso_frame_desc[0].offset = 0; |
428 | urb->iso_frame_desc[i].offset = offs; | ||
429 | } | ||
430 | return 0; | 418 | return 0; |
431 | } | 419 | } |
432 | 420 | ||
@@ -440,15 +428,11 @@ static int prepare_playback_sync_urb_hs(snd_usb_substream_t *subs, | |||
440 | snd_pcm_runtime_t *runtime, | 428 | snd_pcm_runtime_t *runtime, |
441 | struct urb *urb) | 429 | struct urb *urb) |
442 | { | 430 | { |
443 | int i, offs; | ||
444 | snd_urb_ctx_t *ctx = (snd_urb_ctx_t *)urb->context; | 431 | snd_urb_ctx_t *ctx = (snd_urb_ctx_t *)urb->context; |
445 | 432 | ||
446 | urb->number_of_packets = ctx->packets; | ||
447 | urb->dev = ctx->subs->dev; /* we need to set this at each time */ | 433 | urb->dev = ctx->subs->dev; /* we need to set this at each time */ |
448 | for (i = offs = 0; i < urb->number_of_packets; i++, offs += 4) { | 434 | urb->iso_frame_desc[0].length = 4; |
449 | urb->iso_frame_desc[i].length = 4; | 435 | urb->iso_frame_desc[0].offset = 0; |
450 | urb->iso_frame_desc[i].offset = offs; | ||
451 | } | ||
452 | return 0; | 436 | return 0; |
453 | } | 437 | } |
454 | 438 | ||
@@ -462,17 +446,12 @@ static int retire_playback_sync_urb(snd_usb_substream_t *subs, | |||
462 | snd_pcm_runtime_t *runtime, | 446 | snd_pcm_runtime_t *runtime, |
463 | struct urb *urb) | 447 | struct urb *urb) |
464 | { | 448 | { |
465 | int i; | 449 | unsigned int f; |
466 | unsigned int f, found; | ||
467 | unsigned char *cp = urb->transfer_buffer; | ||
468 | unsigned long flags; | 450 | unsigned long flags; |
469 | 451 | ||
470 | found = 0; | 452 | if (urb->iso_frame_desc[0].status == 0 && |
471 | for (i = 0; i < urb->number_of_packets; i++, cp += 4) { | 453 | urb->iso_frame_desc[0].actual_length == 3) { |
472 | if (urb->iso_frame_desc[i].status || | 454 | f = combine_triple((u8*)urb->transfer_buffer) << 2; |
473 | urb->iso_frame_desc[i].actual_length < 3) | ||
474 | continue; | ||
475 | f = combine_triple(cp) << 2; | ||
476 | #if 0 | 455 | #if 0 |
477 | if (f < subs->freqn - (subs->freqn>>3) || f > subs->freqmax) { | 456 | if (f < subs->freqn - (subs->freqn>>3) || f > subs->freqmax) { |
478 | snd_printd(KERN_WARNING "requested frequency %d (%u,%03uHz) out of range (current nominal %d (%u,%03uHz))\n", | 457 | snd_printd(KERN_WARNING "requested frequency %d (%u,%03uHz) out of range (current nominal %d (%u,%03uHz))\n", |
@@ -481,11 +460,8 @@ static int retire_playback_sync_urb(snd_usb_substream_t *subs, | |||
481 | continue; | 460 | continue; |
482 | } | 461 | } |
483 | #endif | 462 | #endif |
484 | found = f; | ||
485 | } | ||
486 | if (found) { | ||
487 | spin_lock_irqsave(&subs->lock, flags); | 463 | spin_lock_irqsave(&subs->lock, flags); |
488 | subs->freqm = found; | 464 | subs->freqm = f; |
489 | spin_unlock_irqrestore(&subs->lock, flags); | 465 | spin_unlock_irqrestore(&subs->lock, flags); |
490 | } | 466 | } |
491 | 467 | ||
@@ -502,21 +478,14 @@ static int retire_playback_sync_urb_hs(snd_usb_substream_t *subs, | |||
502 | snd_pcm_runtime_t *runtime, | 478 | snd_pcm_runtime_t *runtime, |
503 | struct urb *urb) | 479 | struct urb *urb) |
504 | { | 480 | { |
505 | int i; | 481 | unsigned int f; |
506 | unsigned int found; | ||
507 | unsigned char *cp = urb->transfer_buffer; | ||
508 | unsigned long flags; | 482 | unsigned long flags; |
509 | 483 | ||
510 | found = 0; | 484 | if (urb->iso_frame_desc[0].status == 0 && |
511 | for (i = 0; i < urb->number_of_packets; i++, cp += 4) { | 485 | urb->iso_frame_desc[0].actual_length == 4) { |
512 | if (urb->iso_frame_desc[i].status || | 486 | f = combine_quad((u8*)urb->transfer_buffer) & 0x0fffffff; |
513 | urb->iso_frame_desc[i].actual_length < 4) | ||
514 | continue; | ||
515 | found = combine_quad(cp) & 0x0fffffff; | ||
516 | } | ||
517 | if (found) { | ||
518 | spin_lock_irqsave(&subs->lock, flags); | 487 | spin_lock_irqsave(&subs->lock, flags); |
519 | subs->freqm = found; | 488 | subs->freqm = f; |
520 | spin_unlock_irqrestore(&subs->lock, flags); | 489 | spin_unlock_irqrestore(&subs->lock, flags); |
521 | } | 490 | } |
522 | 491 | ||
@@ -1039,18 +1008,18 @@ static int init_substream_urbs(snd_usb_substream_t *subs, unsigned int period_by | |||
1039 | snd_urb_ctx_t *u = &subs->syncurb[i]; | 1008 | snd_urb_ctx_t *u = &subs->syncurb[i]; |
1040 | u->index = i; | 1009 | u->index = i; |
1041 | u->subs = subs; | 1010 | u->subs = subs; |
1042 | u->packets = nrpacks; | 1011 | u->packets = 1; |
1043 | u->urb = usb_alloc_urb(u->packets, GFP_KERNEL); | 1012 | u->urb = usb_alloc_urb(1, GFP_KERNEL); |
1044 | if (! u->urb) { | 1013 | if (! u->urb) { |
1045 | release_substream_urbs(subs, 0); | 1014 | release_substream_urbs(subs, 0); |
1046 | return -ENOMEM; | 1015 | return -ENOMEM; |
1047 | } | 1016 | } |
1048 | u->urb->transfer_buffer = subs->syncbuf + i * nrpacks * 4; | 1017 | u->urb->transfer_buffer = subs->syncbuf + i * 4; |
1049 | u->urb->transfer_buffer_length = nrpacks * 4; | 1018 | u->urb->transfer_buffer_length = 4; |
1050 | u->urb->dev = subs->dev; | 1019 | u->urb->dev = subs->dev; |
1051 | u->urb->pipe = subs->syncpipe; | 1020 | u->urb->pipe = subs->syncpipe; |
1052 | u->urb->transfer_flags = URB_ISO_ASAP; | 1021 | u->urb->transfer_flags = URB_ISO_ASAP; |
1053 | u->urb->number_of_packets = u->packets; | 1022 | u->urb->number_of_packets = 1; |
1054 | u->urb->interval = 1 << subs->syncinterval; | 1023 | u->urb->interval = 1 << subs->syncinterval; |
1055 | u->urb->context = u; | 1024 | u->urb->context = u; |
1056 | u->urb->complete = snd_usb_complete_callback(snd_complete_sync_urb); | 1025 | u->urb->complete = snd_usb_complete_callback(snd_complete_sync_urb); |