GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / linux / linux-2.6.36 / drivers / staging / easycap / easycap_sound.c
blob63562bda738eebc48cd29dac68fdc7751f117b9d
1 /******************************************************************************
2 * *
3 * easycap_sound.c *
4 * *
5 * Audio driver for EasyCAP USB2.0 Video Capture Device DC60 *
6 * *
7 * *
8 ******************************************************************************/
9 /*
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 /*****************************************************************************/
31 #include "easycap.h"
32 #include "easycap_debug.h"
33 #include "easycap_sound.h"
35 /*****************************************************************************/
36 /*---------------------------------------------------------------------------*/
38 * ON COMPLETION OF AN AUDIO URB ITS DATA IS COPIED TO THE AUDIO BUFFERS
39 * PROVIDED peasycap->audio_idle IS ZER0. REGARDLESS OF THIS BEING TRUE,
40 * IT IS RESUBMITTED PROVIDED peasycap->audio_isoc_streaming IS NOT ZERO.
42 /*---------------------------------------------------------------------------*/
43 void
44 easysnd_complete(struct urb *purb)
46 static int mt;
47 struct easycap *peasycap;
48 struct data_buffer *paudio_buffer;
49 char errbuf[16];
50 __u8 *p1, *p2;
51 __s16 s16;
52 int i, j, more, much, leap, rc;
53 #if defined(UPSAMPLE)
54 int k;
55 __s16 oldaudio, newaudio, delta;
56 #endif /*UPSAMPLE*/
58 JOT(16, "\n");
60 if (NULL == purb) {
61 SAY("ERROR: purb is NULL\n");
62 return;
64 peasycap = purb->context;
65 if (NULL == peasycap) {
66 SAY("ERROR: peasycap is NULL\n");
67 return;
69 much = 0;
72 if (peasycap->audio_idle) {
73 JOT(16, "%i=audio_idle %i=audio_isoc_streaming\n", \
74 peasycap->audio_idle, peasycap->audio_isoc_streaming);
75 if (peasycap->audio_isoc_streaming) {
76 rc = usb_submit_urb(purb, GFP_ATOMIC);
77 if (0 != rc) {
78 SAY("ERROR: while %i=audio_idle, " \
79 "usb_submit_urb() failed with rc:\n", \
80 peasycap->audio_idle);
81 switch (rc) {
82 case -ENOMEM: {
83 SAY("ENOMEM\n"); break;
85 case -ENODEV: {
86 SAY("ENODEV\n"); break;
88 case -ENXIO: {
89 SAY("ENXIO\n"); break;
91 case -EINVAL: {
92 SAY("EINVAL\n"); break;
94 case -EAGAIN: {
95 SAY("EAGAIN\n"); break;
97 case -EFBIG: {
98 SAY("EFBIG\n"); break;
100 case -EPIPE: {
101 SAY("EPIPE\n"); break;
103 case -EMSGSIZE: {
104 SAY("EMSGSIZE\n"); break;
106 case -ENOSPC: {
107 SAY("ENOSPC\n"); break;
109 default: {
110 SAY("0x%08X\n", rc); break;
115 return;
117 /*---------------------------------------------------------------------------*/
118 if (purb->status) {
119 if (-ESHUTDOWN == purb->status) {
120 JOT(16, "immediate return because -ESHUTDOWN=purb->status\n");
121 return;
123 SAY("ERROR: non-zero urb status:\n");
124 switch (purb->status) {
125 case -EINPROGRESS: {
126 SAY("-EINPROGRESS\n"); break;
128 case -ENOSR: {
129 SAY("-ENOSR\n"); break;
131 case -EPIPE: {
132 SAY("-EPIPE\n"); break;
134 case -EOVERFLOW: {
135 SAY("-EOVERFLOW\n"); break;
137 case -EPROTO: {
138 SAY("-EPROTO\n"); break;
140 case -EILSEQ: {
141 SAY("-EILSEQ\n"); break;
143 case -ETIMEDOUT: {
144 SAY("-ETIMEDOUT\n"); break;
146 case -EMSGSIZE: {
147 SAY("-EMSGSIZE\n"); break;
149 case -EOPNOTSUPP: {
150 SAY("-EOPNOTSUPP\n"); break;
152 case -EPFNOSUPPORT: {
153 SAY("-EPFNOSUPPORT\n"); break;
155 case -EAFNOSUPPORT: {
156 SAY("-EAFNOSUPPORT\n"); break;
158 case -EADDRINUSE: {
159 SAY("-EADDRINUSE\n"); break;
161 case -EADDRNOTAVAIL: {
162 SAY("-EADDRNOTAVAIL\n"); break;
164 case -ENOBUFS: {
165 SAY("-ENOBUFS\n"); break;
167 case -EISCONN: {
168 SAY("-EISCONN\n"); break;
170 case -ENOTCONN: {
171 SAY("-ENOTCONN\n"); break;
173 case -ESHUTDOWN: {
174 SAY("-ESHUTDOWN\n"); break;
176 case -ENOENT: {
177 SAY("-ENOENT\n"); break;
179 case -ECONNRESET: {
180 SAY("-ECONNRESET\n"); break;
182 case -ENOSPC: {
183 SAY("ENOSPC\n"); break;
185 default: {
186 SAY("unknown error code 0x%08X\n", purb->status); break;
189 /*---------------------------------------------------------------------------*/
191 * RESUBMIT THIS URB AFTER AN ERROR
193 * (THIS IS DUPLICATE CODE TO REDUCE INDENTATION OF THE NO-ERROR PATH)
195 /*---------------------------------------------------------------------------*/
196 if (peasycap->audio_isoc_streaming) {
197 rc = usb_submit_urb(purb, GFP_ATOMIC);
198 if (0 != rc) {
199 SAY("ERROR: while %i=audio_idle, usb_submit_urb() "
200 "failed with rc:\n", peasycap->audio_idle);
201 switch (rc) {
202 case -ENOMEM: {
203 SAY("ENOMEM\n"); break;
205 case -ENODEV: {
206 SAY("ENODEV\n"); break;
208 case -ENXIO: {
209 SAY("ENXIO\n"); break;
211 case -EINVAL: {
212 SAY("EINVAL\n"); break;
214 case -EAGAIN: {
215 SAY("EAGAIN\n"); break;
217 case -EFBIG: {
218 SAY("EFBIG\n"); break;
220 case -EPIPE: {
221 SAY("EPIPE\n"); break;
223 case -EMSGSIZE: {
224 SAY("EMSGSIZE\n"); break;
226 default: {
227 SAY("0x%08X\n", rc); break;
232 return;
234 /*---------------------------------------------------------------------------*/
236 * PROCEED HERE WHEN NO ERROR
238 /*---------------------------------------------------------------------------*/
239 #if defined(UPSAMPLE)
240 oldaudio = peasycap->oldaudio;
241 #endif /*UPSAMPLE*/
243 for (i = 0; i < purb->number_of_packets; i++) {
244 switch (purb->iso_frame_desc[i].status) {
245 case 0: {
246 strcpy(&errbuf[0], "OK"); break;
248 case -ENOENT: {
249 strcpy(&errbuf[0], "-ENOENT"); break;
251 case -EINPROGRESS: {
252 strcpy(&errbuf[0], "-EINPROGRESS"); break;
254 case -EPROTO: {
255 strcpy(&errbuf[0], "-EPROTO"); break;
257 case -EILSEQ: {
258 strcpy(&errbuf[0], "-EILSEQ"); break;
260 case -ETIME: {
261 strcpy(&errbuf[0], "-ETIME"); break;
263 case -ETIMEDOUT: {
264 strcpy(&errbuf[0], "-ETIMEDOUT"); break;
266 case -EPIPE: {
267 strcpy(&errbuf[0], "-EPIPE"); break;
269 case -ECOMM: {
270 strcpy(&errbuf[0], "-ECOMM"); break;
272 case -ENOSR: {
273 strcpy(&errbuf[0], "-ENOSR"); break;
275 case -EOVERFLOW: {
276 strcpy(&errbuf[0], "-EOVERFLOW"); break;
278 case -EREMOTEIO: {
279 strcpy(&errbuf[0], "-EREMOTEIO"); break;
281 case -ENODEV: {
282 strcpy(&errbuf[0], "-ENODEV"); break;
284 case -EXDEV: {
285 strcpy(&errbuf[0], "-EXDEV"); break;
287 case -EINVAL: {
288 strcpy(&errbuf[0], "-EINVAL"); break;
290 case -ECONNRESET: {
291 strcpy(&errbuf[0], "-ECONNRESET"); break;
293 case -ENOSPC: {
294 strcpy(&errbuf[0], "-ENOSPC"); break;
296 case -ESHUTDOWN: {
297 strcpy(&errbuf[0], "-ESHUTDOWN"); break;
299 default: {
300 strcpy(&errbuf[0], "UNKNOWN"); break;
303 if ((!purb->iso_frame_desc[i].status) && 0) {
304 JOT(16, "frame[%2i]: %i=status{=%16s} " \
305 "%5i=actual " \
306 "%5i=length " \
307 "%3i=offset\n", \
308 i, purb->iso_frame_desc[i].status, &errbuf[0],
309 purb->iso_frame_desc[i].actual_length,
310 purb->iso_frame_desc[i].length,
311 purb->iso_frame_desc[i].offset);
313 if (!purb->iso_frame_desc[i].status) {
314 more = purb->iso_frame_desc[i].actual_length;
316 #if defined(TESTTONE)
317 if (!more)
318 more = purb->iso_frame_desc[i].length;
319 #endif
321 if (!more)
322 mt++;
323 else {
324 if (mt) {
325 JOT(16, "%4i empty audio urb frames\n", mt);
326 mt = 0;
329 p1 = (__u8 *)(purb->transfer_buffer + \
330 purb->iso_frame_desc[i].offset);
332 leap = 0;
333 p1 += leap;
334 more -= leap;
335 /*---------------------------------------------------------------------------*/
337 * COPY more BYTES FROM ISOC BUFFER TO AUDIO BUFFER,
338 * CONVERTING 8-BIT MONO TO 16-BIT SIGNED LITTLE-ENDIAN SAMPLES IF NECESSARY
340 /*---------------------------------------------------------------------------*/
341 while (more) {
342 if (0 > more) {
343 SAY("easysnd_complete: MISTAKE: " \
344 "more is negative\n");
345 return;
347 if (peasycap->audio_buffer_page_many <= \
348 peasycap->audio_fill) {
349 SAY("ERROR: bad " \
350 "peasycap->audio_fill\n");
351 return;
354 paudio_buffer = &peasycap->audio_buffer\
355 [peasycap->audio_fill];
356 if (PAGE_SIZE < (paudio_buffer->pto - \
357 paudio_buffer->pgo)) {
358 SAY("ERROR: bad paudio_buffer->pto\n");
359 return;
361 if (PAGE_SIZE == (paudio_buffer->pto - \
362 paudio_buffer->pgo)) {
364 #if defined(TESTTONE)
365 easysnd_testtone(peasycap, \
366 peasycap->audio_fill);
367 #endif /*TESTTONE*/
369 paudio_buffer->pto = \
370 paudio_buffer->pgo;
371 (peasycap->audio_fill)++;
372 if (peasycap->\
373 audio_buffer_page_many <= \
374 peasycap->audio_fill)
375 peasycap->audio_fill = 0;
377 JOT(12, "bumped peasycap->" \
378 "audio_fill to %i\n", \
379 peasycap->audio_fill);
381 paudio_buffer = &peasycap->\
382 audio_buffer\
383 [peasycap->audio_fill];
384 paudio_buffer->pto = \
385 paudio_buffer->pgo;
387 if (!(peasycap->audio_fill % \
388 peasycap->\
389 audio_pages_per_fragment)) {
390 JOT(12, "wakeup call on wq_" \
391 "audio, %i=frag reading %i" \
392 "=fragment fill\n", \
393 (peasycap->audio_read / \
394 peasycap->\
395 audio_pages_per_fragment), \
396 (peasycap->audio_fill / \
397 peasycap->\
398 audio_pages_per_fragment));
399 wake_up_interruptible\
400 (&(peasycap->wq_audio));
404 much = PAGE_SIZE - (int)(paudio_buffer->pto -\
405 paudio_buffer->pgo);
407 if (false == peasycap->microphone) {
408 if (much > more)
409 much = more;
411 memcpy(paudio_buffer->pto, p1, much);
412 p1 += much;
413 more -= much;
414 } else {
415 #if defined(UPSAMPLE)
416 if (much % 16)
417 JOT(8, "MISTAKE? much" \
418 " is not divisible by 16\n");
419 if (much > (16 * \
420 more))
421 much = 16 * \
422 more;
423 p2 = (__u8 *)paudio_buffer->pto;
425 for (j = 0; j < (much/16); j++) {
426 newaudio = ((int) *p1) - 128;
427 newaudio = 128 * \
428 newaudio;
430 delta = (newaudio - oldaudio) \
431 / 4;
432 s16 = oldaudio + delta;
434 for (k = 0; k < 4; k++) {
435 *p2 = (0x00FF & s16);
436 *(p2 + 1) = (0xFF00 & \
437 s16) >> 8;
438 p2 += 2;
439 *p2 = (0x00FF & s16);
440 *(p2 + 1) = (0xFF00 & \
441 s16) >> 8;
442 p2 += 2;
444 s16 += delta;
446 p1++;
447 more--;
448 oldaudio = s16;
450 #else
451 if (much > (2 * more))
452 much = 2 * more;
453 p2 = (__u8 *)paudio_buffer->pto;
455 for (j = 0; j < (much / 2); j++) {
456 s16 = ((int) *p1) - 128;
457 s16 = 128 * \
458 s16;
459 *p2 = (0x00FF & s16);
460 *(p2 + 1) = (0xFF00 & s16) >> \
462 p1++; p2 += 2;
463 more--;
465 #endif /*UPSAMPLE*/
467 (paudio_buffer->pto) += much;
470 } else {
471 JOT(12, "discarding audio samples because " \
472 "%i=purb->iso_frame_desc[i].status\n", \
473 purb->iso_frame_desc[i].status);
476 #if defined(UPSAMPLE)
477 peasycap->oldaudio = oldaudio;
478 #endif /*UPSAMPLE*/
481 /*---------------------------------------------------------------------------*/
483 * RESUBMIT THIS URB AFTER NO ERROR
485 /*---------------------------------------------------------------------------*/
486 if (peasycap->audio_isoc_streaming) {
487 rc = usb_submit_urb(purb, GFP_ATOMIC);
488 if (0 != rc) {
489 SAY("ERROR: while %i=audio_idle, usb_submit_urb() failed " \
490 "with rc:\n", peasycap->audio_idle);
491 switch (rc) {
492 case -ENOMEM: {
493 SAY("ENOMEM\n"); break;
495 case -ENODEV: {
496 SAY("ENODEV\n"); break;
498 case -ENXIO: {
499 SAY("ENXIO\n"); break;
501 case -EINVAL: {
502 SAY("EINVAL\n"); break;
504 case -EAGAIN: {
505 SAY("EAGAIN\n"); break;
507 case -EFBIG: {
508 SAY("EFBIG\n"); break;
510 case -EPIPE: {
511 SAY("EPIPE\n"); break;
513 case -EMSGSIZE: {
514 SAY("EMSGSIZE\n"); break;
516 case -ENOSPC: {
517 SAY("ENOSPC\n"); break;
519 default: {
520 SAY("0x%08X\n", rc); break;
525 return;
527 /*****************************************************************************/
528 /*---------------------------------------------------------------------------*/
530 * THE AUDIO URBS ARE SUBMITTED AT THIS EARLY STAGE SO THAT IT IS POSSIBLE TO
531 * STREAM FROM /dev/easysnd1 WITH SIMPLE PROGRAMS SUCH AS cat WHICH DO NOT
532 * HAVE AN IOCTL INTERFACE. THE VIDEO URBS, BY CONTRAST, MUST BE SUBMITTED
533 * MUCH LATER: SEE COMMENTS IN FILE easycap_main.c.
535 /*---------------------------------------------------------------------------*/
537 easysnd_open(struct inode *inode, struct file *file)
539 struct usb_interface *pusb_interface;
540 struct easycap *peasycap;
541 int subminor, rc;
543 JOT(4, "begins.\n");
545 subminor = iminor(inode);
547 pusb_interface = usb_find_interface(&easycap_usb_driver, subminor);
548 if (NULL == pusb_interface) {
549 SAY("ERROR: pusb_interface is NULL\n");
550 SAY("ending unsuccessfully\n");
551 return -1;
553 peasycap = usb_get_intfdata(pusb_interface);
554 if (NULL == peasycap) {
555 SAY("ERROR: peasycap is NULL\n");
556 SAY("ending unsuccessfully\n");
557 return -1;
560 file->private_data = peasycap;
562 /*---------------------------------------------------------------------------*/
564 * INITIALIZATION.
566 /*---------------------------------------------------------------------------*/
567 JOT(4, "starting initialization\n");
569 if ((struct usb_device *)NULL == peasycap->pusb_device) {
570 SAY("ERROR: peasycap->pusb_device is NULL\n");
571 return -EFAULT;
572 } else {
573 JOT(16, "0x%08lX=peasycap->pusb_device\n", \
574 (long int)peasycap->pusb_device);
577 rc = audio_setup(peasycap);
578 if (0 <= rc)
579 JOT(8, "audio_setup() returned %i\n", rc);
580 else
581 JOT(8, "easysnd open(): ERROR: audio_setup() returned %i\n", rc);
583 if ((struct usb_device *)NULL == peasycap->pusb_device) {
584 SAY("ERROR: peasycap->pusb_device has become NULL\n");
585 return -EFAULT;
587 rc = adjust_volume(peasycap, -8192);
588 if (0 != rc) {
589 SAY("ERROR: adjust_volume(default) returned %i\n", rc);
590 return -EFAULT;
592 /*---------------------------------------------------------------------------*/
593 if ((struct usb_device *)NULL == peasycap->pusb_device) {
594 SAY("ERROR: peasycap->pusb_device has become NULL\n");
595 return -EFAULT;
597 rc = usb_set_interface(peasycap->pusb_device, peasycap->audio_interface, \
598 peasycap->audio_altsetting_on);
599 JOT(8, "usb_set_interface(.,%i,%i) returned %i\n", peasycap->audio_interface, \
600 peasycap->audio_altsetting_on, rc);
602 if ((struct usb_device *)NULL == peasycap->pusb_device) {
603 SAY("ERROR: peasycap->pusb_device has become NULL\n");
604 return -EFAULT;
606 rc = wakeup_device(peasycap->pusb_device);
607 if (0 == rc)
608 JOT(8, "wakeup_device() returned %i\n", rc);
609 else
610 JOT(8, "easysnd open(): ERROR: wakeup_device() returned %i\n", rc);
612 if ((struct usb_device *)NULL == peasycap->pusb_device) {
613 SAY("ERROR: peasycap->pusb_device has become NULL\n");
614 return -EFAULT;
616 submit_audio_urbs(peasycap);
617 peasycap->audio_idle = 0;
619 peasycap->timeval1.tv_sec = 0;
620 peasycap->timeval1.tv_usec = 0;
622 JOT(4, "finished initialization\n");
623 return 0;
625 /*****************************************************************************/
627 easysnd_release(struct inode *inode, struct file *file)
629 struct easycap *peasycap;
631 JOT(4, "begins\n");
633 peasycap = file->private_data;
634 if (NULL == peasycap) {
635 SAY("ERROR: peasycap is NULL.\n");
636 return -EFAULT;
638 if (0 != kill_audio_urbs(peasycap)) {
639 SAY("ERROR: kill_audio_urbs() failed\n");
640 return -EFAULT;
642 JOT(4, "ending successfully\n");
643 return 0;
645 /*****************************************************************************/
646 ssize_t
647 easysnd_read(struct file *file, char __user *puserspacebuffer, \
648 size_t kount, loff_t *poff)
650 struct timeval timeval;
651 static struct timeval timeval1;
652 static long long int audio_bytes, above, below, mean;
653 struct signed_div_result sdr;
654 unsigned char *p0;
655 long int kount1, more, rc, l0, lm;
656 int fragment;
657 struct easycap *peasycap;
658 struct data_buffer *pdata_buffer;
659 size_t szret;
661 /*---------------------------------------------------------------------------*/
663 * DO A BLOCKING READ TO TRANSFER DATA TO USER SPACE.
665 ******************************************************************************
666 ***** N.B. IF THIS FUNCTION RETURNS 0, NOTHING IS SEEN IN USER SPACE. ******
667 ***** THIS CONDITION SIGNIFIES END-OF-FILE. ******
668 ******************************************************************************
670 /*---------------------------------------------------------------------------*/
672 JOT(8, "===== easysnd_read(): kount=%i, *poff=%i\n", (int)kount, (int)(*poff));
674 peasycap = (struct easycap *)(file->private_data);
675 if (NULL == peasycap) {
676 SAY("ERROR in easysnd_read(): peasycap is NULL\n");
677 return -EFAULT;
679 /*---------------------------------------------------------------------------*/
680 if ((0 > peasycap->audio_read) || \
681 (peasycap->audio_buffer_page_many <= peasycap->audio_read)) {
682 SAY("ERROR: peasycap->audio_read out of range\n");
683 return -EFAULT;
685 pdata_buffer = &peasycap->audio_buffer[peasycap->audio_read];
686 if ((struct data_buffer *)NULL == pdata_buffer) {
687 SAY("ERROR: pdata_buffer is NULL\n");
688 return -EFAULT;
690 JOT(12, "before wait, %i=frag read %i=frag fill\n", \
691 (peasycap->audio_read / peasycap->audio_pages_per_fragment), \
692 (peasycap->audio_fill / peasycap->audio_pages_per_fragment));
693 fragment = (peasycap->audio_read / peasycap->audio_pages_per_fragment);
694 while ((fragment == (peasycap->audio_fill / \
695 peasycap->audio_pages_per_fragment)) || \
696 (0 == (PAGE_SIZE - (pdata_buffer->pto - pdata_buffer->pgo)))) {
697 if (file->f_flags & O_NONBLOCK) {
698 JOT(16, "returning -EAGAIN as instructed\n");
699 return -EAGAIN;
701 rc = wait_event_interruptible(peasycap->wq_audio, \
702 (peasycap->audio_idle || peasycap->audio_eof || \
703 ((fragment != (peasycap->audio_fill / \
704 peasycap->audio_pages_per_fragment)) && \
705 (0 < (PAGE_SIZE - (pdata_buffer->pto - pdata_buffer->pgo))))));
706 if (0 != rc) {
707 SAY("aborted by signal\n");
708 return -ERESTARTSYS;
710 if (peasycap->audio_eof) {
711 JOT(8, "returning 0 because %i=audio_eof\n", \
712 peasycap->audio_eof);
713 kill_audio_urbs(peasycap);
714 msleep(500);
715 return 0;
717 if (peasycap->audio_idle) {
718 JOT(16, "returning 0 because %i=audio_idle\n", \
719 peasycap->audio_idle);
720 return 0;
722 if (!peasycap->audio_isoc_streaming) {
723 JOT(16, "returning 0 because audio urbs not streaming\n");
724 return 0;
727 JOT(12, "after wait, %i=frag read %i=frag fill\n", \
728 (peasycap->audio_read / peasycap->audio_pages_per_fragment), \
729 (peasycap->audio_fill / peasycap->audio_pages_per_fragment));
730 szret = (size_t)0;
731 while (fragment == (peasycap->audio_read / \
732 peasycap->audio_pages_per_fragment)) {
733 if (NULL == pdata_buffer->pgo) {
734 SAY("ERROR: pdata_buffer->pgo is NULL\n");
735 return -EFAULT;
737 if (NULL == pdata_buffer->pto) {
738 SAY("ERROR: pdata_buffer->pto is NULL\n");
739 return -EFAULT;
741 kount1 = PAGE_SIZE - (pdata_buffer->pto - pdata_buffer->pgo);
742 if (0 > kount1) {
743 SAY("easysnd_read: MISTAKE: kount1 is negative\n");
744 return -ERESTARTSYS;
746 if (!kount1) {
747 (peasycap->audio_read)++;
748 if (peasycap->audio_buffer_page_many <= peasycap->audio_read)
749 peasycap->audio_read = 0;
750 JOT(12, "bumped peasycap->audio_read to %i\n", \
751 peasycap->audio_read);
753 if (fragment != (peasycap->audio_read / \
754 peasycap->audio_pages_per_fragment))
755 break;
757 if ((0 > peasycap->audio_read) || \
758 (peasycap->audio_buffer_page_many <= \
759 peasycap->audio_read)) {
760 SAY("ERROR: peasycap->audio_read out of range\n");
761 return -EFAULT;
763 pdata_buffer = &peasycap->audio_buffer[peasycap->audio_read];
764 if ((struct data_buffer *)NULL == pdata_buffer) {
765 SAY("ERROR: pdata_buffer is NULL\n");
766 return -EFAULT;
768 if (NULL == pdata_buffer->pgo) {
769 SAY("ERROR: pdata_buffer->pgo is NULL\n");
770 return -EFAULT;
772 if (NULL == pdata_buffer->pto) {
773 SAY("ERROR: pdata_buffer->pto is NULL\n");
774 return -EFAULT;
776 kount1 = PAGE_SIZE - (pdata_buffer->pto - pdata_buffer->pgo);
778 JOT(12, "ready to send %li bytes\n", (long int) kount1);
779 JOT(12, "still to send %li bytes\n", (long int) kount);
780 more = kount1;
781 if (more > kount)
782 more = kount;
783 JOT(12, "agreed to send %li bytes from page %i\n", \
784 more, peasycap->audio_read);
785 if (!more)
786 break;
788 /*---------------------------------------------------------------------------*/
790 * ACCUMULATE DYNAMIC-RANGE INFORMATION
792 /*---------------------------------------------------------------------------*/
793 p0 = (unsigned char *)pdata_buffer->pgo; l0 = 0; lm = more/2;
794 while (l0 < lm) {
795 SUMMER(p0, &peasycap->audio_sample, &peasycap->audio_niveau, \
796 &peasycap->audio_square); l0++; p0 += 2;
798 /*---------------------------------------------------------------------------*/
799 rc = copy_to_user(puserspacebuffer, pdata_buffer->pto, more);
800 if (0 != rc) {
801 SAY("ERROR: copy_to_user() returned %li\n", rc);
802 return -EFAULT;
804 *poff += (loff_t)more;
805 szret += (size_t)more;
806 pdata_buffer->pto += more;
807 puserspacebuffer += more;
808 kount -= (size_t)more;
810 JOT(12, "after read, %i=frag read %i=frag fill\n", \
811 (peasycap->audio_read / peasycap->audio_pages_per_fragment), \
812 (peasycap->audio_fill / peasycap->audio_pages_per_fragment));
813 if (kount < 0) {
814 SAY("MISTAKE: %li=kount %li=szret\n", \
815 (long int)kount, (long int)szret);
817 /*---------------------------------------------------------------------------*/
819 * CALCULATE DYNAMIC RANGE FOR (VAPOURWARE) AUTOMATIC VOLUME CONTROL
821 /*---------------------------------------------------------------------------*/
822 if (peasycap->audio_sample) {
823 below = peasycap->audio_sample;
824 above = peasycap->audio_square;
825 sdr = signed_div(above, below);
826 above = sdr.quotient;
827 mean = peasycap->audio_niveau;
828 sdr = signed_div(mean, peasycap->audio_sample);
830 JOT(8, "%8lli=mean %8lli=meansquare after %lli samples, =>\n", \
831 sdr.quotient, above, peasycap->audio_sample);
833 sdr = signed_div(above, 32768);
834 JOT(8, "audio dynamic range is roughly %lli\n", sdr.quotient);
836 /*---------------------------------------------------------------------------*/
838 * UPDATE THE AUDIO CLOCK
840 /*---------------------------------------------------------------------------*/
841 do_gettimeofday(&timeval);
842 if (!peasycap->timeval1.tv_sec) {
843 audio_bytes = 0;
844 timeval1 = timeval;
846 if (mutex_lock_interruptible(&(peasycap->mutex_timeval1)))
847 return -ERESTARTSYS;
848 peasycap->timeval1 = timeval1;
849 mutex_unlock(&(peasycap->mutex_timeval1));
850 sdr.quotient = 192000;
851 } else {
852 audio_bytes += (long long int) szret;
853 below = ((long long int)(1000000)) * \
854 ((long long int)(timeval.tv_sec - timeval1.tv_sec)) + \
855 (long long int)(timeval.tv_usec - timeval1.tv_usec);
856 above = 1000000 * ((long long int) audio_bytes);
858 if (below)
859 sdr = signed_div(above, below);
860 else
861 sdr.quotient = 192000;
863 JOT(8, "audio streaming at %lli bytes/second\n", sdr.quotient);
864 if (mutex_lock_interruptible(&(peasycap->mutex_timeval1)))
865 return -ERESTARTSYS;
866 peasycap->dnbydt = sdr.quotient;
867 mutex_unlock(&(peasycap->mutex_timeval1));
869 JOT(8, "returning %li\n", (long int)szret);
870 return szret;
872 /*****************************************************************************/
873 /*---------------------------------------------------------------------------*/
875 * SUBMIT ALL AUDIO URBS.
877 /*---------------------------------------------------------------------------*/
879 submit_audio_urbs(struct easycap *peasycap)
881 struct data_urb *pdata_urb;
882 struct urb *purb;
883 struct list_head *plist_head;
884 int j, isbad, m, rc;
885 int isbuf;
887 if ((struct list_head *)NULL == peasycap->purb_audio_head) {
888 SAY("ERROR: peasycap->urb_audio_head uninitialized\n");
889 return -EFAULT;
891 if ((struct usb_device *)NULL == peasycap->pusb_device) {
892 SAY("ERROR: peasycap->pusb_device is NULL\n");
893 return -EFAULT;
895 if (!peasycap->audio_isoc_streaming) {
896 JOT(4, "initial submission of all audio urbs\n");
897 rc = usb_set_interface(peasycap->pusb_device,
898 peasycap->audio_interface, \
899 peasycap->audio_altsetting_on);
900 JOT(8, "usb_set_interface(.,%i,%i) returned %i\n", \
901 peasycap->audio_interface, \
902 peasycap->audio_altsetting_on, rc);
904 isbad = 0; m = 0;
905 list_for_each(plist_head, (peasycap->purb_audio_head)) {
906 pdata_urb = list_entry(plist_head, struct data_urb, list_head);
907 if (NULL != pdata_urb) {
908 purb = pdata_urb->purb;
909 if (NULL != purb) {
910 isbuf = pdata_urb->isbuf;
912 purb->interval = 1;
913 purb->dev = peasycap->pusb_device;
914 purb->pipe = \
915 usb_rcvisocpipe(peasycap->pusb_device,\
916 peasycap->audio_endpointnumber);
917 purb->transfer_flags = URB_ISO_ASAP;
918 purb->transfer_buffer = \
919 peasycap->audio_isoc_buffer[isbuf].pgo;
920 purb->transfer_buffer_length = \
921 peasycap->audio_isoc_buffer_size;
922 purb->complete = easysnd_complete;
923 purb->context = peasycap;
924 purb->start_frame = 0;
925 purb->number_of_packets = \
926 peasycap->audio_isoc_framesperdesc;
927 for (j = 0; j < peasycap->\
928 audio_isoc_framesperdesc; \
929 j++) {
930 purb->iso_frame_desc[j].offset = j * \
931 peasycap->\
932 audio_isoc_maxframesize;
933 purb->iso_frame_desc[j].length = \
934 peasycap->\
935 audio_isoc_maxframesize;
938 rc = usb_submit_urb(purb, GFP_KERNEL);
939 if (0 != rc) {
940 isbad++;
941 SAY("ERROR: usb_submit_urb() failed" \
942 " for urb with rc:\n");
943 switch (rc) {
944 case -ENOMEM: {
945 SAY("ENOMEM\n"); break;
947 case -ENODEV: {
948 SAY("ENODEV\n"); break;
950 case -ENXIO: {
951 SAY("ENXIO\n"); break;
953 case -EINVAL: {
954 SAY("EINVAL\n"); break;
956 case -EAGAIN: {
957 SAY("EAGAIN\n"); break;
959 case -EFBIG: {
960 SAY("EFBIG\n"); break;
962 case -EPIPE: {
963 SAY("EPIPE\n"); break;
965 case -EMSGSIZE: {
966 SAY("EMSGSIZE\n"); break;
968 case -ENOSPC: {
969 SAY("ENOSPC\n"); break;
971 default: {
972 SAY("unknown error code %i\n",\
973 rc); break;
976 } else {
977 m++;
979 } else {
980 isbad++;
982 } else {
983 isbad++;
986 if (isbad) {
987 JOT(4, "attempting cleanup instead of submitting\n");
988 list_for_each(plist_head, (peasycap->purb_audio_head)) {
989 pdata_urb = list_entry(plist_head, struct data_urb, \
990 list_head);
991 if (NULL != pdata_urb) {
992 purb = pdata_urb->purb;
993 if (NULL != purb)
994 usb_kill_urb(purb);
997 peasycap->audio_isoc_streaming = 0;
998 } else {
999 peasycap->audio_isoc_streaming = 1;
1000 JOT(4, "submitted %i audio urbs\n", m);
1002 } else
1003 JOT(4, "already streaming audio urbs\n");
1005 return 0;
1007 /*****************************************************************************/
1008 /*---------------------------------------------------------------------------*/
1010 * KILL ALL AUDIO URBS.
1012 /*---------------------------------------------------------------------------*/
1014 kill_audio_urbs(struct easycap *peasycap)
1016 int m;
1017 struct list_head *plist_head;
1018 struct data_urb *pdata_urb;
1020 if (peasycap->audio_isoc_streaming) {
1021 if ((struct list_head *)NULL != peasycap->purb_audio_head) {
1022 peasycap->audio_isoc_streaming = 0;
1023 JOT(4, "killing audio urbs\n");
1024 m = 0;
1025 list_for_each(plist_head, (peasycap->purb_audio_head)) {
1026 pdata_urb = list_entry(plist_head, struct data_urb,
1027 list_head);
1028 if ((struct data_urb *)NULL != pdata_urb) {
1029 if ((struct urb *)NULL != pdata_urb->purb) {
1030 usb_kill_urb(pdata_urb->purb);
1031 m++;
1035 JOT(4, "%i audio urbs killed\n", m);
1036 } else {
1037 SAY("ERROR: peasycap->purb_audio_head is NULL\n");
1038 return -EFAULT;
1040 } else {
1041 JOT(8, "%i=audio_isoc_streaming, no audio urbs killed\n", \
1042 peasycap->audio_isoc_streaming);
1044 return 0;
1046 /*****************************************************************************/