1 /******************************************************************************
5 * Audio driver for EasyCAP USB2.0 Video Capture Device DC60 *
8 ******************************************************************************/
11 * Copyright (C) 2010 R.M. Thomas <rmthomas@sciolus.org>
14 * This is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
19 * The software is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this software; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 /*****************************************************************************/
33 #ifndef CONFIG_EASYCAP_OSS
34 /*--------------------------------------------------------------------------*/
36 * PARAMETERS USED WHEN REGISTERING THE AUDIO INTERFACE
38 /*--------------------------------------------------------------------------*/
39 static const struct snd_pcm_hardware alsa_hardware
= {
40 .info
= SNDRV_PCM_INFO_BLOCK_TRANSFER
|
42 SNDRV_PCM_INFO_INTERLEAVED
|
43 SNDRV_PCM_INFO_MMAP_VALID
,
44 .formats
= SNDRV_PCM_FMTBIT_S16_LE
,
45 .rates
= SNDRV_PCM_RATE_32000
| SNDRV_PCM_RATE_48000
,
50 .buffer_bytes_max
= PAGE_SIZE
* PAGES_PER_AUDIO_FRAGMENT
*
52 .period_bytes_min
= PAGE_SIZE
* PAGES_PER_AUDIO_FRAGMENT
,
53 .period_bytes_max
= PAGE_SIZE
* PAGES_PER_AUDIO_FRAGMENT
* 2,
54 .periods_min
= AUDIO_FRAGMENT_MANY
,
55 .periods_max
= AUDIO_FRAGMENT_MANY
* 2,
58 static struct snd_pcm_ops easycap_alsa_pcm_ops
= {
59 .open
= easycap_alsa_open
,
60 .close
= easycap_alsa_close
,
61 .ioctl
= snd_pcm_lib_ioctl
,
62 .hw_params
= easycap_alsa_hw_params
,
63 .hw_free
= easycap_alsa_hw_free
,
64 .prepare
= easycap_alsa_prepare
,
65 .ack
= easycap_alsa_ack
,
66 .trigger
= easycap_alsa_trigger
,
67 .pointer
= easycap_alsa_pointer
,
68 .page
= easycap_alsa_page
,
71 /*****************************************************************************/
72 /*---------------------------------------------------------------------------*/
74 * THE FUNCTION snd_card_create() HAS THIS_MODULE AS AN ARGUMENT. THIS
75 * MEANS MODULE easycap. BEWARE.
77 /*---------------------------------------------------------------------------*/
79 easycap_alsa_probe(struct easycap
*peasycap
)
82 struct snd_card
*psnd_card
;
83 struct snd_pcm
*psnd_pcm
;
85 if (NULL
== peasycap
) {
86 SAY("ERROR: peasycap is NULL\n");
89 if (memcmp(&peasycap
->telltale
[0], TELLTALE
, strlen(TELLTALE
))) {
90 SAY("ERROR: bad peasycap\n");
93 if (0 > peasycap
->minor
) {
94 SAY("ERROR: no minor\n");
98 peasycap
->alsa_hardware
= alsa_hardware
;
99 if (true == peasycap
->microphone
) {
100 peasycap
->alsa_hardware
.rates
= SNDRV_PCM_RATE_32000
;
101 peasycap
->alsa_hardware
.rate_min
= 32000;
102 peasycap
->alsa_hardware
.rate_max
= 32000;
104 peasycap
->alsa_hardware
.rates
= SNDRV_PCM_RATE_48000
;
105 peasycap
->alsa_hardware
.rate_min
= 48000;
106 peasycap
->alsa_hardware
.rate_max
= 48000;
109 if (0 != snd_card_create(SNDRV_DEFAULT_IDX1
, "easycap_alsa",
112 SAY("ERROR: Cannot do ALSA snd_card_create()\n");
116 sprintf(&psnd_card
->id
[0], "EasyALSA%i", peasycap
->minor
);
117 strcpy(&psnd_card
->driver
[0], EASYCAP_DRIVER_DESCRIPTION
);
118 strcpy(&psnd_card
->shortname
[0], "easycap_alsa");
119 sprintf(&psnd_card
->longname
[0], "%s", &psnd_card
->shortname
[0]);
121 psnd_card
->dev
= &peasycap
->pusb_device
->dev
;
122 psnd_card
->private_data
= peasycap
;
123 peasycap
->psnd_card
= psnd_card
;
125 rc
= snd_pcm_new(psnd_card
, "easycap_pcm", 0, 0, 1, &psnd_pcm
);
127 SAM("ERROR: Cannot do ALSA snd_pcm_new()\n");
128 snd_card_free(psnd_card
);
132 snd_pcm_set_ops(psnd_pcm
, SNDRV_PCM_STREAM_CAPTURE
,
133 &easycap_alsa_pcm_ops
);
134 psnd_pcm
->info_flags
= 0;
135 strcpy(&psnd_pcm
->name
[0], &psnd_card
->id
[0]);
136 psnd_pcm
->private_data
= peasycap
;
137 peasycap
->psnd_pcm
= psnd_pcm
;
138 peasycap
->psubstream
= (struct snd_pcm_substream
*)NULL
;
140 rc
= snd_card_register(psnd_card
);
142 SAM("ERROR: Cannot do ALSA snd_card_register()\n");
143 snd_card_free(psnd_card
);
147 SAM("registered %s\n", &psnd_card
->id
[0]);
151 /*****************************************************************************/
152 /*---------------------------------------------------------------------------*/
154 * ON COMPLETION OF AN AUDIO URB ITS DATA IS COPIED TO THE DAM BUFFER
155 * PROVIDED peasycap->audio_idle IS ZERO. REGARDLESS OF THIS BEING TRUE,
156 * IT IS RESUBMITTED PROVIDED peasycap->audio_isoc_streaming IS NOT ZERO.
158 /*---------------------------------------------------------------------------*/
160 easycap_alsa_complete(struct urb
*purb
)
162 struct easycap
*peasycap
;
163 struct snd_pcm_substream
*pss
;
164 struct snd_pcm_runtime
*prt
;
165 int dma_bytes
, fragment_bytes
;
169 int i
, j
, more
, much
, rc
;
170 #if defined(UPSAMPLE)
172 __s16 oldaudio
, newaudio
, delta
;
178 SAY("ERROR: purb is NULL\n");
181 peasycap
= purb
->context
;
182 if (NULL
== peasycap
) {
183 SAY("ERROR: peasycap is NULL\n");
186 if (memcmp(&peasycap
->telltale
[0], TELLTALE
, strlen(TELLTALE
))) {
187 SAY("ERROR: bad peasycap\n");
191 if (peasycap
->audio_idle
) {
192 JOM(16, "%i=audio_idle %i=audio_isoc_streaming\n",
193 peasycap
->audio_idle
, peasycap
->audio_isoc_streaming
);
194 if (peasycap
->audio_isoc_streaming
)
197 /*---------------------------------------------------------------------------*/
198 pss
= peasycap
->psubstream
;
204 dma_bytes
= (int)prt
->dma_bytes
;
207 fragment_bytes
= 4 * ((int)prt
->period_size
);
208 if (0 == fragment_bytes
)
210 /* -------------------------------------------------------------------------*/
212 if ((-ESHUTDOWN
== purb
->status
) || (-ENOENT
== purb
->status
)) {
213 JOM(16, "urb status -ESHUTDOWN or -ENOENT\n");
216 SAM("ERROR: non-zero urb status: -%s: %d\n",
217 strerror(purb
->status
), purb
->status
);
220 /*---------------------------------------------------------------------------*/
222 * PROCEED HERE WHEN NO ERROR
224 /*---------------------------------------------------------------------------*/
226 #if defined(UPSAMPLE)
227 oldaudio
= peasycap
->oldaudio
;
230 for (i
= 0; i
< purb
->number_of_packets
; i
++) {
231 if (purb
->iso_frame_desc
[i
].status
< 0) {
233 strerror(purb
->iso_frame_desc
[i
].status
),
234 purb
->iso_frame_desc
[i
].status
);
236 if (!purb
->iso_frame_desc
[i
].status
) {
237 more
= purb
->iso_frame_desc
[i
].actual_length
;
239 peasycap
->audio_mt
++;
241 if (peasycap
->audio_mt
) {
242 JOM(12, "%4i empty audio urb frames\n",
244 peasycap
->audio_mt
= 0;
247 p1
= (__u8
*)(purb
->transfer_buffer
+
248 purb
->iso_frame_desc
[i
].offset
);
250 /*---------------------------------------------------------------------------*/
252 * COPY more BYTES FROM ISOC BUFFER TO THE DMA BUFFER,
253 * CONVERTING 8-BIT MONO TO 16-BIT SIGNED LITTLE-ENDIAN SAMPLES IF NECESSARY
255 /*---------------------------------------------------------------------------*/
258 SAM("MISTAKE: more is negative\n");
261 much
= dma_bytes
- peasycap
->dma_fill
;
263 SAM("MISTAKE: much is negative\n");
267 peasycap
->dma_fill
= 0;
268 peasycap
->dma_next
= fragment_bytes
;
269 JOM(8, "wrapped dma buffer\n");
271 if (false == peasycap
->microphone
) {
274 memcpy(prt
->dma_area
+
280 #if defined(UPSAMPLE)
282 JOM(8, "MISTAKE? much"
283 " is not divisible by 16\n");
288 p2
= (__u8
*)(prt
->dma_area
+
291 for (j
= 0; j
< (much
/16); j
++) {
292 newaudio
= ((int) *p1
) - 128;
296 delta
= (newaudio
- oldaudio
)
298 s16
= oldaudio
+ delta
;
300 for (k
= 0; k
< 4; k
++) {
301 *p2
= (0x00FF & s16
);
302 *(p2
+ 1) = (0xFF00 &
305 *p2
= (0x00FF & s16
);
306 *(p2
+ 1) = (0xFF00 &
316 if (much
> (2 * more
))
318 p2
= (__u8
*)(prt
->dma_area
+
321 for (j
= 0; j
< (much
/ 2); j
++) {
322 s16
= ((int) *p1
) - 128;
325 *p2
= (0x00FF & s16
);
326 *(p2
+ 1) = (0xFF00 & s16
) >>
333 peasycap
->dma_fill
+= much
;
334 if (peasycap
->dma_fill
>= peasycap
->dma_next
) {
335 isfragment
= peasycap
->dma_fill
/
337 if (0 > isfragment
) {
338 SAM("MISTAKE: isfragment is "
342 peasycap
->dma_read
= (isfragment
343 - 1) * fragment_bytes
;
344 peasycap
->dma_next
= (isfragment
345 + 1) * fragment_bytes
;
346 if (dma_bytes
< peasycap
->dma_next
) {
350 if (0 <= peasycap
->dma_read
) {
351 JOM(8, "snd_pcm_period_elap"
355 snd_pcm_period_elapsed(pss
);
361 JOM(12, "discarding audio samples because "
362 "%i=purb->iso_frame_desc[i].status\n",
363 purb
->iso_frame_desc
[i
].status
);
366 #if defined(UPSAMPLE)
367 peasycap
->oldaudio
= oldaudio
;
371 /*---------------------------------------------------------------------------*/
375 /*---------------------------------------------------------------------------*/
377 if (peasycap
->audio_isoc_streaming
) {
378 rc
= usb_submit_urb(purb
, GFP_ATOMIC
);
380 if ((-ENODEV
!= rc
) && (-ENOENT
!= rc
)) {
381 SAM("ERROR: while %i=audio_idle, "
382 "usb_submit_urb() failed "
383 "with rc: -%s :%d\n", peasycap
->audio_idle
,
386 if (0 < peasycap
->audio_isoc_streaming
)
387 (peasycap
->audio_isoc_streaming
)--;
392 /*****************************************************************************/
394 easycap_alsa_open(struct snd_pcm_substream
*pss
)
396 struct snd_pcm
*psnd_pcm
;
397 struct snd_card
*psnd_card
;
398 struct easycap
*peasycap
;
402 SAY("ERROR: pss is NULL\n");
406 if (NULL
== psnd_pcm
) {
407 SAY("ERROR: psnd_pcm is NULL\n");
410 psnd_card
= psnd_pcm
->card
;
411 if (NULL
== psnd_card
) {
412 SAY("ERROR: psnd_card is NULL\n");
416 peasycap
= psnd_card
->private_data
;
417 if (NULL
== peasycap
) {
418 SAY("ERROR: peasycap is NULL\n");
421 if (memcmp(&peasycap
->telltale
[0], TELLTALE
, strlen(TELLTALE
))) {
422 SAY("ERROR: bad peasycap\n");
425 if (peasycap
->psnd_card
!= psnd_card
) {
426 SAM("ERROR: bad peasycap->psnd_card\n");
429 if (NULL
!= peasycap
->psubstream
) {
430 SAM("ERROR: bad peasycap->psubstream\n");
433 pss
->private_data
= peasycap
;
434 peasycap
->psubstream
= pss
;
435 pss
->runtime
->hw
= peasycap
->alsa_hardware
;
436 pss
->runtime
->private_data
= peasycap
;
437 pss
->private_data
= peasycap
;
439 if (0 != easycap_sound_setup(peasycap
)) {
440 JOM(4, "ending unsuccessfully\n");
443 JOM(4, "ending successfully\n");
446 /*****************************************************************************/
448 easycap_alsa_close(struct snd_pcm_substream
*pss
)
450 struct easycap
*peasycap
;
454 SAY("ERROR: pss is NULL\n");
457 peasycap
= snd_pcm_substream_chip(pss
);
458 if (NULL
== peasycap
) {
459 SAY("ERROR: peasycap is NULL\n");
462 if (memcmp(&peasycap
->telltale
[0], TELLTALE
, strlen(TELLTALE
))) {
463 SAY("ERROR: bad peasycap\n");
466 pss
->private_data
= NULL
;
467 peasycap
->psubstream
= (struct snd_pcm_substream
*)NULL
;
468 JOT(4, "ending successfully\n");
471 /*****************************************************************************/
473 easycap_alsa_hw_params(struct snd_pcm_substream
*pss
,
474 struct snd_pcm_hw_params
*phw
)
478 JOT(4, "%i\n", (params_buffer_bytes(phw
)));
480 SAY("ERROR: pss is NULL\n");
483 rc
= easycap_alsa_vmalloc(pss
, params_buffer_bytes(phw
));
488 /*****************************************************************************/
490 easycap_alsa_vmalloc(struct snd_pcm_substream
*pss
, size_t sz
)
492 struct snd_pcm_runtime
*prt
;
496 SAY("ERROR: pss is NULL\n");
501 SAY("ERROR: substream.runtime is NULL\n");
505 if (prt
->dma_bytes
> sz
)
507 vfree(prt
->dma_area
);
509 prt
->dma_area
= vmalloc(sz
);
510 if (NULL
== prt
->dma_area
)
515 /*****************************************************************************/
517 easycap_alsa_hw_free(struct snd_pcm_substream
*pss
)
519 struct snd_pcm_runtime
*prt
;
523 SAY("ERROR: pss is NULL\n");
528 SAY("ERROR: substream.runtime is NULL\n");
531 if (NULL
!= prt
->dma_area
) {
532 JOT(8, "0x%08lX=prt->dma_area\n", (unsigned long int)prt
->dma_area
);
533 vfree(prt
->dma_area
);
534 prt
->dma_area
= NULL
;
536 JOT(8, "dma_area already freed\n");
539 /*****************************************************************************/
541 easycap_alsa_prepare(struct snd_pcm_substream
*pss
)
543 struct easycap
*peasycap
;
544 struct snd_pcm_runtime
*prt
;
548 SAY("ERROR: pss is NULL\n");
552 peasycap
= snd_pcm_substream_chip(pss
);
553 if (NULL
== peasycap
) {
554 SAY("ERROR: peasycap is NULL\n");
557 if (memcmp(&peasycap
->telltale
[0], TELLTALE
, strlen(TELLTALE
))) {
558 SAY("ERROR: bad peasycap\n");
562 JOM(16, "ALSA decides %8i Hz=rate\n", (int)pss
->runtime
->rate
);
563 JOM(16, "ALSA decides %8i =period_size\n", (int)pss
->runtime
->period_size
);
564 JOM(16, "ALSA decides %8i =periods\n", (int)pss
->runtime
->periods
);
565 JOM(16, "ALSA decides %8i =buffer_size\n", (int)pss
->runtime
->buffer_size
);
566 JOM(16, "ALSA decides %8i =dma_bytes\n", (int)pss
->runtime
->dma_bytes
);
567 JOM(16, "ALSA decides %8i =boundary\n", (int)pss
->runtime
->boundary
);
568 JOM(16, "ALSA decides %8i =period_step\n", (int)pss
->runtime
->period_step
);
569 JOM(16, "ALSA decides %8i =sample_bits\n", (int)pss
->runtime
->sample_bits
);
570 JOM(16, "ALSA decides %8i =frame_bits\n", (int)pss
->runtime
->frame_bits
);
571 JOM(16, "ALSA decides %8i =min_align\n", (int)pss
->runtime
->min_align
);
572 JOM(12, "ALSA decides %8i =hw_ptr_base\n", (int)pss
->runtime
->hw_ptr_base
);
573 JOM(12, "ALSA decides %8i =hw_ptr_interrupt\n",
574 (int)pss
->runtime
->hw_ptr_interrupt
);
575 if (prt
->dma_bytes
!= 4 * ((int)prt
->period_size
) * ((int)prt
->periods
)) {
576 SAY("MISTAKE: unexpected ALSA parameters\n");
581 /*****************************************************************************/
583 easycap_alsa_ack(struct snd_pcm_substream
*pss
)
587 /*****************************************************************************/
589 easycap_alsa_trigger(struct snd_pcm_substream
*pss
, int cmd
)
591 struct easycap
*peasycap
;
594 JOT(4, "%i=cmd cf %i=START %i=STOP\n", cmd
, SNDRV_PCM_TRIGGER_START
,
595 SNDRV_PCM_TRIGGER_STOP
);
597 SAY("ERROR: pss is NULL\n");
600 peasycap
= snd_pcm_substream_chip(pss
);
601 if (NULL
== peasycap
) {
602 SAY("ERROR: peasycap is NULL\n");
605 if (memcmp(&peasycap
->telltale
[0], TELLTALE
, strlen(TELLTALE
))) {
606 SAY("ERROR: bad peasycap\n");
611 case SNDRV_PCM_TRIGGER_START
: {
612 peasycap
->audio_idle
= 0;
615 case SNDRV_PCM_TRIGGER_STOP
: {
616 peasycap
->audio_idle
= 1;
624 /*****************************************************************************/
626 easycap_alsa_pointer(struct snd_pcm_substream
*pss
)
628 struct easycap
*peasycap
;
629 snd_pcm_uframes_t offset
;
633 SAY("ERROR: pss is NULL\n");
636 peasycap
= snd_pcm_substream_chip(pss
);
637 if (NULL
== peasycap
) {
638 SAY("ERROR: peasycap is NULL\n");
641 if (memcmp(&peasycap
->telltale
[0], TELLTALE
, strlen(TELLTALE
))) {
642 SAY("ERROR: bad peasycap\n");
645 if ((0 != peasycap
->audio_eof
) || (0 != peasycap
->audio_idle
)) {
646 JOM(8, "returning -EIO because "
647 "%i=audio_idle %i=audio_eof\n",
648 peasycap
->audio_idle
, peasycap
->audio_eof
);
651 /*---------------------------------------------------------------------------*/
652 if (0 > peasycap
->dma_read
) {
653 JOM(8, "returning -EBUSY\n");
656 offset
= ((snd_pcm_uframes_t
)peasycap
->dma_read
)/4;
657 JOM(8, "ALSA decides %8i =hw_ptr_base\n", (int)pss
->runtime
->hw_ptr_base
);
658 JOM(8, "ALSA decides %8i =hw_ptr_interrupt\n",
659 (int)pss
->runtime
->hw_ptr_interrupt
);
660 JOM(8, "%7i=offset %7i=dma_read %7i=dma_next\n",
661 (int)offset
, peasycap
->dma_read
, peasycap
->dma_next
);
664 /*****************************************************************************/
666 easycap_alsa_page(struct snd_pcm_substream
*pss
, unsigned long offset
)
668 return vmalloc_to_page(pss
->runtime
->dma_area
+ offset
);
670 /*****************************************************************************/
672 #endif /*! CONFIG_EASYCAP_OSS */
674 /*****************************************************************************/
675 /*****************************************************************************/
676 /*****************************************************************************/
677 /*****************************************************************************/
678 /*****************************************************************************/
679 /*****************************************************************************/
680 /*---------------------------------------------------------------------------*/
682 * COMMON AUDIO INITIALIZATION
684 /*---------------------------------------------------------------------------*/
686 easycap_sound_setup(struct easycap
*peasycap
)
690 JOM(4, "starting initialization\n");
692 if (NULL
== peasycap
) {
693 SAY("ERROR: peasycap is NULL.\n");
696 if ((struct usb_device
*)NULL
== peasycap
->pusb_device
) {
697 SAM("ERROR: peasycap->pusb_device is NULL\n");
700 JOM(16, "0x%08lX=peasycap->pusb_device\n", (long int)peasycap
->pusb_device
);
702 rc
= audio_setup(peasycap
);
703 JOM(8, "audio_setup() returned %i\n", rc
);
705 if ((struct usb_device
*)NULL
== peasycap
->pusb_device
) {
706 SAM("ERROR: peasycap->pusb_device has become NULL\n");
709 /*---------------------------------------------------------------------------*/
710 if ((struct usb_device
*)NULL
== peasycap
->pusb_device
) {
711 SAM("ERROR: peasycap->pusb_device has become NULL\n");
714 rc
= usb_set_interface(peasycap
->pusb_device
, peasycap
->audio_interface
,
715 peasycap
->audio_altsetting_on
);
716 JOM(8, "usb_set_interface(.,%i,%i) returned %i\n", peasycap
->audio_interface
,
717 peasycap
->audio_altsetting_on
, rc
);
719 rc
= wakeup_device(peasycap
->pusb_device
);
720 JOM(8, "wakeup_device() returned %i\n", rc
);
722 peasycap
->audio_eof
= 0;
723 peasycap
->audio_idle
= 0;
725 peasycap
->timeval1
.tv_sec
= 0;
726 peasycap
->timeval1
.tv_usec
= 0;
728 submit_audio_urbs(peasycap
);
730 JOM(4, "finished initialization\n");
733 /*****************************************************************************/
734 /*---------------------------------------------------------------------------*/
736 * SUBMIT ALL AUDIO URBS.
738 /*---------------------------------------------------------------------------*/
740 submit_audio_urbs(struct easycap
*peasycap
)
742 struct data_urb
*pdata_urb
;
744 struct list_head
*plist_head
;
745 int j
, isbad
, nospc
, m
, rc
;
748 if (NULL
== peasycap
) {
749 SAY("ERROR: peasycap is NULL\n");
752 if ((struct list_head
*)NULL
== peasycap
->purb_audio_head
) {
753 SAM("ERROR: peasycap->urb_audio_head uninitialized\n");
756 if ((struct usb_device
*)NULL
== peasycap
->pusb_device
) {
757 SAM("ERROR: peasycap->pusb_device is NULL\n");
760 if (!peasycap
->audio_isoc_streaming
) {
761 JOM(4, "initial submission of all audio urbs\n");
762 rc
= usb_set_interface(peasycap
->pusb_device
,
763 peasycap
->audio_interface
,
764 peasycap
->audio_altsetting_on
);
765 JOM(8, "usb_set_interface(.,%i,%i) returned %i\n",
766 peasycap
->audio_interface
,
767 peasycap
->audio_altsetting_on
, rc
);
769 isbad
= 0; nospc
= 0; m
= 0;
770 list_for_each(plist_head
, (peasycap
->purb_audio_head
)) {
771 pdata_urb
= list_entry(plist_head
, struct data_urb
, list_head
);
772 if (NULL
!= pdata_urb
) {
773 purb
= pdata_urb
->purb
;
775 isbuf
= pdata_urb
->isbuf
;
778 purb
->dev
= peasycap
->pusb_device
;
780 usb_rcvisocpipe(peasycap
->pusb_device
,
781 peasycap
->audio_endpointnumber
);
782 purb
->transfer_flags
= URB_ISO_ASAP
;
783 purb
->transfer_buffer
=
784 peasycap
->audio_isoc_buffer
[isbuf
].pgo
;
785 purb
->transfer_buffer_length
=
786 peasycap
->audio_isoc_buffer_size
;
787 #ifdef CONFIG_EASYCAP_OSS
788 purb
->complete
= easyoss_complete
;
789 #else /* CONFIG_EASYCAP_OSS */
790 purb
->complete
= easycap_alsa_complete
;
791 #endif /* CONFIG_EASYCAP_OSS */
792 purb
->context
= peasycap
;
793 purb
->start_frame
= 0;
794 purb
->number_of_packets
=
795 peasycap
->audio_isoc_framesperdesc
;
796 for (j
= 0; j
< peasycap
->
797 audio_isoc_framesperdesc
;
799 purb
->iso_frame_desc
[j
].offset
= j
*
801 audio_isoc_maxframesize
;
802 purb
->iso_frame_desc
[j
].length
=
804 audio_isoc_maxframesize
;
807 rc
= usb_submit_urb(purb
, GFP_KERNEL
);
810 SAM("ERROR: usb_submit_urb() failed"
811 " for urb with rc: -%s: %d\n",
824 SAM("-ENOSPC=usb_submit_urb() for %i urbs\n", nospc
);
825 SAM("..... possibly inadequate USB bandwidth\n");
826 peasycap
->audio_eof
= 1;
829 JOM(4, "attempting cleanup instead of submitting\n");
830 list_for_each(plist_head
, (peasycap
->purb_audio_head
)) {
831 pdata_urb
= list_entry(plist_head
, struct data_urb
,
833 if (NULL
!= pdata_urb
) {
834 purb
= pdata_urb
->purb
;
839 peasycap
->audio_isoc_streaming
= 0;
841 peasycap
->audio_isoc_streaming
= m
;
842 JOM(4, "submitted %i audio urbs\n", m
);
845 JOM(4, "already streaming audio urbs\n");
849 /*****************************************************************************/
850 /*---------------------------------------------------------------------------*/
852 * KILL ALL AUDIO URBS.
854 /*---------------------------------------------------------------------------*/
856 kill_audio_urbs(struct easycap
*peasycap
)
859 struct list_head
*plist_head
;
860 struct data_urb
*pdata_urb
;
862 if (NULL
== peasycap
) {
863 SAY("ERROR: peasycap is NULL\n");
866 if (peasycap
->audio_isoc_streaming
) {
867 if ((struct list_head
*)NULL
!= peasycap
->purb_audio_head
) {
868 peasycap
->audio_isoc_streaming
= 0;
869 JOM(4, "killing audio urbs\n");
871 list_for_each(plist_head
, (peasycap
->purb_audio_head
)) {
872 pdata_urb
= list_entry(plist_head
, struct data_urb
,
874 if ((struct data_urb
*)NULL
!= pdata_urb
) {
875 if ((struct urb
*)NULL
!= pdata_urb
->purb
) {
876 usb_kill_urb(pdata_urb
->purb
);
881 JOM(4, "%i audio urbs killed\n", m
);
883 SAM("ERROR: peasycap->purb_audio_head is NULL\n");
887 JOM(8, "%i=audio_isoc_streaming, no audio urbs killed\n",
888 peasycap
->audio_isoc_streaming
);
892 /*****************************************************************************/