1 /******************************************************************************
5 * Video driver for EasyCAP USB2.0 Video Capture Device DC60 *
8 ******************************************************************************/
11 * Copyright (C) 2010 R.M. Thomas <rmthomas@sciolus.org>
14 * This is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
19 * The software is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this software; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 /*****************************************************************************/
32 #include "easycap_standard.h"
35 module_param(easycap_debug, int, S_IRUGO | S_IWUSR);
37 /*---------------------------------------------------------------------------*/
39 * PARAMETERS APPLICABLE TO ENTIRE DRIVER, I.E. BOTH VIDEO AND AUDIO
41 /*---------------------------------------------------------------------------*/
42 struct usb_device_id easycap_usb_device_id_table[] = {
43 { USB_DEVICE(USB_EASYCAP_VENDOR_ID, USB_EASYCAP_PRODUCT_ID) },
46 MODULE_DEVICE_TABLE(usb, easycap_usb_device_id_table);
47 struct usb_driver easycap_usb_driver = {
49 .id_table = easycap_usb_device_id_table,
50 .probe = easycap_usb_probe,
51 .disconnect = easycap_usb_disconnect,
53 /*---------------------------------------------------------------------------*/
55 * PARAMETERS USED WHEN REGISTERING THE VIDEO INTERFACE
57 * NOTE: SOME KERNELS IGNORE usb_class_driver.minor_base, AS MENTIONED BY
58 * CORBET ET AL. "LINUX DEVICE DRIVERS", 3rd EDITION, PAGE 253.
59 * THIS IS THE CASE FOR OpenSUSE.
61 /*---------------------------------------------------------------------------*/
62 const struct file_operations easycap_fops = {
65 .release = easycap_release,
66 .unlocked_ioctl = easycap_ioctl,
71 struct vm_operations_struct easycap_vm_ops = {
72 .open = easycap_vma_open,
73 .close = easycap_vma_close,
74 .fault = easycap_vma_fault,
76 struct usb_class_driver easycap_class = {
77 .name = "usb/easycap%d",
78 .fops = &easycap_fops,
79 .minor_base = USB_SKEL_MINOR_BASE,
82 /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
83 #if defined(EASYCAP_IS_VIDEODEV_CLIENT)
84 #if defined(EASYCAP_NEEDS_V4L2_FOPS)
85 const struct v4l2_file_operations v4l2_fops = {
87 .open = easycap_open_noinode,
88 .release = easycap_release_noinode,
89 .unlocked_ioctl = easycap_ioctl,
93 #endif /*EASYCAP_NEEDS_V4L2_FOPS*/
94 int video_device_many /*=0*/;
95 struct video_device *pvideo_array[VIDEO_DEVICE_MANY], *pvideo_device;
96 #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
97 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
99 /*--------------------------------------------------------------------------*/
101 * PARAMETERS USED WHEN REGISTERING THE AUDIO INTERFACE
103 /*--------------------------------------------------------------------------*/
104 const struct file_operations easysnd_fops = {
105 .owner = THIS_MODULE,
106 .open = easysnd_open,
107 .release = easysnd_release,
108 .unlocked_ioctl = easysnd_ioctl,
109 .read = easysnd_read,
112 struct usb_class_driver easysnd_class = {
113 .name = "usb/easysnd%d",
114 .fops = &easysnd_fops,
115 .minor_base = USB_SKEL_MINOR_BASE,
117 /****************************************************************************/
118 /*--------------------------------------------------------------------------*/
120 * IT IS NOT APPROPRIATE FOR easycap_open() TO SUBMIT THE VIDEO URBS HERE,
121 * BECAUSE THERE WILL ALWAYS BE SUBSEQUENT NEGOTIATION OF TV STANDARD AND
122 * FORMAT BY IOCTL AND IT IS INADVISABLE TO HAVE THE URBS RUNNING WHILE
123 * REGISTERS OF THE SA7113H ARE BEING MANIPULATED.
125 * THE SUBMISSION OF VIDEO URBS IS THEREFORE DELAYED UNTIL THE IOCTL COMMAND
126 * STREAMON IS RECEIVED.
128 /*--------------------------------------------------------------------------*/
129 /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
130 #if defined(EASYCAP_IS_VIDEODEV_CLIENT)
132 easycap_open_noinode(struct file *file)
134 return easycap_open((struct inode *)NULL, file);
136 #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
137 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
139 easycap_open(struct inode *inode, struct file *file)
141 #if (!defined(EASYCAP_IS_VIDEODEV_CLIENT))
142 struct usb_interface *pusb_interface;
143 #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
144 struct usb_device *p;
145 struct easycap *peasycap;
149 SAY("==========OPEN=========\n");
151 peasycap = (struct easycap *)NULL;
152 #if (!defined(EASYCAP_IS_VIDEODEV_CLIENT))
153 if ((struct inode *)NULL == inode) {
154 SAY("ERROR: inode is NULL.\n");
157 pusb_interface = usb_find_interface(&easycap_usb_driver, iminor(inode));
158 if (!pusb_interface) {
159 SAY("ERROR: pusb_interface is NULL.\n");
162 peasycap = usb_get_intfdata(pusb_interface);
163 /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
165 for (i = 0; i < video_device_many; i++) {
166 pvideo_device = pvideo_array[i];
167 if ((struct video_device *)NULL != pvideo_device) {
168 peasycap = (struct easycap *)video_get_drvdata(pvideo_device);
172 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
173 #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
174 if ((struct easycap *)NULL == peasycap) {
175 SAY("MISTAKE: peasycap is NULL\n");
178 file->private_data = peasycap;
179 /*---------------------------------------------------------------------------*/
183 /*---------------------------------------------------------------------------*/
184 JOT(4, "starting initialization\n");
186 for (k = 0; k < FRAME_BUFFER_MANY; k++) {
187 for (m = 0; m < FRAME_BUFFER_SIZE/PAGE_SIZE; m++)
188 memset(peasycap->frame_buffer[k][m].pgo, 0, PAGE_SIZE);
190 p = peasycap->pusb_device;
191 if ((struct usb_device *)NULL == p) {
192 SAY("ERROR: peasycap->pusb_device is NULL\n");
195 JOT(16, "0x%08lX=peasycap->pusb_device\n", \
196 (long int)peasycap->pusb_device);
198 rc = wakeup_device(peasycap->pusb_device);
200 JOT(8, "wakeup_device() OK\n");
202 SAY("ERROR: wakeup_device() returned %i\n", rc);
205 rc = setup_stk(p); peasycap->input = 0;
207 JOT(8, "setup_stk() OK\n");
209 SAY("ERROR: setup_stk() returned %i\n", rc);
214 JOT(8, "setup_saa() OK\n");
216 SAY("ERROR: setup_saa() returned %i\n", rc);
221 JOT(8, "check_saa() OK\n");
223 SAY("check_saa() returned %i\n", rc);
225 SAY("ERROR: check_saa() returned %i\n", rc);
228 peasycap->standard_offset = -1;
229 /*---------------------------------------------------------------------------*/
230 #if defined(PREFER_NTSC)
232 rc = adjust_standard(peasycap, V4L2_STD_NTSC_M);
234 JOT(8, "adjust_standard(.,NTSC_M) OK\n");
236 SAY("ERROR: adjust_standard(.,NTSC_M) returned %i\n", rc);
239 rc = adjust_format(peasycap, 640, 480, V4L2_PIX_FMT_UYVY, V4L2_FIELD_NONE, \
242 JOT(8, "adjust_format(.,640,480,UYVY) OK\n");
244 SAY("ERROR: adjust_format(.,640,480,UYVY) returned %i\n", rc);
250 rc = adjust_standard(peasycap, \
251 (V4L2_STD_PAL_B | V4L2_STD_PAL_G | V4L2_STD_PAL_H | \
252 V4L2_STD_PAL_I | V4L2_STD_PAL_N));
254 JOT(8, "adjust_standard(.,PAL_BGHIN) OK\n");
256 SAY("ERROR: adjust_standard(.,PAL_BGHIN) returned %i\n", rc);
259 rc = adjust_format(peasycap, 640, 480, V4L2_PIX_FMT_UYVY, V4L2_FIELD_NONE, \
262 JOT(8, "adjust_format(.,640,480,uyvy,false) OK\n");
264 SAY("ERROR: adjust_format(.,640,480,uyvy,false) returned %i\n", rc);
268 #endif /* !PREFER_NTSC*/
269 /*---------------------------------------------------------------------------*/
270 rc = adjust_brightness(peasycap, -8192);
272 SAY("ERROR: adjust_brightness(default) returned %i\n", rc);
275 rc = adjust_contrast(peasycap, -8192);
277 SAY("ERROR: adjust_contrast(default) returned %i\n", rc);
280 rc = adjust_saturation(peasycap, -8192);
282 SAY("ERROR: adjust_saturation(default) returned %i\n", rc);
285 rc = adjust_hue(peasycap, -8192);
287 SAY("ERROR: adjust_hue(default) returned %i\n", rc);
290 /*---------------------------------------------------------------------------*/
291 rc = usb_set_interface(peasycap->pusb_device, peasycap->video_interface, \
292 peasycap->video_altsetting_on);
294 JOT(8, "usb_set_interface(.,%i,%i) OK\n", peasycap->video_interface, \
295 peasycap->video_altsetting_on);
297 SAY("ERROR: usb_set_interface() returned %i\n", rc);
302 JOT(8, "start_100() OK\n");
304 SAY("ERROR: start_100() returned %i\n", rc);
307 peasycap->video_isoc_sequence = VIDEO_ISOC_BUFFER_MANY - 1;
308 peasycap->video_idle = 0;
309 peasycap->video_junk = 0;
310 for (i = 0; i < 180; i++)
311 peasycap->merit[i] = 0;
312 peasycap->video_eof = 0;
313 peasycap->audio_eof = 0;
315 do_gettimeofday(&peasycap->timeval7);
319 JOT(4, "finished initialization\n");
322 /*****************************************************************************/
324 submit_video_urbs(struct easycap *peasycap)
326 struct data_urb *pdata_urb;
328 struct list_head *plist_head;
332 if ((struct list_head *)NULL == peasycap->purb_video_head) {
333 SAY("ERROR: peasycap->urb_video_head uninitialized\n");
336 if ((struct usb_device *)NULL == peasycap->pusb_device) {
337 SAY("ERROR: peasycap->pusb_device is NULL\n");
340 if (!peasycap->video_isoc_streaming) {
349 JOT(4, "submission of all video urbs\n");
350 if (0 != ready_saa(peasycap->pusb_device)) {
351 SAY("ERROR: not ready to capture after waiting " \
353 SAY("..... continuing anyway\n");
356 list_for_each(plist_head, (peasycap->purb_video_head)) {
357 pdata_urb = list_entry(plist_head, struct data_urb, list_head);
358 if (NULL != pdata_urb) {
359 purb = pdata_urb->purb;
361 isbuf = pdata_urb->isbuf;
363 purb->dev = peasycap->pusb_device;
365 usb_rcvisocpipe(peasycap->pusb_device,\
366 peasycap->video_endpointnumber);
367 purb->transfer_flags = URB_ISO_ASAP;
368 purb->transfer_buffer = \
369 peasycap->video_isoc_buffer[isbuf].pgo;
370 purb->transfer_buffer_length = \
371 peasycap->video_isoc_buffer_size;
372 purb->complete = easycap_complete;
373 purb->context = peasycap;
374 purb->start_frame = 0;
375 purb->number_of_packets = \
376 peasycap->video_isoc_framesperdesc;
378 for (j = 0; j < peasycap->\
379 video_isoc_framesperdesc; j++) {
380 purb->iso_frame_desc[j].\
383 video_isoc_maxframesize;
384 purb->iso_frame_desc[j].\
386 video_isoc_maxframesize;
389 rc = usb_submit_urb(purb, GFP_KERNEL);
392 SAY("ERROR: usb_submit_urb() failed " \
393 "for urb with rc:\n");
428 SAY("unknown error code %i\n",\
444 JOT(4, "attempting cleanup instead of submitting\n");
445 list_for_each(plist_head, (peasycap->purb_video_head)) {
446 pdata_urb = list_entry(plist_head, struct data_urb, \
448 if (NULL != pdata_urb) {
449 purb = pdata_urb->purb;
454 peasycap->video_isoc_streaming = 0;
456 peasycap->video_isoc_streaming = 1;
457 JOT(4, "submitted %i video urbs\n", m);
466 JOT(4, "already streaming video urbs\n");
470 /*****************************************************************************/
472 kill_video_urbs(struct easycap *peasycap)
475 struct list_head *plist_head;
476 struct data_urb *pdata_urb;
478 if ((struct easycap *)NULL == peasycap) {
479 SAY("ERROR: peasycap is NULL\n");
482 if (peasycap->video_isoc_streaming) {
486 if ((struct list_head *)NULL != peasycap->purb_video_head) {
487 peasycap->video_isoc_streaming = 0;
488 JOT(4, "killing video urbs\n");
490 list_for_each(plist_head, (peasycap->purb_video_head)) {
491 pdata_urb = list_entry(plist_head, struct data_urb, \
493 if ((struct data_urb *)NULL != pdata_urb) {
494 if ((struct urb *)NULL != pdata_urb->purb) {
495 usb_kill_urb(pdata_urb->purb);
500 JOT(4, "%i video urbs killed\n", m);
502 SAY("ERROR: peasycap->purb_video_head is NULL\n");
506 JOT(8, "%i=video_isoc_streaming, no video urbs killed\n", \
507 peasycap->video_isoc_streaming);
511 /****************************************************************************/
512 /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
513 #if defined(EASYCAP_IS_VIDEODEV_CLIENT)
515 easycap_release_noinode(struct file *file)
517 return easycap_release((struct inode *)NULL, file);
519 #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
520 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
521 /*--------------------------------------------------------------------------*/
523 easycap_release(struct inode *inode, struct file *file)
525 #if (!defined(EASYCAP_IS_VIDEODEV_CLIENT))
526 struct easycap *peasycap;
530 peasycap = file->private_data;
531 if (NULL == peasycap) {
532 SAY("ERROR: peasycap is NULL.\n");
533 SAY("ending unsuccessfully\n");
536 if (0 != kill_video_urbs(peasycap)) {
537 SAY("ERROR: kill_video_urbs() failed\n");
540 JOT(4, "ending successfully\n");
541 /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
544 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
545 #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
549 /****************************************************************************/
550 /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
551 #if defined(EASYCAP_IS_VIDEODEV_CLIENT)
553 videodev_release(struct video_device *pvd)
555 struct easycap *peasycap;
561 for (i = 0; i < video_device_many; i++) {
562 pvideo_device = pvideo_array[i];
563 if ((struct video_device *)NULL != pvideo_device) {
564 if (pvd->minor == pvideo_device->minor) {
565 peasycap = (struct easycap *)\
566 video_get_drvdata(pvideo_device);
567 if ((struct easycap *)NULL == peasycap) {
568 SAY("ERROR: peasycap is NULL\n");
569 SAY("ending unsuccessfully\n");
572 if (0 != kill_video_urbs(peasycap)) {
573 SAY("ERROR: kill_video_urbs() failed\n");
576 JOT(4, "freeing video_device structure: " \
577 "/dev/video%i\n", i);
578 kfree((void *)pvideo_device);
579 for (j = i; j < (VIDEO_DEVICE_MANY - 1); j++)
580 pvideo_array[j] = pvideo_array[j + 1];
581 video_device_many--; k++;
587 SAY("ERROR: lost video_device structure for %i=minor\n", pvd->minor);
588 SAY("cannot free: may cause memory leak\n");
589 SAY("ending unsuccessfully\n");
593 JOT(4, "ending successfully\n");
596 #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
597 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
598 /****************************************************************************/
599 /*--------------------------------------------------------------------------*/
601 * THIS FUNCTION IS CALLED FROM WITHIN easycap_usb_disconnect().
602 * BY THIS STAGE THE DEVICE HAS ALREADY BEEN PHYSICALLY UNPLUGGED.
603 * peasycap->pusb_device IS NO LONGER VALID AND SHOULD HAVE BEEN SET TO NULL.
605 /*---------------------------------------------------------------------------*/
607 easycap_delete(struct kref *pkref)
610 int allocation_video_urb, allocation_video_page, allocation_video_struct;
611 int allocation_audio_urb, allocation_audio_page, allocation_audio_struct;
612 int registered_video, registered_audio;
613 struct easycap *peasycap;
614 struct data_urb *pdata_urb;
615 struct list_head *plist_head, *plist_next;
619 peasycap = container_of(pkref, struct easycap, kref);
620 if ((struct easycap *)NULL == peasycap) {
621 SAY("ERROR: peasycap is NULL: cannot perform deletions\n");
624 /*---------------------------------------------------------------------------*/
628 /*---------------------------------------------------------------------------*/
629 if ((struct list_head *)NULL != peasycap->purb_video_head) {
630 JOT(4, "freeing video urbs\n");
632 list_for_each(plist_head, (peasycap->purb_video_head)) {
633 pdata_urb = list_entry(plist_head, struct data_urb, list_head);
634 if (NULL == pdata_urb)
635 JOT(4, "ERROR: pdata_urb is NULL\n");
637 if ((struct urb *)NULL != pdata_urb->purb) {
638 usb_free_urb(pdata_urb->purb);
639 pdata_urb->purb = (struct urb *)NULL;
640 peasycap->allocation_video_urb -= 1;
646 JOT(4, "%i video urbs freed\n", m);
647 /*---------------------------------------------------------------------------*/
648 JOT(4, "freeing video data_urb structures.\n");
650 list_for_each_safe(plist_head, plist_next, peasycap->purb_video_head) {
651 pdata_urb = list_entry(plist_head, struct data_urb, list_head);
652 if ((struct data_urb *)NULL != pdata_urb) {
653 kfree(pdata_urb); pdata_urb = (struct data_urb *)NULL;
654 peasycap->allocation_video_struct -= \
655 sizeof(struct data_urb);
659 JOT(4, "%i video data_urb structures freed\n", m);
660 JOT(4, "setting peasycap->purb_video_head=NULL\n");
661 peasycap->purb_video_head = (struct list_head *)NULL;
663 JOT(4, "peasycap->purb_video_head is NULL\n");
665 /*---------------------------------------------------------------------------*/
666 JOT(4, "freeing video isoc buffers.\n");
668 for (k = 0; k < VIDEO_ISOC_BUFFER_MANY; k++) {
669 if ((void *)NULL != peasycap->video_isoc_buffer[k].pgo) {
670 free_pages((unsigned long)\
671 (peasycap->video_isoc_buffer[k].pgo), \
673 peasycap->video_isoc_buffer[k].pgo = (void *)NULL;
674 peasycap->allocation_video_page -= \
675 ((unsigned int)(0x01 << VIDEO_ISOC_ORDER));
679 JOT(4, "isoc video buffers freed: %i pages\n", m * (0x01 << VIDEO_ISOC_ORDER));
680 /*---------------------------------------------------------------------------*/
681 JOT(4, "freeing video field buffers.\n");
683 for (k = 0; k < FIELD_BUFFER_MANY; k++) {
684 for (m = 0; m < FIELD_BUFFER_SIZE/PAGE_SIZE; m++) {
685 if ((void *)NULL != peasycap->field_buffer[k][m].pgo) {
686 free_page((unsigned long)\
687 (peasycap->field_buffer[k][m].pgo));
688 peasycap->field_buffer[k][m].pgo = (void *)NULL;
689 peasycap->allocation_video_page -= 1;
694 JOT(4, "video field buffers freed: %i pages\n", lost);
695 /*---------------------------------------------------------------------------*/
696 JOT(4, "freeing video frame buffers.\n");
698 for (k = 0; k < FRAME_BUFFER_MANY; k++) {
699 for (m = 0; m < FRAME_BUFFER_SIZE/PAGE_SIZE; m++) {
700 if ((void *)NULL != peasycap->frame_buffer[k][m].pgo) {
701 free_page((unsigned long)\
702 (peasycap->frame_buffer[k][m].pgo));
703 peasycap->frame_buffer[k][m].pgo = (void *)NULL;
704 peasycap->allocation_video_page -= 1;
709 JOT(4, "video frame buffers freed: %i pages\n", lost);
710 /*---------------------------------------------------------------------------*/
714 /*---------------------------------------------------------------------------*/
715 if ((struct list_head *)NULL != peasycap->purb_audio_head) {
716 JOT(4, "freeing audio urbs\n");
718 list_for_each(plist_head, (peasycap->purb_audio_head)) {
719 pdata_urb = list_entry(plist_head, struct data_urb, list_head);
720 if (NULL == pdata_urb)
721 JOT(4, "ERROR: pdata_urb is NULL\n");
723 if ((struct urb *)NULL != pdata_urb->purb) {
724 usb_free_urb(pdata_urb->purb);
725 pdata_urb->purb = (struct urb *)NULL;
726 peasycap->allocation_audio_urb -= 1;
731 JOT(4, "%i audio urbs freed\n", m);
732 /*---------------------------------------------------------------------------*/
733 JOT(4, "freeing audio data_urb structures.\n");
735 list_for_each_safe(plist_head, plist_next, peasycap->purb_audio_head) {
736 pdata_urb = list_entry(plist_head, struct data_urb, list_head);
737 if ((struct data_urb *)NULL != pdata_urb) {
738 kfree(pdata_urb); pdata_urb = (struct data_urb *)NULL;
739 peasycap->allocation_audio_struct -= \
740 sizeof(struct data_urb);
744 JOT(4, "%i audio data_urb structures freed\n", m);
745 JOT(4, "setting peasycap->purb_audio_head=NULL\n");
746 peasycap->purb_audio_head = (struct list_head *)NULL;
748 JOT(4, "peasycap->purb_audio_head is NULL\n");
750 /*---------------------------------------------------------------------------*/
751 JOT(4, "freeing audio isoc buffers.\n");
753 for (k = 0; k < AUDIO_ISOC_BUFFER_MANY; k++) {
754 if ((void *)NULL != peasycap->audio_isoc_buffer[k].pgo) {
755 free_pages((unsigned long)\
756 (peasycap->audio_isoc_buffer[k].pgo), \
758 peasycap->audio_isoc_buffer[k].pgo = (void *)NULL;
759 peasycap->allocation_audio_page -= \
760 ((unsigned int)(0x01 << AUDIO_ISOC_ORDER));
764 JOT(4, "easysnd_delete(): isoc audio buffers freed: %i pages\n", \
765 m * (0x01 << AUDIO_ISOC_ORDER));
766 /*---------------------------------------------------------------------------*/
767 JOT(4, "freeing audio buffers.\n");
769 for (k = 0; k < peasycap->audio_buffer_page_many; k++) {
770 if ((void *)NULL != peasycap->audio_buffer[k].pgo) {
771 free_page((unsigned long)(peasycap->audio_buffer[k].pgo));
772 peasycap->audio_buffer[k].pgo = (void *)NULL;
773 peasycap->allocation_audio_page -= 1;
777 JOT(4, "easysnd_delete(): audio buffers freed: %i pages\n", lost);
778 /*---------------------------------------------------------------------------*/
779 JOT(4, "freeing easycap structure.\n");
780 allocation_video_urb = peasycap->allocation_video_urb;
781 allocation_video_page = peasycap->allocation_video_page;
782 allocation_video_struct = peasycap->allocation_video_struct;
783 registered_video = peasycap->registered_video;
784 allocation_audio_urb = peasycap->allocation_audio_urb;
785 allocation_audio_page = peasycap->allocation_audio_page;
786 allocation_audio_struct = peasycap->allocation_audio_struct;
787 registered_audio = peasycap->registered_audio;
789 if ((struct easycap *)NULL != peasycap) {
790 kfree(peasycap); peasycap = (struct easycap *)NULL;
791 allocation_video_struct -= sizeof(struct easycap);
794 JOT(4, "%i easycap structure freed\n", m);
795 /*---------------------------------------------------------------------------*/
797 SAY("%8i= video urbs after all deletions\n", allocation_video_urb);
798 SAY("%8i= video pages after all deletions\n", allocation_video_page);
799 SAY("%8i= video structs after all deletions\n", allocation_video_struct);
800 SAY("%8i= video devices after all deletions\n", registered_video);
801 SAY("%8i= audio urbs after all deletions\n", allocation_audio_urb);
802 SAY("%8i= audio pages after all deletions\n", allocation_audio_page);
803 SAY("%8i= audio structs after all deletions\n", allocation_audio_struct);
804 SAY("%8i= audio devices after all deletions\n", registered_audio);
809 /*****************************************************************************/
810 unsigned int easycap_poll(struct file *file, poll_table *wait)
812 struct easycap *peasycap;
816 if (NULL == ((poll_table *)wait))
817 JOT(8, "WARNING: poll table pointer is NULL ... continuing\n");
818 if (NULL == ((struct file *)file)) {
819 SAY("ERROR: file pointer is NULL\n");
822 peasycap = file->private_data;
823 if (NULL == peasycap) {
824 SAY("ERROR: peasycap is NULL\n");
827 peasycap->polled = 1;
829 if (0 == easycap_dqbuf(peasycap, 0))
830 return POLLIN | POLLRDNORM;
835 /*****************************************************************************/
836 /*---------------------------------------------------------------------------*/
838 * IF mode IS NONZERO THIS ROUTINE RETURNS -EAGAIN RATHER THAN BLOCKING.
840 /*---------------------------------------------------------------------------*/
842 easycap_dqbuf(struct easycap *peasycap, int mode)
848 if (NULL == peasycap) {
849 SAY("ERROR: peasycap is NULL\n");
852 /*---------------------------------------------------------------------------*/
856 /*---------------------------------------------------------------------------*/
858 if (mutex_lock_interruptible(&(peasycap->mutex_mmap_video[0])))
860 while ((peasycap->field_read == peasycap->field_fill) || \
861 (0 != (0xFF00 & peasycap->field_buffer\
862 [peasycap->field_read][0].kount)) || \
863 (0 != (0x00FF & peasycap->field_buffer\
864 [peasycap->field_read][0].kount))) {
865 mutex_unlock(&(peasycap->mutex_mmap_video[0]));
870 JOT(8, "first wait on wq_video, " \
871 "%i=field_read %i=field_fill\n", \
872 peasycap->field_read, peasycap->field_fill);
875 if (0 != (wait_event_interruptible(peasycap->wq_video, \
876 (peasycap->video_idle || peasycap->video_eof || \
877 ((peasycap->field_read != peasycap->field_fill) && \
878 (0 == (0xFF00 & peasycap->field_buffer\
879 [peasycap->field_read][0].kount)) && \
880 (0 == (0x00FF & peasycap->field_buffer\
881 [peasycap->field_read][0].kount))))))){
882 SAY("aborted by signal\n");
885 if (peasycap->video_idle) {
886 JOT(8, "%i=peasycap->video_idle\n", peasycap->video_idle);
889 if (peasycap->video_eof) {
890 JOT(8, "%i=peasycap->video_eof\n", peasycap->video_eof);
892 kill_video_urbs(peasycap);
896 if (mutex_lock_interruptible(&(peasycap->mutex_mmap_video[0])))
899 mutex_unlock(&(peasycap->mutex_mmap_video[0]));
900 JOT(8, "first awakening on wq_video after %i waits\n", miss);
902 rc = field2frame(peasycap);
904 SAY("ERROR: field2frame() returned %i\n", rc);
906 if (true == peasycap->offerfields) {
907 peasycap->frame_read = peasycap->frame_fill;
908 (peasycap->frame_fill)++;
909 if (peasycap->frame_buffer_many <= peasycap->frame_fill)
910 peasycap->frame_fill = 0;
912 if (0x01 & easycap_standard[peasycap->standard_offset].mask) {
913 peasycap->frame_buffer[peasycap->frame_read][0].kount = \
916 peasycap->frame_buffer[peasycap->frame_read][0].kount = \
919 JOT(8, "setting: %i=peasycap->frame_read\n", peasycap->frame_read);
920 JOT(8, "bumped to: %i=peasycap->frame_fill\n", peasycap->frame_fill);
922 /*---------------------------------------------------------------------------*/
926 /*---------------------------------------------------------------------------*/
928 if (mutex_lock_interruptible(&(peasycap->mutex_mmap_video[0])))
930 while ((peasycap->field_read == peasycap->field_fill) || \
931 (0 != (0xFF00 & peasycap->field_buffer\
932 [peasycap->field_read][0].kount)) || \
933 (0 == (0x00FF & peasycap->field_buffer\
934 [peasycap->field_read][0].kount))) {
935 mutex_unlock(&(peasycap->mutex_mmap_video[0]));
940 JOT(8, "second wait on wq_video, " \
941 "%i=field_read %i=field_fill\n", \
942 peasycap->field_read, peasycap->field_fill);
944 if (0 != (wait_event_interruptible(peasycap->wq_video, \
945 (peasycap->video_idle || peasycap->video_eof || \
946 ((peasycap->field_read != peasycap->field_fill) && \
947 (0 == (0xFF00 & peasycap->field_buffer\
948 [peasycap->field_read][0].kount)) && \
949 (0 != (0x00FF & peasycap->field_buffer\
950 [peasycap->field_read][0].kount))))))){
951 SAY("aborted by signal\n");
954 if (peasycap->video_idle) {
955 JOT(8, "%i=peasycap->video_idle\n", peasycap->video_idle);
958 if (peasycap->video_eof) {
959 JOT(8, "%i=peasycap->video_eof\n", peasycap->video_eof);
961 kill_video_urbs(peasycap);
965 if (mutex_lock_interruptible(&(peasycap->mutex_mmap_video[0])))
968 mutex_unlock(&(peasycap->mutex_mmap_video[0]));
969 JOT(8, "second awakening on wq_video after %i waits\n", miss);
971 rc = field2frame(peasycap);
973 SAY("ERROR: field2frame() returned %i\n", rc);
975 peasycap->frame_read = peasycap->frame_fill;
976 peasycap->queued[peasycap->frame_read] = 0;
977 peasycap->done[peasycap->frame_read] = V4L2_BUF_FLAG_DONE;
979 (peasycap->frame_fill)++;
980 if (peasycap->frame_buffer_many <= peasycap->frame_fill)
981 peasycap->frame_fill = 0;
983 if (0x01 & easycap_standard[peasycap->standard_offset].mask) {
984 peasycap->frame_buffer[peasycap->frame_read][0].kount = \
987 peasycap->frame_buffer[peasycap->frame_read][0].kount = \
991 JOT(8, "setting: %i=peasycap->frame_read\n", peasycap->frame_read);
992 JOT(8, "bumped to: %i=peasycap->frame_fill\n", peasycap->frame_fill);
996 /*****************************************************************************/
997 /*---------------------------------------------------------------------------*/
999 * BY DEFINITION, odd IS true FOR THE FIELD OCCUPYING LINES 1,3,5,...,479
1000 * odd IS false FOR THE FIELD OCCUPYING LINES 0,2,4,...,478
1002 * WHEN BOOLEAN PARAMETER decimatepixel IS true, ONLY THE FIELD FOR WHICH
1003 * odd==false IS TRANSFERRED TO THE FRAME BUFFER.
1005 * THE BOOLEAN PARAMETER offerfields IS true ONLY WHEN THE USER PROGRAM
1006 * CHOOSES THE OPTION V4L2_FIELD_ALTERNATE. NO USERSPACE PROGRAM TESTED
1007 * TO DATE HAS DONE THIS. BUGS ARE LIKELY.
1009 /*---------------------------------------------------------------------------*/
1011 field2frame(struct easycap *peasycap)
1013 static struct timeval timeval0;
1014 struct timeval timeval;
1015 long long int above, below;
1017 struct signed_div_result sdr;
1020 int kex, kad, mex, mad, rex, rad, rad2;
1021 int c2, c3, w2, w3, cz, wz;
1022 int rc, bytesperpixel, multiplier, much, more, over, rump, caches;
1024 bool odd, isuy, decimatepixel, offerfields;
1026 JOT(8, "===== parity %i, field buffer %i --> frame buffer %i\n", \
1027 peasycap->field_buffer[peasycap->field_read][0].kount,\
1028 peasycap->field_read, peasycap->frame_fill);
1029 JOT(8, "===== %i=bytesperpixel\n", peasycap->bytesperpixel);
1030 if (true == peasycap->offerfields)
1031 JOT(8, "===== offerfields\n");
1033 /*---------------------------------------------------------------------------*/
1035 * REJECT OR CLEAN BAD FIELDS
1037 /*---------------------------------------------------------------------------*/
1038 if (peasycap->field_read == peasycap->field_fill) {
1039 SAY("ERROR: on entry, still filling field buffer %i\n", \
1040 peasycap->field_read);
1043 #if defined(EASYCAP_TESTCARD)
1044 easycap_testcard(peasycap, peasycap->field_read);
1046 if (0 != (0x0400 & peasycap->field_buffer[peasycap->field_read][0].kount))
1047 easycap_testcard(peasycap, peasycap->field_read);
1048 #endif /*EASYCAP_TESTCARD*/
1049 /*---------------------------------------------------------------------------*/
1051 offerfields = peasycap->offerfields;
1052 bytesperpixel = peasycap->bytesperpixel;
1053 decimatepixel = peasycap->decimatepixel;
1055 if ((2 != bytesperpixel) && \
1056 (3 != bytesperpixel) && \
1057 (4 != bytesperpixel)) {
1058 SAY("MISTAKE: %i=bytesperpixel\n", bytesperpixel);
1061 if (true == decimatepixel)
1066 w2 = 2 * multiplier * (peasycap->width);
1067 w3 = bytesperpixel * \
1071 (peasycap->height) * \
1075 kex = peasycap->field_read; mex = 0;
1076 kad = peasycap->frame_fill; mad = 0;
1078 pex = peasycap->field_buffer[kex][0].pgo; rex = PAGE_SIZE;
1079 pad = peasycap->frame_buffer[kad][0].pgo; rad = PAGE_SIZE;
1080 if (peasycap->field_buffer[kex][0].kount)
1085 if ((true == odd) && (false == offerfields) &&(false == decimatepixel)) {
1086 JOT(8, " initial skipping %4i bytes p.%4i\n", \
1087 w3/multiplier, mad);
1088 pad += (w3 / multiplier); rad -= (w3 / multiplier);
1091 mask = 0; rump = 0; caches = 0;
1095 /*-------------------------------------------------------------------*/
1097 ** PROCESS ONE LINE OF FRAME AT FULL RESOLUTION:
1098 ** READ w2 BYTES FROM FIELD BUFFER,
1099 ** WRITE w3 BYTES TO FRAME BUFFER
1101 /*-------------------------------------------------------------------*/
1102 if (false == decimatepixel) {
1105 much = over; more = 0; margin = 0; mask = 0x00;
1111 SAY("MISTAKE: much is odd\n");
1115 more = (bytesperpixel * \
1117 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1118 if (1 < bytesperpixel) {
1123 ** INJUDICIOUS ALTERATION OF THIS
1124 ** BLOCK WILL CAUSE BREAKAGE.
1127 rad2 = rad + bytesperpixel - 1;
1129 rad2)/bytesperpixel)/2) * 2);
1130 rump = ((bytesperpixel * \
1138 if ((mex + 1) < FIELD_BUFFER_SIZE/ \
1140 margin = *((__u8 *)(peasycap->\
1142 [kex][mex + 1].pgo));
1146 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1148 SAY("MISTAKE: %i=bytesperpixel\n", \
1152 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1156 rc = redaub(peasycap, pad, pex, much, more, \
1157 mask, margin, isuy);
1159 SAY("ERROR: redaub() failed\n");
1168 over -= much; cz += much;
1169 pex += much; rex -= much;
1172 pex = peasycap->field_buffer[kex][mex].pgo;
1179 pad = peasycap->frame_buffer[kad][mad].pgo;
1187 /*---------------------------------------------------------------------------*/
1189 * SKIP w3 BYTES IN TARGET FRAME BUFFER,
1190 * UNLESS IT IS THE LAST LINE OF AN ODD FRAME
1192 /*---------------------------------------------------------------------------*/
1193 if (((false == odd) || (cz != wz))&&(false == offerfields)) {
1198 pad = peasycap->frame_buffer\
1210 /*---------------------------------------------------------------------------*/
1212 * PROCESS ONE LINE OF FRAME AT REDUCED RESOLUTION:
1213 * ONLY IF false==odd,
1214 * READ w2 BYTES FROM FIELD BUFFER,
1215 * WRITE w3 / 2 BYTES TO FRAME BUFFER
1217 /*---------------------------------------------------------------------------*/
1218 } else if (false == odd) {
1221 much = over; more = 0; margin = 0; mask = 0x00;
1227 SAY("MISTAKE: much is odd\n");
1231 more = (bytesperpixel * \
1233 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1234 if (1 < bytesperpixel) {
1235 if ((rad * 4) < (much * \
1238 ** INJUDICIOUS ALTERATION OF THIS
1239 ** BLOCK WILL CAUSE BREAKAGE.
1242 rad2 = rad + bytesperpixel - 1;
1243 much = ((((2 * rad2)/bytesperpixel)/2)\
1245 rump = ((bytesperpixel * \
1253 if ((mex + 1) < FIELD_BUFFER_SIZE/ \
1255 margin = *((__u8 *)(peasycap->\
1257 [kex][mex + 1].pgo));
1262 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1264 SAY("MISTAKE: %i=bytesperpixel\n", \
1268 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1272 rc = redaub(peasycap, pad, pex, much, more, \
1273 mask, margin, isuy);
1275 SAY("ERROR: redaub() failed\n");
1278 over -= much; cz += much;
1279 pex += much; rex -= much;
1282 pex = peasycap->field_buffer[kex][mex].pgo;
1289 pad = peasycap->frame_buffer[kad][mad].pgo;
1297 /*---------------------------------------------------------------------------*/
1300 * READ w2 BYTES FROM FIELD BUFFER AND DISCARD THEM
1302 /*---------------------------------------------------------------------------*/
1308 pex = peasycap->field_buffer[kex][mex].pgo;
1321 /*---------------------------------------------------------------------------*/
1325 /*---------------------------------------------------------------------------*/
1326 c2 = (mex + 1)*PAGE_SIZE - rex;
1328 SAY("ERROR: discrepancy %i in bytes read\n", c2 - cz);
1329 c3 = (mad + 1)*PAGE_SIZE - rad;
1331 if (false == decimatepixel) {
1332 if (bytesperpixel * \
1334 SAY("ERROR: discrepancy %i in bytes written\n", \
1335 c3 - (bytesperpixel * \
1339 if (bytesperpixel * \
1341 SAY("ERROR: discrepancy %i in bytes written\n", \
1342 (2*c3)-(bytesperpixel * \
1346 SAY("ERROR: discrepancy %i " \
1347 "in bytes written\n", c3);
1351 SAY("ERROR: undischarged cache at end of line in frame buffer\n");
1353 JOT(8, "===== field2frame(): %i bytes --> %i bytes (incl skip)\n", c2, c3);
1354 JOT(8, "===== field2frame(): %i=mad %i=rad\n", mad, rad);
1357 JOT(8, "+++++ field2frame(): frame buffer %i is full\n", kad);
1359 if (peasycap->field_read == peasycap->field_fill)
1360 SAY("WARNING: on exit, filling field buffer %i\n", \
1361 peasycap->field_read);
1362 /*---------------------------------------------------------------------------*/
1364 * CALCULATE VIDEO STREAMING RATE
1366 /*---------------------------------------------------------------------------*/
1367 do_gettimeofday(&timeval);
1368 if (timeval0.tv_sec) {
1369 below = ((long long int)(1000000)) * \
1370 ((long long int)(timeval.tv_sec - timeval0.tv_sec)) + \
1371 (long long int)(timeval.tv_usec - timeval0.tv_usec);
1372 above = (long long int)1000000;
1374 sdr = signed_div(above, below);
1375 above = sdr.quotient;
1376 remainder = (__u32)sdr.remainder;
1378 JOT(8, "video streaming at %3lli.%03i fields per second\n", above, \
1384 JOT(8, "%i=caches\n", caches);
1387 /*****************************************************************************/
1388 struct signed_div_result
1389 signed_div(long long int above, long long int below)
1391 struct signed_div_result sdr;
1393 if (((0 <= above) && (0 <= below)) || ((0 > above) && (0 > below))) {
1394 sdr.remainder = (unsigned long long int) do_div(above, below);
1395 sdr.quotient = (long long int) above;
1401 sdr.remainder = (unsigned long long int) do_div(above, below);
1402 sdr.quotient = -((long long int) above);
1406 /*****************************************************************************/
1407 /*---------------------------------------------------------------------------*/
1409 * DECIMATION AND COLOURSPACE CONVERSION.
1411 * THIS ROUTINE REQUIRES THAT ALL THE DATA TO BE READ RESIDES ON ONE PAGE
1412 * AND THAT ALL THE DATA TO BE WRITTEN RESIDES ON ONE (DIFFERENT) PAGE.
1413 * THE CALLING ROUTINE MUST ENSURE THAT THIS REQUIREMENT IS MET, AND MUST
1414 * ALSO ENSURE THAT much IS EVEN.
1416 * much BYTES ARE READ, AT LEAST (bytesperpixel * much)/2 BYTES ARE WRITTEN
1417 * IF THERE IS NO DECIMATION, HALF THIS AMOUNT IF THERE IS DECIMATION.
1419 * mask IS ZERO WHEN NO SPECIAL BEHAVIOUR REQUIRED. OTHERWISE IT IS SET THUS:
1420 * 0x03 & mask = number of bytes to be written to cache instead of to
1422 * 0x04 & mask => use argument margin to set the chrominance for last pixel
1423 * 0x08 & mask => do not set the chrominance for last pixel
1425 * YUV to RGB CONVERSION IS (OR SHOULD BE) ITU-R BT 601.
1427 * THERE IS A LOT OF CODE REPETITION IN THIS ROUTINE IN ORDER TO AVOID
1428 * INEFFICIENT SWITCHING INSIDE INNER LOOPS. REARRANGING THE LOGIC TO
1429 * REDUCE CODE LENGTH WILL GENERALLY IMPAIR RUNTIME PERFORMANCE. BEWARE.
1431 /*---------------------------------------------------------------------------*/
1433 redaub(struct easycap *peasycap, void *pad, void *pex, int much, int more, \
1434 __u8 mask, __u8 margin, bool isuy)
1436 static __s32 ay[256], bu[256], rv[256], gu[256], gv[256];
1437 static __u8 cache[8], *pcache;
1438 __u8 r, g, b, y, u, v, c, *p2, *p3, *pz, *pr;
1440 bool byteswaporder, decimatepixel, last;
1445 SAY("MISTAKE: much is odd\n");
1448 bytesperpixel = peasycap->bytesperpixel;
1449 byteswaporder = peasycap->byteswaporder;
1450 decimatepixel = peasycap->decimatepixel;
1452 /*---------------------------------------------------------------------------*/
1454 for (j = 0; j < 112; j++) {
1455 s32 = (0xFF00 & (453 * j)) >> 8;
1456 bu[j + 128] = s32; bu[127 - j] = -s32;
1457 s32 = (0xFF00 & (359 * j)) >> 8;
1458 rv[j + 128] = s32; rv[127 - j] = -s32;
1459 s32 = (0xFF00 & (88 * j)) >> 8;
1460 gu[j + 128] = s32; gu[127 - j] = -s32;
1461 s32 = (0xFF00 & (183 * j)) >> 8;
1462 gv[j + 128] = s32; gv[127 - j] = -s32;
1464 for (j = 0; j < 16; j++) {
1465 bu[j] = bu[16]; rv[j] = rv[16];
1466 gu[j] = gu[16]; gv[j] = gv[16];
1468 for (j = 240; j < 256; j++) {
1469 bu[j] = bu[239]; rv[j] = rv[239];
1470 gu[j] = gu[239]; gv[j] = gv[239];
1472 for (j = 16; j < 236; j++)
1474 for (j = 0; j < 16; j++)
1476 for (j = 236; j < 256; j++)
1478 JOT(8, "lookup tables are prepared\n");
1480 if ((__u8 *)NULL == pcache)
1482 /*---------------------------------------------------------------------------*/
1484 * TRANSFER CONTENTS OF CACHE TO THE FRAME BUFFER
1486 /*---------------------------------------------------------------------------*/
1488 SAY("MISTAKE: pcache is NULL\n");
1492 if (pcache != &cache[0])
1493 JOT(16, "cache has %i bytes\n", (int)(pcache - &cache[0]));
1495 p3 = (__u8 *)pad - (int)(pcache - &cache[0]);
1496 while (p2 < pcache) {
1501 SAY("MISTAKE: pointer misalignment\n");
1504 /*---------------------------------------------------------------------------*/
1505 rump = (int)(0x03 & mask);
1507 p2 = (__u8 *)pex; pz = p2 + much; pr = p3 + more; last = false;
1516 JOT(16, "%4i=much %4i=more %i=rump\n", much, more, rump);
1518 /*---------------------------------------------------------------------------*/
1519 switch (bytesperpixel) {
1521 if (false == decimatepixel) {
1522 memcpy(pad, pex, (size_t)much);
1523 if (false == byteswaporder)
1524 /*---------------------------------------------------*/
1528 /*---------------------------------------------------*/
1531 /*---------------------------------------------------*/
1535 /*---------------------------------------------------*/
1536 p3 = (__u8 *)pad; pz = p3 + much;
1546 if (false == byteswaporder) {
1547 /*---------------------------------------------------*/
1551 /*---------------------------------------------------*/
1552 p2 = (__u8 *)pex; p3 = (__u8 *)pad; pz = p2 + much;
1555 *(p3 + 1) = *(p2 + 1);
1556 *(p3 + 2) = *(p2 + 2);
1557 *(p3 + 3) = *(p2 + 3);
1562 /*---------------------------------------------------*/
1566 /*---------------------------------------------------*/
1567 p2 = (__u8 *)pex; p3 = (__u8 *)pad; pz = p2 + much;
1571 *(p3 + 2) = *(p2 + 3);
1572 *(p3 + 3) = *(p2 + 2);
1582 if (false == decimatepixel) {
1583 if (false == byteswaporder) {
1584 /*---------------------------------------------------*/
1588 /*---------------------------------------------------*/
1590 if (pr <= (p3 + bytesperpixel))
1595 if ((true == last) && (0x0C & mask)) {
1611 s32 = ay[(int)y] + rv[(int)v];
1612 r = (255 < s32) ? 255 : ((0 > s32) ? \
1614 s32 = ay[(int)y] - gu[(int)u] - gv[(int)v];
1615 g = (255 < s32) ? 255 : ((0 > s32) ? \
1617 s32 = ay[(int)y] + bu[(int)u];
1618 b = (255 < s32) ? 255 : ((0 > s32) ? \
1621 if ((true == last) && rump) {
1623 switch (bytesperpixel - rump) {
1637 SAY("MISTAKE: %i=rump\n", \
1638 bytesperpixel - rump);
1652 p3 += bytesperpixel;
1656 /*---------------------------------------------------*/
1660 /*---------------------------------------------------*/
1662 if (pr <= (p3 + bytesperpixel))
1667 if ((true == last) && (0x0C & mask)) {
1684 s32 = ay[(int)y] + rv[(int)v];
1685 r = (255 < s32) ? 255 : ((0 > s32) ? \
1687 s32 = ay[(int)y] - gu[(int)u] - gv[(int)v];
1688 g = (255 < s32) ? 255 : ((0 > s32) ? \
1690 s32 = ay[(int)y] + bu[(int)u];
1691 b = (255 < s32) ? 255 : ((0 > s32) ? \
1694 if ((true == last) && rump) {
1696 switch (bytesperpixel - rump) {
1710 SAY("MISTAKE: %i=rump\n", \
1711 bytesperpixel - rump);
1725 p3 += bytesperpixel;
1730 if (false == byteswaporder) {
1731 /*---------------------------------------------------*/
1735 /*---------------------------------------------------*/
1737 if (pr <= (p3 + bytesperpixel))
1742 if ((true == last) && (0x0C & mask)) {
1759 s32 = ay[(int)y] + rv[(int)v];
1760 r = (255 < s32) ? 255 : ((0 > s32) ? \
1762 s32 = ay[(int)y] - gu[(int)u] - \
1764 g = (255 < s32) ? 255 : ((0 > s32) ? \
1766 s32 = ay[(int)y] + bu[(int)u];
1767 b = (255 < s32) ? 255 : ((0 > s32) ? \
1770 if ((true == last) && rump) {
1772 switch (bytesperpixel - rump) {
1788 bytesperpixel - rump);
1798 p3 += bytesperpixel;
1806 /*---------------------------------------------------*/
1810 /*---------------------------------------------------*/
1812 if (pr <= (p3 + bytesperpixel))
1817 if ((true == last) && (0x0C & mask)) {
1835 s32 = ay[(int)y] + rv[(int)v];
1836 r = (255 < s32) ? 255 : ((0 > s32) ? \
1838 s32 = ay[(int)y] - gu[(int)u] - \
1840 g = (255 < s32) ? 255 : ((0 > s32) ? \
1842 s32 = ay[(int)y] + bu[(int)u];
1843 b = (255 < s32) ? 255 : ((0 > s32) ? \
1846 if ((true == last) && rump) {
1848 switch (bytesperpixel - rump) {
1864 bytesperpixel - rump);
1874 p3 += bytesperpixel;
1887 if (false == decimatepixel) {
1888 if (false == byteswaporder) {
1889 /*---------------------------------------------------*/
1893 /*---------------------------------------------------*/
1895 if (pr <= (p3 + bytesperpixel))
1900 if ((true == last) && (0x0C & mask)) {
1916 s32 = ay[(int)y] + rv[(int)v];
1917 r = (255 < s32) ? 255 : ((0 > s32) ? \
1919 s32 = ay[(int)y] - gu[(int)u] - gv[(int)v];
1920 g = (255 < s32) ? 255 : ((0 > s32) ? \
1922 s32 = ay[(int)y] + bu[(int)u];
1923 b = (255 < s32) ? 255 : ((0 > s32) ? \
1926 if ((true == last) && rump) {
1928 switch (bytesperpixel - rump) {
1951 SAY("MISTAKE: %i=rump\n", \
1952 bytesperpixel - rump);
1967 p3 += bytesperpixel;
1971 /*---------------------------------------------------*/
1975 /*---------------------------------------------------*/
1977 if (pr <= (p3 + bytesperpixel))
1982 if ((true == last) && (0x0C & mask)) {
1998 s32 = ay[(int)y] + rv[(int)v];
1999 r = (255 < s32) ? 255 : ((0 > s32) ? \
2001 s32 = ay[(int)y] - gu[(int)u] - gv[(int)v];
2002 g = (255 < s32) ? 255 : ((0 > s32) ? \
2004 s32 = ay[(int)y] + bu[(int)u];
2005 b = (255 < s32) ? 255 : ((0 > s32) ? \
2008 if ((true == last) && rump) {
2010 switch (bytesperpixel - rump) {
2033 SAY("MISTAKE: %i=rump\n", \
2034 bytesperpixel - rump);
2049 p3 += bytesperpixel;
2054 if (false == byteswaporder) {
2055 /*---------------------------------------------------*/
2059 /*---------------------------------------------------*/
2061 if (pr <= (p3 + bytesperpixel))
2066 if ((true == last) && (0x0C & mask)) {
2084 s32 = ay[(int)y] + rv[(int)v];
2085 r = (255 < s32) ? 255 : ((0 > s32) ? \
2087 s32 = ay[(int)y] - gu[(int)u] - \
2089 g = (255 < s32) ? 255 : ((0 > s32) ? \
2091 s32 = ay[(int)y] + bu[(int)u];
2092 b = (255 < s32) ? 255 : ((0 > s32) ? \
2095 if ((true == last) && rump) {
2097 switch (bytesperpixel - rump) {
2134 p3 += bytesperpixel;
2141 /*---------------------------------------------------*/
2145 /*---------------------------------------------------*/
2147 if (pr <= (p3 + bytesperpixel))
2152 if ((true == last) && (0x0C & mask)) {
2169 s32 = ay[(int)y] + rv[(int)v];
2170 r = (255 < s32) ? 255 : ((0 > s32) ? \
2172 s32 = ay[(int)y] - gu[(int)u] - \
2174 g = (255 < s32) ? 255 : ((0 > s32) ? \
2176 s32 = ay[(int)y] + bu[(int)u];
2177 b = (255 < s32) ? 255 : ((0 > s32) ? \
2180 if ((true == last) && rump) {
2182 switch (bytesperpixel - rump) {
2207 bytesperpixel - rump);
2218 p3 += bytesperpixel;
2229 SAY("MISTAKE: %i=bytesperpixel\n", bytesperpixel);
2235 /*****************************************************************************/
2237 debrief(struct easycap *peasycap)
2239 if ((struct usb_device *)NULL != peasycap->pusb_device) {
2240 check_stk(peasycap->pusb_device);
2241 check_saa(peasycap->pusb_device);
2242 sayreadonly(peasycap);
2243 SAY("%i=peasycap->field_fill\n", peasycap->field_fill);
2244 SAY("%i=peasycap->field_read\n", peasycap->field_read);
2245 SAY("%i=peasycap->frame_fill\n", peasycap->frame_fill);
2246 SAY("%i=peasycap->frame_read\n", peasycap->frame_read);
2250 /*****************************************************************************/
2252 sayreadonly(struct easycap *peasycap)
2255 int got00, got1F, got60, got61, got62;
2257 if ((!done) && ((struct usb_device *)NULL != peasycap->pusb_device)) {
2259 got00 = read_saa(peasycap->pusb_device, 0x00);
2260 got1F = read_saa(peasycap->pusb_device, 0x1F);
2261 got60 = read_saa(peasycap->pusb_device, 0x60);
2262 got61 = read_saa(peasycap->pusb_device, 0x61);
2263 got62 = read_saa(peasycap->pusb_device, 0x62);
2264 SAY("0x%02X=reg0x00 0x%02X=reg0x1F\n", got00, got1F);
2265 SAY("0x%02X=reg0x60 0x%02X=reg0x61 0x%02X=reg0x62\n", \
2266 got60, got61, got62);
2270 /*****************************************************************************/
2271 /*---------------------------------------------------------------------------*/
2273 * SEE CORBET ET AL. "LINUX DEVICE DRIVERS", 3rd EDITION, PAGES 430-434
2275 /*---------------------------------------------------------------------------*/
2276 int easycap_mmap(struct file *file, struct vm_area_struct *pvma)
2281 pvma->vm_ops = &easycap_vm_ops;
2282 pvma->vm_flags |= VM_RESERVED;
2284 pvma->vm_private_data = file->private_data;
2285 easycap_vma_open(pvma);
2288 /*****************************************************************************/
2290 easycap_vma_open(struct vm_area_struct *pvma)
2292 struct easycap *peasycap;
2294 peasycap = pvma->vm_private_data;
2295 if (NULL != peasycap)
2296 peasycap->vma_many++;
2298 JOT(8, "%i=peasycap->vma_many\n", peasycap->vma_many);
2302 /*****************************************************************************/
2304 easycap_vma_close(struct vm_area_struct *pvma)
2306 struct easycap *peasycap;
2308 peasycap = pvma->vm_private_data;
2309 if (NULL != peasycap) {
2310 peasycap->vma_many--;
2311 JOT(8, "%i=peasycap->vma_many\n", peasycap->vma_many);
2315 /*****************************************************************************/
2317 easycap_vma_fault(struct vm_area_struct *pvma, struct vm_fault *pvmf)
2322 struct easycap *peasycap;
2324 retcode = VM_FAULT_NOPAGE;
2325 pbuf = (void *)NULL;
2326 page = (struct page *)NULL;
2329 SAY("pvma is NULL\n");
2333 SAY("pvmf is NULL\n");
2337 k = (pvmf->pgoff) / (FRAME_BUFFER_SIZE/PAGE_SIZE);
2338 m = (pvmf->pgoff) % (FRAME_BUFFER_SIZE/PAGE_SIZE);
2341 JOT(4, "%4i=k, %4i=m\n", k, m);
2343 JOT(16, "%4i=k, %4i=m\n", k, m);
2345 if ((0 > k) || (FRAME_BUFFER_MANY <= k)) {
2346 SAY("ERROR: buffer index %i out of range\n", k);
2349 if ((0 > m) || (FRAME_BUFFER_SIZE/PAGE_SIZE <= m)) {
2350 SAY("ERROR: page number %i out of range\n", m);
2353 peasycap = pvma->vm_private_data;
2354 if (NULL == peasycap) {
2355 SAY("ERROR: peasycap is NULL\n");
2358 mutex_lock(&(peasycap->mutex_mmap_video[0]));
2359 /*---------------------------------------------------------------------------*/
2360 pbuf = peasycap->frame_buffer[k][m].pgo;
2362 SAY("ERROR: pbuf is NULL\n");
2365 page = virt_to_page(pbuf);
2367 SAY("ERROR: page is NULL\n");
2371 /*---------------------------------------------------------------------------*/
2373 mutex_unlock(&(peasycap->mutex_mmap_video[0]));
2375 SAY("ERROR: page is NULL after get_page(page)\n");
2378 retcode = VM_FAULT_MINOR;
2382 /*****************************************************************************/
2383 /*---------------------------------------------------------------------------*/
2385 * ON COMPLETION OF A VIDEO URB ITS DATA IS COPIED TO THE FIELD BUFFERS
2386 * PROVIDED peasycap->video_idle IS ZER0. REGARDLESS OF THIS BEING TRUE,
2387 * IT IS RESUBMITTED PROVIDED peasycap->video_isoc_streaming IS NOT ZERO.
2389 * THIS FUNCTION IS AN INTERRUPT SERVICE ROUTINE AND MUST NOT SLEEP.
2391 * INFORMATION ABOUT THE VALIDITY OF THE CONTENTS OF THE FIELD BUFFER ARE
2392 * STORED IN THE TWO-BYTE STATUS PARAMETER
2393 * peasycap->field_buffer[peasycap->field_fill][0].kount
2394 * NOTICE THAT THE INFORMATION IS STORED ONLY WITH PAGE 0 OF THE FIELD BUFFER.
2396 * THE LOWER BYTE CONTAINS THE FIELD PARITY BYTE FURNISHED BY THE SAA7113H
2399 * THE UPPER BYTE IS ZERO IF NO PROBLEMS, OTHERWISE:
2400 * 0 != (kount & 0x8000) => AT LEAST ONE URB COMPLETED WITH ERRORS
2401 * 0 != (kount & 0x4000) => BUFFER HAS TOO MUCH DATA
2402 * 0 != (kount & 0x2000) => BUFFER HAS NOT ENOUGH DATA
2403 * 0 != (kount & 0x0400) => FIELD WAS SUBMITTED BY BRIDGER ROUTINE
2404 * 0 != (kount & 0x0200) => FIELD BUFFER NOT YET CHECKED
2405 * 0 != (kount & 0x0100) => BUFFER HAS TWO EXTRA BYTES - WHY?
2407 /*---------------------------------------------------------------------------*/
2409 easycap_complete(struct urb *purb)
2412 struct easycap *peasycap;
2413 struct data_buffer *pfield_buffer;
2415 int i, more, much, leap, rc, last;
2416 int videofieldamount;
2417 unsigned int override;
2418 int framestatus, framelength, frameactual, frameoffset;
2420 #if defined(BRIDGER)
2421 struct timeval timeval;
2426 SAY("ERROR: easycap_complete(): purb is NULL\n");
2429 peasycap = purb->context;
2430 if (NULL == peasycap) {
2431 SAY("ERROR: easycap_complete(): peasycap is NULL\n");
2435 if (peasycap->video_eof)
2438 for (i = 0; i < VIDEO_ISOC_BUFFER_MANY; i++)
2439 if (purb->transfer_buffer == peasycap->video_isoc_buffer[i].pgo)
2441 JOT(16, "%2i=urb\n", i);
2442 last = peasycap->video_isoc_sequence;
2443 if ((((VIDEO_ISOC_BUFFER_MANY - 1) == last) && \
2445 (((VIDEO_ISOC_BUFFER_MANY - 1) != last) && \
2446 ((last + 1) != i))) {
2447 SAY("ERROR: out-of-order urbs %i,%i ... continuing\n", last, i);
2449 peasycap->video_isoc_sequence = i;
2451 if (peasycap->video_idle) {
2452 JOT(16, "%i=video_idle %i=video_isoc_streaming\n", \
2453 peasycap->video_idle, peasycap->video_isoc_streaming);
2454 if (peasycap->video_isoc_streaming) {
2455 rc = usb_submit_urb(purb, GFP_ATOMIC);
2457 SAY("ERROR: while %i=video_idle, " \
2458 "usb_submit_urb() failed with rc:\n", \
2459 peasycap->video_idle);
2498 SAY("0x%08X\n", rc);
2507 /*---------------------------------------------------------------------------*/
2508 if (FIELD_BUFFER_MANY <= peasycap->field_fill) {
2509 SAY("ERROR: bad peasycap->field_fill\n");
2513 if ((-ESHUTDOWN == purb->status) || (-ENOENT == purb->status)) {
2514 JOT(8, "urb status -ESHUTDOWN or -ENOENT\n");
2518 (peasycap->field_buffer[peasycap->field_fill][0].kount) |= 0x8000 ;
2519 SAY("ERROR: bad urb status:\n");
2520 switch (purb->status) {
2521 case -EINPROGRESS: {
2522 SAY("-EINPROGRESS\n"); break;
2525 SAY("-ENOSR\n"); break;
2528 SAY("-EPIPE\n"); break;
2531 SAY("-EOVERFLOW\n"); break;
2534 SAY("-EPROTO\n"); break;
2537 SAY("-EILSEQ\n"); break;
2540 SAY("-ETIMEDOUT\n"); break;
2543 SAY("-EMSGSIZE\n"); break;
2546 SAY("-EOPNOTSUPP\n"); break;
2548 case -EPFNOSUPPORT: {
2549 SAY("-EPFNOSUPPORT\n"); break;
2551 case -EAFNOSUPPORT: {
2552 SAY("-EAFNOSUPPORT\n"); break;
2555 SAY("-EADDRINUSE\n"); break;
2557 case -EADDRNOTAVAIL: {
2558 SAY("-EADDRNOTAVAIL\n"); break;
2561 SAY("-ENOBUFS\n"); break;
2564 SAY("-EISCONN\n"); break;
2567 SAY("-ENOTCONN\n"); break;
2570 SAY("-ESHUTDOWN\n"); break;
2573 SAY("-ENOENT\n"); break;
2576 SAY("-ECONNRESET\n"); break;
2579 SAY("ENOSPC\n"); break;
2582 SAY("unknown error code 0x%08X\n", purb->status); break;
2585 /*---------------------------------------------------------------------------*/
2587 for (i = 0; i < purb->number_of_packets; i++) {
2588 if (0 != purb->iso_frame_desc[i].status) {
2589 (peasycap->field_buffer\
2590 [peasycap->field_fill][0].kount) |= 0x8000 ;
2591 switch (purb->iso_frame_desc[i].status) {
2593 strcpy(&errbuf[0], "OK"); break;
2596 strcpy(&errbuf[0], "-ENOENT"); break;
2598 case -EINPROGRESS: {
2599 strcpy(&errbuf[0], "-EINPROGRESS"); break;
2602 strcpy(&errbuf[0], "-EPROTO"); break;
2605 strcpy(&errbuf[0], "-EILSEQ"); break;
2608 strcpy(&errbuf[0], "-ETIME"); break;
2611 strcpy(&errbuf[0], "-ETIMEDOUT"); break;
2614 strcpy(&errbuf[0], "-EPIPE"); break;
2617 strcpy(&errbuf[0], "-ECOMM"); break;
2620 strcpy(&errbuf[0], "-ENOSR"); break;
2623 strcpy(&errbuf[0], "-EOVERFLOW"); break;
2626 strcpy(&errbuf[0], "-EREMOTEIO"); break;
2629 strcpy(&errbuf[0], "-ENODEV"); break;
2632 strcpy(&errbuf[0], "-EXDEV"); break;
2635 strcpy(&errbuf[0], "-EINVAL"); break;
2638 strcpy(&errbuf[0], "-ECONNRESET"); break;
2641 SAY("ENOSPC\n"); break;
2644 strcpy(&errbuf[0], "-ESHUTDOWN"); break;
2647 strcpy(&errbuf[0], "unknown error"); break;
2651 framestatus = purb->iso_frame_desc[i].status;
2652 framelength = purb->iso_frame_desc[i].length;
2653 frameactual = purb->iso_frame_desc[i].actual_length;
2654 frameoffset = purb->iso_frame_desc[i].offset;
2656 JOT(16, "frame[%2i]:" \
2661 i, framestatus, frameactual, framelength, frameoffset);
2662 if (!purb->iso_frame_desc[i].status) {
2663 more = purb->iso_frame_desc[i].actual_length;
2664 pfield_buffer = &peasycap->field_buffer\
2665 [peasycap->field_fill][peasycap->field_page];
2666 videofieldamount = (peasycap->field_page * \
2668 (int)(pfield_buffer->pto - pfield_buffer->pgo);
2673 JOT(8, "%4i empty video urb frames\n", mt);
2676 if (FIELD_BUFFER_MANY <= peasycap->field_fill) {
2677 SAY("ERROR: bad peasycap->field_fill\n");
2680 if (FIELD_BUFFER_SIZE/PAGE_SIZE <= \
2681 peasycap->field_page) {
2682 SAY("ERROR: bad peasycap->field_page\n");
2685 pfield_buffer = &peasycap->field_buffer\
2686 [peasycap->field_fill][peasycap->field_page];
2687 pu = (__u8 *)(purb->transfer_buffer + \
2688 purb->iso_frame_desc[i].offset);
2693 /*--------------------------------------------------------------------------*/
2695 * EIGHT-BYTE END-OF-VIDEOFIELD MARKER.
2696 * NOTE: A SUCCESSION OF URB FRAMES FOLLOWING THIS ARE EMPTY,
2697 * CORRESPONDING TO THE FIELD FLYBACK (VERTICAL BLANKING) PERIOD.
2699 * PROVIDED THE FIELD BUFFER CONTAINS GOOD DATA AS INDICATED BY A ZERO UPPER
2701 * peasycap->field_buffer[peasycap->field_fill][0].kount
2702 * THE CONTENTS OF THE FIELD BUFFER ARE OFFERED TO dqbuf(), field_read IS
2703 * UPDATED AND field_fill IS BUMPED. IF THE FIELD BUFFER CONTAINS BAD DATA
2704 * NOTHING IS OFFERED TO dqbuf().
2706 * THE DECISION ON WHETHER THE PARITY OF THE OFFERED FIELD BUFFER IS RIGHT
2707 * RESTS WITH dqbuf().
2709 /*---------------------------------------------------------------------------*/
2710 if ((8 == more) || override) {
2711 if (videofieldamount > \
2712 peasycap->videofieldamount) {
2713 if (2 == videofieldamount - \
2716 (peasycap->field_buffer\
2717 [peasycap->field_fill]\
2718 [0].kount) |= 0x0100;
2720 (peasycap->field_buffer\
2721 [peasycap->field_fill]\
2722 [0].kount) |= 0x4000;
2723 } else if (videofieldamount < \
2726 (peasycap->field_buffer\
2727 [peasycap->field_fill]\
2728 [0].kount) |= 0x2000;
2730 if (!(0xFF00 & peasycap->field_buffer\
2731 [peasycap->field_fill]\
2733 (peasycap->video_junk)--;
2734 if (-16 > peasycap->video_junk)
2735 peasycap->video_junk = -16;
2736 peasycap->field_read = \
2740 if (FIELD_BUFFER_MANY <= \
2741 peasycap->field_fill)
2742 peasycap->field_fill = 0;
2743 peasycap->field_page = 0;
2744 pfield_buffer = &peasycap->\
2746 [peasycap->field_fill]\
2747 [peasycap->field_page];
2748 pfield_buffer->pto = \
2751 JOT(8, "bumped to: %i=peasycap->" \
2752 "field_fill %i=parity\n", \
2753 peasycap->field_fill, \
2754 0x00FF & pfield_buffer->kount);
2755 JOT(8, "field buffer %i has %i " \
2756 "bytes fit to be read\n", \
2757 peasycap->field_read, \
2759 JOT(8, "wakeup call to wq_video, " \
2760 "%i=field_read %i=field_fill "\
2762 peasycap->field_read, \
2763 peasycap->field_fill, \
2764 0x00FF & peasycap->\
2765 field_buffer[peasycap->\
2766 field_read][0].kount);
2767 wake_up_interruptible(&(peasycap->\
2769 do_gettimeofday(&peasycap->timeval7);
2771 peasycap->video_junk++;
2772 JOT(8, "field buffer %i had %i " \
2773 "bytes, now discarded\n", \
2774 peasycap->field_fill, \
2777 (peasycap->field_fill)++;
2779 if (FIELD_BUFFER_MANY <= \
2780 peasycap->field_fill)
2781 peasycap->field_fill = 0;
2782 peasycap->field_page = 0;
2784 &peasycap->field_buffer\
2785 [peasycap->field_fill]\
2786 [peasycap->field_page];
2787 pfield_buffer->pto = \
2790 JOT(8, "bumped to: %i=peasycap->" \
2791 "field_fill %i=parity\n", \
2792 peasycap->field_fill, \
2793 0x00FF & pfield_buffer->kount);
2796 JOT(8, "end-of-field: received " \
2797 "parity byte 0x%02X\n", \
2800 pfield_buffer->kount = 0x0000;
2802 pfield_buffer->kount = 0x0001;
2803 JOT(8, "end-of-field: 0x%02X=kount\n",\
2804 0xFF & pfield_buffer->kount);
2807 /*---------------------------------------------------------------------------*/
2809 * COPY more BYTES FROM ISOC BUFFER TO FIELD BUFFER
2811 /*---------------------------------------------------------------------------*/
2815 if (FIELD_BUFFER_MANY <= peasycap->field_fill) {
2816 SAY("ERROR: bad peasycap->field_fill\n");
2819 if (FIELD_BUFFER_SIZE/PAGE_SIZE <= \
2820 peasycap->field_page) {
2821 SAY("ERROR: bad peasycap->field_page\n");
2824 pfield_buffer = &peasycap->field_buffer\
2825 [peasycap->field_fill][peasycap->field_page];
2827 pfield_buffer = &peasycap->field_buffer\
2828 [peasycap->field_fill]\
2829 [peasycap->field_page];
2830 if (PAGE_SIZE < (pfield_buffer->pto - \
2831 pfield_buffer->pgo)) {
2832 SAY("ERROR: bad pfield_buffer->pto\n");
2835 if (PAGE_SIZE == (pfield_buffer->pto - \
2836 pfield_buffer->pgo)) {
2837 (peasycap->field_page)++;
2838 if (FIELD_BUFFER_SIZE/PAGE_SIZE <= \
2839 peasycap->field_page) {
2840 JOT(16, "wrapping peasycap->" \
2842 peasycap->field_page = 0;
2844 pfield_buffer = &peasycap->\
2846 [peasycap->field_fill]\
2847 [peasycap->field_page];
2848 pfield_buffer->pto = \
2852 much = PAGE_SIZE - (int)(pfield_buffer->pto - \
2853 pfield_buffer->pgo);
2857 memcpy(pfield_buffer->pto, pu, much);
2859 (pfield_buffer->pto) += much;
2866 /*---------------------------------------------------------------------------*/
2870 * *** UNDER DEVELOPMENT/TESTING - NOT READY YET! ***
2874 * VIDEOTAPES MAY HAVE BEEN MANUALLY PAUSED AND RESTARTED DURING RECORDING.
2875 * THIS CAUSES LOSS OF SYNC, CONFUSING DOWNSTREAM USERSPACE PROGRAMS WHICH
2876 * MAY INTERPRET THE INTERRUPTION AS A SYMPTOM OF LATENCY. TO OVERCOME THIS
2877 * THE DRIVER BRIDGES THE HIATUS BY SENDING DUMMY VIDEO FRAMES AT ROUGHLY
2878 * THE RIGHT TIME INTERVALS IN THE HOPE OF PERSUADING THE DOWNSTREAM USERSPACE
2879 * PROGRAM TO RESUME NORMAL SERVICE WHEN THE INTERRUPTION IS OVER.
2881 /*---------------------------------------------------------------------------*/
2882 #if defined(BRIDGER)
2883 do_gettimeofday(&timeval);
2884 if (peasycap->timeval7.tv_sec) {
2885 usec = 1000000*(timeval.tv_sec - peasycap->timeval7.tv_sec) + \
2886 (timeval.tv_usec - peasycap->timeval7.tv_usec);
2887 if (usec > (peasycap->usec + peasycap->tolerate)) {
2888 JOT(8, "bridging hiatus\n");
2889 peasycap->video_junk = 0;
2890 peasycap->field_buffer[peasycap->field_fill][0].kount |= 0x0400;
2892 peasycap->field_read = (peasycap->field_fill)++;
2894 if (FIELD_BUFFER_MANY <= peasycap->field_fill) \
2895 peasycap->field_fill = 0;
2896 peasycap->field_page = 0;
2897 pfield_buffer = &peasycap->field_buffer\
2898 [peasycap->field_fill][peasycap->field_page];
2899 pfield_buffer->pto = pfield_buffer->pgo;
2901 JOT(8, "bumped to: %i=peasycap->field_fill %i=parity\n", \
2902 peasycap->field_fill, 0x00FF & pfield_buffer->kount);
2903 JOT(8, "field buffer %i has %i bytes to be overwritten\n", \
2904 peasycap->field_read, videofieldamount);
2905 JOT(8, "wakeup call to wq_video, " \
2906 "%i=field_read %i=field_fill %i=parity\n", \
2907 peasycap->field_read, peasycap->field_fill, \
2909 peasycap->field_buffer[peasycap->field_read][0].kount);
2910 wake_up_interruptible(&(peasycap->wq_video));
2911 do_gettimeofday(&peasycap->timeval7);
2915 /*---------------------------------------------------------------------------*/
2917 * RESUBMIT THIS URB, UNLESS A SEVERE PERSISTENT ERROR CONDITION EXISTS.
2919 * IF THE WAIT QUEUES ARE NOT CLEARED IN RESPONSE TO AN ERROR CONDITION
2920 * THE USERSPACE PROGRAM, E.G. mplayer, MAY HANG ON EXIT. BEWARE.
2922 /*---------------------------------------------------------------------------*/
2923 if (VIDEO_ISOC_BUFFER_MANY <= peasycap->video_junk) {
2924 SAY("easycap driver shutting down on condition green\n");
2925 peasycap->video_eof = 1;
2926 peasycap->audio_eof = 1;
2927 peasycap->video_junk = -VIDEO_ISOC_BUFFER_MANY;
2928 wake_up_interruptible(&(peasycap->wq_video));
2929 wake_up_interruptible(&(peasycap->wq_audio));
2932 if (peasycap->video_isoc_streaming) {
2933 rc = usb_submit_urb(purb, GFP_ATOMIC);
2935 SAY("ERROR: while %i=video_idle, usb_submit_urb() failed " \
2936 "with rc:\n", peasycap->video_idle);
2939 SAY("ENOMEM\n"); break;
2942 SAY("ENODEV\n"); break;
2945 SAY("ENXIO\n"); break;
2948 SAY("EINVAL\n"); break;
2951 SAY("EAGAIN\n"); break;
2954 SAY("EFBIG\n"); break;
2957 SAY("EPIPE\n"); break;
2960 SAY("EMSGSIZE\n"); break;
2963 SAY("ENOSPC\n"); break;
2966 SAY("0x%08X\n", rc); break;
2973 /*****************************************************************************/
2974 /*---------------------------------------------------------------------------*/
2980 * THIS FUNCTION ASSUMES THAT, ON EACH AND EVERY OCCASION THAT THE DEVICE IS
2981 * PHYSICALLY PLUGGED IN, INTERFACE 0 IS PROBED FIRST.
2982 * IF THIS IS NOT TRUE, THERE IS THE POSSIBILITY OF AN Oops.
2984 * THIS HAS NEVER BEEN A PROBLEM IN PRACTICE, BUT SOMETHING SEEMS WRONG HERE.
2986 /*---------------------------------------------------------------------------*/
2988 easycap_usb_probe(struct usb_interface *pusb_interface, \
2989 const struct usb_device_id *id)
2991 struct usb_device *pusb_device, *pusb_device1;
2992 struct usb_host_interface *pusb_host_interface;
2993 struct usb_endpoint_descriptor *pepd;
2994 struct usb_interface_descriptor *pusb_interface_descriptor;
2995 struct usb_interface_assoc_descriptor *pusb_interface_assoc_descriptor;
2997 static struct easycap *peasycap /*=NULL*/;
2998 struct data_urb *pdata_urb;
2999 size_t wMaxPacketSize;
3000 int ISOCwMaxPacketSize;
3001 int BULKwMaxPacketSize;
3002 int INTwMaxPacketSize;
3003 int CTRLwMaxPacketSize;
3004 __u8 bEndpointAddress;
3005 __u8 ISOCbEndpointAddress;
3006 __u8 INTbEndpointAddress;
3007 int isin, i, j, k, m;
3008 __u8 bInterfaceNumber;
3009 __u8 bInterfaceClass;
3010 __u8 bInterfaceSubClass;
3012 int okalt[8], isokalt;
3013 int okepn[8], isokepn;
3014 int okmps[8], isokmps;
3020 if ((struct usb_interface *)NULL == pusb_interface) {
3021 SAY("ERROR: pusb_interface is NULL\n");
3024 /*---------------------------------------------------------------------------*/
3026 * GET POINTER TO STRUCTURE usb_device
3028 /*---------------------------------------------------------------------------*/
3029 pusb_device1 = container_of(pusb_interface->dev.parent, \
3030 struct usb_device, dev);
3031 if ((struct usb_device *)NULL == pusb_device1) {
3032 SAY("ERROR: pusb_device1 is NULL\n");
3035 pusb_device = usb_get_dev(pusb_device1);
3036 if ((struct usb_device *)NULL == pusb_device) {
3037 SAY("ERROR: pusb_device is NULL\n");
3040 if ((unsigned long int)pusb_device1 != (unsigned long int)pusb_device) {
3041 JOT(4, "ERROR: pusb_device1 != pusb_device\n");
3045 JOT(4, "bNumConfigurations=%i\n", pusb_device->descriptor.bNumConfigurations);
3047 /*---------------------------------------------------------------------------*/
3048 pusb_host_interface = pusb_interface->cur_altsetting;
3049 if (NULL == pusb_host_interface) {
3050 SAY("ERROR: pusb_host_interface is NULL\n");
3053 pusb_interface_descriptor = &(pusb_host_interface->desc);
3054 if (NULL == pusb_interface_descriptor) {
3055 SAY("ERROR: pusb_interface_descriptor is NULL\n");
3058 /*---------------------------------------------------------------------------*/
3060 * GET PROPERTIES OF PROBED INTERFACE
3062 /*---------------------------------------------------------------------------*/
3063 bInterfaceNumber = pusb_interface_descriptor->bInterfaceNumber;
3064 bInterfaceClass = pusb_interface_descriptor->bInterfaceClass;
3065 bInterfaceSubClass = pusb_interface_descriptor->bInterfaceSubClass;
3067 JOT(4, "intf[%i]: pusb_interface->num_altsetting=%i\n", \
3068 bInterfaceNumber, pusb_interface->num_altsetting);
3069 JOT(4, "intf[%i]: pusb_interface->cur_altsetting - " \
3070 "pusb_interface->altsetting=%li\n", bInterfaceNumber, \
3071 (long int)(pusb_interface->cur_altsetting - \
3072 pusb_interface->altsetting));
3073 switch (bInterfaceClass) {
3074 case USB_CLASS_AUDIO: {
3075 JOT(4, "intf[%i]: bInterfaceClass=0x%02X=USB_CLASS_AUDIO\n", \
3076 bInterfaceNumber, bInterfaceClass); break;
3078 case USB_CLASS_VIDEO: {
3079 JOT(4, "intf[%i]: bInterfaceClass=0x%02X=USB_CLASS_VIDEO\n", \
3080 bInterfaceNumber, bInterfaceClass); break;
3082 case USB_CLASS_VENDOR_SPEC: {
3083 JOT(4, "intf[%i]: bInterfaceClass=0x%02X=USB_CLASS_VENDOR_SPEC\n", \
3084 bInterfaceNumber, bInterfaceClass); break;
3089 switch (bInterfaceSubClass) {
3091 JOT(4, "intf[%i]: bInterfaceSubClass=0x%02X=AUDIOCONTROL\n", \
3092 bInterfaceNumber, bInterfaceSubClass); break;
3095 JOT(4, "intf[%i]: bInterfaceSubClass=0x%02X=AUDIOSTREAMING\n", \
3096 bInterfaceNumber, bInterfaceSubClass); break;
3099 JOT(4, "intf[%i]: bInterfaceSubClass=0x%02X=MIDISTREAMING\n", \
3100 bInterfaceNumber, bInterfaceSubClass); break;
3105 /*---------------------------------------------------------------------------*/
3106 pusb_interface_assoc_descriptor = pusb_interface->intf_assoc;
3107 if (NULL != pusb_interface_assoc_descriptor) {
3108 JOT(4, "intf[%i]: bFirstInterface=0x%02X bInterfaceCount=0x%02X\n", \
3110 pusb_interface_assoc_descriptor->bFirstInterface, \
3111 pusb_interface_assoc_descriptor->bInterfaceCount);
3113 JOT(4, "intf[%i]: pusb_interface_assoc_descriptor is NULL\n", \
3116 /*---------------------------------------------------------------------------*/
3118 * A NEW struct easycap IS ALWAYS ALLOCATED WHEN INTERFACE 0 IS PROBED.
3119 * IT IS NOT POSSIBLE HERE TO FREE ANY EXISTING struct easycap. THIS
3120 * SHOULD HAVE BEEN DONE BY easycap_delete() WHEN THE DEVICE WAS PHYSICALLY
3123 /*---------------------------------------------------------------------------*/
3124 if (0 == bInterfaceNumber) {
3125 peasycap = kzalloc(sizeof(struct easycap), GFP_KERNEL);
3126 if (NULL == peasycap) {
3127 SAY("ERROR: Could not allocate peasycap\n");
3130 peasycap->allocation_video_struct = sizeof(struct easycap);
3131 peasycap->allocation_video_page = 0;
3132 peasycap->allocation_video_urb = 0;
3133 peasycap->allocation_audio_struct = 0;
3134 peasycap->allocation_audio_page = 0;
3135 peasycap->allocation_audio_urb = 0;
3137 /*---------------------------------------------------------------------------*/
3139 * INITIALIZE THE NEW easycap STRUCTURE.
3140 * NO PARAMETERS ARE SPECIFIED HERE REQUIRING THE SETTING OF REGISTERS.
3141 * THAT IS DONE FIRST BY easycap_open() AND LATER BY easycap_ioctl().
3143 /*---------------------------------------------------------------------------*/
3144 peasycap->pusb_device = pusb_device;
3145 peasycap->pusb_interface = pusb_interface;
3147 kref_init(&peasycap->kref);
3148 JOT(8, "intf[%i]: after kref_init(..._video) " \
3149 "%i=peasycap->kref.refcount.counter\n", \
3150 bInterfaceNumber, peasycap->kref.refcount.counter);
3152 init_waitqueue_head(&(peasycap->wq_video));
3153 init_waitqueue_head(&(peasycap->wq_audio));
3155 mutex_init(&(peasycap->mutex_timeval0));
3156 mutex_init(&(peasycap->mutex_timeval1));
3158 for (k = 0; k < FRAME_BUFFER_MANY; k++)
3159 mutex_init(&(peasycap->mutex_mmap_video[k]));
3162 peasycap->microphone = false;
3164 peasycap->video_interface = -1;
3165 peasycap->video_altsetting_on = -1;
3166 peasycap->video_altsetting_off = -1;
3167 peasycap->video_endpointnumber = -1;
3168 peasycap->video_isoc_maxframesize = -1;
3169 peasycap->video_isoc_buffer_size = -1;
3171 peasycap->audio_interface = -1;
3172 peasycap->audio_altsetting_on = -1;
3173 peasycap->audio_altsetting_off = -1;
3174 peasycap->audio_endpointnumber = -1;
3175 peasycap->audio_isoc_maxframesize = -1;
3176 peasycap->audio_isoc_buffer_size = -1;
3178 peasycap->frame_buffer_many = FRAME_BUFFER_MANY;
3180 if ((struct mutex *)NULL == &(peasycap->mutex_mmap_video[0])) {
3181 SAY("ERROR: &(peasycap->mutex_mmap_video[%i]) is NULL\n", 0);
3184 /*---------------------------------------------------------------------------*/
3186 * DYNAMICALLY FILL IN THE AVAILABLE FORMATS.
3188 /*---------------------------------------------------------------------------*/
3189 rc = fillin_formats();
3191 SAY("ERROR: fillin_formats() returned %i\n", rc);
3194 JOT(4, "%i formats available\n", rc);
3196 /*---------------------------------------------------------------------------*/
3197 if ((struct easycap *)NULL == peasycap) {
3198 SAY("ERROR: peasycap is NULL " \
3199 "when probing interface %i\n", \
3204 JOT(8, "kref_get() with %i=peasycap->kref.refcount.counter\n", \
3205 (int)peasycap->kref.refcount.counter);
3206 kref_get(&peasycap->kref);
3208 /*---------------------------------------------------------------------------*/
3209 if ((USB_CLASS_VIDEO == bInterfaceClass) || \
3210 (USB_CLASS_VENDOR_SPEC == bInterfaceClass)) {
3211 if (-1 == peasycap->video_interface) {
3212 peasycap->video_interface = bInterfaceNumber;
3213 JOT(4, "setting peasycap->video_interface=%i\n", \
3214 peasycap->video_interface);
3216 if (peasycap->video_interface != bInterfaceNumber) {
3217 SAY("ERROR: attempting to reset " \
3218 "peasycap->video_interface\n");
3219 SAY("...... continuing with " \
3220 "%i=peasycap->video_interface\n", \
3221 peasycap->video_interface);
3224 } else if ((USB_CLASS_AUDIO == bInterfaceClass) && \
3225 (0x02 == bInterfaceSubClass)) {
3226 if (-1 == peasycap->audio_interface) {
3227 peasycap->audio_interface = bInterfaceNumber;
3228 JOT(4, "setting peasycap->audio_interface=%i\n", \
3229 peasycap->audio_interface);
3231 if (peasycap->audio_interface != bInterfaceNumber) {
3232 SAY("ERROR: attempting to reset " \
3233 "peasycap->audio_interface\n");
3234 SAY("...... continuing with " \
3235 "%i=peasycap->audio_interface\n", \
3236 peasycap->audio_interface);
3240 /*---------------------------------------------------------------------------*/
3242 * INVESTIGATE ALL ALTSETTINGS.
3243 * DONE IN DETAIL BECAUSE USB DEVICE 05e1:0408 HAS DISPARATE INCARNATIONS.
3245 /*---------------------------------------------------------------------------*/
3250 for (i = 0; i < pusb_interface->num_altsetting; i++) {
3251 pusb_host_interface = &(pusb_interface->altsetting[i]);
3252 if ((struct usb_host_interface *)NULL == pusb_host_interface) {
3253 SAY("ERROR: pusb_host_interface is NULL\n");
3256 pusb_interface_descriptor = &(pusb_host_interface->desc);
3257 if ((struct usb_interface_descriptor *)NULL == \
3258 pusb_interface_descriptor) {
3259 SAY("ERROR: pusb_interface_descriptor is NULL\n");
3263 JOT(4, "intf[%i]alt[%i]: desc.bDescriptorType=0x%02X\n", \
3264 bInterfaceNumber, i, pusb_interface_descriptor->bDescriptorType);
3265 JOT(4, "intf[%i]alt[%i]: desc.bInterfaceNumber=0x%02X\n", \
3266 bInterfaceNumber, i, pusb_interface_descriptor->bInterfaceNumber);
3267 JOT(4, "intf[%i]alt[%i]: desc.bAlternateSetting=0x%02X\n", \
3268 bInterfaceNumber, i, pusb_interface_descriptor->bAlternateSetting);
3269 JOT(4, "intf[%i]alt[%i]: desc.bNumEndpoints=0x%02X\n", \
3270 bInterfaceNumber, i, pusb_interface_descriptor->bNumEndpoints);
3271 JOT(4, "intf[%i]alt[%i]: desc.bInterfaceClass=0x%02X\n", \
3272 bInterfaceNumber, i, pusb_interface_descriptor->bInterfaceClass);
3273 JOT(4, "intf[%i]alt[%i]: desc.bInterfaceSubClass=0x%02X\n", \
3274 bInterfaceNumber, i, pusb_interface_descriptor->bInterfaceSubClass);
3275 JOT(4, "intf[%i]alt[%i]: desc.bInterfaceProtocol=0x%02X\n", \
3276 bInterfaceNumber, i, pusb_interface_descriptor->bInterfaceProtocol);
3277 JOT(4, "intf[%i]alt[%i]: desc.iInterface=0x%02X\n", \
3278 bInterfaceNumber, i, pusb_interface_descriptor->iInterface);
3280 ISOCwMaxPacketSize = -1;
3281 BULKwMaxPacketSize = -1;
3282 INTwMaxPacketSize = -1;
3283 CTRLwMaxPacketSize = -1;
3284 ISOCbEndpointAddress = 0;
3285 INTbEndpointAddress = 0;
3287 if (0 == pusb_interface_descriptor->bNumEndpoints)
3288 JOT(4, "intf[%i]alt[%i] has no endpoints\n", \
3289 bInterfaceNumber, i);
3290 /*---------------------------------------------------------------------------*/
3291 for (j = 0; j < pusb_interface_descriptor->bNumEndpoints; j++) {
3292 pepd = &(pusb_host_interface->endpoint[j].desc);
3293 if ((struct usb_endpoint_descriptor *)NULL == pepd) {
3294 SAY("ERROR: pepd is NULL.\n");
3295 SAY("...... skipping\n");
3298 wMaxPacketSize = le16_to_cpu(pepd->wMaxPacketSize);
3299 bEndpointAddress = pepd->bEndpointAddress;
3301 JOT(4, "intf[%i]alt[%i]end[%i]: bEndpointAddress=0x%X\n", \
3302 bInterfaceNumber, i, j, \
3303 pepd->bEndpointAddress);
3304 JOT(4, "intf[%i]alt[%i]end[%i]: bmAttributes=0x%X\n", \
3305 bInterfaceNumber, i, j, \
3306 pepd->bmAttributes);
3307 JOT(4, "intf[%i]alt[%i]end[%i]: wMaxPacketSize=%i\n", \
3308 bInterfaceNumber, i, j, \
3309 pepd->wMaxPacketSize);
3310 JOT(4, "intf[%i]alt[%i]end[%i]: bInterval=%i\n",
3311 bInterfaceNumber, i, j, \
3314 if (pepd->bEndpointAddress & USB_DIR_IN) {
3315 JOT(4, "intf[%i]alt[%i]end[%i] is an IN endpoint\n",\
3316 bInterfaceNumber, i, j);
3319 JOT(4, "intf[%i]alt[%i]end[%i] is an OUT endpoint\n",\
3320 bInterfaceNumber, i, j);
3321 SAY("ERROR: OUT endpoint unexpected\n");
3322 SAY("...... continuing\n");
3325 if ((pepd->bmAttributes & \
3326 USB_ENDPOINT_XFERTYPE_MASK) == \
3327 USB_ENDPOINT_XFER_ISOC) {
3328 JOT(4, "intf[%i]alt[%i]end[%i] is an ISOC endpoint\n",\
3329 bInterfaceNumber, i, j);
3331 switch (bInterfaceClass) {
3332 case USB_CLASS_VIDEO:
3333 case USB_CLASS_VENDOR_SPEC: {
3336 "peasycap is NULL\n");
3339 if (pepd->wMaxPacketSize) {
3351 bEndpointAddress & \
3370 if (-1 == peasycap->\
3371 video_altsetting_off) {
3373 video_altsetting_off =\
3375 JOT(4, "%i=video_" \
3379 video_altsetting_off);
3381 SAY("ERROR: peasycap" \
3382 "->video_altsetting_" \
3383 "off already set\n");
3385 "continuing with " \
3386 "%i=peasycap->video_" \
3387 "altsetting_off\n", \
3389 video_altsetting_off);
3394 case USB_CLASS_AUDIO: {
3395 if (0x02 != bInterfaceSubClass)
3399 "peasycap is NULL\n");
3402 if (pepd->wMaxPacketSize) {
3404 okalt[isokalt] = i ;
3414 bEndpointAddress & \
3433 if (-1 == peasycap->\
3434 audio_altsetting_off) {
3436 audio_altsetting_off =\
3438 JOT(4, "%i=audio_" \
3442 audio_altsetting_off);
3444 SAY("ERROR: peasycap" \
3445 "->audio_altsetting_" \
3446 "off already set\n");
3448 "continuing with " \
3450 audio_altsetting_" \
3453 audio_altsetting_off);
3462 } else if ((pepd->bmAttributes & \
3463 USB_ENDPOINT_XFERTYPE_MASK) ==\
3464 USB_ENDPOINT_XFER_BULK) {
3465 JOT(4, "intf[%i]alt[%i]end[%i] is a BULK endpoint\n",\
3466 bInterfaceNumber, i, j);
3467 } else if ((pepd->bmAttributes & \
3468 USB_ENDPOINT_XFERTYPE_MASK) ==\
3469 USB_ENDPOINT_XFER_INT) {
3470 JOT(4, "intf[%i]alt[%i]end[%i] is an INT endpoint\n",\
3471 bInterfaceNumber, i, j);
3473 JOT(4, "intf[%i]alt[%i]end[%i] is a CTRL endpoint\n",\
3474 bInterfaceNumber, i, j);
3476 if (0 == pepd->wMaxPacketSize) {
3477 JOT(4, "intf[%i]alt[%i]end[%i] " \
3478 "has zero packet size\n", \
3479 bInterfaceNumber, i, j);
3483 /*---------------------------------------------------------------------------*/
3485 * PERFORM INITIALIZATION OF THE PROBED INTERFACE
3487 /*---------------------------------------------------------------------------*/
3488 JOT(4, "initialization begins for interface %i\n", \
3489 pusb_interface_descriptor->bInterfaceNumber);
3490 switch (bInterfaceNumber) {
3491 /*---------------------------------------------------------------------------*/
3493 * INTERFACE 0 IS THE VIDEO INTERFACE
3495 /*---------------------------------------------------------------------------*/
3498 SAY("MISTAKE: peasycap is NULL\n");
3502 SAY("ERROR: no viable video_altsetting_on\n");
3505 peasycap->video_altsetting_on = okalt[isokalt - 1];
3506 JOT(4, "%i=video_altsetting_on <====\n", \
3507 peasycap->video_altsetting_on);
3510 SAY("ERROR: no viable video_endpointnumber\n");
3513 peasycap->video_endpointnumber = okepn[isokepn - 1];
3514 JOT(4, "%i=video_endpointnumber\n", \
3515 peasycap->video_endpointnumber);
3518 SAY("ERROR: no viable video_maxpacketsize\n");
3520 /*---------------------------------------------------------------------------*/
3522 * DECIDE THE VIDEO STREAMING PARAMETERS
3524 /*---------------------------------------------------------------------------*/
3526 maxpacketsize = okmps[isokmps - 1] - 1024;
3527 if (USB_2_0_MAXPACKETSIZE > maxpacketsize) {
3528 peasycap->video_isoc_maxframesize = maxpacketsize;
3530 peasycap->video_isoc_maxframesize = \
3531 USB_2_0_MAXPACKETSIZE;
3533 JOT(4, "%i=video_isoc_maxframesize\n", \
3534 peasycap->video_isoc_maxframesize);
3535 if (0 >= peasycap->video_isoc_maxframesize) {
3536 SAY("ERROR: bad video_isoc_maxframesize\n");
3539 peasycap->video_isoc_framesperdesc = VIDEO_ISOC_FRAMESPERDESC;
3540 JOT(4, "%i=video_isoc_framesperdesc\n", \
3541 peasycap->video_isoc_framesperdesc);
3542 if (0 >= peasycap->video_isoc_framesperdesc) {
3543 SAY("ERROR: bad video_isoc_framesperdesc\n");
3546 peasycap->video_isoc_buffer_size = \
3547 peasycap->video_isoc_maxframesize * \
3548 peasycap->video_isoc_framesperdesc;
3549 JOT(4, "%i=video_isoc_buffer_size\n", \
3550 peasycap->video_isoc_buffer_size);
3551 if ((PAGE_SIZE << VIDEO_ISOC_ORDER) < \
3552 peasycap->video_isoc_buffer_size) {
3554 "peasycap->video_isoc_buffer_size too big\n");
3558 /*---------------------------------------------------------------------------*/
3559 if (-1 == peasycap->video_interface) {
3560 SAY("MISTAKE: video_interface is unset\n");
3563 if (-1 == peasycap->video_altsetting_on) {
3564 SAY("MISTAKE: video_altsetting_on is unset\n");
3567 if (-1 == peasycap->video_altsetting_off) {
3568 SAY("MISTAKE: video_interface_off is unset\n");
3571 if (-1 == peasycap->video_endpointnumber) {
3572 SAY("MISTAKE: video_endpointnumber is unset\n");
3575 if (-1 == peasycap->video_isoc_maxframesize) {
3576 SAY("MISTAKE: video_isoc_maxframesize is unset\n");
3579 if (-1 == peasycap->video_isoc_buffer_size) {
3580 SAY("MISTAKE: video_isoc_buffer_size is unset\n");
3583 /*---------------------------------------------------------------------------*/
3585 * ALLOCATE MEMORY FOR VIDEO BUFFERS. LISTS MUST BE INITIALIZED FIRST.
3587 /*---------------------------------------------------------------------------*/
3588 INIT_LIST_HEAD(&(peasycap->urb_video_head));
3589 peasycap->purb_video_head = &(peasycap->urb_video_head);
3590 /*---------------------------------------------------------------------------*/
3591 JOT(4, "allocating %i frame buffers of size %li\n", \
3592 FRAME_BUFFER_MANY, (long int)FRAME_BUFFER_SIZE);
3593 JOT(4, ".... each scattered over %li pages\n", \
3594 FRAME_BUFFER_SIZE/PAGE_SIZE);
3596 for (k = 0; k < FRAME_BUFFER_MANY; k++) {
3597 for (m = 0; m < FRAME_BUFFER_SIZE/PAGE_SIZE; m++) {
3598 if ((void *)NULL != peasycap->frame_buffer[k][m].pgo)
3599 SAY("attempting to reallocate frame " \
3602 pbuf = (void *)__get_free_page(GFP_KERNEL);
3603 if ((void *)NULL == pbuf) {
3604 SAY("ERROR: Could not allocate frame "\
3605 "buffer %i page %i\n", k, m);
3608 peasycap->allocation_video_page += 1;
3609 peasycap->frame_buffer[k][m].pgo = pbuf;
3611 peasycap->frame_buffer[k][m].pto = \
3612 peasycap->frame_buffer[k][m].pgo;
3616 peasycap->frame_fill = 0;
3617 peasycap->frame_read = 0;
3618 JOT(4, "allocation of frame buffers done: %i pages\n", k * \
3620 /*---------------------------------------------------------------------------*/
3621 JOT(4, "allocating %i field buffers of size %li\n", \
3622 FIELD_BUFFER_MANY, (long int)FIELD_BUFFER_SIZE);
3623 JOT(4, ".... each scattered over %li pages\n", \
3624 FIELD_BUFFER_SIZE/PAGE_SIZE);
3626 for (k = 0; k < FIELD_BUFFER_MANY; k++) {
3627 for (m = 0; m < FIELD_BUFFER_SIZE/PAGE_SIZE; m++) {
3628 if ((void *)NULL != peasycap->field_buffer[k][m].pgo) {
3629 SAY("ERROR: attempting to reallocate " \
3632 pbuf = (void *) __get_free_page(GFP_KERNEL);
3633 if ((void *)NULL == pbuf) {
3634 SAY("ERROR: Could not allocate field" \
3635 " buffer %i page %i\n", k, m);
3639 peasycap->allocation_video_page += 1;
3640 peasycap->field_buffer[k][m].pgo = pbuf;
3642 peasycap->field_buffer[k][m].pto = \
3643 peasycap->field_buffer[k][m].pgo;
3645 peasycap->field_buffer[k][0].kount = 0x0200;
3647 peasycap->field_fill = 0;
3648 peasycap->field_page = 0;
3649 peasycap->field_read = 0;
3650 JOT(4, "allocation of field buffers done: %i pages\n", k * \
3652 /*---------------------------------------------------------------------------*/
3653 JOT(4, "allocating %i isoc video buffers of size %i\n", \
3654 VIDEO_ISOC_BUFFER_MANY, \
3655 peasycap->video_isoc_buffer_size);
3656 JOT(4, ".... each occupying contiguous memory pages\n");
3658 for (k = 0; k < VIDEO_ISOC_BUFFER_MANY; k++) {
3659 pbuf = (void *)__get_free_pages(GFP_KERNEL, VIDEO_ISOC_ORDER);
3661 SAY("ERROR: Could not allocate isoc video buffer " \
3665 peasycap->allocation_video_page += \
3666 ((unsigned int)(0x01 << VIDEO_ISOC_ORDER));
3668 peasycap->video_isoc_buffer[k].pgo = pbuf;
3669 peasycap->video_isoc_buffer[k].pto = pbuf + \
3670 peasycap->video_isoc_buffer_size;
3671 peasycap->video_isoc_buffer[k].kount = k;
3673 JOT(4, "allocation of isoc video buffers done: %i pages\n", \
3674 k * (0x01 << VIDEO_ISOC_ORDER));
3675 /*---------------------------------------------------------------------------*/
3677 * ALLOCATE AND INITIALIZE MULTIPLE struct urb ...
3679 /*---------------------------------------------------------------------------*/
3680 JOT(4, "allocating %i struct urb.\n", VIDEO_ISOC_BUFFER_MANY);
3681 JOT(4, "using %i=peasycap->video_isoc_framesperdesc\n", \
3682 peasycap->video_isoc_framesperdesc);
3683 JOT(4, "using %i=peasycap->video_isoc_maxframesize\n", \
3684 peasycap->video_isoc_maxframesize);
3685 JOT(4, "using %i=peasycap->video_isoc_buffer_sizen", \
3686 peasycap->video_isoc_buffer_size);
3688 for (k = 0; k < VIDEO_ISOC_BUFFER_MANY; k++) {
3689 purb = usb_alloc_urb(peasycap->video_isoc_framesperdesc, \
3692 SAY("ERROR: usb_alloc_urb returned NULL for buffer " \
3696 peasycap->allocation_video_urb += 1;
3697 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
3698 pdata_urb = kzalloc(sizeof(struct data_urb), GFP_KERNEL);
3699 if (NULL == pdata_urb) {
3700 SAY("ERROR: Could not allocate struct data_urb.\n");
3703 peasycap->allocation_video_struct += \
3704 sizeof(struct data_urb);
3706 pdata_urb->purb = purb;
3707 pdata_urb->isbuf = k;
3708 pdata_urb->length = 0;
3709 list_add_tail(&(pdata_urb->list_head), \
3710 peasycap->purb_video_head);
3711 /*---------------------------------------------------------------------------*/
3713 * ... AND INITIALIZE THEM
3715 /*---------------------------------------------------------------------------*/
3717 JOT(4, "initializing video urbs thus:\n");
3718 JOT(4, " purb->interval = 1;\n");
3719 JOT(4, " purb->dev = peasycap->pusb_device;\n");
3720 JOT(4, " purb->pipe = usb_rcvisocpipe" \
3721 "(peasycap->pusb_device,%i);\n", \
3722 peasycap->video_endpointnumber);
3723 JOT(4, " purb->transfer_flags = URB_ISO_ASAP;\n");
3724 JOT(4, " purb->transfer_buffer = peasycap->" \
3725 "video_isoc_buffer[.].pgo;\n");
3726 JOT(4, " purb->transfer_buffer_length = %i;\n", \
3727 peasycap->video_isoc_buffer_size);
3728 JOT(4, " purb->complete = easycap_complete;\n");
3729 JOT(4, " purb->context = peasycap;\n");
3730 JOT(4, " purb->start_frame = 0;\n");
3731 JOT(4, " purb->number_of_packets = %i;\n", \
3732 peasycap->video_isoc_framesperdesc);
3733 JOT(4, " for (j = 0; j < %i; j++)\n", \
3734 peasycap->video_isoc_framesperdesc);
3736 JOT(4, " purb->iso_frame_desc[j].offset = j*%i;\n",\
3737 peasycap->video_isoc_maxframesize);
3738 JOT(4, " purb->iso_frame_desc[j].length = %i;\n", \
3739 peasycap->video_isoc_maxframesize);
3744 purb->dev = peasycap->pusb_device;
3745 purb->pipe = usb_rcvisocpipe(peasycap->pusb_device, \
3746 peasycap->video_endpointnumber);
3747 purb->transfer_flags = URB_ISO_ASAP;
3748 purb->transfer_buffer = peasycap->video_isoc_buffer[k].pgo;
3749 purb->transfer_buffer_length = \
3750 peasycap->video_isoc_buffer_size;
3751 purb->complete = easycap_complete;
3752 purb->context = peasycap;
3753 purb->start_frame = 0;
3754 purb->number_of_packets = peasycap->video_isoc_framesperdesc;
3755 for (j = 0; j < peasycap->video_isoc_framesperdesc; j++) {
3756 purb->iso_frame_desc[j].offset = j * \
3757 peasycap->video_isoc_maxframesize;
3758 purb->iso_frame_desc[j].length = \
3759 peasycap->video_isoc_maxframesize;
3762 JOT(4, "allocation of %i struct urb done.\n", k);
3763 /*--------------------------------------------------------------------------*/
3765 * SAVE POINTER peasycap IN THIS INTERFACE.
3767 /*--------------------------------------------------------------------------*/
3768 usb_set_intfdata(pusb_interface, peasycap);
3769 /*--------------------------------------------------------------------------*/
3771 * THE VIDEO DEVICE CAN BE REGISTERED NOW, AS IT IS READY.
3773 /*--------------------------------------------------------------------------*/
3774 #if (!defined(EASYCAP_IS_VIDEODEV_CLIENT))
3775 if (0 != (usb_register_dev(pusb_interface, &easycap_class))) {
3776 err("Not able to get a minor for this device");
3777 usb_set_intfdata(pusb_interface, NULL);
3780 (peasycap->registered_video)++;
3781 SAY("easycap attached to minor #%d\n", pusb_interface->minor);
3783 /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
3785 pvideo_device = (struct video_device *)\
3786 kzalloc(sizeof(struct video_device), GFP_KERNEL);
3787 if ((struct video_device *)NULL == pvideo_device) {
3788 SAY("ERROR: Could not allocate structure video_device\n");
3791 if (VIDEO_DEVICE_MANY <= video_device_many) {
3792 SAY("ERROR: Too many /dev/videos\n");
3795 pvideo_array[video_device_many] = pvideo_device; video_device_many++;
3797 strcpy(&pvideo_device->name[0], "easycapdc60");
3798 #if defined(EASYCAP_NEEDS_V4L2_FOPS)
3799 pvideo_device->fops = &v4l2_fops;
3801 pvideo_device->fops = &easycap_fops;
3802 #endif /*EASYCAP_NEEDS_V4L2_FOPS*/
3803 pvideo_device->minor = -1;
3804 pvideo_device->release = (void *)(&videodev_release);
3806 video_set_drvdata(pvideo_device, (void *)peasycap);
3808 rc = video_register_device(pvideo_device, VFL_TYPE_GRABBER, -1);
3810 err("Not able to register with videodev");
3811 videodev_release(pvideo_device);
3814 peasycap->pvideo_device = pvideo_device;
3815 (peasycap->registered_video)++;
3816 JOT(4, "registered with videodev: %i=minor\n", \
3817 pvideo_device->minor);
3819 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
3820 #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
3823 /*--------------------------------------------------------------------------*/
3825 * INTERFACE 1 IS THE AUDIO CONTROL INTERFACE
3826 * INTERFACE 2 IS THE AUDIO STREAMING INTERFACE
3828 /*--------------------------------------------------------------------------*/
3830 /*--------------------------------------------------------------------------*/
3832 * SAVE POINTER peasycap IN INTERFACE 1
3834 /*--------------------------------------------------------------------------*/
3835 usb_set_intfdata(pusb_interface, peasycap);
3836 JOT(4, "no initialization required for interface %i\n", \
3837 pusb_interface_descriptor->bInterfaceNumber);
3840 /*--------------------------------------------------------------------------*/
3843 SAY("MISTAKE: peasycap is NULL\n");
3847 SAY("ERROR: no viable audio_altsetting_on\n");
3850 peasycap->audio_altsetting_on = okalt[isokalt - 1];
3851 JOT(4, "%i=audio_altsetting_on <====\n", \
3852 peasycap->audio_altsetting_on);
3855 SAY("ERROR: no viable audio_endpointnumber\n");
3858 peasycap->audio_endpointnumber = okepn[isokepn - 1];
3859 JOT(4, "%i=audio_endpointnumber\n", \
3860 peasycap->audio_endpointnumber);
3863 SAY("ERROR: no viable audio_maxpacketsize\n");
3866 peasycap->audio_isoc_maxframesize = okmps[isokmps - 1];
3867 JOT(4, "%i=audio_isoc_maxframesize\n", \
3868 peasycap->audio_isoc_maxframesize);
3869 if (0 >= peasycap->audio_isoc_maxframesize) {
3870 SAY("ERROR: bad audio_isoc_maxframesize\n");
3873 if (9 == peasycap->audio_isoc_maxframesize) {
3874 peasycap->ilk |= 0x02;
3875 SAY("hardware is FOUR-CVBS\n");
3876 peasycap->microphone = true;
3877 peasycap->audio_pages_per_fragment = 4;
3878 } else if (256 == peasycap->audio_isoc_maxframesize) {
3879 peasycap->ilk &= ~0x02;
3880 SAY("hardware is CVBS+S-VIDEO\n");
3881 peasycap->microphone = false;
3882 peasycap->audio_pages_per_fragment = 4;
3884 SAY("hardware is unidentified:\n");
3885 SAY("%i=audio_isoc_maxframesize\n", \
3886 peasycap->audio_isoc_maxframesize);
3890 peasycap->audio_bytes_per_fragment = \
3891 peasycap->audio_pages_per_fragment * \
3893 peasycap->audio_buffer_page_many = (AUDIO_FRAGMENT_MANY * \
3894 peasycap->audio_pages_per_fragment);
3896 JOT(4, "%6i=AUDIO_FRAGMENT_MANY\n", AUDIO_FRAGMENT_MANY);
3897 JOT(4, "%6i=audio_pages_per_fragment\n", \
3898 peasycap->audio_pages_per_fragment);
3899 JOT(4, "%6i=audio_bytes_per_fragment\n", \
3900 peasycap->audio_bytes_per_fragment);
3901 JOT(4, "%6i=audio_buffer_page_many\n", \
3902 peasycap->audio_buffer_page_many);
3904 peasycap->audio_isoc_framesperdesc = 128;
3906 JOT(4, "%i=audio_isoc_framesperdesc\n", \
3907 peasycap->audio_isoc_framesperdesc);
3908 if (0 >= peasycap->audio_isoc_framesperdesc) {
3909 SAY("ERROR: bad audio_isoc_framesperdesc\n");
3913 peasycap->audio_isoc_buffer_size = \
3914 peasycap->audio_isoc_maxframesize * \
3915 peasycap->audio_isoc_framesperdesc;
3916 JOT(4, "%i=audio_isoc_buffer_size\n", \
3917 peasycap->audio_isoc_buffer_size);
3918 if (AUDIO_ISOC_BUFFER_SIZE < \
3919 peasycap->audio_isoc_buffer_size) {
3920 SAY("MISTAKE: audio_isoc_buffer_size bigger "
3921 "than %li=AUDIO_ISOC_BUFFER_SIZE\n", \
3922 AUDIO_ISOC_BUFFER_SIZE);
3927 if (-1 == peasycap->audio_interface) {
3928 SAY("MISTAKE: audio_interface is unset\n");
3931 if (-1 == peasycap->audio_altsetting_on) {
3932 SAY("MISTAKE: audio_altsetting_on is unset\n");
3935 if (-1 == peasycap->audio_altsetting_off) {
3936 SAY("MISTAKE: audio_interface_off is unset\n");
3939 if (-1 == peasycap->audio_endpointnumber) {
3940 SAY("MISTAKE: audio_endpointnumber is unset\n");
3943 if (-1 == peasycap->audio_isoc_maxframesize) {
3944 SAY("MISTAKE: audio_isoc_maxframesize is unset\n");
3947 if (-1 == peasycap->audio_isoc_buffer_size) {
3948 SAY("MISTAKE: audio_isoc_buffer_size is unset\n");
3951 /*---------------------------------------------------------------------------*/
3953 * ALLOCATE MEMORY FOR AUDIO BUFFERS. LISTS MUST BE INITIALIZED FIRST.
3955 /*---------------------------------------------------------------------------*/
3956 INIT_LIST_HEAD(&(peasycap->urb_audio_head));
3957 peasycap->purb_audio_head = &(peasycap->urb_audio_head);
3959 JOT(4, "allocating an audio buffer\n");
3960 JOT(4, ".... scattered over %i pages\n", \
3961 peasycap->audio_buffer_page_many);
3963 for (k = 0; k < peasycap->audio_buffer_page_many; k++) {
3964 if ((void *)NULL != peasycap->audio_buffer[k].pgo) {
3965 SAY("ERROR: attempting to reallocate audio buffers\n");
3967 pbuf = (void *) __get_free_page(GFP_KERNEL);
3968 if ((void *)NULL == pbuf) {
3969 SAY("ERROR: Could not allocate audio " \
3970 "buffer page %i\n", k);
3973 peasycap->allocation_audio_page += 1;
3975 peasycap->audio_buffer[k].pgo = pbuf;
3977 peasycap->audio_buffer[k].pto = peasycap->audio_buffer[k].pgo;
3980 peasycap->audio_fill = 0;
3981 peasycap->audio_read = 0;
3982 JOT(4, "allocation of audio buffer done: %i pages\n", k);
3983 /*---------------------------------------------------------------------------*/
3984 JOT(4, "allocating %i isoc audio buffers of size %i\n", \
3985 AUDIO_ISOC_BUFFER_MANY, peasycap->audio_isoc_buffer_size);
3986 JOT(4, ".... each occupying contiguous memory pages\n");
3988 for (k = 0; k < AUDIO_ISOC_BUFFER_MANY; k++) {
3989 pbuf = (void *)__get_free_pages(GFP_KERNEL, AUDIO_ISOC_ORDER);
3991 SAY("ERROR: Could not allocate isoc audio buffer " \
3995 peasycap->allocation_audio_page += \
3996 ((unsigned int)(0x01 << AUDIO_ISOC_ORDER));
3998 peasycap->audio_isoc_buffer[k].pgo = pbuf;
3999 peasycap->audio_isoc_buffer[k].pto = pbuf + \
4000 peasycap->audio_isoc_buffer_size;
4001 peasycap->audio_isoc_buffer[k].kount = k;
4003 JOT(4, "allocation of isoc audio buffers done.\n");
4004 /*---------------------------------------------------------------------------*/
4006 * ALLOCATE AND INITIALIZE MULTIPLE struct urb ...
4008 /*---------------------------------------------------------------------------*/
4009 JOT(4, "allocating %i struct urb.\n", AUDIO_ISOC_BUFFER_MANY);
4010 JOT(4, "using %i=peasycap->audio_isoc_framesperdesc\n", \
4011 peasycap->audio_isoc_framesperdesc);
4012 JOT(4, "using %i=peasycap->audio_isoc_maxframesize\n", \
4013 peasycap->audio_isoc_maxframesize);
4014 JOT(4, "using %i=peasycap->audio_isoc_buffer_size\n", \
4015 peasycap->audio_isoc_buffer_size);
4017 for (k = 0; k < AUDIO_ISOC_BUFFER_MANY; k++) {
4018 purb = usb_alloc_urb(peasycap->audio_isoc_framesperdesc, \
4021 SAY("ERROR: usb_alloc_urb returned NULL for buffer " \
4025 peasycap->allocation_audio_urb += 1 ;
4026 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
4027 pdata_urb = kzalloc(sizeof(struct data_urb), GFP_KERNEL);
4028 if (NULL == pdata_urb) {
4029 SAY("ERROR: Could not allocate struct data_urb.\n");
4032 peasycap->allocation_audio_struct += \
4033 sizeof(struct data_urb);
4035 pdata_urb->purb = purb;
4036 pdata_urb->isbuf = k;
4037 pdata_urb->length = 0;
4038 list_add_tail(&(pdata_urb->list_head), \
4039 peasycap->purb_audio_head);
4040 /*---------------------------------------------------------------------------*/
4042 * ... AND INITIALIZE THEM
4044 /*---------------------------------------------------------------------------*/
4046 JOT(4, "initializing audio urbs thus:\n");
4047 JOT(4, " purb->interval = 1;\n");
4048 JOT(4, " purb->dev = peasycap->pusb_device;\n");
4049 JOT(4, " purb->pipe = usb_rcvisocpipe(peasycap->" \
4050 "pusb_device,%i);\n", \
4051 peasycap->audio_endpointnumber);
4052 JOT(4, " purb->transfer_flags = URB_ISO_ASAP;\n");
4053 JOT(4, " purb->transfer_buffer = " \
4054 "peasycap->audio_isoc_buffer[.].pgo;\n");
4055 JOT(4, " purb->transfer_buffer_length = %i;\n", \
4056 peasycap->audio_isoc_buffer_size);
4057 JOT(4, " purb->complete = easysnd_complete;\n");
4058 JOT(4, " purb->context = peasycap;\n");
4059 JOT(4, " purb->start_frame = 0;\n");
4060 JOT(4, " purb->number_of_packets = %i;\n", \
4061 peasycap->audio_isoc_framesperdesc);
4062 JOT(4, " for (j = 0; j < %i; j++)\n", \
4063 peasycap->audio_isoc_framesperdesc);
4065 JOT(4, " purb->iso_frame_desc[j].offset = j*%i;\n",\
4066 peasycap->audio_isoc_maxframesize);
4067 JOT(4, " purb->iso_frame_desc[j].length = %i;\n", \
4068 peasycap->audio_isoc_maxframesize);
4073 purb->dev = peasycap->pusb_device;
4074 purb->pipe = usb_rcvisocpipe(peasycap->pusb_device, \
4075 peasycap->audio_endpointnumber);
4076 purb->transfer_flags = URB_ISO_ASAP;
4077 purb->transfer_buffer = peasycap->audio_isoc_buffer[k].pgo;
4078 purb->transfer_buffer_length = \
4079 peasycap->audio_isoc_buffer_size;
4080 purb->complete = easysnd_complete;
4081 purb->context = peasycap;
4082 purb->start_frame = 0;
4083 purb->number_of_packets = peasycap->audio_isoc_framesperdesc;
4084 for (j = 0; j < peasycap->audio_isoc_framesperdesc; j++) {
4085 purb->iso_frame_desc[j].offset = j * \
4086 peasycap->audio_isoc_maxframesize;
4087 purb->iso_frame_desc[j].length = \
4088 peasycap->audio_isoc_maxframesize;
4091 JOT(4, "allocation of %i struct urb done.\n", k);
4092 /*---------------------------------------------------------------------------*/
4094 * SAVE POINTER peasycap IN THIS INTERFACE.
4096 /*---------------------------------------------------------------------------*/
4097 usb_set_intfdata(pusb_interface, peasycap);
4098 /*---------------------------------------------------------------------------*/
4100 * THE AUDIO DEVICE CAN BE REGISTERED NOW, AS IT IS READY.
4102 /*---------------------------------------------------------------------------*/
4103 rc = usb_register_dev(pusb_interface, &easysnd_class);
4105 err("Not able to get a minor for this device.");
4106 usb_set_intfdata(pusb_interface, NULL);
4109 (peasycap->registered_audio)++;
4110 /*---------------------------------------------------------------------------*/
4112 * LET THE USER KNOW WHAT NODE THE AUDIO DEVICE IS ATTACHED TO.
4114 /*---------------------------------------------------------------------------*/
4115 SAY("easysnd attached to minor #%d\n", pusb_interface->minor);
4118 /*---------------------------------------------------------------------------*/
4120 * INTERFACES OTHER THAN 0, 1 AND 2 ARE UNEXPECTED
4122 /*---------------------------------------------------------------------------*/
4124 JOT(4, "ERROR: unexpected interface %i\n", bInterfaceNumber);
4128 JOT(4, "ends successfully for interface %i\n", \
4129 pusb_interface_descriptor->bInterfaceNumber);
4132 /*****************************************************************************/
4133 /*---------------------------------------------------------------------------*/
4135 * WHEN THIS FUNCTION IS CALLED THE DEVICE HAS ALREADY BEEN PHYSICALLY
4137 * HENCE peasycap->pusb_device IS NO LONGER VALID AND MUST BE SET TO NULL.
4139 /*---------------------------------------------------------------------------*/
4141 easycap_usb_disconnect(struct usb_interface *pusb_interface)
4143 struct usb_host_interface *pusb_host_interface;
4144 struct usb_interface_descriptor *pusb_interface_descriptor;
4145 __u8 bInterfaceNumber;
4146 struct easycap *peasycap;
4148 struct list_head *plist_head;
4149 struct data_urb *pdata_urb;
4154 if ((struct usb_interface *)NULL == pusb_interface) {
4155 JOT(4, "ERROR: pusb_interface is NULL\n");
4158 pusb_host_interface = pusb_interface->cur_altsetting;
4159 if ((struct usb_host_interface *)NULL == pusb_host_interface) {
4160 JOT(4, "ERROR: pusb_host_interface is NULL\n");
4163 pusb_interface_descriptor = &(pusb_host_interface->desc);
4164 if ((struct usb_interface_descriptor *)NULL == pusb_interface_descriptor) {
4165 JOT(4, "ERROR: pusb_interface_descriptor is NULL\n");
4168 bInterfaceNumber = pusb_interface_descriptor->bInterfaceNumber;
4169 minor = pusb_interface->minor;
4170 JOT(4, "intf[%i]: minor=%i\n", bInterfaceNumber, minor);
4172 peasycap = usb_get_intfdata(pusb_interface);
4173 if ((struct easycap *)NULL == peasycap)
4174 SAY("ERROR: peasycap is NULL\n");
4176 peasycap->pusb_device = (struct usb_device *)NULL;
4177 switch (bInterfaceNumber) {
4178 /*---------------------------------------------------------------------------*/
4180 if ((struct list_head *)NULL != peasycap->purb_video_head) {
4181 JOT(4, "killing video urbs\n");
4183 list_for_each(plist_head, (peasycap->purb_video_head))
4185 pdata_urb = list_entry(plist_head, \
4186 struct data_urb, list_head);
4187 if ((struct data_urb *)NULL != pdata_urb) {
4188 if ((struct urb *)NULL != \
4190 usb_kill_urb(pdata_urb->purb);
4195 JOT(4, "%i video urbs killed\n", m);
4197 SAY("ERROR: peasycap->purb_video_head is NULL\n");
4200 /*---------------------------------------------------------------------------*/
4202 if ((struct list_head *)NULL != peasycap->purb_audio_head) {
4203 JOT(4, "killing audio urbs\n");
4205 list_for_each(plist_head, \
4206 (peasycap->purb_audio_head)) {
4207 pdata_urb = list_entry(plist_head, \
4208 struct data_urb, list_head);
4209 if ((struct data_urb *)NULL != pdata_urb) {
4210 if ((struct urb *)NULL != \
4212 usb_kill_urb(pdata_urb->purb);
4217 JOT(4, "%i audio urbs killed\n", m);
4219 SAY("ERROR: peasycap->purb_audio_head is NULL\n");
4222 /*---------------------------------------------------------------------------*/
4227 /*--------------------------------------------------------------------------*/
4231 /*--------------------------------------------------------------------------*/
4232 switch (bInterfaceNumber) {
4234 #if (!defined(EASYCAP_IS_VIDEODEV_CLIENT))
4235 if ((struct easycap *)NULL == peasycap) {
4236 SAY("ERROR: peasycap has become NULL\n");
4239 usb_deregister_dev(pusb_interface, &easycap_class);
4240 (peasycap->registered_video)--;
4242 JOT(4, "intf[%i]: usb_deregister_dev()\n", bInterfaceNumber);
4244 SAY("easycap detached from minor #%d\n", minor);
4246 /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
4248 if ((struct easycap *)NULL == peasycap)
4249 SAY("ERROR: peasycap has become NULL\n");
4252 video_unregister_device(peasycap->pvideo_device);
4253 (peasycap->registered_video)--;
4255 JOT(4, "unregistered with videodev: %i=minor\n", \
4256 pvideo_device->minor);
4258 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
4259 #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
4265 usb_deregister_dev(pusb_interface, &easysnd_class);
4266 if ((struct easycap *)NULL != peasycap)
4267 (peasycap->registered_audio)--;
4269 JOT(4, "intf[%i]: usb_deregister_dev()\n", bInterfaceNumber);
4272 SAY("easysnd detached from minor #%d\n", minor);
4278 /*---------------------------------------------------------------------------*/
4280 * CALL easycap_delete() IF NO REMAINING REFERENCES TO peasycap
4282 /*---------------------------------------------------------------------------*/
4283 if ((struct easycap *)NULL == peasycap) {
4284 SAY("ERROR: peasycap has become NULL\n");
4285 SAY("cannot call kref_put()\n");
4286 SAY("ending unsuccessfully: may cause memory leak\n");
4289 if (!peasycap->kref.refcount.counter) {
4290 SAY("ERROR: peasycap->kref.refcount.counter is zero " \
4291 "so cannot call kref_put()\n");
4292 SAY("ending unsuccessfully: may cause memory leak\n");
4295 JOT(4, "intf[%i]: kref_put() with %i=peasycap->kref.refcount.counter\n", \
4296 bInterfaceNumber, (int)peasycap->kref.refcount.counter);
4297 kref_put(&peasycap->kref, easycap_delete);
4298 JOT(4, "intf[%i]: kref_put() done.\n", bInterfaceNumber);
4299 /*---------------------------------------------------------------------------*/
4304 /*****************************************************************************/
4306 easycap_module_init(void)
4310 SAY("========easycap=======\n");
4311 JOT(4, "begins. %i=debug\n", easycap_debug);
4312 SAY("version: " EASYCAP_DRIVER_VERSION "\n");
4313 /*---------------------------------------------------------------------------*/
4315 * REGISTER THIS DRIVER WITH THE USB SUBSYTEM.
4317 /*---------------------------------------------------------------------------*/
4318 JOT(4, "registering driver easycap\n");
4320 result = usb_register(&easycap_usb_driver);
4322 SAY("ERROR: usb_register returned %i\n", result);
4327 /*****************************************************************************/
4329 easycap_module_exit(void)
4333 /*---------------------------------------------------------------------------*/
4335 * DEREGISTER THIS DRIVER WITH THE USB SUBSYTEM.
4337 /*---------------------------------------------------------------------------*/
4338 usb_deregister(&easycap_usb_driver);
4342 /*****************************************************************************/
4344 module_init(easycap_module_init);
4345 module_exit(easycap_module_exit);
4347 MODULE_LICENSE("GPL");
4348 MODULE_AUTHOR("R.M. Thomas <rmthomas@sciolus.org>");
4349 MODULE_DESCRIPTION(EASYCAP_DRIVER_DESCRIPTION);
4350 MODULE_VERSION(EASYCAP_DRIVER_VERSION);
4351 #if defined(EASYCAP_DEBUG)
4352 MODULE_PARM_DESC(easycap_debug, "debug: 0 (default), 1, 2,...");
4353 #endif /*EASYCAP_DEBUG*/
4354 /*****************************************************************************/