aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/usb/card.h2
-rw-r--r--sound/usb/pcm.c2
-rw-r--r--sound/usb/proc.c5
-rw-r--r--sound/usb/urb.c170
4 files changed, 67 insertions, 112 deletions
diff --git a/sound/usb/card.h b/sound/usb/card.h
index 1febf2f23754..ae4251d5abf7 100644
--- a/sound/usb/card.h
+++ b/sound/usb/card.h
@@ -62,12 +62,14 @@ struct snd_usb_substream {
62 unsigned int syncinterval; /* P for adaptive mode, 0 otherwise */ 62 unsigned int syncinterval; /* P for adaptive mode, 0 otherwise */
63 unsigned int freqn; /* nominal sampling rate in fs/fps in Q16.16 format */ 63 unsigned int freqn; /* nominal sampling rate in fs/fps in Q16.16 format */
64 unsigned int freqm; /* momentary sampling rate in fs/fps in Q16.16 format */ 64 unsigned int freqm; /* momentary sampling rate in fs/fps in Q16.16 format */
65 int freqshift; /* how much to shift the feedback value to get Q16.16 */
65 unsigned int freqmax; /* maximum sampling rate, used for buffer management */ 66 unsigned int freqmax; /* maximum sampling rate, used for buffer management */
66 unsigned int phase; /* phase accumulator */ 67 unsigned int phase; /* phase accumulator */
67 unsigned int maxpacksize; /* max packet size in bytes */ 68 unsigned int maxpacksize; /* max packet size in bytes */
68 unsigned int maxframesize; /* max packet size in frames */ 69 unsigned int maxframesize; /* max packet size in frames */
69 unsigned int curpacksize; /* current packet size in bytes (for capture) */ 70 unsigned int curpacksize; /* current packet size in bytes (for capture) */
70 unsigned int curframesize; /* current packet size in frames (for capture) */ 71 unsigned int curframesize; /* current packet size in frames (for capture) */
72 unsigned int syncmaxsize; /* sync endpoint packet size */
71 unsigned int fill_max: 1; /* fill max packet size always */ 73 unsigned int fill_max: 1; /* fill max packet size always */
72 unsigned int txfr_quirk:1; /* allow sub-frame alignment */ 74 unsigned int txfr_quirk:1; /* allow sub-frame alignment */
73 unsigned int fmt_type; /* USB audio format type (1-3) */ 75 unsigned int fmt_type; /* USB audio format type (1-3) */
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c
index f49756c1b837..cff3a3c465d7 100644
--- a/sound/usb/pcm.c
+++ b/sound/usb/pcm.c
@@ -237,6 +237,7 @@ static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt)
237 subs->datainterval = fmt->datainterval; 237 subs->datainterval = fmt->datainterval;
238 subs->syncpipe = subs->syncinterval = 0; 238 subs->syncpipe = subs->syncinterval = 0;
239 subs->maxpacksize = fmt->maxpacksize; 239 subs->maxpacksize = fmt->maxpacksize;
240 subs->syncmaxsize = 0;
240 subs->fill_max = 0; 241 subs->fill_max = 0;
241 242
242 /* we need a sync pipe in async OUT or adaptive IN mode */ 243 /* we need a sync pipe in async OUT or adaptive IN mode */
@@ -283,6 +284,7 @@ static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt)
283 subs->syncinterval = get_endpoint(alts, 1)->bInterval - 1; 284 subs->syncinterval = get_endpoint(alts, 1)->bInterval - 1;
284 else 285 else
285 subs->syncinterval = 3; 286 subs->syncinterval = 3;
287 subs->syncmaxsize = le16_to_cpu(get_endpoint(alts, 1)->wMaxPacketSize);
286 } 288 }
287 289
288 /* always fill max packet size */ 290 /* always fill max packet size */
diff --git a/sound/usb/proc.c b/sound/usb/proc.c
index 3c650ab3c91d..961c9a250686 100644
--- a/sound/usb/proc.c
+++ b/sound/usb/proc.c
@@ -132,6 +132,11 @@ static void proc_dump_substream_status(struct snd_usb_substream *subs, struct sn
132 ? get_full_speed_hz(subs->freqm) 132 ? get_full_speed_hz(subs->freqm)
133 : get_high_speed_hz(subs->freqm), 133 : get_high_speed_hz(subs->freqm),
134 subs->freqm >> 16, subs->freqm & 0xffff); 134 subs->freqm >> 16, subs->freqm & 0xffff);
135 if (subs->freqshift != INT_MIN)
136 snd_iprintf(buffer, " Feedback Format = %d.%d\n",
137 (subs->syncmaxsize > 3 ? 32 : 24)
138 - (16 - subs->freqshift),
139 16 - subs->freqshift);
135 } else { 140 } else {
136 snd_iprintf(buffer, " Status: Stop\n"); 141 snd_iprintf(buffer, " Status: Stop\n");
137 } 142 }
diff --git a/sound/usb/urb.c b/sound/usb/urb.c
index 8deeaad10f10..e184349aee83 100644
--- a/sound/usb/urb.c
+++ b/sound/usb/urb.c
@@ -225,6 +225,7 @@ int snd_usb_init_substream_urbs(struct snd_usb_substream *subs,
225 else 225 else
226 subs->freqn = get_usb_high_speed_rate(rate); 226 subs->freqn = get_usb_high_speed_rate(rate);
227 subs->freqm = subs->freqn; 227 subs->freqm = subs->freqn;
228 subs->freqshift = INT_MIN;
228 /* calculate max. frequency */ 229 /* calculate max. frequency */
229 if (subs->maxpacksize) { 230 if (subs->maxpacksize) {
230 /* whatever fits into a max. size packet */ 231 /* whatever fits into a max. size packet */
@@ -513,11 +514,10 @@ static int retire_paused_capture_urb(struct snd_usb_substream *subs,
513 514
514 515
515/* 516/*
516 * prepare urb for full speed playback sync pipe 517 * prepare urb for playback sync pipe
517 * 518 *
518 * set up the offset and length to receive the current frequency. 519 * set up the offset and length to receive the current frequency.
519 */ 520 */
520
521static int prepare_playback_sync_urb(struct snd_usb_substream *subs, 521static int prepare_playback_sync_urb(struct snd_usb_substream *subs,
522 struct snd_pcm_runtime *runtime, 522 struct snd_pcm_runtime *runtime,
523 struct urb *urb) 523 struct urb *urb)
@@ -525,103 +525,78 @@ static int prepare_playback_sync_urb(struct snd_usb_substream *subs,
525 struct snd_urb_ctx *ctx = urb->context; 525 struct snd_urb_ctx *ctx = urb->context;
526 526
527 urb->dev = ctx->subs->dev; /* we need to set this at each time */ 527 urb->dev = ctx->subs->dev; /* we need to set this at each time */
528 urb->iso_frame_desc[0].length = 3; 528 urb->iso_frame_desc[0].length = min(4u, ctx->subs->syncmaxsize);
529 urb->iso_frame_desc[0].offset = 0; 529 urb->iso_frame_desc[0].offset = 0;
530 return 0; 530 return 0;
531} 531}
532 532
533/* 533/*
534 * prepare urb for high speed playback sync pipe 534 * process after playback sync complete
535 * 535 *
536 * set up the offset and length to receive the current frequency. 536 * Full speed devices report feedback values in 10.14 format as samples per
537 */ 537 * frame, high speed devices in 16.16 format as samples per microframe.
538 538 * Because the Audio Class 1 spec was written before USB 2.0, many high speed
539static int prepare_playback_sync_urb_hs(struct snd_usb_substream *subs, 539 * devices use a wrong interpretation, some others use an entirely different
540 struct snd_pcm_runtime *runtime, 540 * format. Therefore, we cannot predict what format any particular device uses
541 struct urb *urb) 541 * and must detect it automatically.
542{
543 struct snd_urb_ctx *ctx = urb->context;
544
545 urb->dev = ctx->subs->dev; /* we need to set this at each time */
546 urb->iso_frame_desc[0].length = 4;
547 urb->iso_frame_desc[0].offset = 0;
548 return 0;
549}
550
551/*
552 * process after full speed playback sync complete
553 *
554 * retrieve the current 10.14 frequency from pipe, and set it.
555 * the value is referred in prepare_playback_urb().
556 */ 542 */
557static int retire_playback_sync_urb(struct snd_usb_substream *subs, 543static int retire_playback_sync_urb(struct snd_usb_substream *subs,
558 struct snd_pcm_runtime *runtime, 544 struct snd_pcm_runtime *runtime,
559 struct urb *urb) 545 struct urb *urb)
560{ 546{
561 unsigned int f; 547 unsigned int f;
548 int shift;
562 unsigned long flags; 549 unsigned long flags;
563 550
564 if (urb->iso_frame_desc[0].status == 0 && 551 if (urb->iso_frame_desc[0].status != 0 ||
565 urb->iso_frame_desc[0].actual_length == 3) { 552 urb->iso_frame_desc[0].actual_length < 3)
566 f = combine_triple((u8*)urb->transfer_buffer) << 2; 553 return 0;
567 if (f >= subs->freqn - subs->freqn / 8 && f <= subs->freqmax) {
568 spin_lock_irqsave(&subs->lock, flags);
569 subs->freqm = f;
570 spin_unlock_irqrestore(&subs->lock, flags);
571 }
572 }
573
574 return 0;
575}
576 554
577/* 555 f = le32_to_cpup(urb->transfer_buffer);
578 * process after high speed playback sync complete 556 if (urb->iso_frame_desc[0].actual_length == 3)
579 * 557 f &= 0x00ffffff;
580 * retrieve the current 12.13 frequency from pipe, and set it. 558 else
581 * the value is referred in prepare_playback_urb(). 559 f &= 0x0fffffff;
582 */ 560 if (f == 0)
583static int retire_playback_sync_urb_hs(struct snd_usb_substream *subs, 561 return 0;
584 struct snd_pcm_runtime *runtime,
585 struct urb *urb)
586{
587 unsigned int f;
588 unsigned long flags;
589 562
590 if (urb->iso_frame_desc[0].status == 0 && 563 if (unlikely(subs->freqshift == INT_MIN)) {
591 urb->iso_frame_desc[0].actual_length == 4) { 564 /*
592 f = combine_quad((u8*)urb->transfer_buffer) & 0x0fffffff; 565 * The first time we see a feedback value, determine its format
593 if (f >= subs->freqn - subs->freqn / 8 && f <= subs->freqmax) { 566 * by shifting it left or right until it matches the nominal
594 spin_lock_irqsave(&subs->lock, flags); 567 * frequency value. This assumes that the feedback does not
595 subs->freqm = f; 568 * differ from the nominal value more than +50% or -25%.
596 spin_unlock_irqrestore(&subs->lock, flags); 569 */
570 shift = 0;
571 while (f < subs->freqn - subs->freqn / 4) {
572 f <<= 1;
573 shift++;
574 }
575 while (f > subs->freqn + subs->freqn / 2) {
576 f >>= 1;
577 shift--;
597 } 578 }
579 subs->freqshift = shift;
598 } 580 }
581 else if (subs->freqshift >= 0)
582 f <<= subs->freqshift;
583 else
584 f >>= -subs->freqshift;
599 585
600 return 0; 586 if (likely(f >= subs->freqn - subs->freqn / 8 && f <= subs->freqmax)) {
601} 587 /*
602 588 * If the frequency looks valid, set it.
603/* 589 * This value is referred to in prepare_playback_urb().
604 * process after E-Mu 0202/0404/Tracker Pre high speed playback sync complete 590 */
605 * 591 spin_lock_irqsave(&subs->lock, flags);
606 * These devices return the number of samples per packet instead of the number 592 subs->freqm = f;
607 * of samples per microframe. 593 spin_unlock_irqrestore(&subs->lock, flags);
608 */ 594 } else {
609static int retire_playback_sync_urb_hs_emu(struct snd_usb_substream *subs, 595 /*
610 struct snd_pcm_runtime *runtime, 596 * Out of range; maybe the shift value is wrong.
611 struct urb *urb) 597 * Reset it so that we autodetect again the next time.
612{ 598 */
613 unsigned int f; 599 subs->freqshift = INT_MIN;
614 unsigned long flags;
615
616 if (urb->iso_frame_desc[0].status == 0 &&
617 urb->iso_frame_desc[0].actual_length == 4) {
618 f = combine_quad((u8*)urb->transfer_buffer) & 0x0fffffff;
619 f >>= subs->datainterval;
620 if (f >= subs->freqn - subs->freqn / 8 && f <= subs->freqmax) {
621 spin_lock_irqsave(&subs->lock, flags);
622 subs->freqm = f;
623 spin_unlock_irqrestore(&subs->lock, flags);
624 }
625 } 600 }
626 601
627 return 0; 602 return 0;
@@ -878,21 +853,6 @@ static struct snd_urb_ops audio_urb_ops[2] = {
878 }, 853 },
879}; 854};
880 855
881static struct snd_urb_ops audio_urb_ops_high_speed[2] = {
882 {
883 .prepare = prepare_nodata_playback_urb,
884 .retire = retire_playback_urb,
885 .prepare_sync = prepare_playback_sync_urb_hs,
886 .retire_sync = retire_playback_sync_urb_hs,
887 },
888 {
889 .prepare = prepare_capture_urb,
890 .retire = retire_capture_urb,
891 .prepare_sync = prepare_capture_sync_urb_hs,
892 .retire_sync = retire_capture_sync_urb,
893 },
894};
895
896/* 856/*
897 * initialize the substream instance. 857 * initialize the substream instance.
898 */ 858 */
@@ -909,23 +869,9 @@ void snd_usb_init_substream(struct snd_usb_stream *as,
909 subs->direction = stream; 869 subs->direction = stream;
910 subs->dev = as->chip->dev; 870 subs->dev = as->chip->dev;
911 subs->txfr_quirk = as->chip->txfr_quirk; 871 subs->txfr_quirk = as->chip->txfr_quirk;
912 if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL) { 872 subs->ops = audio_urb_ops[stream];
913 subs->ops = audio_urb_ops[stream]; 873 if (snd_usb_get_speed(subs->dev) >= USB_SPEED_HIGH)
914 } else { 874 subs->ops.prepare_sync = prepare_capture_sync_urb_hs;
915 subs->ops = audio_urb_ops_high_speed[stream];
916 switch (as->chip->usb_id) {
917 case USB_ID(0x041e, 0x3f02): /* E-Mu 0202 USB */
918 case USB_ID(0x041e, 0x3f04): /* E-Mu 0404 USB */
919 case USB_ID(0x041e, 0x3f0a): /* E-Mu Tracker Pre */
920 subs->ops.retire_sync = retire_playback_sync_urb_hs_emu;
921 break;
922 case USB_ID(0x0763, 0x2080): /* M-Audio Fast Track Ultra 8 */
923 case USB_ID(0x0763, 0x2081): /* M-Audio Fast Track Ultra 8R */
924 subs->ops.prepare_sync = prepare_playback_sync_urb;
925 subs->ops.retire_sync = retire_playback_sync_urb;
926 break;
927 }
928 }
929 875
930 snd_usb_set_pcm_ops(as->pcm, stream); 876 snd_usb_set_pcm_ops(as->pcm, stream);
931 877