upload tizen1.0 source
[kernel/linux-2.6.36.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 /*****************************************************************************/