35 #include <linux/slab.h>
45 #define USX2Y_NRPACKS 4
55 #define USX2Y_NRPACKS_VARIABLE y
61 #ifdef USX2Y_NRPACKS_VARIABLE
63 #define nr_of_packs() nrpacks
67 #define nr_of_packs() USX2Y_NRPACKS
80 cp = (
unsigned char*)urb->transfer_buffer + urb->iso_frame_desc[i].offset;
81 if (urb->iso_frame_desc[i].status) {
83 "Most probably some hardware problem.\n",
84 urb->iso_frame_desc[i].status);
85 return urb->iso_frame_desc[
i].status;
87 len = urb->iso_frame_desc[
i].actual_length / usX2Y->
stride;
96 int blen = cnt * usX2Y->
stride;
131 int count, counts, pack;
138 counts = cap_urb->iso_frame_desc[pack].actual_length / usX2Y->
stride;
140 if (counts < 43 || counts > 50) {
145 urb->iso_frame_desc[pack].offset = pack ?
146 urb->iso_frame_desc[pack - 1].offset +
147 urb->iso_frame_desc[pack - 1].length :
149 urb->iso_frame_desc[pack].length = cap_urb->iso_frame_desc[pack].actual_length;
158 urb->transfer_buffer = subs->
tmpbuf;
172 urb->transfer_buffer = subs->
tmpbuf;
173 urb->transfer_buffer_length = count * usX2Y->
stride;
185 int len = urb->actual_length / subs->
usX2Y->stride;
204 urb->dev = subs->
usX2Y->dev;
222 usX2Y_urb_play_retire(playbacksubs, urb);
228 urb = playbacksubs->
urb[0];
232 urb = playbacksubs->
urb[1];
238 if ((err = usX2Y_urb_play_prepare(playbacksubs, capsubs->
completed_urb, urb)) ||
239 (err = usX2Y_urb_submit(playbacksubs, urb, frame))) {
249 if ((err = usX2Y_urb_capt_retire(capsubs)))
253 if ((err = usX2Y_urb_submit(capsubs, capsubs->
completed_urb, frame)))
261 static void usX2Y_clients_stop(
struct usX2Ydev *usX2Y)
265 for (s = 0; s < 4; s++) {
272 for (s = 0; s < 4; s++) {
278 for (u = 0; u <
NRURBS; u++) {
279 struct urb *urb = subs->
urb[
u];
282 u, urb->status, urb->start_frame);
290 static void usX2Y_error_urb_status(
struct usX2Ydev *usX2Y,
295 usX2Y_clients_stop(usX2Y);
298 static void usX2Y_error_sequence(
struct usX2Ydev *usX2Y,
302 "Sequence Error!(hcd_frame=%i ep=%i%s;wait=%i,frame=%i).\n"
303 "Most probably some urb of usb-frame %i is still missing.\n"
304 "Cause could be too long delays in usb-hcd interrupt handling.\n",
306 subs->
endpoint, usb_pipein(urb->pipe) ?
"in" :
"out",
308 usX2Y_clients_stop(usX2Y);
311 static void i_usX2Y_urb_complete(
struct urb *urb)
317 snd_printdd(
"hcd_frame=%i ep=%i%s status=%i start_frame=%i\n",
319 subs->
endpoint, usb_pipein(urb->pipe) ?
"in" :
"out",
320 urb->status, urb->start_frame);
324 usX2Y_error_urb_status(usX2Y, subs, urb);
330 usX2Y_error_sequence(usX2Y, subs, urb);
340 if (!usX2Y_usbframe_complete(capsubs, playbacksubs, urb->start_frame))
344 usX2Y_clients_stop(usX2Y);
350 static void usX2Y_urbs_set_complete(
struct usX2Ydev * usX2Y,
354 for (s = 0; s < 4; s++) {
357 for (u = 0; u <
NRURBS; u++) {
358 struct urb * urb = subs->
urb[
u];
365 static void usX2Y_subs_startup_finish(
struct usX2Ydev * usX2Y)
367 usX2Y_urbs_set_complete(usX2Y, i_usX2Y_urb_complete);
371 static void i_usX2Y_subs_startup(
struct urb *urb)
376 if (
NULL != prepare_subs)
377 if (urb->start_frame == prepare_subs->
urb[0]->start_frame) {
378 usX2Y_subs_startup_finish(usX2Y);
383 i_usX2Y_urb_complete(urb);
388 snd_printdd(
"usX2Y_substream_prepare(%p) ep=%i urb0=%p urb1=%p\n",
397 static void usX2Y_urb_release(
struct urb **urb,
int free_tb)
402 kfree((*urb)->transfer_buffer);
414 for (i = 0; i <
NRURBS; i++)
415 usX2Y_urb_release(subs->
urb + i,
429 struct usb_device *
dev = subs->
usX2Y->dev;
431 pipe = is_playback ? usb_sndisocpipe(dev, subs->
endpoint) :
432 usb_rcvisocpipe(dev, subs->
endpoint);
433 subs->
maxpacksize = usb_maxpacket(dev, pipe, is_playback);
445 for (i = 0; i <
NRURBS; i++) {
446 struct urb **purb = subs->
urb +
i;
453 usX2Y_urbs_release(subs);
456 if (!is_playback && !(*purb)->transfer_buffer) {
459 if (
NULL == (*purb)->transfer_buffer) {
460 usX2Y_urbs_release(subs);
465 (*purb)->pipe =
pipe;
467 (*purb)->context = subs;
468 (*purb)->interval = 1;
469 (*purb)->complete = i_usX2Y_subs_startup;
478 subs->
urb[0]->start_frame = -1;
480 usX2Y_urbs_set_complete(usX2Y, i_usX2Y_subs_startup);
488 if ((err = usX2Y_urbs_allocate(subs)) < 0)
491 for (i = 0; i < 4; i++) {
498 usX2Y_subs_startup(subs);
499 for (i = 0; i <
NRURBS; i++) {
500 struct urb *urb = subs->
urb[
i];
501 if (usb_pipein(urb->pipe)) {
505 urb->dev = usX2Y->
dev;
506 urb->transfer_flags = URB_ISO_ASAP;
508 urb->iso_frame_desc[pack].offset = subs->
maxpacksize * pack;
509 urb->iso_frame_desc[pack].length = subs->
maxpacksize;
519 urb->transfer_flags = 0;
532 usX2Y_subs_startup_finish(usX2Y);
533 usX2Y_clients_stop(usX2Y);
624 static struct s_c2 SetRate48000[] =
660 #define NOOF_SETRATE_URBS ARRAY_SIZE(SetRate48000)
662 static void i_usX2Y_04Int(
struct urb *urb)
664 struct usX2Ydev *usX2Y = urb->context;
668 if (0 == --usX2Y->
US04->len)
672 static int usX2Y_rate_set(
struct usX2Ydev *usX2Y,
int rate)
677 struct s_c2 *
ra = rate == 48000 ? SetRate48000 : SetRate44100;
679 if (usX2Y->
rate != rate) {
686 if (
NULL == usbdata) {
695 ((
char*)(usbdata + i))[0] = ra[i].c1;
696 ((
char*)(usbdata + i))[1] = ra[i].c2;
697 usb_fill_bulk_urb(us->
urb[i], usX2Y->
dev, usb_sndbulkpipe(usX2Y->
dev, 4),
698 usbdata + i, 2, i_usX2Y_04Int, usX2Y);
714 struct urb *urb = us->
urb[
i];
773 snd_printdd(
"snd_usX2Y_hw_params(%p, %p)\n", substream, hw_params);
783 for (s = 0; s < 2; ++
s) {
785 test_substream = pcm->
streams[
s].substream;
786 if (test_substream && test_substream != substream &&
788 ((test_substream->
runtime->format &&
789 test_substream->
runtime->format != format) ||
790 (test_substream->
runtime->rate &&
791 test_substream->
runtime->rate != rate)))
816 usX2Y_urbs_release(subs);
822 usX2Y_urbs_release(cap_subs);
828 usX2Y_urbs_release(subs);
846 snd_printdd(
"snd_usX2Y_pcm_prepare(%p)\n", substream);
849 usX2Y_subs_prepare(subs);
854 if ((err = usX2Y_format_set(usX2Y, runtime->
format)) < 0)
855 goto up_prepare_mutex;
857 if ((err = usX2Y_rate_set(usX2Y, runtime->
rate)) < 0)
858 goto up_prepare_mutex;
859 snd_printdd(
"starting capture pipe for %s\n", subs == capsubs ?
"self" :
"playpipe");
860 if (0 > (err = usX2Y_urbs_start(capsubs)))
861 goto up_prepare_mutex;
865 err = usX2Y_urbs_start(subs);
885 .period_bytes_min = 64,
886 .period_bytes_max = (128*1024),
903 runtime->
hw = snd_usX2Y_2c;
925 .open = snd_usX2Y_pcm_open,
926 .close = snd_usX2Y_pcm_close,
928 .hw_params = snd_usX2Y_pcm_hw_params,
929 .hw_free = snd_usX2Y_pcm_hw_free,
930 .prepare = snd_usX2Y_pcm_prepare,
931 .trigger = snd_usX2Y_pcm_trigger,
932 .pointer = snd_usX2Y_pcm_pointer,
948 static void snd_usX2Y_pcm_private_free(
struct snd_pcm *pcm)
952 usX2Y_audio_stream_free(usX2Y_stream);
955 static int usX2Y_audio_stream_new(
struct snd_card *card,
int playback_endpoint,
int capture_endpoint)
960 usX2Y(card)->subs + 2 *
usX2Y(card)->pcm_devs;
965 if (
NULL == usX2Y_substream[i]) {
972 if (playback_endpoint)
977 playback_endpoint ? 1 : 0, 1,
980 usX2Y_audio_stream_free(usX2Y_substream);
984 if (playback_endpoint)
994 if ((playback_endpoint &&
998 64*1024, 128*1024))) ||
1002 64*1024, 128*1024))) {
1003 snd_usX2Y_pcm_private_free(pcm);
1006 usX2Y(card)->pcm_devs++;
1018 INIT_LIST_HEAD(&
usX2Y(card)->pcm_list);
1020 if (0 > (err = usX2Y_audio_stream_new(card, 0xA, 0x8)))
1023 if (0 > (err = usX2Y_audio_stream_new(card, 0, 0xA)))
1026 err = usX2Y_rate_set(
usX2Y(card), 44100);