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"
33 #include "easycap_ioctl.h"
37 module_param(debug, int, S_IRUGO | S_IWUSR);
38 module_param(bars, int, S_IRUGO | S_IWUSR);
40 /*---------------------------------------------------------------------------*/
42 * dongle_this IS INDISPENSIBLY static BECAUSE FUNCTION easycap_usb_probe()
43 * IS CALLED SUCCESSIVELY FOR INTERFACES 0, 1, 2 AND THE POINTER peasycap
44 * ALLOCATED DURING THE PROBING OF INTERFACE 0 MUST BE REMEMBERED WHEN
45 * PROBING INTERFACES 1 AND 2.
47 /*---------------------------------------------------------------------------*/
49 struct easycap *peasycap_dongle[DONGLE_MANY];
50 static int dongle_this;
52 /*---------------------------------------------------------------------------*/
54 * PARAMETERS APPLICABLE TO ENTIRE DRIVER, I.E. BOTH VIDEO AND AUDIO
56 /*---------------------------------------------------------------------------*/
57 struct usb_device_id easycap_usb_device_id_table[] = {
58 { USB_DEVICE(USB_EASYCAP_VENDOR_ID, USB_EASYCAP_PRODUCT_ID) },
61 MODULE_DEVICE_TABLE(usb, easycap_usb_device_id_table);
62 struct usb_driver easycap_usb_driver = {
64 .id_table = easycap_usb_device_id_table,
65 .probe = easycap_usb_probe,
66 .disconnect = easycap_usb_disconnect,
68 /*---------------------------------------------------------------------------*/
70 * PARAMETERS USED WHEN REGISTERING THE VIDEO INTERFACE
72 * NOTE: SOME KERNELS IGNORE usb_class_driver.minor_base, AS MENTIONED BY
73 * CORBET ET AL. "LINUX DEVICE DRIVERS", 3rd EDITION, PAGE 253.
74 * THIS IS THE CASE FOR OpenSUSE.
76 /*---------------------------------------------------------------------------*/
77 const struct file_operations easycap_fops = {
80 .release = easycap_release,
81 .unlocked_ioctl = easycap_ioctl,
86 struct vm_operations_struct easycap_vm_ops = {
87 .open = easycap_vma_open,
88 .close = easycap_vma_close,
89 .fault = easycap_vma_fault,
91 struct usb_class_driver easycap_class = {
92 .name = "usb/easycap%d",
93 .fops = &easycap_fops,
94 .minor_base = USB_SKEL_MINOR_BASE,
97 /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
98 #if defined(EASYCAP_IS_VIDEODEV_CLIENT)
99 #if defined(EASYCAP_NEEDS_V4L2_FOPS)
100 const struct v4l2_file_operations v4l2_fops = {
101 .owner = THIS_MODULE,
102 .open = easycap_open_noinode,
103 .release = easycap_release_noinode,
104 .unlocked_ioctl = easycap_ioctl,
105 .poll = easycap_poll,
106 .mmap = easycap_mmap,
108 #endif /*EASYCAP_NEEDS_V4L2_FOPS*/
109 #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
110 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
112 /*--------------------------------------------------------------------------*/
114 * PARAMETERS USED WHEN REGISTERING THE AUDIO INTERFACE
116 /*--------------------------------------------------------------------------*/
117 const struct file_operations easysnd_fops = {
118 .owner = THIS_MODULE,
119 .open = easysnd_open,
120 .release = easysnd_release,
121 .unlocked_ioctl = easysnd_ioctl,
122 .read = easysnd_read,
125 struct usb_class_driver easysnd_class = {
126 .name = "usb/easysnd%d",
127 .fops = &easysnd_fops,
128 .minor_base = USB_SKEL_MINOR_BASE,
130 /****************************************************************************/
131 /*---------------------------------------------------------------------------*/
133 * THIS ROUTINE DOES NOT DETECT MULTIPLE OCCURRENCES OF POINTER peasycap
135 /*---------------------------------------------------------------------------*/
137 isdongle(struct easycap *peasycap)
140 if ((struct easycap *)NULL == peasycap)
142 for (k = 0; k < DONGLE_MANY; k++) {
143 if (peasycap_dongle[k] == peasycap) {
144 peasycap->isdongle = k;
150 /*****************************************************************************/
151 /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
152 #if defined(EASYCAP_IS_VIDEODEV_CLIENT)
154 easycap_open_noinode(struct file *file)
156 return easycap_open((struct inode *)NULL, file);
158 #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
159 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
161 easycap_open(struct inode *inode, struct file *file)
163 #if (!defined(EASYCAP_IS_VIDEODEV_CLIENT))
164 struct usb_interface *pusb_interface;
166 struct video_device *pvideo_device;
167 #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
168 struct easycap *peasycap;
172 SAY("==========OPEN=========\n");
174 peasycap = (struct easycap *)NULL;
175 /*---------------------------------------------------------------------------*/
176 #if (!defined(EASYCAP_IS_VIDEODEV_CLIENT))
177 if ((struct inode *)NULL == inode) {
178 SAY("ERROR: inode is NULL.\n");
181 pusb_interface = usb_find_interface(&easycap_usb_driver, iminor(inode));
182 if (!pusb_interface) {
183 SAY("ERROR: pusb_interface is NULL.\n");
186 peasycap = usb_get_intfdata(pusb_interface);
187 /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
189 pvideo_device = video_devdata(file);
190 if ((struct video_device *)NULL == pvideo_device) {
191 SAY("ERROR: pvideo_device is NULL.\n");
194 peasycap = (struct easycap *)video_get_drvdata(pvideo_device);
195 #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
196 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
197 if ((struct easycap *)NULL == peasycap) {
198 SAY("ERROR: peasycap is NULL\n");
201 file->private_data = peasycap;
202 if (NULL == peasycap->pusb_device) {
203 SAM("ERROR: peasycap->pusb_device is NULL\n");
206 JOM(16, "0x%08lX=peasycap->pusb_device\n", \
207 (long int)peasycap->pusb_device);
209 rc = wakeup_device(peasycap->pusb_device);
211 JOM(8, "wakeup_device() OK\n");
213 SAM("ERROR: wakeup_device() returned %i\n", rc);
215 SAM("ERROR: wakeup_device() returned -ENODEV\n");
217 SAM("ERROR: wakeup_device() returned %i\n", rc);
221 rc = reset(peasycap);
223 SAM("ERROR: reset() returned %i\n", rc);
228 /*****************************************************************************/
229 /*---------------------------------------------------------------------------*/
231 * RESET THE HARDWARE TO ITS REFERENCE STATE.
233 * THIS ROUTINE MAY BE CALLED REPEATEDLY IF easycap_complete() DETECTS
234 * A BAD VIDEO FRAME SIZE.
236 /*---------------------------------------------------------------------------*/
238 reset(struct easycap *peasycap)
240 struct easycap_standard const *peasycap_standard;
241 int i, rc, input, rate;
244 if ((struct easycap *)NULL == peasycap) {
245 SAY("ERROR: peasycap is NULL\n");
248 input = peasycap->input;
250 /*---------------------------------------------------------------------------*/
252 * IF THE SAA7113H HAS ALREADY ACQUIRED LOCK, USE ITS HARDWARE-DETECTED
253 * FIELD FREQUENCY TO DISTINGUISH NTSC FROM PAL. THIS IS ESSENTIAL FOR
254 * gstreamer AND OTHER USERSPACE PROGRAMS WHICH MAY NOT ATTEMPT TO INITIATE
255 * A SWITCH BETWEEN PAL AND NTSC.
257 * FUNCTION ready_saa() MAY REQUIRE A SUBSTANTIAL FRACTION OF A SECOND TO
258 * COMPLETE, SO SHOULD NOT BE INVOKED WITHOUT GOOD REASON.
260 /*---------------------------------------------------------------------------*/
262 if (true == peasycap->ntsc)
263 JOM(8, "true=peasycap->ntsc\n");
265 JOM(8, "false=peasycap->ntsc\n");
266 rate = ready_saa(peasycap->pusb_device);
268 JOM(8, "not ready to capture after %i ms ...\n", PATIENCE);
269 if (true == peasycap->ntsc) {
270 JOM(8, "... trying PAL ...\n"); ntsc = false;
272 JOM(8, "... trying NTSC ...\n"); ntsc = true;
274 rc = setup_stk(peasycap->pusb_device, ntsc);
276 JOM(4, "setup_stk() OK\n");
278 SAM("ERROR: setup_stk() returned %i\n", rc);
281 rc = setup_saa(peasycap->pusb_device, ntsc);
283 JOM(4, "setup_saa() OK\n");
285 SAM("ERROR: setup_saa() returned %i\n", rc);
288 rate = ready_saa(peasycap->pusb_device);
290 JOM(8, "not ready to capture after %i ms ...\n", PATIENCE);
291 JOM(8, "... saa register 0x1F has 0x%02X\n", \
292 read_saa(peasycap->pusb_device, 0x1F));
293 ntsc = peasycap->ntsc;
295 JOM(8, "... success at second try: %i=rate\n", rate);
296 ntsc = (0 < (rate/2)) ? true : false ;
300 JOM(8, "... success at first try: %i=rate\n", rate);
301 ntsc = (0 < rate/2) ? true : false ;
304 JOM(8, "true=ntsc\n");
306 JOM(8, "false=ntsc\n");
307 /*---------------------------------------------------------------------------*/
309 rc = setup_stk(peasycap->pusb_device, ntsc);
311 JOM(4, "setup_stk() OK\n");
313 SAM("ERROR: setup_stk() returned %i\n", rc);
316 rc = setup_saa(peasycap->pusb_device, ntsc);
318 JOM(4, "setup_saa() OK\n");
320 SAM("ERROR: setup_saa() returned %i\n", rc);
324 for (i = 0; i < 180; i++)
325 peasycap->merit[i] = 0;
326 peasycap->video_eof = 0;
327 peasycap->audio_eof = 0;
328 do_gettimeofday(&peasycap->timeval7);
329 /*---------------------------------------------------------------------------*/
331 * RESTORE INPUT AND FORCE REFRESH OF STANDARD, FORMAT, ETC.
333 * WHILE THIS PROCEDURE IS IN PROGRESS, SOME IOCTL COMMANDS WILL RETURN -EBUSY.
335 /*---------------------------------------------------------------------------*/
336 peasycap->input = -8192;
337 peasycap->standard_offset = -8192;
339 peasycap_standard = &easycap_standard[0];
340 while (0xFFFF != peasycap_standard->mask) {
343 peasycap_standard->v4l2_standard.index) {
344 peasycap->inputset[input].standard_offset = \
345 peasycap_standard - \
346 &easycap_standard[0];
351 peasycap_standard->v4l2_standard.index) {
352 peasycap->inputset[input].standard_offset = \
354 &easycap_standard[0];
360 if (0xFFFF == peasycap_standard->mask) {
361 SAM("ERROR: standard not found\n");
364 JOM(8, "%i=peasycap->inputset[%i].standard_offset\n", \
365 peasycap->inputset[input].standard_offset, input);
367 peasycap->format_offset = -8192;
368 peasycap->brightness = -8192;
369 peasycap->contrast = -8192;
370 peasycap->saturation = -8192;
371 peasycap->hue = -8192;
373 rc = newinput(peasycap, input);
376 JOM(4, "restored input, standard and format\n");
378 SAM("ERROR: newinput(.,%i) returned %i\n", rc, input);
381 if (true == peasycap->ntsc)
382 JOM(8, "true=peasycap->ntsc\n");
384 JOM(8, "false=peasycap->ntsc\n");
386 if (0 > peasycap->input) {
387 SAM("MISTAKE: %i=peasycap->input\n", peasycap->input);
390 if (0 > peasycap->standard_offset) {
391 SAM("MISTAKE: %i=peasycap->standard_offset\n", \
392 peasycap->standard_offset);
395 if (0 > peasycap->format_offset) {
396 SAM("MISTAKE: %i=peasycap->format_offset\n", \
397 peasycap->format_offset);
400 if (0 > peasycap->brightness) {
401 SAM("MISTAKE: %i=peasycap->brightness\n", peasycap->brightness);
404 if (0 > peasycap->contrast) {
405 SAM("MISTAKE: %i=peasycap->contrast\n", peasycap->contrast);
408 if (0 > peasycap->saturation) {
409 SAM("MISTAKE: %i=peasycap->saturation\n", peasycap->saturation);
412 if (0 > peasycap->hue) {
413 SAM("MISTAKE: %i=peasycap->hue\n", peasycap->hue);
418 /*****************************************************************************/
419 /*---------------------------------------------------------------------------*/
421 * IF THE REQUESTED INPUT IS THE SAME AS THE EXISTING INPUT, DO NOTHING.
423 * KILL URBS, CLEAR FIELD AND FRAME BUFFERS AND RESET THEIR
424 * _read AND _fill POINTERS.
425 * SELECT THE NEW INPUT.
426 * ADJUST THE STANDARD, FORMAT, BRIGHTNESS, CONTRAST, SATURATION AND HUE
427 * ON THE BASIS OF INFORMATION IN STRUCTURE easycap.inputset[input].
428 * RESUBMIT THE URBS IF STREAMING WAS ALREADY IN PROGRESS.
431 * THIS ROUTINE MAY BE CALLED FREQUENTLY BY ZONEMINDER VIA IOCTL,
432 * SO IT SHOULD WRITE ONLY SPARINGLY TO THE LOGFILE.
434 /*---------------------------------------------------------------------------*/
436 newinput(struct easycap *peasycap, int input)
438 int rc, k, m, mood, off;
439 int inputnow, video_idlenow, audio_idlenow;
442 if (NULL == peasycap) {
443 SAY("ERROR: peasycap is NULL\n");
446 JOM(8, "%i=input sought\n", input);
448 if ((0 > input) &&(INPUT_MANY <= input))
450 inputnow = peasycap->input;
451 if (input == inputnow)
453 /*---------------------------------------------------------------------------*/
455 * IF STREAMING IS IN PROGRESS THE URBS ARE KILLED AT THIS
456 * STAGE AND WILL BE RESUBMITTED PRIOR TO EXIT FROM THE ROUTINE.
457 * IF NO STREAMING IS IN PROGRESS NO URBS WILL BE SUBMITTED BY THE
460 /*---------------------------------------------------------------------------*/
461 video_idlenow = peasycap->video_idle;
462 audio_idlenow = peasycap->audio_idle;
464 peasycap->video_idle = 1;
465 peasycap->audio_idle = 1;
466 if (peasycap->video_isoc_streaming) {
468 kill_video_urbs(peasycap);
471 /*---------------------------------------------------------------------------*/
472 if (NULL == peasycap->pusb_device) {
473 SAM("ERROR: peasycap->pusb_device is NULL\n");
476 rc = usb_set_interface(peasycap->pusb_device,
477 peasycap->video_interface, \
478 peasycap->video_altsetting_off);
480 SAM("ERROR: usb_set_interface() returned %i\n", rc);
483 rc = stop_100(peasycap->pusb_device);
485 SAM("ERROR: stop_100() returned %i\n", rc);
488 for (k = 0; k < FIELD_BUFFER_MANY; k++) {
489 for (m = 0; m < FIELD_BUFFER_SIZE/PAGE_SIZE; m++)
490 memset(peasycap->field_buffer[k][m].pgo, 0, PAGE_SIZE);
492 for (k = 0; k < FRAME_BUFFER_MANY; k++) {
493 for (m = 0; m < FRAME_BUFFER_SIZE/PAGE_SIZE; m++)
494 memset(peasycap->frame_buffer[k][m].pgo, 0, PAGE_SIZE);
496 peasycap->field_page = 0;
497 peasycap->field_read = 0;
498 peasycap->field_fill = 0;
500 peasycap->frame_read = 0;
501 peasycap->frame_fill = 0;
502 for (k = 0; k < peasycap->input; k++) {
503 (peasycap->frame_fill)++;
504 if (peasycap->frame_buffer_many <= peasycap->frame_fill)
505 peasycap->frame_fill = 0;
507 peasycap->input = input;
508 select_input(peasycap->pusb_device, peasycap->input, 9);
509 /*---------------------------------------------------------------------------*/
510 if (input == peasycap->inputset[input].input) {
511 off = peasycap->inputset[input].standard_offset;
512 if (off != peasycap->standard_offset) {
513 rc = adjust_standard(peasycap, \
514 easycap_standard[off].v4l2_standard.id);
516 SAM("ERROR: adjust_standard() returned %i\n", rc);
519 JOM(8, "%i=peasycap->standard_offset\n", \
520 peasycap->standard_offset);
522 JOM(8, "%i=peasycap->standard_offset unchanged\n", \
523 peasycap->standard_offset);
525 off = peasycap->inputset[input].format_offset;
526 if (off != peasycap->format_offset) {
527 rc = adjust_format(peasycap, \
528 easycap_format[off].v4l2_format.fmt.pix.width, \
529 easycap_format[off].v4l2_format.fmt.pix.height, \
530 easycap_format[off].v4l2_format.fmt.pix.pixelformat, \
531 easycap_format[off].v4l2_format.fmt.pix.field, false);
533 SAM("ERROR: adjust_format() returned %i\n", rc);
536 JOM(8, "%i=peasycap->format_offset\n", peasycap->format_offset);
538 JOM(8, "%i=peasycap->format_offset unchanged\n", \
539 peasycap->format_offset);
541 mood = peasycap->inputset[input].brightness;
542 if (mood != peasycap->brightness) {
543 rc = adjust_brightness(peasycap, mood);
545 SAM("ERROR: adjust_brightness returned %i\n", rc);
548 JOM(8, "%i=peasycap->brightness\n", peasycap->brightness);
550 mood = peasycap->inputset[input].contrast;
551 if (mood != peasycap->contrast) {
552 rc = adjust_contrast(peasycap, mood);
554 SAM("ERROR: adjust_contrast returned %i\n", rc);
557 JOM(8, "%i=peasycap->contrast\n", peasycap->contrast);
559 mood = peasycap->inputset[input].saturation;
560 if (mood != peasycap->saturation) {
561 rc = adjust_saturation(peasycap, mood);
563 SAM("ERROR: adjust_saturation returned %i\n", rc);
566 JOM(8, "%i=peasycap->saturation\n", peasycap->saturation);
568 mood = peasycap->inputset[input].hue;
569 if (mood != peasycap->hue) {
570 rc = adjust_hue(peasycap, mood);
572 SAM("ERROR: adjust_hue returned %i\n", rc);
575 JOM(8, "%i=peasycap->hue\n", peasycap->hue);
578 SAM("MISTAKE: easycap.inputset[%i] unpopulated\n", input);
581 /*---------------------------------------------------------------------------*/
582 if ((struct usb_device *)NULL == peasycap->pusb_device) {
583 SAM("ERROR: peasycap->pusb_device is NULL\n");
586 rc = usb_set_interface(peasycap->pusb_device,
587 peasycap->video_interface, \
588 peasycap->video_altsetting_on);
590 SAM("ERROR: usb_set_interface() returned %i\n", rc);
593 rc = start_100(peasycap->pusb_device);
595 SAM("ERROR: start_100() returned %i\n", rc);
598 if (true == resubmit)
599 submit_video_urbs(peasycap);
601 peasycap->video_isoc_sequence = VIDEO_ISOC_BUFFER_MANY - 1;
602 peasycap->video_idle = video_idlenow;
603 peasycap->audio_idle = audio_idlenow;
604 peasycap->video_junk = 0;
608 /*****************************************************************************/
610 submit_video_urbs(struct easycap *peasycap)
612 struct data_urb *pdata_urb;
614 struct list_head *plist_head;
615 int j, isbad, nospc, m, rc;
618 if ((struct easycap *)NULL == peasycap) {
619 SAY("ERROR: peasycap is NULL\n");
623 if ((struct list_head *)NULL == peasycap->purb_video_head) {
624 SAY("ERROR: peasycap->urb_video_head uninitialized\n");
627 if ((struct usb_device *)NULL == peasycap->pusb_device) {
628 SAY("ERROR: peasycap->pusb_device is NULL\n");
631 if (!peasycap->video_isoc_streaming) {
632 JOM(4, "submission of all video urbs\n");
633 isbad = 0; nospc = 0; m = 0;
634 list_for_each(plist_head, (peasycap->purb_video_head)) {
635 pdata_urb = list_entry(plist_head, struct data_urb, list_head);
636 if (NULL != pdata_urb) {
637 purb = pdata_urb->purb;
639 isbuf = pdata_urb->isbuf;
641 purb->dev = peasycap->pusb_device;
643 usb_rcvisocpipe(peasycap->pusb_device,\
644 peasycap->video_endpointnumber);
645 purb->transfer_flags = URB_ISO_ASAP;
646 purb->transfer_buffer = \
647 peasycap->video_isoc_buffer[isbuf].pgo;
648 purb->transfer_buffer_length = \
649 peasycap->video_isoc_buffer_size;
650 purb->complete = easycap_complete;
651 purb->context = peasycap;
652 purb->start_frame = 0;
653 purb->number_of_packets = \
654 peasycap->video_isoc_framesperdesc;
656 for (j = 0; j < peasycap->\
657 video_isoc_framesperdesc; j++) {
658 purb->iso_frame_desc[j].\
661 video_isoc_maxframesize;
662 purb->iso_frame_desc[j].\
664 video_isoc_maxframesize;
667 rc = usb_submit_urb(purb, GFP_KERNEL);
670 SAM("ERROR: usb_submit_urb() failed " \
671 "for urb with rc:\n");
674 SAM("ERROR: -ENOMEM=" \
675 "usb_submit_urb()\n");
679 SAM("ERROR: -ENODEV=" \
680 "usb_submit_urb()\n");
684 SAM("ERROR: -ENXIO=" \
685 "usb_submit_urb()\n");
689 SAM("ERROR: -EINVAL=" \
690 "usb_submit_urb()\n");
694 SAM("ERROR: -EAGAIN=" \
695 "usb_submit_urb()\n");
699 SAM("ERROR: -EFBIG=" \
700 "usb_submit_urb()\n");
704 SAM("ERROR: -EPIPE=" \
705 "usb_submit_urb()\n");
709 SAM("ERROR: -EMSGSIZE=" \
710 "usb_submit_urb()\n");
719 "usb_submit_urb()\n",\
735 SAM("-ENOSPC=usb_submit_urb() for %i urbs\n", nospc);
736 SAM("..... possibly inadequate USB bandwidth\n");
737 peasycap->video_eof = 1;
741 JOM(4, "attempting cleanup instead of submitting\n");
742 list_for_each(plist_head, (peasycap->purb_video_head)) {
743 pdata_urb = list_entry(plist_head, struct data_urb, \
745 if (NULL != pdata_urb) {
746 purb = pdata_urb->purb;
751 peasycap->video_isoc_streaming = 0;
753 peasycap->video_isoc_streaming = 1;
754 JOM(4, "submitted %i video urbs\n", m);
757 JOM(4, "already streaming video urbs\n");
761 /*****************************************************************************/
763 kill_video_urbs(struct easycap *peasycap)
766 struct list_head *plist_head;
767 struct data_urb *pdata_urb;
769 if ((struct easycap *)NULL == peasycap) {
770 SAY("ERROR: peasycap is NULL\n");
773 if (peasycap->video_isoc_streaming) {
774 if ((struct list_head *)NULL != peasycap->purb_video_head) {
775 peasycap->video_isoc_streaming = 0;
776 JOM(4, "killing video urbs\n");
778 list_for_each(plist_head, (peasycap->purb_video_head)) {
779 pdata_urb = list_entry(plist_head, struct data_urb, \
781 if ((struct data_urb *)NULL != pdata_urb) {
782 if ((struct urb *)NULL != pdata_urb->purb) {
783 usb_kill_urb(pdata_urb->purb);
788 JOM(4, "%i video urbs killed\n", m);
790 SAM("ERROR: peasycap->purb_video_head is NULL\n");
794 JOM(8, "%i=video_isoc_streaming, no video urbs killed\n", \
795 peasycap->video_isoc_streaming);
799 /****************************************************************************/
800 /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
801 #if defined(EASYCAP_IS_VIDEODEV_CLIENT)
803 easycap_release_noinode(struct file *file)
805 return easycap_release((struct inode *)NULL, file);
807 #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
808 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
809 /*--------------------------------------------------------------------------*/
811 easycap_release(struct inode *inode, struct file *file)
813 #if (!defined(EASYCAP_IS_VIDEODEV_CLIENT))
814 struct easycap *peasycap;
818 peasycap = file->private_data;
819 if (NULL == peasycap) {
820 SAY("ERROR: peasycap is NULL.\n");
821 SAY("ending unsuccessfully\n");
824 if (0 != kill_video_urbs(peasycap)) {
825 SAM("ERROR: kill_video_urbs() failed\n");
828 JOM(4, "ending successfully\n");
829 /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
832 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
833 #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
837 /****************************************************************************/
838 /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
839 #if defined(EASYCAP_IS_VIDEODEV_CLIENT)
841 videodev_release(struct video_device *pvideo_device)
843 struct easycap *peasycap;
847 peasycap = video_get_drvdata(pvideo_device);
848 if (NULL == peasycap) {
849 SAY("ERROR: peasycap is NULL\n");
850 SAY("ending unsuccessfully\n");
853 if (0 != kill_video_urbs(peasycap)) {
854 SAM("ERROR: kill_video_urbs() failed\n");
857 JOM(4, "ending successfully\n");
860 #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
861 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
862 /*****************************************************************************/
863 /*--------------------------------------------------------------------------*/
865 * THIS FUNCTION IS CALLED FROM WITHIN easycap_usb_disconnect().
866 * BY THIS STAGE THE DEVICE HAS ALREADY BEEN PHYSICALLY UNPLUGGED.
867 * peasycap->pusb_device IS NO LONGER VALID AND SHOULD HAVE BEEN SET TO NULL.
869 /*---------------------------------------------------------------------------*/
871 easycap_delete(struct kref *pkref)
874 int allocation_video_urb, allocation_video_page, allocation_video_struct;
875 int allocation_audio_urb, allocation_audio_page, allocation_audio_struct;
876 int registered_video, registered_audio;
877 struct easycap *peasycap;
878 struct data_urb *pdata_urb;
879 struct list_head *plist_head, *plist_next;
883 peasycap = container_of(pkref, struct easycap, kref);
884 if ((struct easycap *)NULL == peasycap) {
885 SAM("ERROR: peasycap is NULL: cannot perform deletions\n");
888 /*---------------------------------------------------------------------------*/
892 /*---------------------------------------------------------------------------*/
893 if ((struct list_head *)NULL != peasycap->purb_video_head) {
894 JOM(4, "freeing video urbs\n");
896 list_for_each(plist_head, (peasycap->purb_video_head)) {
897 pdata_urb = list_entry(plist_head, struct data_urb, list_head);
898 if (NULL == pdata_urb)
899 JOM(4, "ERROR: pdata_urb is NULL\n");
901 if ((struct urb *)NULL != pdata_urb->purb) {
902 usb_free_urb(pdata_urb->purb);
903 pdata_urb->purb = (struct urb *)NULL;
904 peasycap->allocation_video_urb -= 1;
910 JOM(4, "%i video urbs freed\n", m);
911 /*---------------------------------------------------------------------------*/
912 JOM(4, "freeing video data_urb structures.\n");
914 list_for_each_safe(plist_head, plist_next, peasycap->purb_video_head) {
915 pdata_urb = list_entry(plist_head, struct data_urb, list_head);
916 if ((struct data_urb *)NULL != pdata_urb) {
917 kfree(pdata_urb); pdata_urb = (struct data_urb *)NULL;
918 peasycap->allocation_video_struct -= \
919 sizeof(struct data_urb);
923 JOM(4, "%i video data_urb structures freed\n", m);
924 JOM(4, "setting peasycap->purb_video_head=NULL\n");
925 peasycap->purb_video_head = (struct list_head *)NULL;
927 JOM(4, "peasycap->purb_video_head is NULL\n");
929 /*---------------------------------------------------------------------------*/
930 JOM(4, "freeing video isoc buffers.\n");
932 for (k = 0; k < VIDEO_ISOC_BUFFER_MANY; k++) {
933 if ((void *)NULL != peasycap->video_isoc_buffer[k].pgo) {
934 free_pages((unsigned long)\
935 (peasycap->video_isoc_buffer[k].pgo), \
937 peasycap->video_isoc_buffer[k].pgo = (void *)NULL;
938 peasycap->allocation_video_page -= \
939 ((unsigned int)(0x01 << VIDEO_ISOC_ORDER));
943 JOM(4, "isoc video buffers freed: %i pages\n", m * (0x01 << VIDEO_ISOC_ORDER));
944 /*---------------------------------------------------------------------------*/
945 JOM(4, "freeing video field buffers.\n");
947 for (k = 0; k < FIELD_BUFFER_MANY; k++) {
948 for (m = 0; m < FIELD_BUFFER_SIZE/PAGE_SIZE; m++) {
949 if ((void *)NULL != peasycap->field_buffer[k][m].pgo) {
950 free_page((unsigned long)\
951 (peasycap->field_buffer[k][m].pgo));
952 peasycap->field_buffer[k][m].pgo = (void *)NULL;
953 peasycap->allocation_video_page -= 1;
958 JOM(4, "video field buffers freed: %i pages\n", gone);
959 /*---------------------------------------------------------------------------*/
960 JOM(4, "freeing video frame buffers.\n");
962 for (k = 0; k < FRAME_BUFFER_MANY; k++) {
963 for (m = 0; m < FRAME_BUFFER_SIZE/PAGE_SIZE; m++) {
964 if ((void *)NULL != peasycap->frame_buffer[k][m].pgo) {
965 free_page((unsigned long)\
966 (peasycap->frame_buffer[k][m].pgo));
967 peasycap->frame_buffer[k][m].pgo = (void *)NULL;
968 peasycap->allocation_video_page -= 1;
973 JOM(4, "video frame buffers freed: %i pages\n", gone);
974 /*---------------------------------------------------------------------------*/
978 /*---------------------------------------------------------------------------*/
979 if ((struct list_head *)NULL != peasycap->purb_audio_head) {
980 JOM(4, "freeing audio urbs\n");
982 list_for_each(plist_head, (peasycap->purb_audio_head)) {
983 pdata_urb = list_entry(plist_head, struct data_urb, list_head);
984 if (NULL == pdata_urb)
985 JOM(4, "ERROR: pdata_urb is NULL\n");
987 if ((struct urb *)NULL != pdata_urb->purb) {
988 usb_free_urb(pdata_urb->purb);
989 pdata_urb->purb = (struct urb *)NULL;
990 peasycap->allocation_audio_urb -= 1;
995 JOM(4, "%i audio urbs freed\n", m);
996 /*---------------------------------------------------------------------------*/
997 JOM(4, "freeing audio data_urb structures.\n");
999 list_for_each_safe(plist_head, plist_next, peasycap->purb_audio_head) {
1000 pdata_urb = list_entry(plist_head, struct data_urb, list_head);
1001 if ((struct data_urb *)NULL != pdata_urb) {
1002 kfree(pdata_urb); pdata_urb = (struct data_urb *)NULL;
1003 peasycap->allocation_audio_struct -= \
1004 sizeof(struct data_urb);
1008 JOM(4, "%i audio data_urb structures freed\n", m);
1009 JOM(4, "setting peasycap->purb_audio_head=NULL\n");
1010 peasycap->purb_audio_head = (struct list_head *)NULL;
1012 JOM(4, "peasycap->purb_audio_head is NULL\n");
1014 /*---------------------------------------------------------------------------*/
1015 JOM(4, "freeing audio isoc buffers.\n");
1017 for (k = 0; k < AUDIO_ISOC_BUFFER_MANY; k++) {
1018 if ((void *)NULL != peasycap->audio_isoc_buffer[k].pgo) {
1019 free_pages((unsigned long)\
1020 (peasycap->audio_isoc_buffer[k].pgo), \
1022 peasycap->audio_isoc_buffer[k].pgo = (void *)NULL;
1023 peasycap->allocation_audio_page -= \
1024 ((unsigned int)(0x01 << AUDIO_ISOC_ORDER));
1028 JOM(4, "easysnd_delete(): isoc audio buffers freed: %i pages\n", \
1029 m * (0x01 << AUDIO_ISOC_ORDER));
1030 /*---------------------------------------------------------------------------*/
1031 JOM(4, "freeing audio buffers.\n");
1033 for (k = 0; k < peasycap->audio_buffer_page_many; k++) {
1034 if ((void *)NULL != peasycap->audio_buffer[k].pgo) {
1035 free_page((unsigned long)(peasycap->audio_buffer[k].pgo));
1036 peasycap->audio_buffer[k].pgo = (void *)NULL;
1037 peasycap->allocation_audio_page -= 1;
1041 JOM(4, "easysnd_delete(): audio buffers freed: %i pages\n", gone);
1042 /*---------------------------------------------------------------------------*/
1043 JOM(4, "freeing easycap structure.\n");
1044 allocation_video_urb = peasycap->allocation_video_urb;
1045 allocation_video_page = peasycap->allocation_video_page;
1046 allocation_video_struct = peasycap->allocation_video_struct;
1047 registered_video = peasycap->registered_video;
1048 allocation_audio_urb = peasycap->allocation_audio_urb;
1049 allocation_audio_page = peasycap->allocation_audio_page;
1050 allocation_audio_struct = peasycap->allocation_audio_struct;
1051 registered_audio = peasycap->registered_audio;
1053 if ((struct easycap *)NULL != peasycap) {
1054 kfree(peasycap); peasycap = (struct easycap *)NULL;
1055 allocation_video_struct -= sizeof(struct easycap);
1058 JOT(4, "%i easycap structure freed\n", m);
1059 /*---------------------------------------------------------------------------*/
1061 SAY("%8i= video urbs after all deletions\n", allocation_video_urb);
1062 SAY("%8i= video pages after all deletions\n", allocation_video_page);
1063 SAY("%8i= video structs after all deletions\n", allocation_video_struct);
1064 SAY("%8i= video devices after all deletions\n", registered_video);
1065 SAY("%8i= audio urbs after all deletions\n", allocation_audio_urb);
1066 SAY("%8i= audio pages after all deletions\n", allocation_audio_page);
1067 SAY("%8i= audio structs after all deletions\n", allocation_audio_struct);
1068 SAY("%8i= audio devices after all deletions\n", registered_audio);
1070 JOT(4, "ending.\n");
1073 /*****************************************************************************/
1074 unsigned int easycap_poll(struct file *file, poll_table *wait)
1076 struct easycap *peasycap;
1080 if (NULL == ((poll_table *)wait))
1081 JOT(8, "WARNING: poll table pointer is NULL ... continuing\n");
1082 if (NULL == ((struct file *)file)) {
1083 SAY("ERROR: file pointer is NULL\n");
1086 peasycap = file->private_data;
1087 if (NULL == peasycap) {
1088 SAY("ERROR: peasycap is NULL\n");
1091 peasycap->polled = 1;
1093 if (0 == easycap_dqbuf(peasycap, 0))
1094 return POLLIN | POLLRDNORM;
1099 /*****************************************************************************/
1100 /*---------------------------------------------------------------------------*/
1102 * IF mode IS NONZERO THIS ROUTINE RETURNS -EAGAIN RATHER THAN BLOCKING.
1104 /*---------------------------------------------------------------------------*/
1106 easycap_dqbuf(struct easycap *peasycap, int mode)
1108 int input, ifield, miss, rc;
1112 if (NULL == peasycap) {
1113 SAY("ERROR: peasycap is NULL\n");
1117 JOM(8, "%i=ifield\n", ifield);
1118 /*---------------------------------------------------------------------------*/
1120 * CHECK FOR LOST INPUT SIGNAL.
1122 * FOR THE FOUR-CVBS EasyCAP, THIS DOES NOT WORK AS EXPECTED.
1123 * IF INPUT 0 IS PRESENT AND LOCKED, UNPLUGGING INPUT 4 DOES NOT RESULT IN
1124 * SETTING BIT 0x40 ON REGISTER 0x1F, PRESUMABLY BECAUSE THERE IS FLYWHEELING
1125 * ON INPUT 0. THE UPSHOT IS:
1127 * INPUT 0 PLUGGED, INPUT 4 PLUGGED => SCREEN 0 OK, SCREEN 4 OK
1128 * INPUT 0 PLUGGED, INPUT 4 UNPLUGGED => SCREEN 0 OK, SCREEN 4 BLACK
1129 * INPUT 0 UNPLUGGED, INPUT 4 PLUGGED => SCREEN 0 BARS, SCREEN 4 OK
1130 * INPUT 0 UNPLUGGED, INPUT 4 UNPLUGGED => SCREEN 0 BARS, SCREEN 4 BARS
1132 /*---------------------------------------------------------------------------*/
1133 input = peasycap->input;
1134 if (0 <= input && INPUT_MANY > input) {
1135 rc = read_saa(peasycap->pusb_device, 0x1F);
1138 peasycap->lost[input] += 1;
1140 peasycap->lost[input] -= 2;
1142 if (0 > peasycap->lost[input])
1143 peasycap->lost[input] = 0;
1144 else if ((2 * VIDEO_LOST_TOLERATE) < peasycap->lost[input])
1145 peasycap->lost[input] = (2 * VIDEO_LOST_TOLERATE);
1148 /*---------------------------------------------------------------------------*/
1150 * WAIT FOR FIELD ifield (0 => TOP, 1 => BOTTOM)
1152 /*---------------------------------------------------------------------------*/
1154 while ((peasycap->field_read == peasycap->field_fill) || \
1155 (0 != (0xFF00 & peasycap->field_buffer\
1156 [peasycap->field_read][0].kount)) || \
1157 (ifield != (0x00FF & peasycap->field_buffer\
1158 [peasycap->field_read][0].kount))) {
1162 JOM(8, "first wait on wq_video, " \
1163 "%i=field_read %i=field_fill\n", \
1164 peasycap->field_read, peasycap->field_fill);
1166 if (0 != (wait_event_interruptible(peasycap->wq_video, \
1167 (peasycap->video_idle || peasycap->video_eof || \
1168 ((peasycap->field_read != peasycap->field_fill) && \
1169 (0 == (0xFF00 & peasycap->field_buffer\
1170 [peasycap->field_read][0].kount)) && \
1171 (ifield == (0x00FF & peasycap->field_buffer\
1172 [peasycap->field_read][0].kount))))))) {
1173 SAM("aborted by signal\n");
1176 if (peasycap->video_idle) {
1177 JOM(8, "%i=peasycap->video_idle ... returning -EAGAIN\n", \
1178 peasycap->video_idle);
1181 if (peasycap->video_eof) {
1182 JOM(8, "%i=peasycap->video_eof\n", peasycap->video_eof);
1183 #if defined(PERSEVERE)
1184 if (1 == peasycap->status) {
1185 JOM(8, "persevering ...\n");
1186 peasycap->video_eof = 0;
1187 peasycap->audio_eof = 0;
1188 if (0 != reset(peasycap)) {
1189 JOM(8, " ... failed ... returning -EIO\n");
1190 peasycap->video_eof = 1;
1191 peasycap->audio_eof = 1;
1192 kill_video_urbs(peasycap);
1195 peasycap->status = 0;
1196 JOM(8, " ... OK ... returning -EAGAIN\n");
1199 #endif /*PERSEVERE*/
1200 peasycap->video_eof = 1;
1201 peasycap->audio_eof = 1;
1202 kill_video_urbs(peasycap);
1203 JOM(8, "returning -EIO\n");
1208 JOM(8, "first awakening on wq_video after %i waits\n", miss);
1210 rc = field2frame(peasycap);
1212 SAM("ERROR: field2frame() returned %i\n", rc);
1213 /*---------------------------------------------------------------------------*/
1215 * WAIT FOR THE OTHER FIELD
1217 /*---------------------------------------------------------------------------*/
1223 while ((peasycap->field_read == peasycap->field_fill) || \
1224 (0 != (0xFF00 & peasycap->field_buffer\
1225 [peasycap->field_read][0].kount)) || \
1226 (ifield != (0x00FF & peasycap->field_buffer\
1227 [peasycap->field_read][0].kount))) {
1231 JOM(8, "second wait on wq_video, " \
1232 "%i=field_read %i=field_fill\n", \
1233 peasycap->field_read, peasycap->field_fill);
1234 if (0 != (wait_event_interruptible(peasycap->wq_video, \
1235 (peasycap->video_idle || peasycap->video_eof || \
1236 ((peasycap->field_read != peasycap->field_fill) && \
1237 (0 == (0xFF00 & peasycap->field_buffer\
1238 [peasycap->field_read][0].kount)) && \
1239 (ifield == (0x00FF & peasycap->field_buffer\
1240 [peasycap->field_read][0].\
1242 SAM("aborted by signal\n");
1245 if (peasycap->video_idle) {
1246 JOM(8, "%i=peasycap->video_idle ... returning -EAGAIN\n", \
1247 peasycap->video_idle);
1250 if (peasycap->video_eof) {
1251 JOM(8, "%i=peasycap->video_eof\n", peasycap->video_eof);
1252 #if defined(PERSEVERE)
1253 if (1 == peasycap->status) {
1254 JOM(8, "persevering ...\n");
1255 peasycap->video_eof = 0;
1256 peasycap->audio_eof = 0;
1257 if (0 != reset(peasycap)) {
1258 JOM(8, " ... failed ... returning -EIO\n");
1259 peasycap->video_eof = 1;
1260 peasycap->audio_eof = 1;
1261 kill_video_urbs(peasycap);
1264 peasycap->status = 0;
1265 JOM(8, " ... OK ... returning -EAGAIN\n");
1268 #endif /*PERSEVERE*/
1269 peasycap->video_eof = 1;
1270 peasycap->audio_eof = 1;
1271 kill_video_urbs(peasycap);
1272 JOM(8, "returning -EIO\n");
1277 JOM(8, "second awakening on wq_video after %i waits\n", miss);
1279 rc = field2frame(peasycap);
1281 SAM("ERROR: field2frame() returned %i\n", rc);
1282 /*---------------------------------------------------------------------------*/
1286 /*---------------------------------------------------------------------------*/
1287 if (0 != peasycap->skip) {
1288 peasycap->skipped++;
1289 if (peasycap->skip != peasycap->skipped)
1290 return peasycap->skip - peasycap->skipped;
1291 peasycap->skipped = 0;
1293 /*---------------------------------------------------------------------------*/
1294 peasycap->frame_read = peasycap->frame_fill;
1295 peasycap->queued[peasycap->frame_read] = 0;
1296 peasycap->done[peasycap->frame_read] = V4L2_BUF_FLAG_DONE;
1298 (peasycap->frame_fill)++;
1299 if (peasycap->frame_buffer_many <= peasycap->frame_fill)
1300 peasycap->frame_fill = 0;
1302 if (0x01 & easycap_standard[peasycap->standard_offset].mask) {
1303 peasycap->frame_buffer[peasycap->frame_read][0].kount = \
1306 peasycap->frame_buffer[peasycap->frame_read][0].kount = \
1310 JOM(8, "setting: %i=peasycap->frame_read\n", peasycap->frame_read);
1311 JOM(8, "bumped to: %i=peasycap->frame_fill\n", peasycap->frame_fill);
1315 /*****************************************************************************/
1316 /*---------------------------------------------------------------------------*/
1318 * BY DEFINITION, odd IS true FOR THE FIELD OCCUPYING LINES 1,3,5,...,479
1319 * odd IS false FOR THE FIELD OCCUPYING LINES 0,2,4,...,478
1321 * WHEN BOOLEAN PARAMETER decimatepixel IS true, ONLY THE FIELD FOR WHICH
1322 * odd==false IS TRANSFERRED TO THE FRAME BUFFER.
1324 * THE BOOLEAN PARAMETER offerfields IS true ONLY WHEN THE USER PROGRAM
1325 * CHOOSES THE OPTION V4L2_FIELD_INTERLACED.
1327 /*---------------------------------------------------------------------------*/
1329 field2frame(struct easycap *peasycap)
1331 struct timeval timeval;
1332 long long int above, below;
1334 struct signed_div_result sdr;
1337 int kex, kad, mex, mad, rex, rad, rad2;
1338 int c2, c3, w2, w3, cz, wz;
1339 int rc, bytesperpixel, multiplier, much, more, over, rump, caches, input;
1341 bool odd, isuy, decimatepixel, offerfields, badinput;
1343 if ((struct easycap *)NULL == peasycap) {
1344 SAY("ERROR: peasycap is NULL\n");
1349 input = 0x07 & peasycap->field_buffer[peasycap->field_read][0].input;
1351 JOM(8, "===== parity %i, input 0x%02X, field buffer %i --> " \
1352 "frame buffer %i\n", \
1353 peasycap->field_buffer[peasycap->field_read][0].kount,\
1354 peasycap->field_buffer[peasycap->field_read][0].input,\
1355 peasycap->field_read, peasycap->frame_fill);
1356 JOM(8, "===== %i=bytesperpixel\n", peasycap->bytesperpixel);
1357 if (true == peasycap->offerfields)
1358 JOM(8, "===== offerfields\n");
1360 /*---------------------------------------------------------------------------*/
1362 * REJECT OR CLEAN BAD FIELDS
1364 /*---------------------------------------------------------------------------*/
1365 if (peasycap->field_read == peasycap->field_fill) {
1366 SAM("ERROR: on entry, still filling field buffer %i\n", \
1367 peasycap->field_read);
1370 #if defined(EASYCAP_TESTCARD)
1371 easycap_testcard(peasycap, peasycap->field_read);
1373 if (0 <= input && INPUT_MANY > input) {
1374 if (bars && VIDEO_LOST_TOLERATE <= peasycap->lost[input])
1375 easycap_testcard(peasycap, peasycap->field_read);
1377 #endif /*EASYCAP_TESTCARD*/
1378 /*---------------------------------------------------------------------------*/
1380 offerfields = peasycap->offerfields;
1381 bytesperpixel = peasycap->bytesperpixel;
1382 decimatepixel = peasycap->decimatepixel;
1384 if ((2 != bytesperpixel) && \
1385 (3 != bytesperpixel) && \
1386 (4 != bytesperpixel)) {
1387 SAM("MISTAKE: %i=bytesperpixel\n", bytesperpixel);
1390 if (true == decimatepixel)
1395 w2 = 2 * multiplier * (peasycap->width);
1396 w3 = bytesperpixel * \
1400 (peasycap->height) * \
1404 kex = peasycap->field_read; mex = 0;
1405 kad = peasycap->frame_fill; mad = 0;
1407 pex = peasycap->field_buffer[kex][0].pgo; rex = PAGE_SIZE;
1408 pad = peasycap->frame_buffer[kad][0].pgo; rad = PAGE_SIZE;
1409 if (peasycap->field_buffer[kex][0].kount)
1414 if ((true == odd) && (false == decimatepixel)) {
1415 JOM(8, " initial skipping %4i bytes p.%4i\n", \
1416 w3/multiplier, mad);
1417 pad += (w3 / multiplier); rad -= (w3 / multiplier);
1420 mask = 0; rump = 0; caches = 0;
1424 /*-------------------------------------------------------------------*/
1426 ** PROCESS ONE LINE OF FRAME AT FULL RESOLUTION:
1427 ** READ w2 BYTES FROM FIELD BUFFER,
1428 ** WRITE w3 BYTES TO FRAME BUFFER
1430 /*-------------------------------------------------------------------*/
1431 if (false == decimatepixel) {
1434 much = over; more = 0; margin = 0; mask = 0x00;
1440 SAM("MISTAKE: much is odd\n");
1444 more = (bytesperpixel * \
1446 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1447 if (1 < bytesperpixel) {
1452 ** INJUDICIOUS ALTERATION OF THIS
1453 ** BLOCK WILL CAUSE BREAKAGE.
1456 rad2 = rad + bytesperpixel - 1;
1458 rad2)/bytesperpixel)/2) * 2);
1459 rump = ((bytesperpixel * \
1467 if ((mex + 1) < FIELD_BUFFER_SIZE/ \
1469 margin = *((__u8 *)(peasycap->\
1471 [kex][mex + 1].pgo));
1475 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1477 SAM("MISTAKE: %i=bytesperpixel\n", \
1481 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1485 if (true == badinput) {
1486 JOM(8, "ERROR: 0x%02X=->field_buffer" \
1487 "[%i][%i].input, " \
1488 "0x%02X=(0x08|->input)\n", \
1489 peasycap->field_buffer\
1490 [kex][mex].input, kex, mex, \
1491 (0x08|peasycap->input));
1494 rc = redaub(peasycap, pad, pex, much, more, \
1495 mask, margin, isuy);
1497 SAM("ERROR: redaub() failed\n");
1506 over -= much; cz += much;
1507 pex += much; rex -= much;
1510 pex = peasycap->field_buffer[kex][mex].pgo;
1512 if (peasycap->field_buffer[kex][mex].input != \
1513 (0x08|peasycap->input))
1520 pad = peasycap->frame_buffer[kad][mad].pgo;
1528 /*---------------------------------------------------------------------------*/
1530 * SKIP w3 BYTES IN TARGET FRAME BUFFER,
1531 * UNLESS IT IS THE LAST LINE OF AN ODD FRAME
1533 /*---------------------------------------------------------------------------*/
1534 if ((false == odd) || (cz != wz)) {
1539 pad = peasycap->frame_buffer\
1551 /*---------------------------------------------------------------------------*/
1553 * PROCESS ONE LINE OF FRAME AT REDUCED RESOLUTION:
1554 * ONLY IF false==odd,
1555 * READ w2 BYTES FROM FIELD BUFFER,
1556 * WRITE w3 / 2 BYTES TO FRAME BUFFER
1558 /*---------------------------------------------------------------------------*/
1559 } else if (false == odd) {
1562 much = over; more = 0; margin = 0; mask = 0x00;
1568 SAM("MISTAKE: much is odd\n");
1572 more = (bytesperpixel * \
1574 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1575 if (1 < bytesperpixel) {
1576 if ((rad * 4) < (much * \
1579 ** INJUDICIOUS ALTERATION OF THIS
1580 ** BLOCK WILL CAUSE BREAKAGE.
1583 rad2 = rad + bytesperpixel - 1;
1584 much = ((((2 * rad2)/bytesperpixel)/2)\
1586 rump = ((bytesperpixel * \
1594 if ((mex + 1) < FIELD_BUFFER_SIZE/ \
1596 margin = *((__u8 *)(peasycap->\
1598 [kex][mex + 1].pgo));
1603 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1605 SAM("MISTAKE: %i=bytesperpixel\n", \
1609 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1613 if (true == badinput) {
1614 JOM(8, "ERROR: 0x%02X=->field_buffer" \
1615 "[%i][%i].input, " \
1616 "0x%02X=(0x08|->input)\n", \
1617 peasycap->field_buffer\
1618 [kex][mex].input, kex, mex, \
1619 (0x08|peasycap->input));
1622 rc = redaub(peasycap, pad, pex, much, more, \
1623 mask, margin, isuy);
1625 SAM("ERROR: redaub() failed\n");
1628 over -= much; cz += much;
1629 pex += much; rex -= much;
1632 pex = peasycap->field_buffer[kex][mex].pgo;
1634 if (peasycap->field_buffer[kex][mex].input != \
1635 (0x08|peasycap->input))
1642 pad = peasycap->frame_buffer[kad][mad].pgo;
1650 /*---------------------------------------------------------------------------*/
1653 * READ w2 BYTES FROM FIELD BUFFER AND DISCARD THEM
1655 /*---------------------------------------------------------------------------*/
1661 pex = peasycap->field_buffer[kex][mex].pgo;
1663 if (peasycap->field_buffer[kex][mex].input != \
1664 (0x08|peasycap->input)) {
1665 JOM(8, "ERROR: 0x%02X=->field_buffer"\
1666 "[%i][%i].input, " \
1667 "0x%02X=(0x08|->input)\n", \
1668 peasycap->field_buffer\
1669 [kex][mex].input, kex, mex, \
1670 (0x08|peasycap->input));
1684 /*---------------------------------------------------------------------------*/
1688 /*---------------------------------------------------------------------------*/
1689 c2 = (mex + 1)*PAGE_SIZE - rex;
1691 SAM("ERROR: discrepancy %i in bytes read\n", c2 - cz);
1692 c3 = (mad + 1)*PAGE_SIZE - rad;
1694 if (false == decimatepixel) {
1695 if (bytesperpixel * \
1697 SAM("ERROR: discrepancy %i in bytes written\n", \
1698 c3 - (bytesperpixel * \
1702 if (bytesperpixel * \
1704 SAM("ERROR: discrepancy %i in bytes written\n", \
1705 (2*c3)-(bytesperpixel * \
1709 SAM("ERROR: discrepancy %i " \
1710 "in bytes written\n", c3);
1714 SAM("WORRY: undischarged cache at end of line in frame buffer\n");
1716 JOM(8, "===== field2frame(): %i bytes --> %i bytes (incl skip)\n", c2, c3);
1717 JOM(8, "===== field2frame(): %i=mad %i=rad\n", mad, rad);
1720 JOM(8, "+++++ field2frame(): frame buffer %i is full\n", kad);
1722 if (peasycap->field_read == peasycap->field_fill)
1723 SAM("WARNING: on exit, filling field buffer %i\n", \
1724 peasycap->field_read);
1725 /*---------------------------------------------------------------------------*/
1727 * CALCULATE VIDEO STREAMING RATE
1729 /*---------------------------------------------------------------------------*/
1730 do_gettimeofday(&timeval);
1731 if (peasycap->timeval6.tv_sec) {
1732 below = ((long long int)(1000000)) * \
1733 ((long long int)(timeval.tv_sec - \
1734 peasycap->timeval6.tv_sec)) + \
1735 (long long int)(timeval.tv_usec - peasycap->timeval6.tv_usec);
1736 above = (long long int)1000000;
1738 sdr = signed_div(above, below);
1739 above = sdr.quotient;
1740 remainder = (__u32)sdr.remainder;
1742 JOM(8, "video streaming at %3lli.%03i fields per second\n", above, \
1745 peasycap->timeval6 = timeval;
1748 JOM(8, "%i=caches\n", caches);
1751 /*****************************************************************************/
1752 struct signed_div_result
1753 signed_div(long long int above, long long int below)
1755 struct signed_div_result sdr;
1757 if (((0 <= above) && (0 <= below)) || ((0 > above) && (0 > below))) {
1758 sdr.remainder = (unsigned long long int) do_div(above, below);
1759 sdr.quotient = (long long int) above;
1765 sdr.remainder = (unsigned long long int) do_div(above, below);
1766 sdr.quotient = -((long long int) above);
1770 /*****************************************************************************/
1771 /*---------------------------------------------------------------------------*/
1773 * DECIMATION AND COLOURSPACE CONVERSION.
1775 * THIS ROUTINE REQUIRES THAT ALL THE DATA TO BE READ RESIDES ON ONE PAGE
1776 * AND THAT ALL THE DATA TO BE WRITTEN RESIDES ON ONE (DIFFERENT) PAGE.
1777 * THE CALLING ROUTINE MUST ENSURE THAT THIS REQUIREMENT IS MET, AND MUST
1778 * ALSO ENSURE THAT much IS EVEN.
1780 * much BYTES ARE READ, AT LEAST (bytesperpixel * much)/2 BYTES ARE WRITTEN
1781 * IF THERE IS NO DECIMATION, HALF THIS AMOUNT IF THERE IS DECIMATION.
1783 * mask IS ZERO WHEN NO SPECIAL BEHAVIOUR REQUIRED. OTHERWISE IT IS SET THUS:
1784 * 0x03 & mask = number of bytes to be written to cache instead of to
1786 * 0x04 & mask => use argument margin to set the chrominance for last pixel
1787 * 0x08 & mask => do not set the chrominance for last pixel
1789 * YUV to RGB CONVERSION IS (OR SHOULD BE) ITU-R BT 601.
1791 * THERE IS A LOT OF CODE REPETITION IN THIS ROUTINE IN ORDER TO AVOID
1792 * INEFFICIENT SWITCHING INSIDE INNER LOOPS. REARRANGING THE LOGIC TO
1793 * REDUCE CODE LENGTH WILL GENERALLY IMPAIR RUNTIME PERFORMANCE. BEWARE.
1795 /*---------------------------------------------------------------------------*/
1797 redaub(struct easycap *peasycap, void *pad, void *pex, int much, int more, \
1798 __u8 mask, __u8 margin, bool isuy)
1800 static __s32 ay[256], bu[256], rv[256], gu[256], gv[256];
1802 __u8 r, g, b, y, u, v, c, *p2, *p3, *pz, *pr;
1804 bool byteswaporder, decimatepixel, last;
1809 SAM("MISTAKE: much is odd\n");
1812 bytesperpixel = peasycap->bytesperpixel;
1813 byteswaporder = peasycap->byteswaporder;
1814 decimatepixel = peasycap->decimatepixel;
1816 /*---------------------------------------------------------------------------*/
1818 for (j = 0; j < 112; j++) {
1819 s32 = (0xFF00 & (453 * j)) >> 8;
1820 bu[j + 128] = s32; bu[127 - j] = -s32;
1821 s32 = (0xFF00 & (359 * j)) >> 8;
1822 rv[j + 128] = s32; rv[127 - j] = -s32;
1823 s32 = (0xFF00 & (88 * j)) >> 8;
1824 gu[j + 128] = s32; gu[127 - j] = -s32;
1825 s32 = (0xFF00 & (183 * j)) >> 8;
1826 gv[j + 128] = s32; gv[127 - j] = -s32;
1828 for (j = 0; j < 16; j++) {
1829 bu[j] = bu[16]; rv[j] = rv[16];
1830 gu[j] = gu[16]; gv[j] = gv[16];
1832 for (j = 240; j < 256; j++) {
1833 bu[j] = bu[239]; rv[j] = rv[239];
1834 gu[j] = gu[239]; gv[j] = gv[239];
1836 for (j = 16; j < 236; j++)
1838 for (j = 0; j < 16; j++)
1840 for (j = 236; j < 256; j++)
1842 JOM(8, "lookup tables are prepared\n");
1844 pcache = peasycap->pcache;
1846 pcache = &peasycap->cache[0];
1847 /*---------------------------------------------------------------------------*/
1849 * TRANSFER CONTENTS OF CACHE TO THE FRAME BUFFER
1851 /*---------------------------------------------------------------------------*/
1853 SAM("MISTAKE: pcache is NULL\n");
1857 if (pcache != &peasycap->cache[0])
1858 JOM(16, "cache has %i bytes\n", (int)(pcache - &peasycap->cache[0]));
1859 p2 = &peasycap->cache[0];
1860 p3 = (__u8 *)pad - (int)(pcache - &peasycap->cache[0]);
1861 while (p2 < pcache) {
1864 pcache = &peasycap->cache[0];
1866 SAM("MISTAKE: pointer misalignment\n");
1869 /*---------------------------------------------------------------------------*/
1870 rump = (int)(0x03 & mask);
1872 p2 = (__u8 *)pex; pz = p2 + much; pr = p3 + more; last = false;
1881 JOM(16, "%4i=much %4i=more %i=rump\n", much, more, rump);
1883 /*---------------------------------------------------------------------------*/
1884 switch (bytesperpixel) {
1886 if (false == decimatepixel) {
1887 memcpy(pad, pex, (size_t)much);
1888 if (false == byteswaporder)
1889 /*---------------------------------------------------*/
1893 /*---------------------------------------------------*/
1896 /*---------------------------------------------------*/
1900 /*---------------------------------------------------*/
1901 p3 = (__u8 *)pad; pz = p3 + much;
1911 if (false == byteswaporder) {
1912 /*---------------------------------------------------*/
1916 /*---------------------------------------------------*/
1917 p2 = (__u8 *)pex; p3 = (__u8 *)pad; pz = p2 + much;
1920 *(p3 + 1) = *(p2 + 1);
1921 *(p3 + 2) = *(p2 + 2);
1922 *(p3 + 3) = *(p2 + 3);
1927 /*---------------------------------------------------*/
1931 /*---------------------------------------------------*/
1932 p2 = (__u8 *)pex; p3 = (__u8 *)pad; pz = p2 + much;
1936 *(p3 + 2) = *(p2 + 3);
1937 *(p3 + 3) = *(p2 + 2);
1947 if (false == decimatepixel) {
1948 if (false == byteswaporder) {
1949 /*---------------------------------------------------*/
1953 /*---------------------------------------------------*/
1955 if (pr <= (p3 + bytesperpixel))
1960 if ((true == last) && (0x0C & mask)) {
1976 s32 = ay[(int)y] + rv[(int)v];
1977 r = (255 < s32) ? 255 : ((0 > s32) ? \
1979 s32 = ay[(int)y] - gu[(int)u] - gv[(int)v];
1980 g = (255 < s32) ? 255 : ((0 > s32) ? \
1982 s32 = ay[(int)y] + bu[(int)u];
1983 b = (255 < s32) ? 255 : ((0 > s32) ? \
1986 if ((true == last) && rump) {
1987 pcache = &peasycap->cache[0];
1988 switch (bytesperpixel - rump) {
2002 SAM("MISTAKE: %i=rump\n", \
2003 bytesperpixel - rump);
2017 p3 += bytesperpixel;
2021 /*---------------------------------------------------*/
2025 /*---------------------------------------------------*/
2027 if (pr <= (p3 + bytesperpixel))
2032 if ((true == last) && (0x0C & mask)) {
2049 s32 = ay[(int)y] + rv[(int)v];
2050 r = (255 < s32) ? 255 : ((0 > s32) ? \
2052 s32 = ay[(int)y] - gu[(int)u] - gv[(int)v];
2053 g = (255 < s32) ? 255 : ((0 > s32) ? \
2055 s32 = ay[(int)y] + bu[(int)u];
2056 b = (255 < s32) ? 255 : ((0 > s32) ? \
2059 if ((true == last) && rump) {
2060 pcache = &peasycap->cache[0];
2061 switch (bytesperpixel - rump) {
2075 SAM("MISTAKE: %i=rump\n", \
2076 bytesperpixel - rump);
2090 p3 += bytesperpixel;
2095 if (false == byteswaporder) {
2096 /*---------------------------------------------------*/
2100 /*---------------------------------------------------*/
2102 if (pr <= (p3 + bytesperpixel))
2107 if ((true == last) && (0x0C & mask)) {
2124 s32 = ay[(int)y] + rv[(int)v];
2125 r = (255 < s32) ? 255 : ((0 > s32) ? \
2127 s32 = ay[(int)y] - gu[(int)u] - \
2129 g = (255 < s32) ? 255 : ((0 > s32) ? \
2131 s32 = ay[(int)y] + bu[(int)u];
2132 b = (255 < s32) ? 255 : ((0 > s32) ? \
2135 if ((true == last) && rump) {
2136 pcache = &peasycap->cache[0];
2137 switch (bytesperpixel - rump) {
2153 bytesperpixel - rump);
2163 p3 += bytesperpixel;
2171 /*---------------------------------------------------*/
2175 /*---------------------------------------------------*/
2177 if (pr <= (p3 + bytesperpixel))
2182 if ((true == last) && (0x0C & mask)) {
2200 s32 = ay[(int)y] + rv[(int)v];
2201 r = (255 < s32) ? 255 : ((0 > s32) ? \
2203 s32 = ay[(int)y] - gu[(int)u] - \
2205 g = (255 < s32) ? 255 : ((0 > s32) ? \
2207 s32 = ay[(int)y] + bu[(int)u];
2208 b = (255 < s32) ? 255 : ((0 > s32) ? \
2211 if ((true == last) && rump) {
2212 pcache = &peasycap->cache[0];
2213 switch (bytesperpixel - rump) {
2229 bytesperpixel - rump);
2239 p3 += bytesperpixel;
2252 if (false == decimatepixel) {
2253 if (false == byteswaporder) {
2254 /*---------------------------------------------------*/
2258 /*---------------------------------------------------*/
2260 if (pr <= (p3 + bytesperpixel))
2265 if ((true == last) && (0x0C & mask)) {
2281 s32 = ay[(int)y] + rv[(int)v];
2282 r = (255 < s32) ? 255 : ((0 > s32) ? \
2284 s32 = ay[(int)y] - gu[(int)u] - gv[(int)v];
2285 g = (255 < s32) ? 255 : ((0 > s32) ? \
2287 s32 = ay[(int)y] + bu[(int)u];
2288 b = (255 < s32) ? 255 : ((0 > s32) ? \
2291 if ((true == last) && rump) {
2292 pcache = &peasycap->cache[0];
2293 switch (bytesperpixel - rump) {
2316 SAM("MISTAKE: %i=rump\n", \
2317 bytesperpixel - rump);
2332 p3 += bytesperpixel;
2336 /*---------------------------------------------------*/
2340 /*---------------------------------------------------*/
2342 if (pr <= (p3 + bytesperpixel))
2347 if ((true == last) && (0x0C & mask)) {
2363 s32 = ay[(int)y] + rv[(int)v];
2364 r = (255 < s32) ? 255 : ((0 > s32) ? \
2366 s32 = ay[(int)y] - gu[(int)u] - gv[(int)v];
2367 g = (255 < s32) ? 255 : ((0 > s32) ? \
2369 s32 = ay[(int)y] + bu[(int)u];
2370 b = (255 < s32) ? 255 : ((0 > s32) ? \
2373 if ((true == last) && rump) {
2374 pcache = &peasycap->cache[0];
2375 switch (bytesperpixel - rump) {
2398 SAM("MISTAKE: %i=rump\n", \
2399 bytesperpixel - rump);
2414 p3 += bytesperpixel;
2419 if (false == byteswaporder) {
2420 /*---------------------------------------------------*/
2424 /*---------------------------------------------------*/
2426 if (pr <= (p3 + bytesperpixel))
2431 if ((true == last) && (0x0C & mask)) {
2449 s32 = ay[(int)y] + rv[(int)v];
2450 r = (255 < s32) ? 255 : ((0 > s32) ? \
2452 s32 = ay[(int)y] - gu[(int)u] - \
2454 g = (255 < s32) ? 255 : ((0 > s32) ? \
2456 s32 = ay[(int)y] + bu[(int)u];
2457 b = (255 < s32) ? 255 : ((0 > s32) ? \
2460 if ((true == last) && rump) {
2461 pcache = &peasycap->cache[0];
2462 switch (bytesperpixel - rump) {
2499 p3 += bytesperpixel;
2506 /*---------------------------------------------------*/
2510 /*---------------------------------------------------*/
2512 if (pr <= (p3 + bytesperpixel))
2517 if ((true == last) && (0x0C & mask)) {
2534 s32 = ay[(int)y] + rv[(int)v];
2535 r = (255 < s32) ? 255 : ((0 > s32) ? \
2537 s32 = ay[(int)y] - gu[(int)u] - \
2539 g = (255 < s32) ? 255 : ((0 > s32) ? \
2541 s32 = ay[(int)y] + bu[(int)u];
2542 b = (255 < s32) ? 255 : ((0 > s32) ? \
2545 if ((true == last) && rump) {
2546 pcache = &peasycap->cache[0];
2547 switch (bytesperpixel - rump) {
2572 bytesperpixel - rump);
2583 p3 += bytesperpixel;
2594 SAM("MISTAKE: %i=bytesperpixel\n", bytesperpixel);
2600 /*****************************************************************************/
2601 /*---------------------------------------------------------------------------*/
2603 * SEE CORBET ET AL. "LINUX DEVICE DRIVERS", 3rd EDITION, PAGES 430-434
2605 /*---------------------------------------------------------------------------*/
2606 int easycap_mmap(struct file *file, struct vm_area_struct *pvma)
2611 pvma->vm_ops = &easycap_vm_ops;
2612 pvma->vm_flags |= VM_RESERVED;
2614 pvma->vm_private_data = file->private_data;
2615 easycap_vma_open(pvma);
2618 /*****************************************************************************/
2620 easycap_vma_open(struct vm_area_struct *pvma)
2622 struct easycap *peasycap;
2624 peasycap = pvma->vm_private_data;
2625 if (NULL != peasycap)
2626 peasycap->vma_many++;
2628 JOT(8, "%i=peasycap->vma_many\n", peasycap->vma_many);
2632 /*****************************************************************************/
2634 easycap_vma_close(struct vm_area_struct *pvma)
2636 struct easycap *peasycap;
2638 peasycap = pvma->vm_private_data;
2639 if (NULL != peasycap) {
2640 peasycap->vma_many--;
2641 JOT(8, "%i=peasycap->vma_many\n", peasycap->vma_many);
2645 /*****************************************************************************/
2647 easycap_vma_fault(struct vm_area_struct *pvma, struct vm_fault *pvmf)
2652 struct easycap *peasycap;
2654 retcode = VM_FAULT_NOPAGE;
2655 pbuf = (void *)NULL;
2656 page = (struct page *)NULL;
2659 SAY("pvma is NULL\n");
2663 SAY("pvmf is NULL\n");
2667 k = (pvmf->pgoff) / (FRAME_BUFFER_SIZE/PAGE_SIZE);
2668 m = (pvmf->pgoff) % (FRAME_BUFFER_SIZE/PAGE_SIZE);
2671 JOT(4, "%4i=k, %4i=m\n", k, m);
2673 JOT(16, "%4i=k, %4i=m\n", k, m);
2675 if ((0 > k) || (FRAME_BUFFER_MANY <= k)) {
2676 SAY("ERROR: buffer index %i out of range\n", k);
2679 if ((0 > m) || (FRAME_BUFFER_SIZE/PAGE_SIZE <= m)) {
2680 SAY("ERROR: page number %i out of range\n", m);
2683 peasycap = pvma->vm_private_data;
2684 if (NULL == peasycap) {
2685 SAY("ERROR: peasycap is NULL\n");
2688 /*---------------------------------------------------------------------------*/
2689 pbuf = peasycap->frame_buffer[k][m].pgo;
2691 SAM("ERROR: pbuf is NULL\n");
2694 page = virt_to_page(pbuf);
2696 SAM("ERROR: page is NULL\n");
2700 /*---------------------------------------------------------------------------*/
2703 SAM("ERROR: page is NULL after get_page(page)\n");
2706 retcode = VM_FAULT_MINOR;
2710 /*****************************************************************************/
2711 /*---------------------------------------------------------------------------*/
2713 * ON COMPLETION OF A VIDEO URB ITS DATA IS COPIED TO THE FIELD BUFFERS
2714 * PROVIDED peasycap->video_idle IS ZERO. REGARDLESS OF THIS BEING TRUE,
2715 * IT IS RESUBMITTED PROVIDED peasycap->video_isoc_streaming IS NOT ZERO.
2717 * THIS FUNCTION IS AN INTERRUPT SERVICE ROUTINE AND MUST NOT SLEEP.
2719 * INFORMATION ABOUT THE VALIDITY OF THE CONTENTS OF THE FIELD BUFFER ARE
2720 * STORED IN THE TWO-BYTE STATUS PARAMETER
2721 * peasycap->field_buffer[peasycap->field_fill][0].kount
2722 * NOTICE THAT THE INFORMATION IS STORED ONLY WITH PAGE 0 OF THE FIELD BUFFER.
2724 * THE LOWER BYTE CONTAINS THE FIELD PARITY BYTE FURNISHED BY THE SAA7113H
2727 * THE UPPER BYTE IS ZERO IF NO PROBLEMS, OTHERWISE:
2728 * 0 != (kount & 0x8000) => AT LEAST ONE URB COMPLETED WITH ERRORS
2729 * 0 != (kount & 0x4000) => BUFFER HAS TOO MUCH DATA
2730 * 0 != (kount & 0x2000) => BUFFER HAS NOT ENOUGH DATA
2731 * 0 != (kount & 0x1000) => BUFFER HAS DATA FROM DISPARATE INPUTS
2732 * 0 != (kount & 0x0400) => RESERVED
2733 * 0 != (kount & 0x0200) => FIELD BUFFER NOT YET CHECKED
2734 * 0 != (kount & 0x0100) => BUFFER HAS TWO EXTRA BYTES - WHY?
2736 /*---------------------------------------------------------------------------*/
2738 easycap_complete(struct urb *purb)
2740 struct easycap *peasycap;
2741 struct data_buffer *pfield_buffer;
2743 int i, more, much, leap, rc, last;
2744 int videofieldamount;
2745 unsigned int override, bad;
2746 int framestatus, framelength, frameactual, frameoffset;
2750 SAY("ERROR: easycap_complete(): purb is NULL\n");
2753 peasycap = purb->context;
2754 if (NULL == peasycap) {
2755 SAY("ERROR: easycap_complete(): peasycap is NULL\n");
2759 if (peasycap->video_eof)
2762 for (i = 0; i < VIDEO_ISOC_BUFFER_MANY; i++)
2763 if (purb->transfer_buffer == peasycap->video_isoc_buffer[i].pgo)
2765 JOM(16, "%2i=urb\n", i);
2766 last = peasycap->video_isoc_sequence;
2767 if ((((VIDEO_ISOC_BUFFER_MANY - 1) == last) && \
2769 (((VIDEO_ISOC_BUFFER_MANY - 1) != last) && \
2770 ((last + 1) != i))) {
2771 JOM(16, "ERROR: out-of-order urbs %i,%i ... continuing\n", last, i);
2773 peasycap->video_isoc_sequence = i;
2775 if (peasycap->video_idle) {
2776 JOM(16, "%i=video_idle %i=video_isoc_streaming\n", \
2777 peasycap->video_idle, peasycap->video_isoc_streaming);
2778 if (peasycap->video_isoc_streaming) {
2779 rc = usb_submit_urb(purb, GFP_ATOMIC);
2819 SAM("0x%08X\n", rc);
2823 if (-ENODEV != rc) \
2824 SAM("ERROR: while %i=video_idle, " \
2825 "usb_submit_urb() " \
2826 "failed with rc:\n", \
2827 peasycap->video_idle);
2833 /*---------------------------------------------------------------------------*/
2834 if (FIELD_BUFFER_MANY <= peasycap->field_fill) {
2835 SAM("ERROR: bad peasycap->field_fill\n");
2839 if ((-ESHUTDOWN == purb->status) || (-ENOENT == purb->status)) {
2840 JOM(8, "urb status -ESHUTDOWN or -ENOENT\n");
2844 (peasycap->field_buffer[peasycap->field_fill][0].kount) |= 0x8000 ;
2845 SAM("ERROR: bad urb status:\n");
2846 switch (purb->status) {
2847 case -EINPROGRESS: {
2848 SAM("-EINPROGRESS\n"); break;
2851 SAM("-ENOSR\n"); break;
2854 SAM("-EPIPE\n"); break;
2857 SAM("-EOVERFLOW\n"); break;
2860 SAM("-EPROTO\n"); break;
2863 SAM("-EILSEQ\n"); break;
2866 SAM("-ETIMEDOUT\n"); break;
2869 SAM("-EMSGSIZE\n"); break;
2872 SAM("-EOPNOTSUPP\n"); break;
2874 case -EPFNOSUPPORT: {
2875 SAM("-EPFNOSUPPORT\n"); break;
2877 case -EAFNOSUPPORT: {
2878 SAM("-EAFNOSUPPORT\n"); break;
2881 SAM("-EADDRINUSE\n"); break;
2883 case -EADDRNOTAVAIL: {
2884 SAM("-EADDRNOTAVAIL\n"); break;
2887 SAM("-ENOBUFS\n"); break;
2890 SAM("-EISCONN\n"); break;
2893 SAM("-ENOTCONN\n"); break;
2896 SAM("-ESHUTDOWN\n"); break;
2899 SAM("-ENOENT\n"); break;
2902 SAM("-ECONNRESET\n"); break;
2905 SAM("ENOSPC\n"); break;
2908 SAM("unknown error code 0x%08X\n", purb->status); break;
2911 /*---------------------------------------------------------------------------*/
2913 for (i = 0; i < purb->number_of_packets; i++) {
2914 if (0 != purb->iso_frame_desc[i].status) {
2915 (peasycap->field_buffer\
2916 [peasycap->field_fill][0].kount) |= 0x8000 ;
2917 switch (purb->iso_frame_desc[i].status) {
2919 strcpy(&errbuf[0], "OK"); break;
2922 strcpy(&errbuf[0], "-ENOENT"); break;
2924 case -EINPROGRESS: {
2925 strcpy(&errbuf[0], "-EINPROGRESS"); break;
2928 strcpy(&errbuf[0], "-EPROTO"); break;
2931 strcpy(&errbuf[0], "-EILSEQ"); break;
2934 strcpy(&errbuf[0], "-ETIME"); break;
2937 strcpy(&errbuf[0], "-ETIMEDOUT"); break;
2940 strcpy(&errbuf[0], "-EPIPE"); break;
2943 strcpy(&errbuf[0], "-ECOMM"); break;
2946 strcpy(&errbuf[0], "-ENOSR"); break;
2949 strcpy(&errbuf[0], "-EOVERFLOW"); break;
2952 strcpy(&errbuf[0], "-EREMOTEIO"); break;
2955 strcpy(&errbuf[0], "-ENODEV"); break;
2958 strcpy(&errbuf[0], "-EXDEV"); break;
2961 strcpy(&errbuf[0], "-EINVAL"); break;
2964 strcpy(&errbuf[0], "-ECONNRESET"); break;
2967 SAM("ENOSPC\n"); break;
2970 strcpy(&errbuf[0], "-ESHUTDOWN"); break;
2973 strcpy(&errbuf[0], "unknown error"); break;
2977 framestatus = purb->iso_frame_desc[i].status;
2978 framelength = purb->iso_frame_desc[i].length;
2979 frameactual = purb->iso_frame_desc[i].actual_length;
2980 frameoffset = purb->iso_frame_desc[i].offset;
2982 JOM(16, "frame[%2i]:" \
2987 i, framestatus, frameactual, framelength, frameoffset);
2988 if (!purb->iso_frame_desc[i].status) {
2989 more = purb->iso_frame_desc[i].actual_length;
2990 pfield_buffer = &peasycap->field_buffer\
2991 [peasycap->field_fill][peasycap->field_page];
2992 videofieldamount = (peasycap->field_page * \
2994 (int)(pfield_buffer->pto - pfield_buffer->pgo);
2996 peasycap->video_mt++;
2998 if (peasycap->video_mt) {
2999 JOM(8, "%4i empty video urb frames\n", \
3000 peasycap->video_mt);
3001 peasycap->video_mt = 0;
3003 if (FIELD_BUFFER_MANY <= peasycap->field_fill) {
3004 SAM("ERROR: bad peasycap->field_fill\n");
3007 if (FIELD_BUFFER_SIZE/PAGE_SIZE <= \
3008 peasycap->field_page) {
3009 SAM("ERROR: bad peasycap->field_page\n");
3012 pfield_buffer = &peasycap->field_buffer\
3013 [peasycap->field_fill][peasycap->field_page];
3014 pu = (__u8 *)(purb->transfer_buffer + \
3015 purb->iso_frame_desc[i].offset);
3020 /*--------------------------------------------------------------------------*/
3022 * EIGHT-BYTE END-OF-VIDEOFIELD MARKER.
3023 * NOTE: A SUCCESSION OF URB FRAMES FOLLOWING THIS ARE EMPTY,
3024 * CORRESPONDING TO THE FIELD FLYBACK (VERTICAL BLANKING) PERIOD.
3026 * PROVIDED THE FIELD BUFFER CONTAINS GOOD DATA AS INDICATED BY A ZERO UPPER
3028 * peasycap->field_buffer[peasycap->field_fill][0].kount
3029 * THE CONTENTS OF THE FIELD BUFFER ARE OFFERED TO dqbuf(), field_read IS
3030 * UPDATED AND field_fill IS BUMPED. IF THE FIELD BUFFER CONTAINS BAD DATA
3031 * NOTHING IS OFFERED TO dqbuf().
3033 * THE DECISION ON WHETHER THE PARITY OF THE OFFERED FIELD BUFFER IS RIGHT
3034 * RESTS WITH dqbuf().
3036 /*---------------------------------------------------------------------------*/
3037 if ((8 == more) || override) {
3038 if (videofieldamount > \
3039 peasycap->videofieldamount) {
3040 if (2 == videofieldamount - \
3043 (peasycap->field_buffer\
3044 [peasycap->field_fill]\
3045 [0].kount) |= 0x0100;
3046 peasycap->video_junk += (1 + \
3047 VIDEO_JUNK_TOLERATE);
3049 (peasycap->field_buffer\
3050 [peasycap->field_fill]\
3051 [0].kount) |= 0x4000;
3052 } else if (videofieldamount < \
3055 (peasycap->field_buffer\
3056 [peasycap->field_fill]\
3057 [0].kount) |= 0x2000;
3059 bad = 0xFF00 & peasycap->field_buffer\
3060 [peasycap->field_fill]\
3063 (peasycap->video_junk)--;
3064 if (-VIDEO_JUNK_TOLERATE > \
3065 peasycap->video_junk) \
3066 peasycap->video_junk =\
3067 -VIDEO_JUNK_TOLERATE;
3068 peasycap->field_read = \
3071 if (FIELD_BUFFER_MANY <= \
3076 peasycap->field_page = 0;
3077 pfield_buffer = &peasycap->\
3083 pfield_buffer->pto = \
3085 JOM(8, "bumped to: %i="\
3089 peasycap->field_fill, \
3091 pfield_buffer->kount);
3092 JOM(8, "field buffer %i has "\
3093 "%i bytes fit to be "\
3095 peasycap->field_read, \
3097 JOM(8, "wakeup call to "\
3102 peasycap->field_read, \
3103 peasycap->field_fill, \
3104 0x00FF & peasycap->\
3107 field_read][0].kount);
3108 wake_up_interruptible\
3112 (&peasycap->timeval7);
3114 peasycap->video_junk++;
3116 peasycap->video_junk += \
3117 (1 + VIDEO_JUNK_TOLERATE/2);
3118 JOM(8, "field buffer %i had %i " \
3119 "bytes, now discarded: "\
3121 peasycap->field_fill, \
3124 peasycap->field_buffer\
3125 [peasycap->field_fill][0].\
3127 (peasycap->field_fill)++;
3129 if (FIELD_BUFFER_MANY <= \
3130 peasycap->field_fill)
3131 peasycap->field_fill = 0;
3132 peasycap->field_page = 0;
3134 &peasycap->field_buffer\
3135 [peasycap->field_fill]\
3136 [peasycap->field_page];
3137 pfield_buffer->pto = \
3140 JOM(8, "bumped to: %i=peasycap->" \
3141 "field_fill %i=parity\n", \
3142 peasycap->field_fill, \
3143 0x00FF & pfield_buffer->kount);
3146 JOM(8, "end-of-field: received " \
3147 "parity byte 0x%02X\n", \
3150 pfield_buffer->kount = 0x0000;
3152 pfield_buffer->kount = 0x0001;
3153 pfield_buffer->input = 0x08 | \
3154 (0x07 & peasycap->input);
3155 JOM(8, "end-of-field: 0x%02X=kount\n",\
3156 0xFF & pfield_buffer->kount);
3159 /*---------------------------------------------------------------------------*/
3161 * COPY more BYTES FROM ISOC BUFFER TO FIELD BUFFER
3163 /*---------------------------------------------------------------------------*/
3167 if (FIELD_BUFFER_MANY <= peasycap->field_fill) {
3168 SAM("ERROR: bad peasycap->field_fill\n");
3171 if (FIELD_BUFFER_SIZE/PAGE_SIZE <= \
3172 peasycap->field_page) {
3173 SAM("ERROR: bad peasycap->field_page\n");
3176 pfield_buffer = &peasycap->field_buffer\
3177 [peasycap->field_fill][peasycap->field_page];
3179 pfield_buffer = &peasycap->field_buffer\
3180 [peasycap->field_fill]\
3181 [peasycap->field_page];
3182 if (PAGE_SIZE < (pfield_buffer->pto - \
3183 pfield_buffer->pgo)) {
3184 SAM("ERROR: bad pfield_buffer->pto\n");
3187 if (PAGE_SIZE == (pfield_buffer->pto - \
3188 pfield_buffer->pgo)) {
3189 (peasycap->field_page)++;
3190 if (FIELD_BUFFER_SIZE/PAGE_SIZE <= \
3191 peasycap->field_page) {
3192 JOM(16, "wrapping peasycap->" \
3194 peasycap->field_page = 0;
3196 pfield_buffer = &peasycap->\
3198 [peasycap->field_fill]\
3199 [peasycap->field_page];
3200 pfield_buffer->pto = \
3202 pfield_buffer->input = 0x08 | \
3203 (0x07 & peasycap->input);
3204 if ((peasycap->field_buffer[peasycap->\
3207 pfield_buffer->input)
3208 (peasycap->field_buffer\
3209 [peasycap->field_fill]\
3210 [0]).kount |= 0x1000;
3213 much = PAGE_SIZE - (int)(pfield_buffer->pto - \
3214 pfield_buffer->pgo);
3218 memcpy(pfield_buffer->pto, pu, much);
3220 (pfield_buffer->pto) += much;
3227 /*---------------------------------------------------------------------------*/
3229 * RESUBMIT THIS URB, UNLESS A SEVERE PERSISTENT ERROR CONDITION EXISTS.
3231 * IF THE WAIT QUEUES ARE NOT CLEARED IN RESPONSE TO AN ERROR CONDITION
3232 * THE USERSPACE PROGRAM, E.G. mplayer, MAY HANG ON EXIT. BEWARE.
3234 /*---------------------------------------------------------------------------*/
3235 if (VIDEO_ISOC_BUFFER_MANY <= peasycap->video_junk) {
3236 SAM("easycap driver shutting down on condition green\n");
3237 peasycap->status = 1;
3238 peasycap->video_eof = 1;
3239 peasycap->video_junk = 0;
3240 wake_up_interruptible(&peasycap->wq_video);
3241 #if !defined(PERSEVERE)
3242 peasycap->audio_eof = 1;
3243 wake_up_interruptible(&peasycap->wq_audio);
3244 #endif /*PERSEVERE*/
3247 if (peasycap->video_isoc_streaming) {
3248 rc = usb_submit_urb(purb, GFP_ATOMIC);
3252 SAM("ENOMEM\n"); break;
3255 SAM("ENODEV\n"); break;
3258 SAM("ENXIO\n"); break;
3261 SAM("EINVAL\n"); break;
3264 SAM("EAGAIN\n"); break;
3267 SAM("EFBIG\n"); break;
3270 SAM("EPIPE\n"); break;
3273 SAM("EMSGSIZE\n"); break;
3276 SAM("ENOSPC\n"); break;
3279 SAM("0x%08X\n", rc); break;
3282 if (-ENODEV != rc) \
3283 SAM("ERROR: while %i=video_idle, " \
3284 "usb_submit_urb() " \
3285 "failed with rc:\n", \
3286 peasycap->video_idle);
3291 /*****************************************************************************/
3292 /*---------------------------------------------------------------------------*/
3298 * THIS FUNCTION ASSUMES THAT, ON EACH AND EVERY OCCASION THAT THE DEVICE IS
3299 * PHYSICALLY PLUGGED IN, INTERFACE 0 IS PROBED FIRST.
3300 * IF THIS IS NOT TRUE, THERE IS THE POSSIBILITY OF AN Oops.
3302 * THIS HAS NEVER BEEN A PROBLEM IN PRACTICE, BUT SOMETHING SEEMS WRONG HERE.
3304 /*---------------------------------------------------------------------------*/
3306 easycap_usb_probe(struct usb_interface *pusb_interface, \
3307 const struct usb_device_id *id)
3309 struct usb_device *pusb_device, *pusb_device1;
3310 struct usb_host_interface *pusb_host_interface;
3311 struct usb_endpoint_descriptor *pepd;
3312 struct usb_interface_descriptor *pusb_interface_descriptor;
3313 struct usb_interface_assoc_descriptor *pusb_interface_assoc_descriptor;
3315 struct easycap *peasycap;
3316 struct data_urb *pdata_urb;
3317 size_t wMaxPacketSize;
3318 int ISOCwMaxPacketSize;
3319 int BULKwMaxPacketSize;
3320 int INTwMaxPacketSize;
3321 int CTRLwMaxPacketSize;
3322 __u8 bEndpointAddress;
3323 __u8 ISOCbEndpointAddress;
3324 __u8 INTbEndpointAddress;
3325 int isin, i, j, k, m, rc;
3326 __u8 bInterfaceNumber;
3327 __u8 bInterfaceClass;
3328 __u8 bInterfaceSubClass;
3330 int okalt[8], isokalt;
3336 struct easycap_format *peasycap_format;
3339 peasycap = (struct easycap *)NULL;
3341 if ((struct usb_interface *)NULL == pusb_interface) {
3342 SAY("ERROR: pusb_interface is NULL\n");
3345 /*---------------------------------------------------------------------------*/
3347 * GET POINTER TO STRUCTURE usb_device
3349 /*---------------------------------------------------------------------------*/
3350 pusb_device1 = container_of(pusb_interface->dev.parent, \
3351 struct usb_device, dev);
3352 if ((struct usb_device *)NULL == pusb_device1) {
3353 SAY("ERROR: pusb_device1 is NULL\n");
3356 pusb_device = usb_get_dev(pusb_device1);
3357 if ((struct usb_device *)NULL == pusb_device) {
3358 SAY("ERROR: pusb_device is NULL\n");
3361 if ((unsigned long int)pusb_device1 != (unsigned long int)pusb_device) {
3362 JOT(4, "ERROR: pusb_device1 != pusb_device\n");
3366 JOT(4, "bNumConfigurations=%i\n", pusb_device->descriptor.bNumConfigurations);
3368 /*---------------------------------------------------------------------------*/
3369 pusb_host_interface = pusb_interface->cur_altsetting;
3370 if (NULL == pusb_host_interface) {
3371 SAY("ERROR: pusb_host_interface is NULL\n");
3374 pusb_interface_descriptor = &(pusb_host_interface->desc);
3375 if (NULL == pusb_interface_descriptor) {
3376 SAY("ERROR: pusb_interface_descriptor is NULL\n");
3379 /*---------------------------------------------------------------------------*/
3381 * GET PROPERTIES OF PROBED INTERFACE
3383 /*---------------------------------------------------------------------------*/
3384 bInterfaceNumber = pusb_interface_descriptor->bInterfaceNumber;
3385 bInterfaceClass = pusb_interface_descriptor->bInterfaceClass;
3386 bInterfaceSubClass = pusb_interface_descriptor->bInterfaceSubClass;
3388 JOT(4, "intf[%i]: pusb_interface->num_altsetting=%i\n", \
3389 bInterfaceNumber, pusb_interface->num_altsetting);
3390 JOT(4, "intf[%i]: pusb_interface->cur_altsetting - " \
3391 "pusb_interface->altsetting=%li\n", bInterfaceNumber, \
3392 (long int)(pusb_interface->cur_altsetting - \
3393 pusb_interface->altsetting));
3394 switch (bInterfaceClass) {
3395 case USB_CLASS_AUDIO: {
3396 JOT(4, "intf[%i]: bInterfaceClass=0x%02X=USB_CLASS_AUDIO\n", \
3397 bInterfaceNumber, bInterfaceClass); break;
3399 case USB_CLASS_VIDEO: {
3400 JOT(4, "intf[%i]: bInterfaceClass=0x%02X=USB_CLASS_VIDEO\n", \
3401 bInterfaceNumber, bInterfaceClass); break;
3403 case USB_CLASS_VENDOR_SPEC: {
3404 JOT(4, "intf[%i]: bInterfaceClass=0x%02X=USB_CLASS_VENDOR_SPEC\n", \
3405 bInterfaceNumber, bInterfaceClass); break;
3410 switch (bInterfaceSubClass) {
3412 JOT(4, "intf[%i]: bInterfaceSubClass=0x%02X=AUDIOCONTROL\n", \
3413 bInterfaceNumber, bInterfaceSubClass); break;
3416 JOT(4, "intf[%i]: bInterfaceSubClass=0x%02X=AUDIOSTREAMING\n", \
3417 bInterfaceNumber, bInterfaceSubClass); break;
3420 JOT(4, "intf[%i]: bInterfaceSubClass=0x%02X=MIDISTREAMING\n", \
3421 bInterfaceNumber, bInterfaceSubClass); break;
3426 /*---------------------------------------------------------------------------*/
3427 pusb_interface_assoc_descriptor = pusb_interface->intf_assoc;
3428 if (NULL != pusb_interface_assoc_descriptor) {
3429 JOT(4, "intf[%i]: bFirstInterface=0x%02X bInterfaceCount=0x%02X\n", \
3431 pusb_interface_assoc_descriptor->bFirstInterface, \
3432 pusb_interface_assoc_descriptor->bInterfaceCount);
3434 JOT(4, "intf[%i]: pusb_interface_assoc_descriptor is NULL\n", \
3437 /*---------------------------------------------------------------------------*/
3439 * A NEW struct easycap IS ALWAYS ALLOCATED WHEN INTERFACE 0 IS PROBED.
3440 * IT IS NOT POSSIBLE HERE TO FREE ANY EXISTING struct easycap. THIS
3441 * SHOULD HAVE BEEN DONE BY easycap_delete() WHEN THE EasyCAP WAS
3442 * PHYSICALLY UNPLUGGED.
3444 * THE POINTER peasycap TO THE struct easycap IS REMEMBERED WHEN
3445 * INTERFACES 1 AND 2 ARE PROBED.
3447 * IF TWO EasyCAPs ARE PLUGGED IN NEARLY SIMULTANEOUSLY THERE WILL
3448 * BE TROUBLE. BEWARE.
3450 /*---------------------------------------------------------------------------*/
3451 if (0 == bInterfaceNumber) {
3452 peasycap = kzalloc(sizeof(struct easycap), GFP_KERNEL);
3453 if (NULL == peasycap) {
3454 SAY("ERROR: Could not allocate peasycap\n");
3457 SAM("allocated 0x%08lX=peasycap\n", (unsigned long int) peasycap);
3458 /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
3459 #if defined(EASYCAP_IS_VIDEODEV_CLIENT)
3460 SAM("where 0x%08lX=&peasycap->video_device\n", \
3461 (unsigned long int) &peasycap->video_device);
3462 #if defined(EASYCAP_NEEDS_V4L2_DEVICE_H)
3463 SAM("and 0x%08lX=&peasycap->v4l2_device\n", \
3464 (unsigned long int) &peasycap->v4l2_device);
3465 #endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/
3466 #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
3467 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
3468 /*---------------------------------------------------------------------------*/
3470 * PERFORM URGENT INTIALIZATIONS ...
3472 /*---------------------------------------------------------------------------*/
3473 kref_init(&peasycap->kref);
3474 JOM(8, "intf[%i]: after kref_init(..._video) " \
3475 "%i=peasycap->kref.refcount.counter\n", \
3476 bInterfaceNumber, peasycap->kref.refcount.counter);
3478 init_waitqueue_head(&peasycap->wq_video);
3479 init_waitqueue_head(&peasycap->wq_audio);
3481 for (dongle_this = 0; dongle_this < DONGLE_MANY; dongle_this++) {
3482 if ((struct easycap *)NULL == peasycap_dongle[dongle_this]) {
3483 peasycap_dongle[dongle_this] = peasycap;
3484 JOM(8, "intf[%i]: peasycap-->easycap" \
3485 "_dongle[%i].peasycap\n", \
3486 bInterfaceNumber, dongle_this);
3490 if (DONGLE_MANY <= dongle_this) {
3491 SAM("ERROR: too many dongles\n");
3495 peasycap->allocation_video_struct = sizeof(struct easycap);
3496 peasycap->allocation_video_page = 0;
3497 peasycap->allocation_video_urb = 0;
3498 peasycap->allocation_audio_struct = 0;
3499 peasycap->allocation_audio_page = 0;
3500 peasycap->allocation_audio_urb = 0;
3502 /*---------------------------------------------------------------------------*/
3504 * ... AND FURTHER INITIALIZE THE STRUCTURE
3506 /*---------------------------------------------------------------------------*/
3507 peasycap->pusb_device = pusb_device;
3508 peasycap->pusb_interface = pusb_interface;
3511 peasycap->microphone = false;
3513 peasycap->video_interface = -1;
3514 peasycap->video_altsetting_on = -1;
3515 peasycap->video_altsetting_off = -1;
3516 peasycap->video_endpointnumber = -1;
3517 peasycap->video_isoc_maxframesize = -1;
3518 peasycap->video_isoc_buffer_size = -1;
3520 peasycap->audio_interface = -1;
3521 peasycap->audio_altsetting_on = -1;
3522 peasycap->audio_altsetting_off = -1;
3523 peasycap->audio_endpointnumber = -1;
3524 peasycap->audio_isoc_maxframesize = -1;
3525 peasycap->audio_isoc_buffer_size = -1;
3527 peasycap->frame_buffer_many = FRAME_BUFFER_MANY;
3529 for (k = 0; k < INPUT_MANY; k++)
3530 peasycap->lost[k] = 0;
3532 peasycap->skipped = 0;
3533 peasycap->offerfields = 0;
3534 /*---------------------------------------------------------------------------*/
3536 * DYNAMICALLY FILL IN THE AVAILABLE FORMATS ...
3538 /*---------------------------------------------------------------------------*/
3539 rc = fillin_formats();
3541 SAM("ERROR: fillin_formats() returned %i\n", rc);
3544 JOM(4, "%i formats available\n", rc);
3545 /*---------------------------------------------------------------------------*/
3547 * ... AND POPULATE easycap.inputset[]
3549 /*---------------------------------------------------------------------------*/
3550 for (k = 0; k < INPUT_MANY; k++) {
3551 peasycap->inputset[k].input_ok = 0;
3552 peasycap->inputset[k].standard_offset_ok = 0;
3553 peasycap->inputset[k].format_offset_ok = 0;
3554 peasycap->inputset[k].brightness_ok = 0;
3555 peasycap->inputset[k].contrast_ok = 0;
3556 peasycap->inputset[k].saturation_ok = 0;
3557 peasycap->inputset[k].hue_ok = 0;
3559 if (true == peasycap->ntsc) {
3563 while (0xFFFF != easycap_standard[i].mask) {
3564 if (NTSC_M == easycap_standard[i].\
3565 v4l2_standard.index) {
3567 for (k = 0; k < INPUT_MANY; k++) {
3568 peasycap->inputset[k].\
3569 standard_offset = i;
3571 mask = easycap_standard[i].mask;
3579 while (0xFFFF != easycap_standard[i].mask) {
3580 if (PAL_BGHIN == easycap_standard[i].\
3581 v4l2_standard.index) {
3583 for (k = 0; k < INPUT_MANY; k++) {
3584 peasycap->inputset[k].\
3585 standard_offset = i;
3587 mask = easycap_standard[i].mask;
3594 SAM("MISTAKE: easycap.inputset[].standard_offset " \
3595 "unpopulated, %i=m\n", m);
3599 peasycap_format = &easycap_format[0];
3602 while (0 != peasycap_format->v4l2_format.fmt.pix.width) {
3603 if (((peasycap_format->mask & 0x0F) == (mask & 0x0F)) && \
3605 v4l2_format.fmt.pix.field == \
3606 V4L2_FIELD_NONE) && \
3608 v4l2_format.fmt.pix.pixelformat == \
3609 V4L2_PIX_FMT_UYVY) && \
3611 v4l2_format.fmt.pix.width == \
3614 v4l2_format.fmt.pix.height == 480)) {
3616 for (k = 0; k < INPUT_MANY; k++)
3617 peasycap->inputset[k].format_offset = i;
3624 SAM("MISTAKE: easycap.inputset[].format_offset unpopulated\n");
3630 while (0xFFFFFFFF != easycap_control[i].id) {
3631 value = easycap_control[i].default_value;
3632 if (V4L2_CID_BRIGHTNESS == easycap_control[i].id) {
3634 for (k = 0; k < INPUT_MANY; k++)
3635 peasycap->inputset[k].brightness = value;
3636 } else if (V4L2_CID_CONTRAST == easycap_control[i].id) {
3638 for (k = 0; k < INPUT_MANY; k++)
3639 peasycap->inputset[k].contrast = value;
3640 } else if (V4L2_CID_SATURATION == easycap_control[i].id) {
3642 for (k = 0; k < INPUT_MANY; k++)
3643 peasycap->inputset[k].saturation = value;
3644 } else if (V4L2_CID_HUE == easycap_control[i].id) {
3646 for (k = 0; k < INPUT_MANY; k++)
3647 peasycap->inputset[k].hue = value;
3652 SAM("MISTAKE: easycap.inputset[].brightness,... " \
3653 "underpopulated\n");
3656 for (k = 0; k < INPUT_MANY; k++)
3657 peasycap->inputset[k].input = k;
3658 JOM(4, "populated easycap.inputset[]\n");
3659 JOM(4, "finished initialization\n");
3661 /*---------------------------------------------------------------------------*/
3663 * FOR INTERFACES 1 AND 2 THE POINTER peasycap IS OBTAINED BY ASSUMING
3664 * THAT dongle_this HAS NOT CHANGED SINCE INTERFACE 0 WAS PROBED. IF
3665 * THIS IS NOT THE CASE, FOR EXAMPLE WHEN TWO EASYCAPs ARE PLUGGED IN
3666 * SIMULTANEOUSLY, THERE WILL BE VERY SERIOUS TROUBLE.
3668 /*---------------------------------------------------------------------------*/
3669 if ((0 > dongle_this) || (DONGLE_MANY <= dongle_this)) {
3670 SAY("ERROR: bad dongle count\n");
3673 peasycap = peasycap_dongle[dongle_this];
3674 JOT(8, "intf[%i]: peasycap_dongle[%i]-->peasycap\n", \
3675 bInterfaceNumber, dongle_this);
3677 if ((struct easycap *)NULL == peasycap) {
3678 SAY("ERROR: peasycap is NULL when probing interface %i\n", \
3683 /*---------------------------------------------------------------------------*/
3684 if ((USB_CLASS_VIDEO == bInterfaceClass) || \
3685 (USB_CLASS_VENDOR_SPEC == bInterfaceClass)) {
3686 if (-1 == peasycap->video_interface) {
3687 peasycap->video_interface = bInterfaceNumber;
3688 JOM(4, "setting peasycap->video_interface=%i\n", \
3689 peasycap->video_interface);
3691 if (peasycap->video_interface != bInterfaceNumber) {
3692 SAM("ERROR: attempting to reset " \
3693 "peasycap->video_interface\n");
3694 SAM("...... continuing with " \
3695 "%i=peasycap->video_interface\n", \
3696 peasycap->video_interface);
3699 } else if ((USB_CLASS_AUDIO == bInterfaceClass) && \
3700 (0x02 == bInterfaceSubClass)) {
3701 if (-1 == peasycap->audio_interface) {
3702 peasycap->audio_interface = bInterfaceNumber;
3703 JOM(4, "setting peasycap->audio_interface=%i\n", \
3704 peasycap->audio_interface);
3706 if (peasycap->audio_interface != bInterfaceNumber) {
3707 SAM("ERROR: attempting to reset " \
3708 "peasycap->audio_interface\n");
3709 SAM("...... continuing with " \
3710 "%i=peasycap->audio_interface\n", \
3711 peasycap->audio_interface);
3715 /*---------------------------------------------------------------------------*/
3717 * INVESTIGATE ALL ALTSETTINGS.
3718 * DONE IN DETAIL BECAUSE USB DEVICE 05e1:0408 HAS DISPARATE INCARNATIONS.
3720 /*---------------------------------------------------------------------------*/
3722 for (i = 0; i < pusb_interface->num_altsetting; i++) {
3723 pusb_host_interface = &(pusb_interface->altsetting[i]);
3724 if ((struct usb_host_interface *)NULL == pusb_host_interface) {
3725 SAM("ERROR: pusb_host_interface is NULL\n");
3728 pusb_interface_descriptor = &(pusb_host_interface->desc);
3729 if ((struct usb_interface_descriptor *)NULL == \
3730 pusb_interface_descriptor) {
3731 SAM("ERROR: pusb_interface_descriptor is NULL\n");
3735 JOM(4, "intf[%i]alt[%i]: desc.bDescriptorType=0x%02X\n", \
3736 bInterfaceNumber, i, pusb_interface_descriptor->bDescriptorType);
3737 JOM(4, "intf[%i]alt[%i]: desc.bInterfaceNumber=0x%02X\n", \
3738 bInterfaceNumber, i, pusb_interface_descriptor->bInterfaceNumber);
3739 JOM(4, "intf[%i]alt[%i]: desc.bAlternateSetting=0x%02X\n", \
3740 bInterfaceNumber, i, pusb_interface_descriptor->bAlternateSetting);
3741 JOM(4, "intf[%i]alt[%i]: desc.bNumEndpoints=0x%02X\n", \
3742 bInterfaceNumber, i, pusb_interface_descriptor->bNumEndpoints);
3743 JOM(4, "intf[%i]alt[%i]: desc.bInterfaceClass=0x%02X\n", \
3744 bInterfaceNumber, i, pusb_interface_descriptor->bInterfaceClass);
3745 JOM(4, "intf[%i]alt[%i]: desc.bInterfaceSubClass=0x%02X\n", \
3746 bInterfaceNumber, i, pusb_interface_descriptor->bInterfaceSubClass);
3747 JOM(4, "intf[%i]alt[%i]: desc.bInterfaceProtocol=0x%02X\n", \
3748 bInterfaceNumber, i, pusb_interface_descriptor->bInterfaceProtocol);
3749 JOM(4, "intf[%i]alt[%i]: desc.iInterface=0x%02X\n", \
3750 bInterfaceNumber, i, pusb_interface_descriptor->iInterface);
3752 ISOCwMaxPacketSize = -1;
3753 BULKwMaxPacketSize = -1;
3754 INTwMaxPacketSize = -1;
3755 CTRLwMaxPacketSize = -1;
3756 ISOCbEndpointAddress = 0;
3757 INTbEndpointAddress = 0;
3759 if (0 == pusb_interface_descriptor->bNumEndpoints)
3760 JOM(4, "intf[%i]alt[%i] has no endpoints\n", \
3761 bInterfaceNumber, i);
3762 /*---------------------------------------------------------------------------*/
3763 for (j = 0; j < pusb_interface_descriptor->bNumEndpoints; j++) {
3764 pepd = &(pusb_host_interface->endpoint[j].desc);
3765 if ((struct usb_endpoint_descriptor *)NULL == pepd) {
3766 SAM("ERROR: pepd is NULL.\n");
3767 SAM("...... skipping\n");
3770 wMaxPacketSize = le16_to_cpu(pepd->wMaxPacketSize);
3771 bEndpointAddress = pepd->bEndpointAddress;
3773 JOM(4, "intf[%i]alt[%i]end[%i]: bEndpointAddress=0x%X\n", \
3774 bInterfaceNumber, i, j, \
3775 pepd->bEndpointAddress);
3776 JOM(4, "intf[%i]alt[%i]end[%i]: bmAttributes=0x%X\n", \
3777 bInterfaceNumber, i, j, \
3778 pepd->bmAttributes);
3779 JOM(4, "intf[%i]alt[%i]end[%i]: wMaxPacketSize=%i\n", \
3780 bInterfaceNumber, i, j, \
3781 pepd->wMaxPacketSize);
3782 JOM(4, "intf[%i]alt[%i]end[%i]: bInterval=%i\n",
3783 bInterfaceNumber, i, j, \
3786 if (pepd->bEndpointAddress & USB_DIR_IN) {
3787 JOM(4, "intf[%i]alt[%i]end[%i] is an IN endpoint\n",\
3788 bInterfaceNumber, i, j);
3791 JOM(4, "intf[%i]alt[%i]end[%i] is an OUT endpoint\n",\
3792 bInterfaceNumber, i, j);
3793 SAM("ERROR: OUT endpoint unexpected\n");
3794 SAM("...... continuing\n");
3797 if ((pepd->bmAttributes & \
3798 USB_ENDPOINT_XFERTYPE_MASK) == \
3799 USB_ENDPOINT_XFER_ISOC) {
3800 JOM(4, "intf[%i]alt[%i]end[%i] is an ISOC endpoint\n",\
3801 bInterfaceNumber, i, j);
3803 switch (bInterfaceClass) {
3804 case USB_CLASS_VIDEO:
3805 case USB_CLASS_VENDOR_SPEC: {
3808 "peasycap is NULL\n");
3811 if (pepd->wMaxPacketSize) {
3820 bEndpointAddress & \
3836 if (-1 == peasycap->\
3837 video_altsetting_off) {
3839 video_altsetting_off =\
3841 JOM(4, "%i=video_" \
3845 video_altsetting_off);
3847 SAM("ERROR: peasycap" \
3848 "->video_altsetting_" \
3849 "off already set\n");
3851 "continuing with " \
3852 "%i=peasycap->video_" \
3853 "altsetting_off\n", \
3855 video_altsetting_off);
3860 case USB_CLASS_AUDIO: {
3861 if (0x02 != bInterfaceSubClass)
3865 "peasycap is NULL\n");
3868 if (pepd->wMaxPacketSize) {
3870 okalt[isokalt] = i ;
3877 bEndpointAddress & \
3893 if (-1 == peasycap->\
3894 audio_altsetting_off) {
3896 audio_altsetting_off =\
3898 JOM(4, "%i=audio_" \
3902 audio_altsetting_off);
3904 SAM("ERROR: peasycap" \
3905 "->audio_altsetting_" \
3906 "off already set\n");
3908 "continuing with " \
3910 audio_altsetting_" \
3913 audio_altsetting_off);
3922 } else if ((pepd->bmAttributes & \
3923 USB_ENDPOINT_XFERTYPE_MASK) ==\
3924 USB_ENDPOINT_XFER_BULK) {
3925 JOM(4, "intf[%i]alt[%i]end[%i] is a BULK endpoint\n",\
3926 bInterfaceNumber, i, j);
3927 } else if ((pepd->bmAttributes & \
3928 USB_ENDPOINT_XFERTYPE_MASK) ==\
3929 USB_ENDPOINT_XFER_INT) {
3930 JOM(4, "intf[%i]alt[%i]end[%i] is an INT endpoint\n",\
3931 bInterfaceNumber, i, j);
3933 JOM(4, "intf[%i]alt[%i]end[%i] is a CTRL endpoint\n",\
3934 bInterfaceNumber, i, j);
3936 if (0 == pepd->wMaxPacketSize) {
3937 JOM(4, "intf[%i]alt[%i]end[%i] " \
3938 "has zero packet size\n", \
3939 bInterfaceNumber, i, j);
3943 /*---------------------------------------------------------------------------*/
3945 * PERFORM INITIALIZATION OF THE PROBED INTERFACE
3947 /*---------------------------------------------------------------------------*/
3948 JOM(4, "initialization begins for interface %i\n", \
3949 pusb_interface_descriptor->bInterfaceNumber);
3950 switch (bInterfaceNumber) {
3951 /*---------------------------------------------------------------------------*/
3953 * INTERFACE 0 IS THE VIDEO INTERFACE
3955 /*---------------------------------------------------------------------------*/
3958 SAM("MISTAKE: peasycap is NULL\n");
3962 SAM("ERROR: no viable video_altsetting_on\n");
3965 peasycap->video_altsetting_on = okalt[isokalt - 1];
3966 JOM(4, "%i=video_altsetting_on <====\n", \
3967 peasycap->video_altsetting_on);
3969 /*---------------------------------------------------------------------------*/
3971 * DECIDE THE VIDEO STREAMING PARAMETERS
3973 /*---------------------------------------------------------------------------*/
3974 peasycap->video_endpointnumber = okepn[isokalt - 1];
3975 JOM(4, "%i=video_endpointnumber\n", peasycap->video_endpointnumber);
3976 maxpacketsize = okmps[isokalt - 1];
3977 if (USB_2_0_MAXPACKETSIZE > maxpacketsize) {
3978 peasycap->video_isoc_maxframesize = maxpacketsize;
3980 peasycap->video_isoc_maxframesize = \
3981 USB_2_0_MAXPACKETSIZE;
3983 JOM(4, "%i=video_isoc_maxframesize\n", \
3984 peasycap->video_isoc_maxframesize);
3985 if (0 >= peasycap->video_isoc_maxframesize) {
3986 SAM("ERROR: bad video_isoc_maxframesize\n");
3987 SAM(" possibly because port is USB 1.1\n");
3990 peasycap->video_isoc_framesperdesc = VIDEO_ISOC_FRAMESPERDESC;
3991 JOM(4, "%i=video_isoc_framesperdesc\n", \
3992 peasycap->video_isoc_framesperdesc);
3993 if (0 >= peasycap->video_isoc_framesperdesc) {
3994 SAM("ERROR: bad video_isoc_framesperdesc\n");
3997 peasycap->video_isoc_buffer_size = \
3998 peasycap->video_isoc_maxframesize * \
3999 peasycap->video_isoc_framesperdesc;
4000 JOM(4, "%i=video_isoc_buffer_size\n", \
4001 peasycap->video_isoc_buffer_size);
4002 if ((PAGE_SIZE << VIDEO_ISOC_ORDER) < \
4003 peasycap->video_isoc_buffer_size) {
4004 SAM("MISTAKE: peasycap->video_isoc_buffer_size too big\n");
4007 /*---------------------------------------------------------------------------*/
4008 if (-1 == peasycap->video_interface) {
4009 SAM("MISTAKE: video_interface is unset\n");
4012 if (-1 == peasycap->video_altsetting_on) {
4013 SAM("MISTAKE: video_altsetting_on is unset\n");
4016 if (-1 == peasycap->video_altsetting_off) {
4017 SAM("MISTAKE: video_interface_off is unset\n");
4020 if (-1 == peasycap->video_endpointnumber) {
4021 SAM("MISTAKE: video_endpointnumber is unset\n");
4024 if (-1 == peasycap->video_isoc_maxframesize) {
4025 SAM("MISTAKE: video_isoc_maxframesize is unset\n");
4028 if (-1 == peasycap->video_isoc_buffer_size) {
4029 SAM("MISTAKE: video_isoc_buffer_size is unset\n");
4032 /*---------------------------------------------------------------------------*/
4034 * ALLOCATE MEMORY FOR VIDEO BUFFERS. LISTS MUST BE INITIALIZED FIRST.
4036 /*---------------------------------------------------------------------------*/
4037 INIT_LIST_HEAD(&(peasycap->urb_video_head));
4038 peasycap->purb_video_head = &(peasycap->urb_video_head);
4039 /*---------------------------------------------------------------------------*/
4040 JOM(4, "allocating %i frame buffers of size %li\n", \
4041 FRAME_BUFFER_MANY, (long int)FRAME_BUFFER_SIZE);
4042 JOM(4, ".... each scattered over %li pages\n", \
4043 FRAME_BUFFER_SIZE/PAGE_SIZE);
4045 for (k = 0; k < FRAME_BUFFER_MANY; k++) {
4046 for (m = 0; m < FRAME_BUFFER_SIZE/PAGE_SIZE; m++) {
4047 if ((void *)NULL != peasycap->frame_buffer[k][m].pgo)
4048 SAM("attempting to reallocate frame " \
4051 pbuf = (void *)__get_free_page(GFP_KERNEL);
4052 if ((void *)NULL == pbuf) {
4053 SAM("ERROR: Could not allocate frame "\
4054 "buffer %i page %i\n", k, m);
4057 peasycap->allocation_video_page += 1;
4058 peasycap->frame_buffer[k][m].pgo = pbuf;
4060 peasycap->frame_buffer[k][m].pto = \
4061 peasycap->frame_buffer[k][m].pgo;
4065 peasycap->frame_fill = 0;
4066 peasycap->frame_read = 0;
4067 JOM(4, "allocation of frame buffers done: %i pages\n", k * \
4069 /*---------------------------------------------------------------------------*/
4070 JOM(4, "allocating %i field buffers of size %li\n", \
4071 FIELD_BUFFER_MANY, (long int)FIELD_BUFFER_SIZE);
4072 JOM(4, ".... each scattered over %li pages\n", \
4073 FIELD_BUFFER_SIZE/PAGE_SIZE);
4075 for (k = 0; k < FIELD_BUFFER_MANY; k++) {
4076 for (m = 0; m < FIELD_BUFFER_SIZE/PAGE_SIZE; m++) {
4077 if ((void *)NULL != peasycap->field_buffer[k][m].pgo) {
4078 SAM("ERROR: attempting to reallocate " \
4081 pbuf = (void *) __get_free_page(GFP_KERNEL);
4082 if ((void *)NULL == pbuf) {
4083 SAM("ERROR: Could not allocate field" \
4084 " buffer %i page %i\n", k, m);
4088 peasycap->allocation_video_page += 1;
4089 peasycap->field_buffer[k][m].pgo = pbuf;
4091 peasycap->field_buffer[k][m].pto = \
4092 peasycap->field_buffer[k][m].pgo;
4094 peasycap->field_buffer[k][0].kount = 0x0200;
4096 peasycap->field_fill = 0;
4097 peasycap->field_page = 0;
4098 peasycap->field_read = 0;
4099 JOM(4, "allocation of field buffers done: %i pages\n", k * \
4101 /*---------------------------------------------------------------------------*/
4102 JOM(4, "allocating %i isoc video buffers of size %i\n", \
4103 VIDEO_ISOC_BUFFER_MANY, \
4104 peasycap->video_isoc_buffer_size);
4105 JOM(4, ".... each occupying contiguous memory pages\n");
4107 for (k = 0; k < VIDEO_ISOC_BUFFER_MANY; k++) {
4108 pbuf = (void *)__get_free_pages(GFP_KERNEL, VIDEO_ISOC_ORDER);
4110 SAM("ERROR: Could not allocate isoc video buffer " \
4114 peasycap->allocation_video_page += \
4115 ((unsigned int)(0x01 << VIDEO_ISOC_ORDER));
4117 peasycap->video_isoc_buffer[k].pgo = pbuf;
4118 peasycap->video_isoc_buffer[k].pto = pbuf + \
4119 peasycap->video_isoc_buffer_size;
4120 peasycap->video_isoc_buffer[k].kount = k;
4122 JOM(4, "allocation of isoc video buffers done: %i pages\n", \
4123 k * (0x01 << VIDEO_ISOC_ORDER));
4124 /*---------------------------------------------------------------------------*/
4126 * ALLOCATE AND INITIALIZE MULTIPLE struct urb ...
4128 /*---------------------------------------------------------------------------*/
4129 JOM(4, "allocating %i struct urb.\n", VIDEO_ISOC_BUFFER_MANY);
4130 JOM(4, "using %i=peasycap->video_isoc_framesperdesc\n", \
4131 peasycap->video_isoc_framesperdesc);
4132 JOM(4, "using %i=peasycap->video_isoc_maxframesize\n", \
4133 peasycap->video_isoc_maxframesize);
4134 JOM(4, "using %i=peasycap->video_isoc_buffer_sizen", \
4135 peasycap->video_isoc_buffer_size);
4137 for (k = 0; k < VIDEO_ISOC_BUFFER_MANY; k++) {
4138 purb = usb_alloc_urb(peasycap->video_isoc_framesperdesc, \
4141 SAM("ERROR: usb_alloc_urb returned NULL for buffer " \
4145 peasycap->allocation_video_urb += 1;
4146 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
4147 pdata_urb = kzalloc(sizeof(struct data_urb), GFP_KERNEL);
4148 if (NULL == pdata_urb) {
4149 SAM("ERROR: Could not allocate struct data_urb.\n");
4152 peasycap->allocation_video_struct += \
4153 sizeof(struct data_urb);
4155 pdata_urb->purb = purb;
4156 pdata_urb->isbuf = k;
4157 pdata_urb->length = 0;
4158 list_add_tail(&(pdata_urb->list_head), \
4159 peasycap->purb_video_head);
4160 /*---------------------------------------------------------------------------*/
4162 * ... AND INITIALIZE THEM
4164 /*---------------------------------------------------------------------------*/
4166 JOM(4, "initializing video urbs thus:\n");
4167 JOM(4, " purb->interval = 1;\n");
4168 JOM(4, " purb->dev = peasycap->pusb_device;\n");
4169 JOM(4, " purb->pipe = usb_rcvisocpipe" \
4170 "(peasycap->pusb_device,%i);\n", \
4171 peasycap->video_endpointnumber);
4172 JOM(4, " purb->transfer_flags = URB_ISO_ASAP;\n");
4173 JOM(4, " purb->transfer_buffer = peasycap->" \
4174 "video_isoc_buffer[.].pgo;\n");
4175 JOM(4, " purb->transfer_buffer_length = %i;\n", \
4176 peasycap->video_isoc_buffer_size);
4177 JOM(4, " purb->complete = easycap_complete;\n");
4178 JOM(4, " purb->context = peasycap;\n");
4179 JOM(4, " purb->start_frame = 0;\n");
4180 JOM(4, " purb->number_of_packets = %i;\n", \
4181 peasycap->video_isoc_framesperdesc);
4182 JOM(4, " for (j = 0; j < %i; j++)\n", \
4183 peasycap->video_isoc_framesperdesc);
4185 JOM(4, " purb->iso_frame_desc[j].offset = j*%i;\n",\
4186 peasycap->video_isoc_maxframesize);
4187 JOM(4, " purb->iso_frame_desc[j].length = %i;\n", \
4188 peasycap->video_isoc_maxframesize);
4193 purb->dev = peasycap->pusb_device;
4194 purb->pipe = usb_rcvisocpipe(peasycap->pusb_device, \
4195 peasycap->video_endpointnumber);
4196 purb->transfer_flags = URB_ISO_ASAP;
4197 purb->transfer_buffer = peasycap->video_isoc_buffer[k].pgo;
4198 purb->transfer_buffer_length = \
4199 peasycap->video_isoc_buffer_size;
4200 purb->complete = easycap_complete;
4201 purb->context = peasycap;
4202 purb->start_frame = 0;
4203 purb->number_of_packets = peasycap->video_isoc_framesperdesc;
4204 for (j = 0; j < peasycap->video_isoc_framesperdesc; j++) {
4205 purb->iso_frame_desc[j].offset = j * \
4206 peasycap->video_isoc_maxframesize;
4207 purb->iso_frame_desc[j].length = \
4208 peasycap->video_isoc_maxframesize;
4211 JOM(4, "allocation of %i struct urb done.\n", k);
4212 /*--------------------------------------------------------------------------*/
4214 * SAVE POINTER peasycap IN THIS INTERFACE.
4216 /*--------------------------------------------------------------------------*/
4217 usb_set_intfdata(pusb_interface, peasycap);
4218 /*--------------------------------------------------------------------------*/
4220 * THE VIDEO DEVICE CAN BE REGISTERED NOW, AS IT IS READY.
4222 /*--------------------------------------------------------------------------*/
4223 #if (!defined(EASYCAP_IS_VIDEODEV_CLIENT))
4224 if (0 != (usb_register_dev(pusb_interface, &easycap_class))) {
4225 err("Not able to get a minor for this device");
4226 usb_set_intfdata(pusb_interface, NULL);
4229 (peasycap->registered_video)++;
4230 SAM("easycap attached to minor #%d\n", pusb_interface->minor);
4233 /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
4235 #if defined(EASYCAP_NEEDS_V4L2_DEVICE_H)
4236 if (0 != (v4l2_device_register(&(pusb_interface->dev), \
4237 &(peasycap->v4l2_device)))) {
4238 SAM("v4l2_device_register() failed\n");
4241 JOM(4, "registered device instance: %s\n", \
4242 &(peasycap->v4l2_device.name[0]));
4244 /*---------------------------------------------------------------------------*/
4246 * THIS IS BELIEVED TO BE HARMLESS, BUT MAY WELL BE UNNECESSARY OR WRONG:
4248 /*---------------------------------------------------------------------------*/
4249 peasycap->video_device.v4l2_dev = (struct v4l2_device *)NULL;
4250 /*---------------------------------------------------------------------------*/
4252 #endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/
4254 strcpy(&peasycap->video_device.name[0], "easycapdc60");
4255 #if defined(EASYCAP_NEEDS_V4L2_FOPS)
4256 peasycap->video_device.fops = &v4l2_fops;
4258 peasycap->video_device.fops = &easycap_fops;
4259 #endif /*EASYCAP_NEEDS_V4L2_FOPS*/
4260 peasycap->video_device.minor = -1;
4261 peasycap->video_device.release = (void *)(&videodev_release);
4263 video_set_drvdata(&(peasycap->video_device), (void *)peasycap);
4265 if (0 != (video_register_device(&(peasycap->video_device), \
4266 VFL_TYPE_GRABBER, -1))) {
4267 err("Not able to register with videodev");
4268 videodev_release(&(peasycap->video_device));
4271 (peasycap->registered_video)++;
4272 SAM("registered with videodev: %i=minor\n", \
4273 peasycap->video_device.minor);
4275 #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
4276 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
4279 /*--------------------------------------------------------------------------*/
4281 * INTERFACE 1 IS THE AUDIO CONTROL INTERFACE
4282 * INTERFACE 2 IS THE AUDIO STREAMING INTERFACE
4284 /*--------------------------------------------------------------------------*/
4287 SAM("ERROR: peasycap is NULL\n");
4290 /*--------------------------------------------------------------------------*/
4292 * SAVE POINTER peasycap IN INTERFACE 1
4294 /*--------------------------------------------------------------------------*/
4295 usb_set_intfdata(pusb_interface, peasycap);
4296 JOM(4, "no initialization required for interface %i\n", \
4297 pusb_interface_descriptor->bInterfaceNumber);
4300 /*--------------------------------------------------------------------------*/
4303 SAM("MISTAKE: peasycap is NULL\n");
4307 SAM("ERROR: no viable audio_altsetting_on\n");
4310 peasycap->audio_altsetting_on = okalt[isokalt - 1];
4311 JOM(4, "%i=audio_altsetting_on <====\n", \
4312 peasycap->audio_altsetting_on);
4315 peasycap->audio_endpointnumber = okepn[isokalt - 1];
4316 JOM(4, "%i=audio_endpointnumber\n", peasycap->audio_endpointnumber);
4318 peasycap->audio_isoc_maxframesize = okmps[isokalt - 1];
4319 JOM(4, "%i=audio_isoc_maxframesize\n", \
4320 peasycap->audio_isoc_maxframesize);
4321 if (0 >= peasycap->audio_isoc_maxframesize) {
4322 SAM("ERROR: bad audio_isoc_maxframesize\n");
4325 if (9 == peasycap->audio_isoc_maxframesize) {
4326 peasycap->ilk |= 0x02;
4327 SAM("hardware is FOUR-CVBS\n");
4328 peasycap->microphone = true;
4329 peasycap->audio_pages_per_fragment = 4;
4330 } else if (256 == peasycap->audio_isoc_maxframesize) {
4331 peasycap->ilk &= ~0x02;
4332 SAM("hardware is CVBS+S-VIDEO\n");
4333 peasycap->microphone = false;
4334 peasycap->audio_pages_per_fragment = 4;
4336 SAM("hardware is unidentified:\n");
4337 SAM("%i=audio_isoc_maxframesize\n", \
4338 peasycap->audio_isoc_maxframesize);
4342 peasycap->audio_bytes_per_fragment = \
4343 peasycap->audio_pages_per_fragment * \
4345 peasycap->audio_buffer_page_many = (AUDIO_FRAGMENT_MANY * \
4346 peasycap->audio_pages_per_fragment);
4348 JOM(4, "%6i=AUDIO_FRAGMENT_MANY\n", AUDIO_FRAGMENT_MANY);
4349 JOM(4, "%6i=audio_pages_per_fragment\n", \
4350 peasycap->audio_pages_per_fragment);
4351 JOM(4, "%6i=audio_bytes_per_fragment\n", \
4352 peasycap->audio_bytes_per_fragment);
4353 JOM(4, "%6i=audio_buffer_page_many\n", \
4354 peasycap->audio_buffer_page_many);
4356 peasycap->audio_isoc_framesperdesc = 128;
4358 JOM(4, "%i=audio_isoc_framesperdesc\n", \
4359 peasycap->audio_isoc_framesperdesc);
4360 if (0 >= peasycap->audio_isoc_framesperdesc) {
4361 SAM("ERROR: bad audio_isoc_framesperdesc\n");
4365 peasycap->audio_isoc_buffer_size = \
4366 peasycap->audio_isoc_maxframesize * \
4367 peasycap->audio_isoc_framesperdesc;
4368 JOM(4, "%i=audio_isoc_buffer_size\n", \
4369 peasycap->audio_isoc_buffer_size);
4370 if (AUDIO_ISOC_BUFFER_SIZE < peasycap->audio_isoc_buffer_size) {
4371 SAM("MISTAKE: audio_isoc_buffer_size bigger "
4372 "than %li=AUDIO_ISOC_BUFFER_SIZE\n", \
4373 AUDIO_ISOC_BUFFER_SIZE);
4376 if (-1 == peasycap->audio_interface) {
4377 SAM("MISTAKE: audio_interface is unset\n");
4380 if (-1 == peasycap->audio_altsetting_on) {
4381 SAM("MISTAKE: audio_altsetting_on is unset\n");
4384 if (-1 == peasycap->audio_altsetting_off) {
4385 SAM("MISTAKE: audio_interface_off is unset\n");
4388 if (-1 == peasycap->audio_endpointnumber) {
4389 SAM("MISTAKE: audio_endpointnumber is unset\n");
4392 if (-1 == peasycap->audio_isoc_maxframesize) {
4393 SAM("MISTAKE: audio_isoc_maxframesize is unset\n");
4396 if (-1 == peasycap->audio_isoc_buffer_size) {
4397 SAM("MISTAKE: audio_isoc_buffer_size is unset\n");
4400 /*---------------------------------------------------------------------------*/
4402 * ALLOCATE MEMORY FOR AUDIO BUFFERS. LISTS MUST BE INITIALIZED FIRST.
4404 /*---------------------------------------------------------------------------*/
4405 INIT_LIST_HEAD(&(peasycap->urb_audio_head));
4406 peasycap->purb_audio_head = &(peasycap->urb_audio_head);
4408 JOM(4, "allocating an audio buffer\n");
4409 JOM(4, ".... scattered over %i pages\n", \
4410 peasycap->audio_buffer_page_many);
4412 for (k = 0; k < peasycap->audio_buffer_page_many; k++) {
4413 if ((void *)NULL != peasycap->audio_buffer[k].pgo) {
4414 SAM("ERROR: attempting to reallocate audio buffers\n");
4416 pbuf = (void *) __get_free_page(GFP_KERNEL);
4417 if ((void *)NULL == pbuf) {
4418 SAM("ERROR: Could not allocate audio " \
4419 "buffer page %i\n", k);
4422 peasycap->allocation_audio_page += 1;
4424 peasycap->audio_buffer[k].pgo = pbuf;
4426 peasycap->audio_buffer[k].pto = peasycap->audio_buffer[k].pgo;
4429 peasycap->audio_fill = 0;
4430 peasycap->audio_read = 0;
4431 JOM(4, "allocation of audio buffer done: %i pages\n", k);
4432 /*---------------------------------------------------------------------------*/
4433 JOM(4, "allocating %i isoc audio buffers of size %i\n", \
4434 AUDIO_ISOC_BUFFER_MANY, peasycap->audio_isoc_buffer_size);
4435 JOM(4, ".... each occupying contiguous memory pages\n");
4437 for (k = 0; k < AUDIO_ISOC_BUFFER_MANY; k++) {
4438 pbuf = (void *)__get_free_pages(GFP_KERNEL, AUDIO_ISOC_ORDER);
4440 SAM("ERROR: Could not allocate isoc audio buffer " \
4444 peasycap->allocation_audio_page += \
4445 ((unsigned int)(0x01 << AUDIO_ISOC_ORDER));
4447 peasycap->audio_isoc_buffer[k].pgo = pbuf;
4448 peasycap->audio_isoc_buffer[k].pto = pbuf + \
4449 peasycap->audio_isoc_buffer_size;
4450 peasycap->audio_isoc_buffer[k].kount = k;
4452 JOM(4, "allocation of isoc audio buffers done.\n");
4453 /*---------------------------------------------------------------------------*/
4455 * ALLOCATE AND INITIALIZE MULTIPLE struct urb ...
4457 /*---------------------------------------------------------------------------*/
4458 JOM(4, "allocating %i struct urb.\n", AUDIO_ISOC_BUFFER_MANY);
4459 JOM(4, "using %i=peasycap->audio_isoc_framesperdesc\n", \
4460 peasycap->audio_isoc_framesperdesc);
4461 JOM(4, "using %i=peasycap->audio_isoc_maxframesize\n", \
4462 peasycap->audio_isoc_maxframesize);
4463 JOM(4, "using %i=peasycap->audio_isoc_buffer_size\n", \
4464 peasycap->audio_isoc_buffer_size);
4466 for (k = 0; k < AUDIO_ISOC_BUFFER_MANY; k++) {
4467 purb = usb_alloc_urb(peasycap->audio_isoc_framesperdesc, \
4470 SAM("ERROR: usb_alloc_urb returned NULL for buffer " \
4474 peasycap->allocation_audio_urb += 1 ;
4475 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
4476 pdata_urb = kzalloc(sizeof(struct data_urb), GFP_KERNEL);
4477 if (NULL == pdata_urb) {
4478 SAM("ERROR: Could not allocate struct data_urb.\n");
4481 peasycap->allocation_audio_struct += \
4482 sizeof(struct data_urb);
4484 pdata_urb->purb = purb;
4485 pdata_urb->isbuf = k;
4486 pdata_urb->length = 0;
4487 list_add_tail(&(pdata_urb->list_head), \
4488 peasycap->purb_audio_head);
4489 /*---------------------------------------------------------------------------*/
4491 * ... AND INITIALIZE THEM
4493 /*---------------------------------------------------------------------------*/
4495 JOM(4, "initializing audio urbs thus:\n");
4496 JOM(4, " purb->interval = 1;\n");
4497 JOM(4, " purb->dev = peasycap->pusb_device;\n");
4498 JOM(4, " purb->pipe = usb_rcvisocpipe(peasycap->" \
4499 "pusb_device,%i);\n", \
4500 peasycap->audio_endpointnumber);
4501 JOM(4, " purb->transfer_flags = URB_ISO_ASAP;\n");
4502 JOM(4, " purb->transfer_buffer = " \
4503 "peasycap->audio_isoc_buffer[.].pgo;\n");
4504 JOM(4, " purb->transfer_buffer_length = %i;\n", \
4505 peasycap->audio_isoc_buffer_size);
4506 JOM(4, " purb->complete = easysnd_complete;\n");
4507 JOM(4, " purb->context = peasycap;\n");
4508 JOM(4, " purb->start_frame = 0;\n");
4509 JOM(4, " purb->number_of_packets = %i;\n", \
4510 peasycap->audio_isoc_framesperdesc);
4511 JOM(4, " for (j = 0; j < %i; j++)\n", \
4512 peasycap->audio_isoc_framesperdesc);
4514 JOM(4, " purb->iso_frame_desc[j].offset = j*%i;\n",\
4515 peasycap->audio_isoc_maxframesize);
4516 JOM(4, " purb->iso_frame_desc[j].length = %i;\n", \
4517 peasycap->audio_isoc_maxframesize);
4522 purb->dev = peasycap->pusb_device;
4523 purb->pipe = usb_rcvisocpipe(peasycap->pusb_device, \
4524 peasycap->audio_endpointnumber);
4525 purb->transfer_flags = URB_ISO_ASAP;
4526 purb->transfer_buffer = peasycap->audio_isoc_buffer[k].pgo;
4527 purb->transfer_buffer_length = \
4528 peasycap->audio_isoc_buffer_size;
4529 purb->complete = easysnd_complete;
4530 purb->context = peasycap;
4531 purb->start_frame = 0;
4532 purb->number_of_packets = peasycap->audio_isoc_framesperdesc;
4533 for (j = 0; j < peasycap->audio_isoc_framesperdesc; j++) {
4534 purb->iso_frame_desc[j].offset = j * \
4535 peasycap->audio_isoc_maxframesize;
4536 purb->iso_frame_desc[j].length = \
4537 peasycap->audio_isoc_maxframesize;
4540 JOM(4, "allocation of %i struct urb done.\n", k);
4541 /*---------------------------------------------------------------------------*/
4543 * SAVE POINTER peasycap IN THIS INTERFACE.
4545 /*---------------------------------------------------------------------------*/
4546 usb_set_intfdata(pusb_interface, peasycap);
4547 /*---------------------------------------------------------------------------*/
4549 * THE AUDIO DEVICE CAN BE REGISTERED NOW, AS IT IS READY.
4551 /*---------------------------------------------------------------------------*/
4552 rc = usb_register_dev(pusb_interface, &easysnd_class);
4554 err("Not able to get a minor for this device.");
4555 usb_set_intfdata(pusb_interface, NULL);
4558 JOM(8, "kref_get() with %i=peasycap->kref.refcount.counter\n",\
4559 (int)peasycap->kref.refcount.counter);
4560 kref_get(&peasycap->kref);
4561 (peasycap->registered_audio)++;
4563 /*---------------------------------------------------------------------------*/
4565 * LET THE USER KNOW WHAT NODE THE AUDIO DEVICE IS ATTACHED TO.
4567 /*---------------------------------------------------------------------------*/
4568 SAM("easysnd attached to minor #%d\n", pusb_interface->minor);
4571 /*---------------------------------------------------------------------------*/
4573 * INTERFACES OTHER THAN 0, 1 AND 2 ARE UNEXPECTED
4575 /*---------------------------------------------------------------------------*/
4577 JOM(4, "ERROR: unexpected interface %i\n", bInterfaceNumber);
4581 JOM(4, "ends successfully for interface %i\n", \
4582 pusb_interface_descriptor->bInterfaceNumber);
4585 /*****************************************************************************/
4586 /*---------------------------------------------------------------------------*/
4588 * WHEN THIS FUNCTION IS CALLED THE DEVICE HAS ALREADY BEEN PHYSICALLY
4590 * HENCE peasycap->pusb_device IS NO LONGER VALID AND MUST BE SET TO NULL.
4592 /*---------------------------------------------------------------------------*/
4594 easycap_usb_disconnect(struct usb_interface *pusb_interface)
4596 struct usb_host_interface *pusb_host_interface;
4597 struct usb_interface_descriptor *pusb_interface_descriptor;
4598 __u8 bInterfaceNumber;
4599 struct easycap *peasycap;
4601 struct list_head *plist_head;
4602 struct data_urb *pdata_urb;
4607 if ((struct usb_interface *)NULL == pusb_interface) {
4608 JOT(4, "ERROR: pusb_interface is NULL\n");
4611 pusb_host_interface = pusb_interface->cur_altsetting;
4612 if ((struct usb_host_interface *)NULL == pusb_host_interface) {
4613 JOT(4, "ERROR: pusb_host_interface is NULL\n");
4616 pusb_interface_descriptor = &(pusb_host_interface->desc);
4617 if ((struct usb_interface_descriptor *)NULL == pusb_interface_descriptor) {
4618 JOT(4, "ERROR: pusb_interface_descriptor is NULL\n");
4621 bInterfaceNumber = pusb_interface_descriptor->bInterfaceNumber;
4622 minor = pusb_interface->minor;
4623 JOT(4, "intf[%i]: minor=%i\n", bInterfaceNumber, minor);
4625 if (1 == bInterfaceNumber)
4628 peasycap = usb_get_intfdata(pusb_interface);
4629 if (NULL == peasycap) {
4630 SAY("ERROR: peasycap is NULL\n");
4633 /*---------------------------------------------------------------------------*/
4635 * IF THE WAIT QUEUES ARE NOT CLEARED A DEADLOCK IS POSSIBLE. BEWARE.
4637 /*---------------------------------------------------------------------------*/
4638 peasycap->video_eof = 1;
4639 peasycap->audio_eof = 1;
4640 wake_up_interruptible(&(peasycap->wq_video));
4641 wake_up_interruptible(&(peasycap->wq_audio));
4642 /*---------------------------------------------------------------------------*/
4643 switch (bInterfaceNumber) {
4645 if ((struct list_head *)NULL != peasycap->purb_video_head) {
4646 JOM(4, "killing video urbs\n");
4648 list_for_each(plist_head, (peasycap->purb_video_head))
4650 pdata_urb = list_entry(plist_head, \
4651 struct data_urb, list_head);
4652 if ((struct data_urb *)NULL != pdata_urb) {
4653 if ((struct urb *)NULL != \
4655 usb_kill_urb(pdata_urb->purb);
4660 JOM(4, "%i video urbs killed\n", m);
4664 /*---------------------------------------------------------------------------*/
4666 if ((struct list_head *)NULL != peasycap->purb_audio_head) {
4667 JOM(4, "killing audio urbs\n");
4669 list_for_each(plist_head, \
4670 (peasycap->purb_audio_head)) {
4671 pdata_urb = list_entry(plist_head, \
4672 struct data_urb, list_head);
4673 if ((struct data_urb *)NULL != pdata_urb) {
4674 if ((struct urb *)NULL != \
4676 usb_kill_urb(pdata_urb->purb);
4681 JOM(4, "%i audio urbs killed\n", m);
4685 /*---------------------------------------------------------------------------*/
4689 /*--------------------------------------------------------------------------*/
4693 /*--------------------------------------------------------------------------*/
4694 switch (bInterfaceNumber) {
4696 #if (!defined(EASYCAP_IS_VIDEODEV_CLIENT))
4697 if ((struct easycap *)NULL == peasycap) {
4698 SAM("ERROR: peasycap has become NULL\n");
4701 usb_deregister_dev(pusb_interface, &easycap_class);
4702 (peasycap->registered_video)--;
4704 JOM(4, "intf[%i]: usb_deregister_dev()\n", bInterfaceNumber);
4706 SAM("easycap detached from minor #%d\n", minor);
4708 /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
4710 if ((struct easycap *)NULL == peasycap)
4711 SAM("ERROR: peasycap has become NULL\n");
4714 video_unregister_device(&peasycap->video_device);
4715 (peasycap->registered_video)--;
4717 JOM(4, "unregistered with videodev: %i=minor\n", \
4718 peasycap->video_device.minor);
4720 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
4721 #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
4727 usb_deregister_dev(pusb_interface, &easysnd_class);
4728 if ((struct easycap *)NULL != peasycap)
4729 (peasycap->registered_audio)--;
4731 JOM(4, "intf[%i]: usb_deregister_dev()\n", bInterfaceNumber);
4734 SAM("easysnd detached from minor #%d\n", minor);
4740 /*---------------------------------------------------------------------------*/
4742 * CALL easycap_delete() IF NO REMAINING REFERENCES TO peasycap
4744 /*---------------------------------------------------------------------------*/
4745 if ((struct easycap *)NULL == peasycap) {
4746 SAM("ERROR: peasycap has become NULL\n");
4747 SAM("cannot call kref_put()\n");
4748 SAM("ending unsuccessfully: may cause memory leak\n");
4751 if (!peasycap->kref.refcount.counter) {
4752 SAM("ERROR: peasycap->kref.refcount.counter is zero " \
4753 "so cannot call kref_put()\n");
4754 SAM("ending unsuccessfully: may cause memory leak\n");
4757 JOM(4, "intf[%i]: kref_put() with %i=peasycap->kref.refcount.counter\n", \
4758 bInterfaceNumber, (int)peasycap->kref.refcount.counter);
4759 kref_put(&peasycap->kref, easycap_delete);
4760 JOM(4, "intf[%i]: kref_put() done.\n", bInterfaceNumber);
4761 /*---------------------------------------------------------------------------*/
4766 /*****************************************************************************/
4768 easycap_module_init(void)
4772 SAY("========easycap=======\n");
4773 JOT(4, "begins. %i=debug %i=bars\n", debug, bars);
4774 SAY("version: " EASYCAP_DRIVER_VERSION "\n");
4775 /*---------------------------------------------------------------------------*/
4777 * REGISTER THIS DRIVER WITH THE USB SUBSYTEM.
4779 /*---------------------------------------------------------------------------*/
4780 JOT(4, "registering driver easycap\n");
4782 result = usb_register(&easycap_usb_driver);
4784 SAY("ERROR: usb_register returned %i\n", result);
4789 /*****************************************************************************/
4791 easycap_module_exit(void)
4795 /*---------------------------------------------------------------------------*/
4797 * DEREGISTER THIS DRIVER WITH THE USB SUBSYTEM.
4799 /*---------------------------------------------------------------------------*/
4800 usb_deregister(&easycap_usb_driver);
4804 /*****************************************************************************/
4806 module_init(easycap_module_init);
4807 module_exit(easycap_module_exit);
4809 MODULE_LICENSE("GPL");
4810 MODULE_AUTHOR("R.M. Thomas <rmthomas@sciolus.org>");
4811 MODULE_DESCRIPTION(EASYCAP_DRIVER_DESCRIPTION);
4812 MODULE_VERSION(EASYCAP_DRIVER_VERSION);
4813 #if defined(EASYCAP_DEBUG)
4814 MODULE_PARM_DESC(debug, "Debug level: 0 (default),1,2,...,9");
4815 #endif /*EASYCAP_DEBUG*/
4816 MODULE_PARM_DESC(bars, \
4817 "Testcard bars on input signal failure: 0=>no, 1=>yes(default)");
4818 /*****************************************************************************/