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 /*****************************************************************************/
32 #include "easycap_sound.h"
34 #if defined(EASYCAP_NEEDS_ALSA)
35 /*--------------------------------------------------------------------------*/
37 * PARAMETERS USED WHEN REGISTERING THE AUDIO INTERFACE
39 /*--------------------------------------------------------------------------*/
40 static const struct snd_pcm_hardware alsa_hardware
= {
41 .info
= SNDRV_PCM_INFO_BLOCK_TRANSFER
|
43 SNDRV_PCM_INFO_INTERLEAVED
|
44 SNDRV_PCM_INFO_MMAP_VALID
,
45 .formats
= SNDRV_PCM_FMTBIT_S16_LE
,
46 .rates
= SNDRV_PCM_RATE_32000
| SNDRV_PCM_RATE_48000
,
51 .buffer_bytes_max
= PAGE_SIZE
* PAGES_PER_AUDIO_FRAGMENT
*
53 .period_bytes_min
= PAGE_SIZE
* PAGES_PER_AUDIO_FRAGMENT
,
54 .period_bytes_max
= PAGE_SIZE
* PAGES_PER_AUDIO_FRAGMENT
* 2,
55 .periods_min
= AUDIO_FRAGMENT_MANY
,
56 .periods_max
= AUDIO_FRAGMENT_MANY
* 2,
59 static struct snd_pcm_ops easycap_alsa_pcm_ops
= {
60 .open
= easycap_alsa_open
,
61 .close
= easycap_alsa_close
,
62 .ioctl
= snd_pcm_lib_ioctl
,
63 .hw_params
= easycap_alsa_hw_params
,
64 .hw_free
= easycap_alsa_hw_free
,
65 .prepare
= easycap_alsa_prepare
,
66 .ack
= easycap_alsa_ack
,
67 .trigger
= easycap_alsa_trigger
,
68 .pointer
= easycap_alsa_pointer
,
69 .page
= easycap_alsa_page
,
72 /*****************************************************************************/
73 /*---------------------------------------------------------------------------*/
75 * THE FUNCTION snd_card_create() HAS THIS_MODULE AS AN ARGUMENT. THIS
76 * MEANS MODULE easycap. BEWARE.
78 /*---------------------------------------------------------------------------*/
80 easycap_alsa_probe(struct easycap
*peasycap
)
83 struct snd_card
*psnd_card
;
84 struct snd_pcm
*psnd_pcm
;
86 if (NULL
== peasycap
) {
87 SAY("ERROR: peasycap is NULL\n");
90 if (memcmp(&peasycap
->telltale
[0], TELLTALE
, strlen(TELLTALE
))) {
91 SAY("ERROR: bad peasycap\n");
94 if (0 > peasycap
->minor
) {
95 SAY("ERROR: no minor\n");
99 peasycap
->alsa_hardware
= alsa_hardware
;
100 if (true == peasycap
->microphone
) {
101 peasycap
->alsa_hardware
.rates
= SNDRV_PCM_RATE_32000
;
102 peasycap
->alsa_hardware
.rate_min
= 32000;
103 peasycap
->alsa_hardware
.rate_max
= 32000;
105 peasycap
->alsa_hardware
.rates
= SNDRV_PCM_RATE_48000
;
106 peasycap
->alsa_hardware
.rate_min
= 48000;
107 peasycap
->alsa_hardware
.rate_max
= 48000;
110 #if defined(EASYCAP_NEEDS_CARD_CREATE)
111 if (0 != snd_card_create(SNDRV_DEFAULT_IDX1
, "easycap_alsa",
114 SAY("ERROR: Cannot do ALSA snd_card_create()\n");
118 psnd_card
= snd_card_new(SNDRV_DEFAULT_IDX1
, "easycap_alsa",
120 if (NULL
== psnd_card
) {
121 SAY("ERROR: Cannot do ALSA snd_card_new()\n");
124 #endif /*EASYCAP_NEEDS_CARD_CREATE*/
126 sprintf(&psnd_card
->id
[0], "EasyALSA%i", peasycap
->minor
);
127 strcpy(&psnd_card
->driver
[0], EASYCAP_DRIVER_DESCRIPTION
);
128 strcpy(&psnd_card
->shortname
[0], "easycap_alsa");
129 sprintf(&psnd_card
->longname
[0], "%s", &psnd_card
->shortname
[0]);
131 psnd_card
->dev
= &peasycap
->pusb_device
->dev
;
132 psnd_card
->private_data
= peasycap
;
133 peasycap
->psnd_card
= psnd_card
;
135 rc
= snd_pcm_new(psnd_card
, "easycap_pcm", 0, 0, 1, &psnd_pcm
);
137 SAM("ERROR: Cannot do ALSA snd_pcm_new()\n");
138 snd_card_free(psnd_card
);
142 snd_pcm_set_ops(psnd_pcm
, SNDRV_PCM_STREAM_CAPTURE
,
143 &easycap_alsa_pcm_ops
);
144 psnd_pcm
->info_flags
= 0;
145 strcpy(&psnd_pcm
->name
[0], &psnd_card
->id
[0]);
146 psnd_pcm
->private_data
= peasycap
;
147 peasycap
->psnd_pcm
= psnd_pcm
;
148 peasycap
->psubstream
= (struct snd_pcm_substream
*)NULL
;
150 rc
= snd_card_register(psnd_card
);
152 SAM("ERROR: Cannot do ALSA snd_card_register()\n");
153 snd_card_free(psnd_card
);
157 SAM("registered %s\n", &psnd_card
->id
[0]);
161 /*****************************************************************************/
162 /*---------------------------------------------------------------------------*/
164 * ON COMPLETION OF AN AUDIO URB ITS DATA IS COPIED TO THE DAM BUFFER
165 * PROVIDED peasycap->audio_idle IS ZERO. REGARDLESS OF THIS BEING TRUE,
166 * IT IS RESUBMITTED PROVIDED peasycap->audio_isoc_streaming IS NOT ZERO.
168 /*---------------------------------------------------------------------------*/
170 easycap_alsa_complete(struct urb
*purb
)
172 struct easycap
*peasycap
;
173 struct snd_pcm_substream
*pss
;
174 struct snd_pcm_runtime
*prt
;
175 int dma_bytes
, fragment_bytes
;
179 int i
, j
, more
, much
, rc
;
180 #if defined(UPSAMPLE)
182 __s16 oldaudio
, newaudio
, delta
;
188 SAY("ERROR: purb is NULL\n");
191 peasycap
= purb
->context
;
192 if (NULL
== peasycap
) {
193 SAY("ERROR: peasycap is NULL\n");
196 if (memcmp(&peasycap
->telltale
[0], TELLTALE
, strlen(TELLTALE
))) {
197 SAY("ERROR: bad peasycap\n");
201 if (peasycap
->audio_idle
) {
202 JOM(16, "%i=audio_idle %i=audio_isoc_streaming\n",
203 peasycap
->audio_idle
, peasycap
->audio_isoc_streaming
);
204 if (peasycap
->audio_isoc_streaming
)
207 /*---------------------------------------------------------------------------*/
208 pss
= peasycap
->psubstream
;
214 dma_bytes
= (int)prt
->dma_bytes
;
217 fragment_bytes
= 4 * ((int)prt
->period_size
);
218 if (0 == fragment_bytes
)
220 /* -------------------------------------------------------------------------*/
222 if ((-ESHUTDOWN
== purb
->status
) || (-ENOENT
== purb
->status
)) {
223 JOM(16, "urb status -ESHUTDOWN or -ENOENT\n");
226 SAM("ERROR: non-zero urb status:\n");
227 switch (purb
->status
) {
229 SAM("-EINPROGRESS\n");
261 SAM("-EOPNOTSUPP\n");
264 case -EPFNOSUPPORT
: {
265 SAM("-EPFNOSUPPORT\n");
268 case -EAFNOSUPPORT
: {
269 SAM("-EAFNOSUPPORT\n");
273 SAM("-EADDRINUSE\n");
276 case -EADDRNOTAVAIL
: {
277 SAM("-EADDRNOTAVAIL\n");
301 SAM("-ECONNRESET\n");
309 SAM("unknown error: %i\n", purb
->status
);
315 /*---------------------------------------------------------------------------*/
317 * PROCEED HERE WHEN NO ERROR
319 /*---------------------------------------------------------------------------*/
321 #if defined(UPSAMPLE)
322 oldaudio
= peasycap
->oldaudio
;
325 for (i
= 0; i
< purb
->number_of_packets
; i
++) {
326 switch (purb
->iso_frame_desc
[i
].status
) {
335 SAM("-EINPROGRESS\n");
387 SAM("-ECONNRESET\n");
403 SAM("unknown error: %i\n", purb
->iso_frame_desc
[i
].status
);
407 if (!purb
->iso_frame_desc
[i
].status
) {
408 more
= purb
->iso_frame_desc
[i
].actual_length
;
410 peasycap
->audio_mt
++;
412 if (peasycap
->audio_mt
) {
413 JOM(12, "%4i empty audio urb frames\n",
415 peasycap
->audio_mt
= 0;
418 p1
= (__u8
*)(purb
->transfer_buffer
+
419 purb
->iso_frame_desc
[i
].offset
);
421 /*---------------------------------------------------------------------------*/
423 * COPY more BYTES FROM ISOC BUFFER TO THE DMA BUFFER,
424 * CONVERTING 8-BIT MONO TO 16-BIT SIGNED LITTLE-ENDIAN SAMPLES IF NECESSARY
426 /*---------------------------------------------------------------------------*/
429 SAM("MISTAKE: more is negative\n");
432 much
= dma_bytes
- peasycap
->dma_fill
;
434 SAM("MISTAKE: much is negative\n");
438 peasycap
->dma_fill
= 0;
439 peasycap
->dma_next
= fragment_bytes
;
440 JOM(8, "wrapped dma buffer\n");
442 if (false == peasycap
->microphone
) {
445 memcpy(prt
->dma_area
+
451 #if defined(UPSAMPLE)
453 JOM(8, "MISTAKE? much"
454 " is not divisible by 16\n");
459 p2
= (__u8
*)(prt
->dma_area
+
462 for (j
= 0; j
< (much
/16); j
++) {
463 newaudio
= ((int) *p1
) - 128;
467 delta
= (newaudio
- oldaudio
)
469 s16
= oldaudio
+ delta
;
471 for (k
= 0; k
< 4; k
++) {
472 *p2
= (0x00FF & s16
);
473 *(p2
+ 1) = (0xFF00 &
476 *p2
= (0x00FF & s16
);
477 *(p2
+ 1) = (0xFF00 &
487 if (much
> (2 * more
))
489 p2
= (__u8
*)(prt
->dma_area
+
492 for (j
= 0; j
< (much
/ 2); j
++) {
493 s16
= ((int) *p1
) - 128;
496 *p2
= (0x00FF & s16
);
497 *(p2
+ 1) = (0xFF00 & s16
) >>
504 peasycap
->dma_fill
+= much
;
505 if (peasycap
->dma_fill
>= peasycap
->dma_next
) {
506 isfragment
= peasycap
->dma_fill
/
508 if (0 > isfragment
) {
509 SAM("MISTAKE: isfragment is "
513 peasycap
->dma_read
= (isfragment
514 - 1) * fragment_bytes
;
515 peasycap
->dma_next
= (isfragment
516 + 1) * fragment_bytes
;
517 if (dma_bytes
< peasycap
->dma_next
) {
521 if (0 <= peasycap
->dma_read
) {
522 JOM(8, "snd_pcm_period_elap"
526 snd_pcm_period_elapsed(pss
);
532 JOM(12, "discarding audio samples because "
533 "%i=purb->iso_frame_desc[i].status\n",
534 purb
->iso_frame_desc
[i
].status
);
537 #if defined(UPSAMPLE)
538 peasycap
->oldaudio
= oldaudio
;
542 /*---------------------------------------------------------------------------*/
546 /*---------------------------------------------------------------------------*/
548 if (peasycap
->audio_isoc_streaming
) {
549 rc
= usb_submit_urb(purb
, GFP_ATOMIC
);
551 if ((-ENODEV
!= rc
) && (-ENOENT
!= rc
)) {
552 SAM("ERROR: while %i=audio_idle, "
553 "usb_submit_urb() failed "
554 "with rc:\n", peasycap
->audio_idle
);
597 SAM("unknown error: %i\n", rc
);
601 if (0 < peasycap
->audio_isoc_streaming
)
602 (peasycap
->audio_isoc_streaming
)--;
607 /*****************************************************************************/
609 easycap_alsa_open(struct snd_pcm_substream
*pss
)
611 struct snd_pcm
*psnd_pcm
;
612 struct snd_card
*psnd_card
;
613 struct easycap
*peasycap
;
617 SAY("ERROR: pss is NULL\n");
621 if (NULL
== psnd_pcm
) {
622 SAY("ERROR: psnd_pcm is NULL\n");
625 psnd_card
= psnd_pcm
->card
;
626 if (NULL
== psnd_card
) {
627 SAY("ERROR: psnd_card is NULL\n");
631 peasycap
= psnd_card
->private_data
;
632 if (NULL
== peasycap
) {
633 SAY("ERROR: peasycap is NULL\n");
636 if (memcmp(&peasycap
->telltale
[0], TELLTALE
, strlen(TELLTALE
))) {
637 SAY("ERROR: bad peasycap\n");
640 if (peasycap
->psnd_card
!= psnd_card
) {
641 SAM("ERROR: bad peasycap->psnd_card\n");
644 if (NULL
!= peasycap
->psubstream
) {
645 SAM("ERROR: bad peasycap->psubstream\n");
648 pss
->private_data
= peasycap
;
649 peasycap
->psubstream
= pss
;
650 pss
->runtime
->hw
= peasycap
->alsa_hardware
;
651 pss
->runtime
->private_data
= peasycap
;
652 pss
->private_data
= peasycap
;
654 if (0 != easycap_sound_setup(peasycap
)) {
655 JOM(4, "ending unsuccessfully\n");
658 JOM(4, "ending successfully\n");
661 /*****************************************************************************/
663 easycap_alsa_close(struct snd_pcm_substream
*pss
)
665 struct easycap
*peasycap
;
669 SAY("ERROR: pss is NULL\n");
672 peasycap
= snd_pcm_substream_chip(pss
);
673 if (NULL
== peasycap
) {
674 SAY("ERROR: peasycap is NULL\n");
677 if (memcmp(&peasycap
->telltale
[0], TELLTALE
, strlen(TELLTALE
))) {
678 SAY("ERROR: bad peasycap\n");
681 pss
->private_data
= NULL
;
682 peasycap
->psubstream
= (struct snd_pcm_substream
*)NULL
;
683 JOT(4, "ending successfully\n");
686 /*****************************************************************************/
688 easycap_alsa_hw_params(struct snd_pcm_substream
*pss
,
689 struct snd_pcm_hw_params
*phw
)
693 JOT(4, "%i\n", (params_buffer_bytes(phw
)));
695 SAY("ERROR: pss is NULL\n");
698 rc
= easycap_alsa_vmalloc(pss
, params_buffer_bytes(phw
));
703 /*****************************************************************************/
705 easycap_alsa_vmalloc(struct snd_pcm_substream
*pss
, size_t sz
)
707 struct snd_pcm_runtime
*prt
;
711 SAY("ERROR: pss is NULL\n");
716 SAY("ERROR: substream.runtime is NULL\n");
720 if (prt
->dma_bytes
> sz
)
722 vfree(prt
->dma_area
);
724 prt
->dma_area
= vmalloc(sz
);
725 if (NULL
== prt
->dma_area
)
730 /*****************************************************************************/
732 easycap_alsa_hw_free(struct snd_pcm_substream
*pss
)
734 struct snd_pcm_runtime
*prt
;
738 SAY("ERROR: pss is NULL\n");
743 SAY("ERROR: substream.runtime is NULL\n");
746 if (NULL
!= prt
->dma_area
) {
747 JOT(8, "0x%08lX=prt->dma_area\n", (unsigned long int)prt
->dma_area
);
748 vfree(prt
->dma_area
);
749 prt
->dma_area
= NULL
;
751 JOT(8, "dma_area already freed\n");
754 /*****************************************************************************/
756 easycap_alsa_prepare(struct snd_pcm_substream
*pss
)
758 struct easycap
*peasycap
;
759 struct snd_pcm_runtime
*prt
;
763 SAY("ERROR: pss is NULL\n");
767 peasycap
= snd_pcm_substream_chip(pss
);
768 if (NULL
== peasycap
) {
769 SAY("ERROR: peasycap is NULL\n");
772 if (memcmp(&peasycap
->telltale
[0], TELLTALE
, strlen(TELLTALE
))) {
773 SAY("ERROR: bad peasycap\n");
777 JOM(16, "ALSA decides %8i Hz=rate\n", (int)pss
->runtime
->rate
);
778 JOM(16, "ALSA decides %8i =period_size\n", (int)pss
->runtime
->period_size
);
779 JOM(16, "ALSA decides %8i =periods\n", (int)pss
->runtime
->periods
);
780 JOM(16, "ALSA decides %8i =buffer_size\n", (int)pss
->runtime
->buffer_size
);
781 JOM(16, "ALSA decides %8i =dma_bytes\n", (int)pss
->runtime
->dma_bytes
);
782 JOM(16, "ALSA decides %8i =boundary\n", (int)pss
->runtime
->boundary
);
783 JOM(16, "ALSA decides %8i =period_step\n", (int)pss
->runtime
->period_step
);
784 JOM(16, "ALSA decides %8i =sample_bits\n", (int)pss
->runtime
->sample_bits
);
785 JOM(16, "ALSA decides %8i =frame_bits\n", (int)pss
->runtime
->frame_bits
);
786 JOM(16, "ALSA decides %8i =min_align\n", (int)pss
->runtime
->min_align
);
787 JOM(12, "ALSA decides %8i =hw_ptr_base\n", (int)pss
->runtime
->hw_ptr_base
);
788 JOM(12, "ALSA decides %8i =hw_ptr_interrupt\n",
789 (int)pss
->runtime
->hw_ptr_interrupt
);
790 if (prt
->dma_bytes
!= 4 * ((int)prt
->period_size
) * ((int)prt
->periods
)) {
791 SAY("MISTAKE: unexpected ALSA parameters\n");
796 /*****************************************************************************/
798 easycap_alsa_ack(struct snd_pcm_substream
*pss
)
802 /*****************************************************************************/
804 easycap_alsa_trigger(struct snd_pcm_substream
*pss
, int cmd
)
806 struct easycap
*peasycap
;
809 JOT(4, "%i=cmd cf %i=START %i=STOP\n", cmd
, SNDRV_PCM_TRIGGER_START
,
810 SNDRV_PCM_TRIGGER_STOP
);
812 SAY("ERROR: pss is NULL\n");
815 peasycap
= snd_pcm_substream_chip(pss
);
816 if (NULL
== peasycap
) {
817 SAY("ERROR: peasycap is NULL\n");
820 if (memcmp(&peasycap
->telltale
[0], TELLTALE
, strlen(TELLTALE
))) {
821 SAY("ERROR: bad peasycap\n");
826 case SNDRV_PCM_TRIGGER_START
: {
827 peasycap
->audio_idle
= 0;
830 case SNDRV_PCM_TRIGGER_STOP
: {
831 peasycap
->audio_idle
= 1;
839 /*****************************************************************************/
841 easycap_alsa_pointer(struct snd_pcm_substream
*pss
)
843 struct easycap
*peasycap
;
844 snd_pcm_uframes_t offset
;
848 SAY("ERROR: pss is NULL\n");
851 peasycap
= snd_pcm_substream_chip(pss
);
852 if (NULL
== peasycap
) {
853 SAY("ERROR: peasycap is NULL\n");
856 if (memcmp(&peasycap
->telltale
[0], TELLTALE
, strlen(TELLTALE
))) {
857 SAY("ERROR: bad peasycap\n");
860 if ((0 != peasycap
->audio_eof
) || (0 != peasycap
->audio_idle
)) {
861 JOM(8, "returning -EIO because "
862 "%i=audio_idle %i=audio_eof\n",
863 peasycap
->audio_idle
, peasycap
->audio_eof
);
866 /*---------------------------------------------------------------------------*/
867 if (0 > peasycap
->dma_read
) {
868 JOM(8, "returning -EBUSY\n");
871 offset
= ((snd_pcm_uframes_t
)peasycap
->dma_read
)/4;
872 JOM(8, "ALSA decides %8i =hw_ptr_base\n", (int)pss
->runtime
->hw_ptr_base
);
873 JOM(8, "ALSA decides %8i =hw_ptr_interrupt\n",
874 (int)pss
->runtime
->hw_ptr_interrupt
);
875 JOM(8, "%7i=offset %7i=dma_read %7i=dma_next\n",
876 (int)offset
, peasycap
->dma_read
, peasycap
->dma_next
);
879 /*****************************************************************************/
881 easycap_alsa_page(struct snd_pcm_substream
*pss
, unsigned long offset
)
883 return vmalloc_to_page(pss
->runtime
->dma_area
+ offset
);
885 /*****************************************************************************/
887 #else /*!EASYCAP_NEEDS_ALSA*/
889 /*****************************************************************************/
890 /**************************** **************************/
891 /**************************** Open Sound System **************************/
892 /**************************** **************************/
893 /*****************************************************************************/
894 /*--------------------------------------------------------------------------*/
896 * PARAMETERS USED WHEN REGISTERING THE AUDIO INTERFACE
898 /*--------------------------------------------------------------------------*/
899 const struct file_operations easyoss_fops
= {
900 .owner
= THIS_MODULE
,
901 .open
= easyoss_open
,
902 .release
= easyoss_release
,
903 #if defined(EASYCAP_NEEDS_UNLOCKED_IOCTL)
904 .unlocked_ioctl
= easyoss_ioctl_noinode
,
906 .ioctl
= easyoss_ioctl
,
907 #endif /*EASYCAP_NEEDS_UNLOCKED_IOCTL*/
908 .read
= easyoss_read
,
911 struct usb_class_driver easyoss_class
= {
912 .name
= "usb/easyoss%d",
913 .fops
= &easyoss_fops
,
914 .minor_base
= USB_SKEL_MINOR_BASE
,
916 /*****************************************************************************/
917 /*---------------------------------------------------------------------------*/
919 * ON COMPLETION OF AN AUDIO URB ITS DATA IS COPIED TO THE AUDIO BUFFERS
920 * PROVIDED peasycap->audio_idle IS ZERO. REGARDLESS OF THIS BEING TRUE,
921 * IT IS RESUBMITTED PROVIDED peasycap->audio_isoc_streaming IS NOT ZERO.
923 /*---------------------------------------------------------------------------*/
925 easyoss_complete(struct urb
*purb
)
927 struct easycap
*peasycap
;
928 struct data_buffer
*paudio_buffer
;
931 int i
, j
, more
, much
, leap
, rc
;
932 #if defined(UPSAMPLE)
934 __s16 oldaudio
, newaudio
, delta
;
940 SAY("ERROR: purb is NULL\n");
943 peasycap
= purb
->context
;
944 if (NULL
== peasycap
) {
945 SAY("ERROR: peasycap is NULL\n");
948 if (memcmp(&peasycap
->telltale
[0], TELLTALE
, strlen(TELLTALE
))) {
949 SAY("ERROR: bad peasycap\n");
953 if (peasycap
->audio_idle
) {
954 JOM(16, "%i=audio_idle %i=audio_isoc_streaming\n",
955 peasycap
->audio_idle
, peasycap
->audio_isoc_streaming
);
956 if (peasycap
->audio_isoc_streaming
) {
957 rc
= usb_submit_urb(purb
, GFP_ATOMIC
);
959 if (-ENODEV
!= rc
&& -ENOENT
!= rc
) {
960 SAM("ERROR: while %i=audio_idle, "
961 "usb_submit_urb() failed with rc:\n",
962 peasycap
->audio_idle
);
1005 SAM("unknown error: %i\n", rc
);
1013 /*---------------------------------------------------------------------------*/
1015 if ((-ESHUTDOWN
== purb
->status
) || (-ENOENT
== purb
->status
)) {
1016 JOM(16, "urb status -ESHUTDOWN or -ENOENT\n");
1019 SAM("ERROR: non-zero urb status:\n");
1020 switch (purb
->status
) {
1021 case -EINPROGRESS
: {
1022 SAM("-EINPROGRESS\n");
1034 SAM("-EOVERFLOW\n");
1046 SAM("-ETIMEDOUT\n");
1054 SAM("-EOPNOTSUPP\n");
1057 case -EPFNOSUPPORT
: {
1058 SAM("-EPFNOSUPPORT\n");
1061 case -EAFNOSUPPORT
: {
1062 SAM("-EAFNOSUPPORT\n");
1066 SAM("-EADDRINUSE\n");
1069 case -EADDRNOTAVAIL
: {
1070 SAM("-EADDRNOTAVAIL\n");
1086 SAM("-ESHUTDOWN\n");
1094 SAM("-ECONNRESET\n");
1106 SAM("unknown error: %i\n", purb
->status
);
1112 /*---------------------------------------------------------------------------*/
1114 * PROCEED HERE WHEN NO ERROR
1116 /*---------------------------------------------------------------------------*/
1117 #if defined(UPSAMPLE)
1118 oldaudio
= peasycap
->oldaudio
;
1121 for (i
= 0; i
< purb
->number_of_packets
; i
++) {
1122 switch (purb
->iso_frame_desc
[i
].status
) {
1134 case -EINPROGRESS
: {
1135 SAM("-EINPROGRESS\n");
1151 SAM("-ETIMEDOUT\n");
1167 SAM("-EOVERFLOW\n");
1171 SAM("-EREMOTEIO\n");
1183 SAM("-ECONNRESET\n");
1191 SAM("-ESHUTDOWN\n");
1199 SAM("unknown error: %i\n", purb
->iso_frame_desc
[i
].status
);
1203 if (!purb
->iso_frame_desc
[i
].status
) {
1204 more
= purb
->iso_frame_desc
[i
].actual_length
;
1206 #if defined(TESTTONE)
1208 more
= purb
->iso_frame_desc
[i
].length
;
1212 peasycap
->audio_mt
++;
1214 if (peasycap
->audio_mt
) {
1215 JOM(12, "%4i empty audio urb frames\n",
1216 peasycap
->audio_mt
);
1217 peasycap
->audio_mt
= 0;
1220 p1
= (__u8
*)(purb
->transfer_buffer
+
1221 purb
->iso_frame_desc
[i
].offset
);
1226 /*---------------------------------------------------------------------------*/
1228 * COPY more BYTES FROM ISOC BUFFER TO AUDIO BUFFER,
1229 * CONVERTING 8-BIT MONO TO 16-BIT SIGNED LITTLE-ENDIAN SAMPLES IF NECESSARY
1231 /*---------------------------------------------------------------------------*/
1234 SAM("MISTAKE: more is negative\n");
1237 if (peasycap
->audio_buffer_page_many
<=
1238 peasycap
->audio_fill
) {
1240 "peasycap->audio_fill\n");
1244 paudio_buffer
= &peasycap
->audio_buffer
1245 [peasycap
->audio_fill
];
1246 if (PAGE_SIZE
< (paudio_buffer
->pto
-
1247 paudio_buffer
->pgo
)) {
1248 SAM("ERROR: bad paudio_buffer->pto\n");
1251 if (PAGE_SIZE
== (paudio_buffer
->pto
-
1252 paudio_buffer
->pgo
)) {
1254 #if defined(TESTTONE)
1255 easyoss_testtone(peasycap
,
1256 peasycap
->audio_fill
);
1259 paudio_buffer
->pto
=
1261 (peasycap
->audio_fill
)++;
1263 audio_buffer_page_many
<=
1264 peasycap
->audio_fill
)
1265 peasycap
->audio_fill
= 0;
1267 JOM(8, "bumped peasycap->"
1268 "audio_fill to %i\n",
1269 peasycap
->audio_fill
);
1271 paudio_buffer
= &peasycap
->
1273 [peasycap
->audio_fill
];
1274 paudio_buffer
->pto
=
1277 if (!(peasycap
->audio_fill
%
1279 audio_pages_per_fragment
)) {
1280 JOM(12, "wakeup call on wq_"
1281 "audio, %i=frag reading %i"
1283 (peasycap
->audio_read
/
1285 audio_pages_per_fragment
),
1286 (peasycap
->audio_fill
/
1288 audio_pages_per_fragment
));
1289 wake_up_interruptible
1290 (&(peasycap
->wq_audio
));
1294 much
= PAGE_SIZE
- (int)(paudio_buffer
->pto
-
1295 paudio_buffer
->pgo
);
1297 if (false == peasycap
->microphone
) {
1301 memcpy(paudio_buffer
->pto
, p1
, much
);
1305 #if defined(UPSAMPLE)
1307 JOM(8, "MISTAKE? much"
1308 " is not divisible by 16\n");
1313 p2
= (__u8
*)paudio_buffer
->pto
;
1315 for (j
= 0; j
< (much
/16); j
++) {
1316 newaudio
= ((int) *p1
) - 128;
1320 delta
= (newaudio
- oldaudio
)
1322 s16
= oldaudio
+ delta
;
1324 for (k
= 0; k
< 4; k
++) {
1325 *p2
= (0x00FF & s16
);
1326 *(p2
+ 1) = (0xFF00 &
1329 *p2
= (0x00FF & s16
);
1330 *(p2
+ 1) = (0xFF00 &
1341 if (much
> (2 * more
))
1343 p2
= (__u8
*)paudio_buffer
->pto
;
1345 for (j
= 0; j
< (much
/ 2); j
++) {
1346 s16
= ((int) *p1
) - 128;
1349 *p2
= (0x00FF & s16
);
1350 *(p2
+ 1) = (0xFF00 & s16
) >>
1357 (paudio_buffer
->pto
) += much
;
1361 JOM(12, "discarding audio samples because "
1362 "%i=purb->iso_frame_desc[i].status\n",
1363 purb
->iso_frame_desc
[i
].status
);
1366 #if defined(UPSAMPLE)
1367 peasycap
->oldaudio
= oldaudio
;
1371 /*---------------------------------------------------------------------------*/
1375 /*---------------------------------------------------------------------------*/
1377 if (peasycap
->audio_isoc_streaming
) {
1378 rc
= usb_submit_urb(purb
, GFP_ATOMIC
);
1380 if (-ENODEV
!= rc
&& -ENOENT
!= rc
) {
1381 SAM("ERROR: while %i=audio_idle, "
1382 "usb_submit_urb() failed "
1383 "with rc:\n", peasycap
->audio_idle
);
1426 SAM("unknown error: %i\n", rc
);
1434 /*****************************************************************************/
1435 /*---------------------------------------------------------------------------*/
1437 * THE AUDIO URBS ARE SUBMITTED AT THIS EARLY STAGE SO THAT IT IS POSSIBLE TO
1438 * STREAM FROM /dev/easyoss1 WITH SIMPLE PROGRAMS SUCH AS cat WHICH DO NOT
1439 * HAVE AN IOCTL INTERFACE.
1441 /*---------------------------------------------------------------------------*/
1443 easyoss_open(struct inode
*inode
, struct file
*file
)
1445 struct usb_interface
*pusb_interface
;
1446 struct easycap
*peasycap
;
1448 /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
1449 #if defined(EASYCAP_IS_VIDEODEV_CLIENT)
1450 #if defined(EASYCAP_NEEDS_V4L2_DEVICE_H)
1451 struct v4l2_device
*pv4l2_device
;
1452 #endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/
1453 #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
1454 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
1458 subminor
= iminor(inode
);
1460 pusb_interface
= usb_find_interface(&easycap_usb_driver
, subminor
);
1461 if (NULL
== pusb_interface
) {
1462 SAY("ERROR: pusb_interface is NULL\n");
1463 SAY("ending unsuccessfully\n");
1466 peasycap
= usb_get_intfdata(pusb_interface
);
1467 if (NULL
== peasycap
) {
1468 SAY("ERROR: peasycap is NULL\n");
1469 SAY("ending unsuccessfully\n");
1472 /*---------------------------------------------------------------------------*/
1473 #if (!defined(EASYCAP_IS_VIDEODEV_CLIENT))
1475 /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
1477 #if defined(EASYCAP_NEEDS_V4L2_DEVICE_H)
1478 /*---------------------------------------------------------------------------*/
1480 * SOME VERSIONS OF THE videodev MODULE OVERWRITE THE DATA WHICH HAS
1481 * BEEN WRITTEN BY THE CALL TO usb_set_intfdata() IN easycap_usb_probe(),
1482 * REPLACING IT WITH A POINTER TO THE EMBEDDED v4l2_device STRUCTURE.
1483 * TO DETECT THIS, THE STRING IN THE easycap.telltale[] BUFFER IS CHECKED.
1485 /*---------------------------------------------------------------------------*/
1486 if (memcmp(&peasycap
->telltale
[0], TELLTALE
, strlen(TELLTALE
))) {
1487 pv4l2_device
= usb_get_intfdata(pusb_interface
);
1488 if ((struct v4l2_device
*)NULL
== pv4l2_device
) {
1489 SAY("ERROR: pv4l2_device is NULL\n");
1492 peasycap
= (struct easycap
*)
1493 container_of(pv4l2_device
, struct easycap
, v4l2_device
);
1495 #endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/
1497 #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
1498 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
1499 /*---------------------------------------------------------------------------*/
1500 if (memcmp(&peasycap
->telltale
[0], TELLTALE
, strlen(TELLTALE
))) {
1501 SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap
);
1504 /*---------------------------------------------------------------------------*/
1506 file
->private_data
= peasycap
;
1508 if (0 != easycap_sound_setup(peasycap
)) {
1514 /*****************************************************************************/
1516 easyoss_release(struct inode
*inode
, struct file
*file
)
1518 struct easycap
*peasycap
;
1522 peasycap
= file
->private_data
;
1523 if (NULL
== peasycap
) {
1524 SAY("ERROR: peasycap is NULL.\n");
1527 if (memcmp(&peasycap
->telltale
[0], TELLTALE
, strlen(TELLTALE
))) {
1528 SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap
);
1531 if (0 != kill_audio_urbs(peasycap
)) {
1532 SAM("ERROR: kill_audio_urbs() failed\n");
1535 JOM(4, "ending successfully\n");
1538 /*****************************************************************************/
1540 easyoss_read(struct file
*file
, char __user
*puserspacebuffer
,
1541 size_t kount
, loff_t
*poff
)
1543 struct timeval timeval
;
1544 long long int above
, below
, mean
;
1545 struct signed_div_result sdr
;
1547 long int kount1
, more
, rc
, l0
, lm
;
1549 struct easycap
*peasycap
;
1550 struct data_buffer
*pdata_buffer
;
1553 /*---------------------------------------------------------------------------*/
1555 * DO A BLOCKING READ TO TRANSFER DATA TO USER SPACE.
1557 ******************************************************************************
1558 ***** N.B. IF THIS FUNCTION RETURNS 0, NOTHING IS SEEN IN USER SPACE. ******
1559 ***** THIS CONDITION SIGNIFIES END-OF-FILE. ******
1560 ******************************************************************************
1562 /*---------------------------------------------------------------------------*/
1564 JOT(8, "%5i=kount %5i=*poff\n", (int)kount
, (int)(*poff
));
1567 SAY("ERROR: file is NULL\n");
1568 return -ERESTARTSYS
;
1570 peasycap
= file
->private_data
;
1571 if (NULL
== peasycap
) {
1572 SAY("ERROR in easyoss_read(): peasycap is NULL\n");
1575 if (memcmp(&peasycap
->telltale
[0], TELLTALE
, strlen(TELLTALE
))) {
1576 SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap
);
1579 if (NULL
== peasycap
->pusb_device
) {
1580 SAY("ERROR: peasycap->pusb_device is NULL\n");
1583 kd
= isdongle(peasycap
);
1584 if (0 <= kd
&& DONGLE_MANY
> kd
) {
1585 if (mutex_lock_interruptible(&(easycapdc60_dongle
[kd
].mutex_audio
))) {
1587 "cannot lock easycapdc60_dongle[%i].mutex_audio\n", kd
);
1588 return -ERESTARTSYS
;
1590 JOM(4, "locked easycapdc60_dongle[%i].mutex_audio\n", kd
);
1591 /*---------------------------------------------------------------------------*/
1593 * MEANWHILE, easycap_usb_disconnect() MAY HAVE FREED POINTER peasycap,
1594 * IN WHICH CASE A REPEAT CALL TO isdongle() WILL FAIL.
1595 * IF NECESSARY, BAIL OUT.
1597 /*---------------------------------------------------------------------------*/
1598 if (kd
!= isdongle(peasycap
))
1599 return -ERESTARTSYS
;
1601 SAY("ERROR: file is NULL\n");
1602 mutex_unlock(&easycapdc60_dongle
[kd
].mutex_audio
);
1603 return -ERESTARTSYS
;
1605 peasycap
= file
->private_data
;
1606 if (NULL
== peasycap
) {
1607 SAY("ERROR: peasycap is NULL\n");
1608 mutex_unlock(&easycapdc60_dongle
[kd
].mutex_audio
);
1609 return -ERESTARTSYS
;
1611 if (memcmp(&peasycap
->telltale
[0], TELLTALE
, strlen(TELLTALE
))) {
1612 SAY("ERROR: bad peasycap: 0x%08lX\n",
1613 (unsigned long int) peasycap
);
1614 mutex_unlock(&easycapdc60_dongle
[kd
].mutex_audio
);
1615 return -ERESTARTSYS
;
1617 if (NULL
== peasycap
->pusb_device
) {
1618 SAM("ERROR: peasycap->pusb_device is NULL\n");
1619 mutex_unlock(&easycapdc60_dongle
[kd
].mutex_audio
);
1620 return -ERESTARTSYS
;
1623 /*---------------------------------------------------------------------------*/
1625 * IF easycap_usb_disconnect() HAS ALREADY FREED POINTER peasycap BEFORE THE
1626 * ATTEMPT TO ACQUIRE THE SEMAPHORE, isdongle() WILL HAVE FAILED. BAIL OUT.
1628 /*---------------------------------------------------------------------------*/
1629 return -ERESTARTSYS
;
1631 /*---------------------------------------------------------------------------*/
1632 if (file
->f_flags
& O_NONBLOCK
)
1633 JOT(16, "NONBLOCK kount=%i, *poff=%i\n", (int)kount
, (int)(*poff
));
1635 JOT(8, "BLOCKING kount=%i, *poff=%i\n", (int)kount
, (int)(*poff
));
1637 if ((0 > peasycap
->audio_read
) ||
1638 (peasycap
->audio_buffer_page_many
<= peasycap
->audio_read
)) {
1639 SAM("ERROR: peasycap->audio_read out of range\n");
1640 mutex_unlock(&easycapdc60_dongle
[kd
].mutex_audio
);
1643 pdata_buffer
= &peasycap
->audio_buffer
[peasycap
->audio_read
];
1644 if ((struct data_buffer
*)NULL
== pdata_buffer
) {
1645 SAM("ERROR: pdata_buffer is NULL\n");
1646 mutex_unlock(&easycapdc60_dongle
[kd
].mutex_audio
);
1649 JOM(12, "before wait, %i=frag read %i=frag fill\n",
1650 (peasycap
->audio_read
/ peasycap
->audio_pages_per_fragment
),
1651 (peasycap
->audio_fill
/ peasycap
->audio_pages_per_fragment
));
1652 fragment
= (peasycap
->audio_read
/ peasycap
->audio_pages_per_fragment
);
1653 while ((fragment
== (peasycap
->audio_fill
/
1654 peasycap
->audio_pages_per_fragment
)) ||
1655 (0 == (PAGE_SIZE
- (pdata_buffer
->pto
- pdata_buffer
->pgo
)))) {
1656 if (file
->f_flags
& O_NONBLOCK
) {
1657 JOM(16, "returning -EAGAIN as instructed\n");
1658 mutex_unlock(&easycapdc60_dongle
[kd
].mutex_audio
);
1661 rc
= wait_event_interruptible(peasycap
->wq_audio
,
1662 (peasycap
->audio_idle
|| peasycap
->audio_eof
||
1663 ((fragment
!= (peasycap
->audio_fill
/
1664 peasycap
->audio_pages_per_fragment
)) &&
1665 (0 < (PAGE_SIZE
- (pdata_buffer
->pto
- pdata_buffer
->pgo
))))));
1667 SAM("aborted by signal\n");
1668 mutex_unlock(&easycapdc60_dongle
[kd
].mutex_audio
);
1669 return -ERESTARTSYS
;
1671 if (peasycap
->audio_eof
) {
1672 JOM(8, "returning 0 because %i=audio_eof\n",
1673 peasycap
->audio_eof
);
1674 kill_audio_urbs(peasycap
);
1675 mutex_unlock(&easycapdc60_dongle
[kd
].mutex_audio
);
1678 if (peasycap
->audio_idle
) {
1679 JOM(16, "returning 0 because %i=audio_idle\n",
1680 peasycap
->audio_idle
);
1681 mutex_unlock(&easycapdc60_dongle
[kd
].mutex_audio
);
1684 if (!peasycap
->audio_isoc_streaming
) {
1685 JOM(16, "returning 0 because audio urbs not streaming\n");
1686 mutex_unlock(&easycapdc60_dongle
[kd
].mutex_audio
);
1690 JOM(12, "after wait, %i=frag read %i=frag fill\n",
1691 (peasycap
->audio_read
/ peasycap
->audio_pages_per_fragment
),
1692 (peasycap
->audio_fill
/ peasycap
->audio_pages_per_fragment
));
1694 fragment
= (peasycap
->audio_read
/ peasycap
->audio_pages_per_fragment
);
1695 while (fragment
== (peasycap
->audio_read
/
1696 peasycap
->audio_pages_per_fragment
)) {
1697 if (NULL
== pdata_buffer
->pgo
) {
1698 SAM("ERROR: pdata_buffer->pgo is NULL\n");
1699 mutex_unlock(&easycapdc60_dongle
[kd
].mutex_audio
);
1702 if (NULL
== pdata_buffer
->pto
) {
1703 SAM("ERROR: pdata_buffer->pto is NULL\n");
1704 mutex_unlock(&easycapdc60_dongle
[kd
].mutex_audio
);
1707 kount1
= PAGE_SIZE
- (pdata_buffer
->pto
- pdata_buffer
->pgo
);
1709 SAM("MISTAKE: kount1 is negative\n");
1710 mutex_unlock(&easycapdc60_dongle
[kd
].mutex_audio
);
1711 return -ERESTARTSYS
;
1714 (peasycap
->audio_read
)++;
1715 if (peasycap
->audio_buffer_page_many
<= peasycap
->audio_read
)
1716 peasycap
->audio_read
= 0;
1717 JOM(12, "bumped peasycap->audio_read to %i\n",
1718 peasycap
->audio_read
);
1720 if (fragment
!= (peasycap
->audio_read
/
1721 peasycap
->audio_pages_per_fragment
))
1724 if ((0 > peasycap
->audio_read
) ||
1725 (peasycap
->audio_buffer_page_many
<=
1726 peasycap
->audio_read
)) {
1727 SAM("ERROR: peasycap->audio_read out of range\n");
1728 mutex_unlock(&easycapdc60_dongle
[kd
].mutex_audio
);
1731 pdata_buffer
= &peasycap
->audio_buffer
[peasycap
->audio_read
];
1732 if ((struct data_buffer
*)NULL
== pdata_buffer
) {
1733 SAM("ERROR: pdata_buffer is NULL\n");
1734 mutex_unlock(&easycapdc60_dongle
[kd
].mutex_audio
);
1737 if (NULL
== pdata_buffer
->pgo
) {
1738 SAM("ERROR: pdata_buffer->pgo is NULL\n");
1739 mutex_unlock(&easycapdc60_dongle
[kd
].mutex_audio
);
1742 if (NULL
== pdata_buffer
->pto
) {
1743 SAM("ERROR: pdata_buffer->pto is NULL\n");
1744 mutex_unlock(&easycapdc60_dongle
[kd
].mutex_audio
);
1747 kount1
= PAGE_SIZE
- (pdata_buffer
->pto
- pdata_buffer
->pgo
);
1749 JOM(12, "ready to send %li bytes\n", (long int) kount1
);
1750 JOM(12, "still to send %li bytes\n", (long int) kount
);
1754 JOM(12, "agreed to send %li bytes from page %i\n",
1755 more
, peasycap
->audio_read
);
1759 /*---------------------------------------------------------------------------*/
1761 * ACCUMULATE DYNAMIC-RANGE INFORMATION
1763 /*---------------------------------------------------------------------------*/
1764 p0
= (unsigned char *)pdata_buffer
->pgo
; l0
= 0; lm
= more
/2;
1766 SUMMER(p0
, &peasycap
->audio_sample
, &peasycap
->audio_niveau
,
1767 &peasycap
->audio_square
); l0
++; p0
+= 2;
1769 /*---------------------------------------------------------------------------*/
1770 rc
= copy_to_user(puserspacebuffer
, pdata_buffer
->pto
, more
);
1772 SAM("ERROR: copy_to_user() returned %li\n", rc
);
1773 mutex_unlock(&easycapdc60_dongle
[kd
].mutex_audio
);
1776 *poff
+= (loff_t
)more
;
1777 szret
+= (size_t)more
;
1778 pdata_buffer
->pto
+= more
;
1779 puserspacebuffer
+= more
;
1780 kount
-= (size_t)more
;
1782 JOM(12, "after read, %i=frag read %i=frag fill\n",
1783 (peasycap
->audio_read
/ peasycap
->audio_pages_per_fragment
),
1784 (peasycap
->audio_fill
/ peasycap
->audio_pages_per_fragment
));
1786 SAM("MISTAKE: %li=kount %li=szret\n",
1787 (long int)kount
, (long int)szret
);
1789 /*---------------------------------------------------------------------------*/
1791 * CALCULATE DYNAMIC RANGE FOR (VAPOURWARE) AUTOMATIC VOLUME CONTROL
1793 /*---------------------------------------------------------------------------*/
1794 if (peasycap
->audio_sample
) {
1795 below
= peasycap
->audio_sample
;
1796 above
= peasycap
->audio_square
;
1797 sdr
= signed_div(above
, below
);
1798 above
= sdr
.quotient
;
1799 mean
= peasycap
->audio_niveau
;
1800 sdr
= signed_div(mean
, peasycap
->audio_sample
);
1802 JOM(8, "%8lli=mean %8lli=meansquare after %lli samples, =>\n",
1803 sdr
.quotient
, above
, peasycap
->audio_sample
);
1805 sdr
= signed_div(above
, 32768);
1806 JOM(8, "audio dynamic range is roughly %lli\n", sdr
.quotient
);
1808 /*---------------------------------------------------------------------------*/
1810 * UPDATE THE AUDIO CLOCK
1812 /*---------------------------------------------------------------------------*/
1813 do_gettimeofday(&timeval
);
1814 if (!peasycap
->timeval1
.tv_sec
) {
1815 peasycap
->audio_bytes
= 0;
1816 peasycap
->timeval3
= timeval
;
1817 peasycap
->timeval1
= peasycap
->timeval3
;
1818 sdr
.quotient
= 192000;
1820 peasycap
->audio_bytes
+= (long long int) szret
;
1821 below
= ((long long int)(1000000)) *
1822 ((long long int)(timeval
.tv_sec
-
1823 peasycap
->timeval3
.tv_sec
)) +
1824 (long long int)(timeval
.tv_usec
- peasycap
->timeval3
.tv_usec
);
1825 above
= 1000000 * ((long long int) peasycap
->audio_bytes
);
1828 sdr
= signed_div(above
, below
);
1830 sdr
.quotient
= 192000;
1832 JOM(8, "audio streaming at %lli bytes/second\n", sdr
.quotient
);
1833 peasycap
->dnbydt
= sdr
.quotient
;
1835 mutex_unlock(&easycapdc60_dongle
[kd
].mutex_audio
);
1836 JOM(4, "unlocked easycapdc60_dongle[%i].mutex_audio\n", kd
);
1837 JOM(8, "returning %li\n", (long int)szret
);
1840 /*****************************************************************************/
1842 #endif /*!EASYCAP_NEEDS_ALSA*/
1844 /*****************************************************************************/
1845 /*****************************************************************************/
1846 /*****************************************************************************/
1847 /*****************************************************************************/
1848 /*****************************************************************************/
1849 /*****************************************************************************/
1850 /*---------------------------------------------------------------------------*/
1852 * COMMON AUDIO INITIALIZATION
1854 /*---------------------------------------------------------------------------*/
1856 easycap_sound_setup(struct easycap
*peasycap
)
1860 JOM(4, "starting initialization\n");
1862 if (NULL
== peasycap
) {
1863 SAY("ERROR: peasycap is NULL.\n");
1866 if ((struct usb_device
*)NULL
== peasycap
->pusb_device
) {
1867 SAM("ERROR: peasycap->pusb_device is NULL\n");
1870 JOM(16, "0x%08lX=peasycap->pusb_device\n", (long int)peasycap
->pusb_device
);
1872 rc
= audio_setup(peasycap
);
1873 JOM(8, "audio_setup() returned %i\n", rc
);
1875 if ((struct usb_device
*)NULL
== peasycap
->pusb_device
) {
1876 SAM("ERROR: peasycap->pusb_device has become NULL\n");
1879 /*---------------------------------------------------------------------------*/
1880 if ((struct usb_device
*)NULL
== peasycap
->pusb_device
) {
1881 SAM("ERROR: peasycap->pusb_device has become NULL\n");
1884 rc
= usb_set_interface(peasycap
->pusb_device
, peasycap
->audio_interface
,
1885 peasycap
->audio_altsetting_on
);
1886 JOM(8, "usb_set_interface(.,%i,%i) returned %i\n", peasycap
->audio_interface
,
1887 peasycap
->audio_altsetting_on
, rc
);
1889 rc
= wakeup_device(peasycap
->pusb_device
);
1890 JOM(8, "wakeup_device() returned %i\n", rc
);
1892 peasycap
->audio_eof
= 0;
1893 peasycap
->audio_idle
= 0;
1895 peasycap
->timeval1
.tv_sec
= 0;
1896 peasycap
->timeval1
.tv_usec
= 0;
1898 submit_audio_urbs(peasycap
);
1900 JOM(4, "finished initialization\n");
1903 /*****************************************************************************/
1904 /*---------------------------------------------------------------------------*/
1906 * SUBMIT ALL AUDIO URBS.
1908 /*---------------------------------------------------------------------------*/
1910 submit_audio_urbs(struct easycap
*peasycap
)
1912 struct data_urb
*pdata_urb
;
1914 struct list_head
*plist_head
;
1915 int j
, isbad
, nospc
, m
, rc
;
1918 if (NULL
== peasycap
) {
1919 SAY("ERROR: peasycap is NULL\n");
1922 if ((struct list_head
*)NULL
== peasycap
->purb_audio_head
) {
1923 SAM("ERROR: peasycap->urb_audio_head uninitialized\n");
1926 if ((struct usb_device
*)NULL
== peasycap
->pusb_device
) {
1927 SAM("ERROR: peasycap->pusb_device is NULL\n");
1930 if (!peasycap
->audio_isoc_streaming
) {
1931 JOM(4, "initial submission of all audio urbs\n");
1932 rc
= usb_set_interface(peasycap
->pusb_device
,
1933 peasycap
->audio_interface
,
1934 peasycap
->audio_altsetting_on
);
1935 JOM(8, "usb_set_interface(.,%i,%i) returned %i\n",
1936 peasycap
->audio_interface
,
1937 peasycap
->audio_altsetting_on
, rc
);
1939 isbad
= 0; nospc
= 0; m
= 0;
1940 list_for_each(plist_head
, (peasycap
->purb_audio_head
)) {
1941 pdata_urb
= list_entry(plist_head
, struct data_urb
, list_head
);
1942 if (NULL
!= pdata_urb
) {
1943 purb
= pdata_urb
->purb
;
1945 isbuf
= pdata_urb
->isbuf
;
1948 purb
->dev
= peasycap
->pusb_device
;
1950 usb_rcvisocpipe(peasycap
->pusb_device
,
1951 peasycap
->audio_endpointnumber
);
1952 purb
->transfer_flags
= URB_ISO_ASAP
;
1953 purb
->transfer_buffer
=
1954 peasycap
->audio_isoc_buffer
[isbuf
].pgo
;
1955 purb
->transfer_buffer_length
=
1956 peasycap
->audio_isoc_buffer_size
;
1957 #if defined(EASYCAP_NEEDS_ALSA)
1958 purb
->complete
= easycap_alsa_complete
;
1960 purb
->complete
= easyoss_complete
;
1961 #endif /*EASYCAP_NEEDS_ALSA*/
1962 purb
->context
= peasycap
;
1963 purb
->start_frame
= 0;
1964 purb
->number_of_packets
=
1965 peasycap
->audio_isoc_framesperdesc
;
1966 for (j
= 0; j
< peasycap
->
1967 audio_isoc_framesperdesc
;
1969 purb
->iso_frame_desc
[j
].offset
= j
*
1971 audio_isoc_maxframesize
;
1972 purb
->iso_frame_desc
[j
].length
=
1974 audio_isoc_maxframesize
;
1977 rc
= usb_submit_urb(purb
, GFP_KERNEL
);
1980 SAM("ERROR: usb_submit_urb() failed"
1981 " for urb with rc:\n");
2028 SAM("unknown error: %i\n", rc
);
2043 SAM("-ENOSPC=usb_submit_urb() for %i urbs\n", nospc
);
2044 SAM("..... possibly inadequate USB bandwidth\n");
2045 peasycap
->audio_eof
= 1;
2048 JOM(4, "attempting cleanup instead of submitting\n");
2049 list_for_each(plist_head
, (peasycap
->purb_audio_head
)) {
2050 pdata_urb
= list_entry(plist_head
, struct data_urb
,
2052 if (NULL
!= pdata_urb
) {
2053 purb
= pdata_urb
->purb
;
2058 peasycap
->audio_isoc_streaming
= 0;
2060 peasycap
->audio_isoc_streaming
= m
;
2061 JOM(4, "submitted %i audio urbs\n", m
);
2064 JOM(4, "already streaming audio urbs\n");
2068 /*****************************************************************************/
2069 /*---------------------------------------------------------------------------*/
2071 * KILL ALL AUDIO URBS.
2073 /*---------------------------------------------------------------------------*/
2075 kill_audio_urbs(struct easycap
*peasycap
)
2078 struct list_head
*plist_head
;
2079 struct data_urb
*pdata_urb
;
2081 if (NULL
== peasycap
) {
2082 SAY("ERROR: peasycap is NULL\n");
2085 if (peasycap
->audio_isoc_streaming
) {
2086 if ((struct list_head
*)NULL
!= peasycap
->purb_audio_head
) {
2087 peasycap
->audio_isoc_streaming
= 0;
2088 JOM(4, "killing audio urbs\n");
2090 list_for_each(plist_head
, (peasycap
->purb_audio_head
)) {
2091 pdata_urb
= list_entry(plist_head
, struct data_urb
,
2093 if ((struct data_urb
*)NULL
!= pdata_urb
) {
2094 if ((struct urb
*)NULL
!= pdata_urb
->purb
) {
2095 usb_kill_urb(pdata_urb
->purb
);
2100 JOM(4, "%i audio urbs killed\n", m
);
2102 SAM("ERROR: peasycap->purb_audio_head is NULL\n");
2106 JOM(8, "%i=audio_isoc_streaming, no audio urbs killed\n",
2107 peasycap
->audio_isoc_streaming
);
2111 /*****************************************************************************/