57 #if defined(USX2Y_NRPACKS_VARIABLE) || USX2Y_NRPACKS == 1
76 if (urb->iso_frame_desc[i].status) {
77 snd_printk(
KERN_ERR "active frame status %i. Most probably some hardware problem.\n", urb->iso_frame_desc[i].status);
78 return urb->iso_frame_desc[
i].status;
80 lens += urb->iso_frame_desc[
i].actual_length / usX2Y->
stride;
94 static inline int usX2Y_iso_frames_per_buffer(
struct snd_pcm_runtime *runtime,
113 int count, counts, pack;
120 usX2Y_iso_frames_per_buffer(runtime, usX2Y);
130 if (counts < 43 || counts > 50) {
138 memset((
char *)urb->transfer_buffer + urb->iso_frame_desc[pack].offset, 0,
139 urb->iso_frame_desc[pack].length);
144 urb->transfer_buffer_length = count * usX2Y->
stride;
154 struct usb_iso_packet_descriptor *
desc = urb->iso_frame_desc + pack;
168 desc->offset -= (
SSS - desc->length);
183 usX2Y_urb_play_retire(playbacksubs, urb);
189 urb = playbacksubs->
urb[0];
193 urb = playbacksubs->
urb[1];
199 if ((err = usX2Y_hwdep_urb_play_prepare(playbacksubs, urb)) ||
200 (err = usX2Y_urb_submit(playbacksubs, urb, frame))) {
210 if ((err = usX2Y_usbpcm_urb_capt_retire(capsubs)))
214 usX2Y_usbpcm_urb_capt_iso_advance(capsubs, capsubs->
completed_urb);
215 if (
NULL != capsubs2)
217 if ((err = usX2Y_urb_submit(capsubs, capsubs->
completed_urb, frame)))
219 if (
NULL != capsubs2)
220 if ((err = usX2Y_urb_submit(capsubs2, capsubs2->
completed_urb, frame)))
224 if (
NULL != capsubs2)
230 static void i_usX2Y_usbpcm_urb_complete(
struct urb *urb)
237 snd_printdd(
"hcd_frame=%i ep=%i%s status=%i start_frame=%i\n",
239 subs->
endpoint, usb_pipein(urb->pipe) ?
"in" :
"out",
240 urb->status, urb->start_frame);
244 usX2Y_error_urb_status(usX2Y, subs, urb);
250 usX2Y_error_sequence(usX2Y, subs, urb);
260 if (!usX2Y_usbpcm_usbframe_complete(capsubs, capsubs2, playbacksubs, urb->start_frame))
264 usX2Y_clients_stop(usX2Y);
270 static void usX2Y_hwdep_urb_release(
struct urb **urb)
284 for (i = 0; i <
NRURBS; i++)
285 usX2Y_hwdep_urb_release(subs->
urb + i);
288 static void usX2Y_usbpcm_subs_startup_finish(
struct usX2Ydev * usX2Y)
290 usX2Y_urbs_set_complete(usX2Y, i_usX2Y_usbpcm_urb_complete);
294 static void i_usX2Y_usbpcm_subs_startup(
struct urb *urb)
299 if (
NULL != prepare_subs &&
300 urb->start_frame == prepare_subs->
urb[0]->start_frame) {
304 if (cap_subs2 !=
NULL)
307 usX2Y_usbpcm_subs_startup_finish(usX2Y);
311 i_usX2Y_usbpcm_urb_complete(urb);
322 struct usb_device *
dev = subs->
usX2Y->dev;
324 pipe = is_playback ? usb_sndisocpipe(dev, subs->
endpoint) :
325 usb_rcvisocpipe(dev, subs->
endpoint);
326 subs->
maxpacksize = usb_maxpacket(dev, pipe, is_playback);
331 for (i = 0; i <
NRURBS; i++) {
332 struct urb **purb = subs->
urb +
i;
339 usX2Y_usbpcm_urbs_release(subs);
342 (*purb)->transfer_buffer = is_playback ?
343 subs->
usX2Y->hwdep_pcm_shm->playback : (
345 subs->
usX2Y->hwdep_pcm_shm->capture0x8 :
346 subs->
usX2Y->hwdep_pcm_shm->capture0xA);
349 (*purb)->pipe =
pipe;
351 (*purb)->context = subs;
352 (*purb)->interval = 1;
353 (*purb)->complete = i_usX2Y_usbpcm_subs_startup;
367 snd_printdd(
"snd_usX2Y_usbpcm_hw_free(%p)\n", substream);
372 usX2Y_usbpcm_urbs_release(subs);
378 if (
NULL != cap_subs2)
380 usX2Y_usbpcm_urbs_release(cap_subs);
381 if (
NULL != cap_subs2)
382 usX2Y_usbpcm_urbs_release(cap_subs2);
388 if (
NULL != cap_subs2)
390 usX2Y_usbpcm_urbs_release(subs);
391 if (
NULL != cap_subs2)
392 usX2Y_usbpcm_urbs_release(cap_subs2);
403 subs->
urb[0]->start_frame = -1;
405 usX2Y_urbs_set_complete(usX2Y, i_usX2Y_usbpcm_subs_startup);
419 for (p = 0; 3 >= (stream +
p); p += 2) {
422 if ((err = usX2Y_usbpcm_urbs_allocate(subs)) < 0)
428 for (p = 0; p < 4; p++) {
435 usX2Y_usbpcm_subs_startup(subs);
436 for (u = 0; u <
NRURBS; u++) {
437 for (p = 0; 3 >= (stream +
p); p += 2) {
440 struct urb *urb = subs->
urb[
u];
441 if (usb_pipein(urb->pipe)) {
445 urb->dev = usX2Y->
dev;
446 urb->transfer_flags = URB_ISO_ASAP;
449 urb->iso_frame_desc[pack].length = subs->
maxpacksize;
461 urb->transfer_flags = 0;
476 usX2Y_subs_startup_finish(usX2Y);
477 usX2Y_clients_stop(usX2Y);
494 snd_printdd(
"snd_usX2Y_pcm_prepare(%p)\n", substream);
503 usX2Y_subs_prepare(subs);
508 if ((err = usX2Y_format_set(usX2Y, runtime->
format)) < 0)
509 goto up_prepare_mutex;
511 if ((err = usX2Y_rate_set(usX2Y, runtime->
rate)) < 0)
512 goto up_prepare_mutex;
513 snd_printdd(
"starting capture pipe for %s\n", subs == capsubs ?
514 "self" :
"playpipe");
515 if (0 > (err = usX2Y_usbpcm_urbs_start(capsubs)))
516 goto up_prepare_mutex;
519 if (subs != capsubs) {
522 while (usX2Y_iso_frames_per_buffer(runtime, usX2Y) >
525 "captured_iso_frames=%i\n",
526 usX2Y_iso_frames_per_buffer(runtime, usX2Y),
530 goto up_prepare_mutex;
533 if (0 > (err = usX2Y_usbpcm_urbs_start(subs)))
534 goto up_prepare_mutex;
536 snd_printdd(
"Ready: iso_frames_per_buffer=%i,captured_iso_frames=%i\n",
537 usX2Y_iso_frames_per_buffer(runtime, usX2Y),
559 .period_bytes_min = 64,
560 .period_bytes_max = (128*1024),
578 (subs->
usX2Y->subs[3] ? snd_usX2Y_4c : snd_usX2Y_2c);
598 .open = snd_usX2Y_usbpcm_open,
599 .close = snd_usX2Y_usbpcm_close,
601 .hw_params = snd_usX2Y_pcm_hw_params,
602 .hw_free = snd_usX2Y_usbpcm_hw_free,
603 .prepare = snd_usX2Y_usbpcm_prepare,
604 .trigger = snd_usX2Y_pcm_trigger,
605 .pointer = snd_usX2Y_pcm_pointer,
628 for (s = 0; s < 2; ++
s) {
630 substream = pcm->
streams[
s].substream;
639 static void usX2Y_pcms_unlock(
struct snd_card *card)
658 int err = usX2Y_pcms_lock_check(card);
661 usX2Y_pcms_unlock(card);
666 static int snd_usX2Y_hwdep_pcm_release(
struct snd_hwdep *hw,
struct file *file)
669 int err = usX2Y_pcms_lock_check(card);
672 usX2Y_pcms_unlock(card);
677 static void snd_usX2Y_hwdep_pcm_vm_open(
struct vm_area_struct *area)
682 static void snd_usX2Y_hwdep_pcm_vm_close(
struct vm_area_struct *area)
687 static int snd_usX2Y_hwdep_pcm_vm_fault(
struct vm_area_struct *area,
688 struct vm_fault *vmf)
701 static const struct vm_operations_struct snd_usX2Y_hwdep_pcm_vm_ops = {
702 .open = snd_usX2Y_hwdep_pcm_vm_open,
703 .close = snd_usX2Y_hwdep_pcm_vm_close,
704 .fault = snd_usX2Y_hwdep_pcm_vm_fault,
725 area->
vm_ops = &snd_usX2Y_hwdep_pcm_vm_ops;
726 area->
vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
732 static void snd_usX2Y_hwdep_pcm_private_free(
struct snd_hwdep *hwdep)
745 struct usb_device *dev =
usX2Y(card)->dev;
755 hw->
ops.open = snd_usX2Y_hwdep_pcm_open;
756 hw->
ops.release = snd_usX2Y_hwdep_pcm_release;
757 hw->
ops.mmap = snd_usX2Y_hwdep_pcm_mmap;
759 sprintf(hw->
name,
"/proc/bus/usb/%03d/%03d/hwdeppcm", dev->bus->busnum, dev->devnum);
775 64*1024, 128*1024)) ||
779 64*1024, 128*1024))) {