Merge branch 'message-callback' into kbuild/kconfig
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / staging / easycap / easycap_sound.c
1 /******************************************************************************
2 * *
3 * easycap_sound.c *
4 * *
5 * Audio driver for EasyCAP USB2.0 Video Capture Device DC60 *
6 * *
7 * *
8 ******************************************************************************/
9 /*
10 *
11 * Copyright (C) 2010 R.M. Thomas <rmthomas@sciolus.org>
12 *
13 *
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.
18 *
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.
23 *
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
27 *
28 */
29 /*****************************************************************************/
30
31 #include "easycap.h"
32 #include "easycap_debug.h"
33 #include "easycap_sound.h"
34
35 /*****************************************************************************/
36 /*---------------------------------------------------------------------------*/
37 /*
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.
41 */
42 /*---------------------------------------------------------------------------*/
43 void
44 easysnd_complete(struct urb *purb)
45 {
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*/
57
58 JOT(16, "\n");
59
60 if (NULL == purb) {
61 SAY("ERROR: purb is NULL\n");
62 return;
63 }
64 peasycap = purb->context;
65 if (NULL == peasycap) {
66 SAY("ERROR: peasycap is NULL\n");
67 return;
68 }
69 much = 0;
70
71
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;
84 }
85 case -ENODEV: {
86 SAY("ENODEV\n"); break;
87 }
88 case -ENXIO: {
89 SAY("ENXIO\n"); break;
90 }
91 case -EINVAL: {
92 SAY("EINVAL\n"); break;
93 }
94 case -EAGAIN: {
95 SAY("EAGAIN\n"); break;
96 }
97 case -EFBIG: {
98 SAY("EFBIG\n"); break;
99 }
100 case -EPIPE: {
101 SAY("EPIPE\n"); break;
102 }
103 case -EMSGSIZE: {
104 SAY("EMSGSIZE\n"); break;
105 }
106 case -ENOSPC: {
107 SAY("ENOSPC\n"); break;
108 }
109 default: {
110 SAY("0x%08X\n", rc); break;
111 }
112 }
113 }
114 }
115 return;
116 }
117 /*---------------------------------------------------------------------------*/
118 if (purb->status) {
119 if (-ESHUTDOWN == purb->status) {
120 JOT(16, "immediate return because -ESHUTDOWN=purb->status\n");
121 return;
122 }
123 SAY("ERROR: non-zero urb status:\n");
124 switch (purb->status) {
125 case -EINPROGRESS: {
126 SAY("-EINPROGRESS\n"); break;
127 }
128 case -ENOSR: {
129 SAY("-ENOSR\n"); break;
130 }
131 case -EPIPE: {
132 SAY("-EPIPE\n"); break;
133 }
134 case -EOVERFLOW: {
135 SAY("-EOVERFLOW\n"); break;
136 }
137 case -EPROTO: {
138 SAY("-EPROTO\n"); break;
139 }
140 case -EILSEQ: {
141 SAY("-EILSEQ\n"); break;
142 }
143 case -ETIMEDOUT: {
144 SAY("-ETIMEDOUT\n"); break;
145 }
146 case -EMSGSIZE: {
147 SAY("-EMSGSIZE\n"); break;
148 }
149 case -EOPNOTSUPP: {
150 SAY("-EOPNOTSUPP\n"); break;
151 }
152 case -EPFNOSUPPORT: {
153 SAY("-EPFNOSUPPORT\n"); break;
154 }
155 case -EAFNOSUPPORT: {
156 SAY("-EAFNOSUPPORT\n"); break;
157 }
158 case -EADDRINUSE: {
159 SAY("-EADDRINUSE\n"); break;
160 }
161 case -EADDRNOTAVAIL: {
162 SAY("-EADDRNOTAVAIL\n"); break;
163 }
164 case -ENOBUFS: {
165 SAY("-ENOBUFS\n"); break;
166 }
167 case -EISCONN: {
168 SAY("-EISCONN\n"); break;
169 }
170 case -ENOTCONN: {
171 SAY("-ENOTCONN\n"); break;
172 }
173 case -ESHUTDOWN: {
174 SAY("-ESHUTDOWN\n"); break;
175 }
176 case -ENOENT: {
177 SAY("-ENOENT\n"); break;
178 }
179 case -ECONNRESET: {
180 SAY("-ECONNRESET\n"); break;
181 }
182 case -ENOSPC: {
183 SAY("ENOSPC\n"); break;
184 }
185 default: {
186 SAY("unknown error code 0x%08X\n", purb->status); break;
187 }
188 }
189 /*---------------------------------------------------------------------------*/
190 /*
191 * RESUBMIT THIS URB AFTER AN ERROR
192 *
193 * (THIS IS DUPLICATE CODE TO REDUCE INDENTATION OF THE NO-ERROR PATH)
194 */
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;
204 }
205 case -ENODEV: {
206 SAY("ENODEV\n"); break;
207 }
208 case -ENXIO: {
209 SAY("ENXIO\n"); break;
210 }
211 case -EINVAL: {
212 SAY("EINVAL\n"); break;
213 }
214 case -EAGAIN: {
215 SAY("EAGAIN\n"); break;
216 }
217 case -EFBIG: {
218 SAY("EFBIG\n"); break;
219 }
220 case -EPIPE: {
221 SAY("EPIPE\n"); break;
222 }
223 case -EMSGSIZE: {
224 SAY("EMSGSIZE\n"); break;
225 }
226 default: {
227 SAY("0x%08X\n", rc); break;
228 }
229 }
230 }
231 }
232 return;
233 }
234 /*---------------------------------------------------------------------------*/
235 /*
236 * PROCEED HERE WHEN NO ERROR
237 */
238 /*---------------------------------------------------------------------------*/
239 #if defined(UPSAMPLE)
240 oldaudio = peasycap->oldaudio;
241 #endif /*UPSAMPLE*/
242
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;
247 }
248 case -ENOENT: {
249 strcpy(&errbuf[0], "-ENOENT"); break;
250 }
251 case -EINPROGRESS: {
252 strcpy(&errbuf[0], "-EINPROGRESS"); break;
253 }
254 case -EPROTO: {
255 strcpy(&errbuf[0], "-EPROTO"); break;
256 }
257 case -EILSEQ: {
258 strcpy(&errbuf[0], "-EILSEQ"); break;
259 }
260 case -ETIME: {
261 strcpy(&errbuf[0], "-ETIME"); break;
262 }
263 case -ETIMEDOUT: {
264 strcpy(&errbuf[0], "-ETIMEDOUT"); break;
265 }
266 case -EPIPE: {
267 strcpy(&errbuf[0], "-EPIPE"); break;
268 }
269 case -ECOMM: {
270 strcpy(&errbuf[0], "-ECOMM"); break;
271 }
272 case -ENOSR: {
273 strcpy(&errbuf[0], "-ENOSR"); break;
274 }
275 case -EOVERFLOW: {
276 strcpy(&errbuf[0], "-EOVERFLOW"); break;
277 }
278 case -EREMOTEIO: {
279 strcpy(&errbuf[0], "-EREMOTEIO"); break;
280 }
281 case -ENODEV: {
282 strcpy(&errbuf[0], "-ENODEV"); break;
283 }
284 case -EXDEV: {
285 strcpy(&errbuf[0], "-EXDEV"); break;
286 }
287 case -EINVAL: {
288 strcpy(&errbuf[0], "-EINVAL"); break;
289 }
290 case -ECONNRESET: {
291 strcpy(&errbuf[0], "-ECONNRESET"); break;
292 }
293 case -ENOSPC: {
294 strcpy(&errbuf[0], "-ENOSPC"); break;
295 }
296 case -ESHUTDOWN: {
297 strcpy(&errbuf[0], "-ESHUTDOWN"); break;
298 }
299 default: {
300 strcpy(&errbuf[0], "UNKNOWN"); break;
301 }
302 }
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);
312 }
313 if (!purb->iso_frame_desc[i].status) {
314 more = purb->iso_frame_desc[i].actual_length;
315
316 #if defined(TESTTONE)
317 if (!more)
318 more = purb->iso_frame_desc[i].length;
319 #endif
320
321 if (!more)
322 mt++;
323 else {
324 if (mt) {
325 JOT(16, "%4i empty audio urb frames\n", mt);
326 mt = 0;
327 }
328
329 p1 = (__u8 *)(purb->transfer_buffer + \
330 purb->iso_frame_desc[i].offset);
331
332 leap = 0;
333 p1 += leap;
334 more -= leap;
335 /*---------------------------------------------------------------------------*/
336 /*
337 * COPY more BYTES FROM ISOC BUFFER TO AUDIO BUFFER,
338 * CONVERTING 8-BIT MONO TO 16-BIT SIGNED LITTLE-ENDIAN SAMPLES IF NECESSARY
339 */
340 /*---------------------------------------------------------------------------*/
341 while (more) {
342 if (0 > more) {
343 SAY("easysnd_complete: MISTAKE: " \
344 "more is negative\n");
345 return;
346 }
347 if (peasycap->audio_buffer_page_many <= \
348 peasycap->audio_fill) {
349 SAY("ERROR: bad " \
350 "peasycap->audio_fill\n");
351 return;
352 }
353
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;
360 }
361 if (PAGE_SIZE == (paudio_buffer->pto - \
362 paudio_buffer->pgo)) {
363
364 #if defined(TESTTONE)
365 easysnd_testtone(peasycap, \
366 peasycap->audio_fill);
367 #endif /*TESTTONE*/
368
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;
376
377 JOT(12, "bumped peasycap->" \
378 "audio_fill to %i\n", \
379 peasycap->audio_fill);
380
381 paudio_buffer = &peasycap->\
382 audio_buffer\
383 [peasycap->audio_fill];
384 paudio_buffer->pto = \
385 paudio_buffer->pgo;
386
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));
401 }
402 }
403
404 much = PAGE_SIZE - (int)(paudio_buffer->pto -\
405 paudio_buffer->pgo);
406
407 if (false == peasycap->microphone) {
408 if (much > more)
409 much = more;
410
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;
424
425 for (j = 0; j < (much/16); j++) {
426 newaudio = ((int) *p1) - 128;
427 newaudio = 128 * \
428 newaudio;
429
430 delta = (newaudio - oldaudio) \
431 / 4;
432 s16 = oldaudio + delta;
433
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;
443
444 s16 += delta;
445 }
446 p1++;
447 more--;
448 oldaudio = s16;
449 }
450 #else
451 if (much > (2 * more))
452 much = 2 * more;
453 p2 = (__u8 *)paudio_buffer->pto;
454
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) >> \
461 8;
462 p1++; p2 += 2;
463 more--;
464 }
465 #endif /*UPSAMPLE*/
466 }
467 (paudio_buffer->pto) += much;
468 }
469 }
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);
474 }
475
476 #if defined(UPSAMPLE)
477 peasycap->oldaudio = oldaudio;
478 #endif /*UPSAMPLE*/
479
480 }
481 /*---------------------------------------------------------------------------*/
482 /*
483 * RESUBMIT THIS URB AFTER NO ERROR
484 */
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;
494 }
495 case -ENODEV: {
496 SAY("ENODEV\n"); break;
497 }
498 case -ENXIO: {
499 SAY("ENXIO\n"); break;
500 }
501 case -EINVAL: {
502 SAY("EINVAL\n"); break;
503 }
504 case -EAGAIN: {
505 SAY("EAGAIN\n"); break;
506 }
507 case -EFBIG: {
508 SAY("EFBIG\n"); break;
509 }
510 case -EPIPE: {
511 SAY("EPIPE\n"); break;
512 }
513 case -EMSGSIZE: {
514 SAY("EMSGSIZE\n"); break;
515 }
516 case -ENOSPC: {
517 SAY("ENOSPC\n"); break;
518 }
519 default: {
520 SAY("0x%08X\n", rc); break;
521 }
522 }
523 }
524 }
525 return;
526 }
527 /*****************************************************************************/
528 /*---------------------------------------------------------------------------*/
529 /*
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.
534 */
535 /*---------------------------------------------------------------------------*/
536 int
537 easysnd_open(struct inode *inode, struct file *file)
538 {
539 struct usb_interface *pusb_interface;
540 struct easycap *peasycap;
541 int subminor, rc;
542
543 JOT(4, "begins.\n");
544
545 subminor = iminor(inode);
546
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;
552 }
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;
558 }
559
560 file->private_data = peasycap;
561
562 /*---------------------------------------------------------------------------*/
563 /*
564 * INITIALIZATION.
565 */
566 /*---------------------------------------------------------------------------*/
567 JOT(4, "starting initialization\n");
568
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);
575 }
576
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);
582
583 if ((struct usb_device *)NULL == peasycap->pusb_device) {
584 SAY("ERROR: peasycap->pusb_device has become NULL\n");
585 return -EFAULT;
586 }
587 rc = adjust_volume(peasycap, -8192);
588 if (0 != rc) {
589 SAY("ERROR: adjust_volume(default) returned %i\n", rc);
590 return -EFAULT;
591 }
592 /*---------------------------------------------------------------------------*/
593 if ((struct usb_device *)NULL == peasycap->pusb_device) {
594 SAY("ERROR: peasycap->pusb_device has become NULL\n");
595 return -EFAULT;
596 }
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);
601
602 if ((struct usb_device *)NULL == peasycap->pusb_device) {
603 SAY("ERROR: peasycap->pusb_device has become NULL\n");
604 return -EFAULT;
605 }
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);
611
612 if ((struct usb_device *)NULL == peasycap->pusb_device) {
613 SAY("ERROR: peasycap->pusb_device has become NULL\n");
614 return -EFAULT;
615 }
616 submit_audio_urbs(peasycap);
617 peasycap->audio_idle = 0;
618
619 peasycap->timeval1.tv_sec = 0;
620 peasycap->timeval1.tv_usec = 0;
621
622 JOT(4, "finished initialization\n");
623 return 0;
624 }
625 /*****************************************************************************/
626 int
627 easysnd_release(struct inode *inode, struct file *file)
628 {
629 struct easycap *peasycap;
630
631 JOT(4, "begins\n");
632
633 peasycap = file->private_data;
634 if (NULL == peasycap) {
635 SAY("ERROR: peasycap is NULL.\n");
636 return -EFAULT;
637 }
638 if (0 != kill_audio_urbs(peasycap)) {
639 SAY("ERROR: kill_audio_urbs() failed\n");
640 return -EFAULT;
641 }
642 JOT(4, "ending successfully\n");
643 return 0;
644 }
645 /*****************************************************************************/
646 ssize_t
647 easysnd_read(struct file *file, char __user *puserspacebuffer, \
648 size_t kount, loff_t *poff)
649 {
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;
660
661 /*---------------------------------------------------------------------------*/
662 /*
663 * DO A BLOCKING READ TO TRANSFER DATA TO USER SPACE.
664 *
665 ******************************************************************************
666 ***** N.B. IF THIS FUNCTION RETURNS 0, NOTHING IS SEEN IN USER SPACE. ******
667 ***** THIS CONDITION SIGNIFIES END-OF-FILE. ******
668 ******************************************************************************
669 */
670 /*---------------------------------------------------------------------------*/
671
672 JOT(8, "===== easysnd_read(): kount=%i, *poff=%i\n", (int)kount, (int)(*poff));
673
674 peasycap = (struct easycap *)(file->private_data);
675 if (NULL == peasycap) {
676 SAY("ERROR in easysnd_read(): peasycap is NULL\n");
677 return -EFAULT;
678 }
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;
684 }
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;
689 }
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;
700 }
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;
709 }
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;
716 }
717 if (peasycap->audio_idle) {
718 JOT(16, "returning 0 because %i=audio_idle\n", \
719 peasycap->audio_idle);
720 return 0;
721 }
722 if (!peasycap->audio_isoc_streaming) {
723 JOT(16, "returning 0 because audio urbs not streaming\n");
724 return 0;
725 }
726 }
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;
736 }
737 if (NULL == pdata_buffer->pto) {
738 SAY("ERROR: pdata_buffer->pto is NULL\n");
739 return -EFAULT;
740 }
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;
745 }
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);
752
753 if (fragment != (peasycap->audio_read / \
754 peasycap->audio_pages_per_fragment))
755 break;
756
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;
762 }
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;
767 }
768 if (NULL == pdata_buffer->pgo) {
769 SAY("ERROR: pdata_buffer->pgo is NULL\n");
770 return -EFAULT;
771 }
772 if (NULL == pdata_buffer->pto) {
773 SAY("ERROR: pdata_buffer->pto is NULL\n");
774 return -EFAULT;
775 }
776 kount1 = PAGE_SIZE - (pdata_buffer->pto - pdata_buffer->pgo);
777 }
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;
787
788 /*---------------------------------------------------------------------------*/
789 /*
790 * ACCUMULATE DYNAMIC-RANGE INFORMATION
791 */
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;
797 }
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;
803 }
804 *poff += (loff_t)more;
805 szret += (size_t)more;
806 pdata_buffer->pto += more;
807 puserspacebuffer += more;
808 kount -= (size_t)more;
809 }
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);
816 }
817 /*---------------------------------------------------------------------------*/
818 /*
819 * CALCULATE DYNAMIC RANGE FOR (VAPOURWARE) AUTOMATIC VOLUME CONTROL
820 */
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);
829
830 JOT(8, "%8lli=mean %8lli=meansquare after %lli samples, =>\n", \
831 sdr.quotient, above, peasycap->audio_sample);
832
833 sdr = signed_div(above, 32768);
834 JOT(8, "audio dynamic range is roughly %lli\n", sdr.quotient);
835 }
836 /*---------------------------------------------------------------------------*/
837 /*
838 * UPDATE THE AUDIO CLOCK
839 */
840 /*---------------------------------------------------------------------------*/
841 do_gettimeofday(&timeval);
842 if (!peasycap->timeval1.tv_sec) {
843 audio_bytes = 0;
844 timeval1 = timeval;
845
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);
857
858 if (below)
859 sdr = signed_div(above, below);
860 else
861 sdr.quotient = 192000;
862 }
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));
868
869 JOT(8, "returning %li\n", (long int)szret);
870 return szret;
871 }
872 /*****************************************************************************/
873 /*---------------------------------------------------------------------------*/
874 /*
875 * SUBMIT ALL AUDIO URBS.
876 */
877 /*---------------------------------------------------------------------------*/
878 int
879 submit_audio_urbs(struct easycap *peasycap)
880 {
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;
886
887 if ((struct list_head *)NULL == peasycap->purb_audio_head) {
888 SAY("ERROR: peasycap->urb_audio_head uninitialized\n");
889 return -EFAULT;
890 }
891 if ((struct usb_device *)NULL == peasycap->pusb_device) {
892 SAY("ERROR: peasycap->pusb_device is NULL\n");
893 return -EFAULT;
894 }
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);
903
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;
911
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;
936 }
937
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;
946 }
947 case -ENODEV: {
948 SAY("ENODEV\n"); break;
949 }
950 case -ENXIO: {
951 SAY("ENXIO\n"); break;
952 }
953 case -EINVAL: {
954 SAY("EINVAL\n"); break;
955 }
956 case -EAGAIN: {
957 SAY("EAGAIN\n"); break;
958 }
959 case -EFBIG: {
960 SAY("EFBIG\n"); break;
961 }
962 case -EPIPE: {
963 SAY("EPIPE\n"); break;
964 }
965 case -EMSGSIZE: {
966 SAY("EMSGSIZE\n"); break;
967 }
968 case -ENOSPC: {
969 SAY("ENOSPC\n"); break;
970 }
971 default: {
972 SAY("unknown error code %i\n",\
973 rc); break;
974 }
975 }
976 } else {
977 m++;
978 }
979 } else {
980 isbad++;
981 }
982 } else {
983 isbad++;
984 }
985 }
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);
995 }
996 }
997 peasycap->audio_isoc_streaming = 0;
998 } else {
999 peasycap->audio_isoc_streaming = 1;
1000 JOT(4, "submitted %i audio urbs\n", m);
1001 }
1002 } else
1003 JOT(4, "already streaming audio urbs\n");
1004
1005 return 0;
1006 }
1007 /*****************************************************************************/
1008 /*---------------------------------------------------------------------------*/
1009 /*
1010 * KILL ALL AUDIO URBS.
1011 */
1012 /*---------------------------------------------------------------------------*/
1013 int
1014 kill_audio_urbs(struct easycap *peasycap)
1015 {
1016 int m;
1017 struct list_head *plist_head;
1018 struct data_urb *pdata_urb;
1019
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++;
1032 }
1033 }
1034 }
1035 JOT(4, "%i audio urbs killed\n", m);
1036 } else {
1037 SAY("ERROR: peasycap->purb_audio_head is NULL\n");
1038 return -EFAULT;
1039 }
1040 } else {
1041 JOT(8, "%i=audio_isoc_streaming, no audio urbs killed\n", \
1042 peasycap->audio_isoc_streaming);
1043 }
1044 return 0;
1045 }
1046 /*****************************************************************************/