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 /*****************************************************************************/
34 static int easycap_bars = 1;
35 static int easycap_gain = 16;
36 module_param_named(debug, easycap_debug, int, S_IRUGO | S_IWUSR);
37 module_param_named(bars, easycap_bars, int, S_IRUGO | S_IWUSR);
38 module_param_named(gain, easycap_gain, int, S_IRUGO | S_IWUSR);
40 struct easycap_dongle easycapdc60_dongle[DONGLE_MANY];
41 static struct mutex mutex_dongle;
43 /*---------------------------------------------------------------------------*/
45 * PARAMETERS APPLICABLE TO ENTIRE DRIVER, I.E. BOTH VIDEO AND AUDIO
47 /*---------------------------------------------------------------------------*/
48 static struct usb_device_id easycap_usb_device_id_table[] = {
49 { USB_DEVICE(USB_EASYCAP_VENDOR_ID, USB_EASYCAP_PRODUCT_ID) },
52 MODULE_DEVICE_TABLE(usb, easycap_usb_device_id_table);
53 struct usb_driver easycap_usb_driver = {
55 .id_table = easycap_usb_device_id_table,
56 .probe = easycap_usb_probe,
57 .disconnect = easycap_usb_disconnect,
59 /*---------------------------------------------------------------------------*/
61 * PARAMETERS USED WHEN REGISTERING THE VIDEO INTERFACE
63 * NOTE: SOME KERNELS IGNORE usb_class_driver.minor_base, AS MENTIONED BY
64 * CORBET ET AL. "LINUX DEVICE DRIVERS", 3rd EDITION, PAGE 253.
65 * THIS IS THE CASE FOR OpenSUSE.
67 /*---------------------------------------------------------------------------*/
68 static const struct file_operations easycap_fops = {
71 .release = easycap_release,
72 #if defined(EASYCAP_NEEDS_UNLOCKED_IOCTL)
73 .unlocked_ioctl = easycap_ioctl_noinode,
75 .ioctl = easycap_ioctl,
76 #endif /*EASYCAP_NEEDS_UNLOCKED_IOCTL*/
81 static const struct vm_operations_struct easycap_vm_ops = {
82 .open = easycap_vma_open,
83 .close = easycap_vma_close,
84 .fault = easycap_vma_fault,
86 static const struct usb_class_driver easycap_class = {
87 .name = "usb/easycap%d",
88 .fops = &easycap_fops,
89 .minor_base = USB_SKEL_MINOR_BASE,
91 /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
92 #if defined(EASYCAP_IS_VIDEODEV_CLIENT)
93 #if defined(EASYCAP_NEEDS_V4L2_FOPS)
94 static const struct v4l2_file_operations v4l2_fops = {
96 .open = easycap_open_noinode,
97 .release = easycap_release_noinode,
98 #if defined(EASYCAP_NEEDS_UNLOCKED_IOCTL)
99 .unlocked_ioctl = easycap_ioctl_noinode,
101 .ioctl = easycap_ioctl,
102 #endif /*EASYCAP_NEEDS_UNLOCKED_IOCTL*/
103 .poll = easycap_poll,
104 .mmap = easycap_mmap,
106 #endif /*EASYCAP_NEEDS_V4L2_FOPS*/
107 #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
108 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
109 /****************************************************************************/
110 /*---------------------------------------------------------------------------*/
112 * THIS ROUTINE DOES NOT DETECT DUPLICATE OCCURRENCES OF POINTER peasycap
114 /*---------------------------------------------------------------------------*/
116 isdongle(struct easycap *peasycap)
119 if (NULL == peasycap)
121 for (k = 0; k < DONGLE_MANY; k++) {
122 if (easycapdc60_dongle[k].peasycap == peasycap) {
123 peasycap->isdongle = k;
129 /*****************************************************************************/
130 /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
131 #if defined(EASYCAP_IS_VIDEODEV_CLIENT)
133 easycap_open_noinode(struct file *file)
135 return easycap_open((struct inode *)NULL, file);
137 #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
138 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
140 easycap_open(struct inode *inode, struct file *file)
142 #if (!defined(EASYCAP_IS_VIDEODEV_CLIENT))
143 struct usb_interface *pusb_interface;
145 struct video_device *pvideo_device;
146 #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
147 struct easycap *peasycap;
151 SAY("==========OPEN=========\n");
153 peasycap = (struct easycap *)NULL;
154 /*---------------------------------------------------------------------------*/
155 #if (!defined(EASYCAP_IS_VIDEODEV_CLIENT))
156 if ((struct inode *)NULL == inode) {
157 SAY("ERROR: inode is NULL.\n");
160 pusb_interface = usb_find_interface(&easycap_usb_driver, iminor(inode));
161 if (!pusb_interface) {
162 SAY("ERROR: pusb_interface is NULL.\n");
165 peasycap = usb_get_intfdata(pusb_interface);
166 /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
168 pvideo_device = video_devdata(file);
169 if ((struct video_device *)NULL == pvideo_device) {
170 SAY("ERROR: pvideo_device is NULL.\n");
173 peasycap = (struct easycap *)video_get_drvdata(pvideo_device);
174 #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
175 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
176 if (NULL == peasycap) {
177 SAY("ERROR: peasycap is NULL\n");
180 if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
181 SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap);
184 if (NULL == peasycap->pusb_device) {
185 SAM("ERROR: peasycap->pusb_device is NULL\n");
188 JOM(16, "0x%08lX=peasycap->pusb_device\n",
189 (long int)peasycap->pusb_device);
191 file->private_data = peasycap;
192 rc = wakeup_device(peasycap->pusb_device);
194 JOM(8, "wakeup_device() OK\n");
196 SAM("ERROR: wakeup_device() returned %i\n", rc);
198 SAM("ERROR: wakeup_device() returned -ENODEV\n");
200 SAM("ERROR: wakeup_device() returned %i\n", rc);
204 rc = reset(peasycap);
206 SAM("ERROR: reset() returned %i\n", rc);
211 /*****************************************************************************/
212 /*---------------------------------------------------------------------------*/
214 * RESET THE HARDWARE TO ITS REFERENCE STATE.
216 * THIS ROUTINE MAY BE CALLED REPEATEDLY IF easycap_complete() DETECTS
217 * A BAD VIDEO FRAME SIZE.
219 /*---------------------------------------------------------------------------*/
221 reset(struct easycap *peasycap)
223 struct easycap_standard const *peasycap_standard;
224 int i, rc, input, rate;
227 if (NULL == peasycap) {
228 SAY("ERROR: peasycap is NULL\n");
231 input = peasycap->input;
233 /*---------------------------------------------------------------------------*/
235 * IF THE SAA7113H HAS ALREADY ACQUIRED SYNC, USE ITS HARDWARE-DETECTED
236 * FIELD FREQUENCY TO DISTINGUISH NTSC FROM PAL. THIS IS ESSENTIAL FOR
237 * gstreamer AND OTHER USERSPACE PROGRAMS WHICH MAY NOT ATTEMPT TO INITIATE
238 * A SWITCH BETWEEN PAL AND NTSC.
240 * FUNCTION ready_saa() MAY REQUIRE A SUBSTANTIAL FRACTION OF A SECOND TO
241 * COMPLETE, SO SHOULD NOT BE INVOKED WITHOUT GOOD REASON.
243 /*---------------------------------------------------------------------------*/
245 if (true == peasycap->ntsc)
246 JOM(8, "true=peasycap->ntsc\n");
248 JOM(8, "false=peasycap->ntsc\n");
249 rate = ready_saa(peasycap->pusb_device);
251 JOM(8, "not ready to capture after %i ms ...\n", PATIENCE);
252 if (true == peasycap->ntsc) {
253 JOM(8, "... trying PAL ...\n"); ntsc = false;
255 JOM(8, "... trying NTSC ...\n"); ntsc = true;
257 rc = setup_stk(peasycap->pusb_device, ntsc);
259 JOM(4, "setup_stk() OK\n");
261 SAM("ERROR: setup_stk() returned %i\n", rc);
264 rc = setup_saa(peasycap->pusb_device, ntsc);
266 JOM(4, "setup_saa() OK\n");
268 SAM("ERROR: setup_saa() returned %i\n", rc);
271 rate = ready_saa(peasycap->pusb_device);
273 JOM(8, "not ready to capture after %i ms ...\n", PATIENCE);
274 JOM(8, "... saa register 0x1F has 0x%02X\n",
275 read_saa(peasycap->pusb_device, 0x1F));
276 ntsc = peasycap->ntsc;
278 JOM(8, "... success at second try: %i=rate\n", rate);
279 ntsc = (0 < (rate/2)) ? true : false ;
283 JOM(8, "... success at first try: %i=rate\n", rate);
284 ntsc = (0 < rate/2) ? true : false ;
287 JOM(8, "true=ntsc\n");
289 JOM(8, "false=ntsc\n");
290 /*---------------------------------------------------------------------------*/
292 rc = setup_stk(peasycap->pusb_device, ntsc);
294 JOM(4, "setup_stk() OK\n");
296 SAM("ERROR: setup_stk() returned %i\n", rc);
299 rc = setup_saa(peasycap->pusb_device, ntsc);
301 JOM(4, "setup_saa() OK\n");
303 SAM("ERROR: setup_saa() returned %i\n", rc);
307 for (i = 0; i < 180; i++)
308 peasycap->merit[i] = 0;
309 peasycap->video_eof = 0;
310 peasycap->audio_eof = 0;
311 do_gettimeofday(&peasycap->timeval7);
312 /*---------------------------------------------------------------------------*/
314 * RESTORE INPUT AND FORCE REFRESH OF STANDARD, FORMAT, ETC.
316 * WHILE THIS PROCEDURE IS IN PROGRESS, SOME IOCTL COMMANDS WILL RETURN -EBUSY.
318 /*---------------------------------------------------------------------------*/
319 peasycap->input = -8192;
320 peasycap->standard_offset = -8192;
322 peasycap_standard = &easycap_standard[0];
323 while (0xFFFF != peasycap_standard->mask) {
326 peasycap_standard->v4l2_standard.index) {
327 peasycap->inputset[input].standard_offset =
329 &easycap_standard[0];
334 peasycap_standard->v4l2_standard.index) {
335 peasycap->inputset[input].standard_offset =
337 &easycap_standard[0];
343 if (0xFFFF == peasycap_standard->mask) {
344 SAM("ERROR: standard not found\n");
347 JOM(8, "%i=peasycap->inputset[%i].standard_offset\n",
348 peasycap->inputset[input].standard_offset, input);
350 peasycap->format_offset = -8192;
351 peasycap->brightness = -8192;
352 peasycap->contrast = -8192;
353 peasycap->saturation = -8192;
354 peasycap->hue = -8192;
356 rc = newinput(peasycap, input);
359 JOM(4, "restored input, standard and format\n");
361 SAM("ERROR: newinput(.,%i) returned %i\n", rc, input);
364 if (true == peasycap->ntsc)
365 JOM(8, "true=peasycap->ntsc\n");
367 JOM(8, "false=peasycap->ntsc\n");
369 if (0 > peasycap->input) {
370 SAM("MISTAKE: %i=peasycap->input\n", peasycap->input);
373 if (0 > peasycap->standard_offset) {
374 SAM("MISTAKE: %i=peasycap->standard_offset\n",
375 peasycap->standard_offset);
378 if (0 > peasycap->format_offset) {
379 SAM("MISTAKE: %i=peasycap->format_offset\n",
380 peasycap->format_offset);
383 if (0 > peasycap->brightness) {
384 SAM("MISTAKE: %i=peasycap->brightness\n", peasycap->brightness);
387 if (0 > peasycap->contrast) {
388 SAM("MISTAKE: %i=peasycap->contrast\n", peasycap->contrast);
391 if (0 > peasycap->saturation) {
392 SAM("MISTAKE: %i=peasycap->saturation\n", peasycap->saturation);
395 if (0 > peasycap->hue) {
396 SAM("MISTAKE: %i=peasycap->hue\n", peasycap->hue);
401 /*****************************************************************************/
402 /*---------------------------------------------------------------------------*/
404 * IF THE REQUESTED INPUT IS THE SAME AS THE EXISTING INPUT, DO NOTHING.
406 * KILL URBS, CLEAR FIELD AND FRAME BUFFERS AND RESET THEIR
407 * _read AND _fill POINTERS.
408 * SELECT THE NEW INPUT.
409 * ADJUST THE STANDARD, FORMAT, BRIGHTNESS, CONTRAST, SATURATION AND HUE
410 * ON THE BASIS OF INFORMATION IN STRUCTURE easycap.inputset[input].
411 * RESUBMIT THE URBS IF STREAMING WAS ALREADY IN PROGRESS.
414 * THIS ROUTINE MAY BE CALLED FREQUENTLY BY ZONEMINDER VIA IOCTL,
415 * SO IT SHOULD WRITE ONLY SPARINGLY TO THE LOGFILE.
417 /*---------------------------------------------------------------------------*/
419 newinput(struct easycap *peasycap, int input)
421 int rc, k, m, mood, off;
422 int inputnow, video_idlenow, audio_idlenow;
425 if (NULL == peasycap) {
426 SAY("ERROR: peasycap is NULL\n");
429 JOM(8, "%i=input sought\n", input);
431 if (0 > input && INPUT_MANY <= input)
433 inputnow = peasycap->input;
434 if (input == inputnow)
436 /*---------------------------------------------------------------------------*/
438 * IF STREAMING IS IN PROGRESS THE URBS ARE KILLED AT THIS
439 * STAGE AND WILL BE RESUBMITTED PRIOR TO EXIT FROM THE ROUTINE.
440 * IF NO STREAMING IS IN PROGRESS NO URBS WILL BE SUBMITTED BY THE
443 /*---------------------------------------------------------------------------*/
444 video_idlenow = peasycap->video_idle;
445 audio_idlenow = peasycap->audio_idle;
447 peasycap->video_idle = 1;
448 peasycap->audio_idle = 1;
449 if (peasycap->video_isoc_streaming) {
451 kill_video_urbs(peasycap);
454 /*---------------------------------------------------------------------------*/
455 if (NULL == peasycap->pusb_device) {
456 SAM("ERROR: peasycap->pusb_device is NULL\n");
459 rc = usb_set_interface(peasycap->pusb_device,
460 peasycap->video_interface,
461 peasycap->video_altsetting_off);
463 SAM("ERROR: usb_set_interface() returned %i\n", rc);
466 rc = stop_100(peasycap->pusb_device);
468 SAM("ERROR: stop_100() returned %i\n", rc);
471 for (k = 0; k < FIELD_BUFFER_MANY; k++) {
472 for (m = 0; m < FIELD_BUFFER_SIZE/PAGE_SIZE; m++)
473 memset(peasycap->field_buffer[k][m].pgo, 0, PAGE_SIZE);
475 for (k = 0; k < FRAME_BUFFER_MANY; k++) {
476 for (m = 0; m < FRAME_BUFFER_SIZE/PAGE_SIZE; m++)
477 memset(peasycap->frame_buffer[k][m].pgo, 0, PAGE_SIZE);
479 peasycap->field_page = 0;
480 peasycap->field_read = 0;
481 peasycap->field_fill = 0;
483 peasycap->frame_read = 0;
484 peasycap->frame_fill = 0;
485 for (k = 0; k < peasycap->input; k++) {
486 (peasycap->frame_fill)++;
487 if (peasycap->frame_buffer_many <= peasycap->frame_fill)
488 peasycap->frame_fill = 0;
490 peasycap->input = input;
491 select_input(peasycap->pusb_device, peasycap->input, 9);
492 /*---------------------------------------------------------------------------*/
493 if (input == peasycap->inputset[input].input) {
494 off = peasycap->inputset[input].standard_offset;
495 if (off != peasycap->standard_offset) {
496 rc = adjust_standard(peasycap,
497 easycap_standard[off].v4l2_standard.id);
499 SAM("ERROR: adjust_standard() returned %i\n", rc);
502 JOM(8, "%i=peasycap->standard_offset\n",
503 peasycap->standard_offset);
505 JOM(8, "%i=peasycap->standard_offset unchanged\n",
506 peasycap->standard_offset);
508 off = peasycap->inputset[input].format_offset;
509 if (off != peasycap->format_offset) {
510 rc = adjust_format(peasycap,
511 easycap_format[off].v4l2_format.fmt.pix.width,
512 easycap_format[off].v4l2_format.fmt.pix.height,
513 easycap_format[off].v4l2_format.fmt.pix.pixelformat,
514 easycap_format[off].v4l2_format.fmt.pix.field, false);
516 SAM("ERROR: adjust_format() returned %i\n", rc);
519 JOM(8, "%i=peasycap->format_offset\n", peasycap->format_offset);
521 JOM(8, "%i=peasycap->format_offset unchanged\n",
522 peasycap->format_offset);
524 mood = peasycap->inputset[input].brightness;
525 if (mood != peasycap->brightness) {
526 rc = adjust_brightness(peasycap, mood);
528 SAM("ERROR: adjust_brightness returned %i\n", rc);
531 JOM(8, "%i=peasycap->brightness\n", peasycap->brightness);
533 mood = peasycap->inputset[input].contrast;
534 if (mood != peasycap->contrast) {
535 rc = adjust_contrast(peasycap, mood);
537 SAM("ERROR: adjust_contrast returned %i\n", rc);
540 JOM(8, "%i=peasycap->contrast\n", peasycap->contrast);
542 mood = peasycap->inputset[input].saturation;
543 if (mood != peasycap->saturation) {
544 rc = adjust_saturation(peasycap, mood);
546 SAM("ERROR: adjust_saturation returned %i\n", rc);
549 JOM(8, "%i=peasycap->saturation\n", peasycap->saturation);
551 mood = peasycap->inputset[input].hue;
552 if (mood != peasycap->hue) {
553 rc = adjust_hue(peasycap, mood);
555 SAM("ERROR: adjust_hue returned %i\n", rc);
558 JOM(8, "%i=peasycap->hue\n", peasycap->hue);
561 SAM("MISTAKE: easycap.inputset[%i] unpopulated\n", input);
564 /*---------------------------------------------------------------------------*/
565 if (NULL == peasycap->pusb_device) {
566 SAM("ERROR: peasycap->pusb_device is NULL\n");
569 rc = usb_set_interface(peasycap->pusb_device,
570 peasycap->video_interface,
571 peasycap->video_altsetting_on);
573 SAM("ERROR: usb_set_interface() returned %i\n", rc);
576 rc = start_100(peasycap->pusb_device);
578 SAM("ERROR: start_100() returned %i\n", rc);
581 if (true == resubmit)
582 submit_video_urbs(peasycap);
584 peasycap->video_isoc_sequence = VIDEO_ISOC_BUFFER_MANY - 1;
585 peasycap->video_idle = video_idlenow;
586 peasycap->audio_idle = audio_idlenow;
587 peasycap->video_junk = 0;
591 /*****************************************************************************/
593 submit_video_urbs(struct easycap *peasycap)
595 struct data_urb *pdata_urb;
597 struct list_head *plist_head;
598 int j, isbad, nospc, m, rc;
601 if (NULL == peasycap) {
602 SAY("ERROR: peasycap is NULL\n");
606 if (NULL == peasycap->purb_video_head) {
607 SAY("ERROR: peasycap->urb_video_head uninitialized\n");
610 if (NULL == peasycap->pusb_device) {
611 SAY("ERROR: peasycap->pusb_device is NULL\n");
614 if (!peasycap->video_isoc_streaming) {
615 JOM(4, "submission of all video urbs\n");
616 isbad = 0; nospc = 0; m = 0;
617 list_for_each(plist_head, (peasycap->purb_video_head)) {
618 pdata_urb = list_entry(plist_head, struct data_urb, list_head);
619 if (NULL != pdata_urb) {
620 purb = pdata_urb->purb;
622 isbuf = pdata_urb->isbuf;
624 purb->dev = peasycap->pusb_device;
626 usb_rcvisocpipe(peasycap->pusb_device,
627 peasycap->video_endpointnumber);
628 purb->transfer_flags = URB_ISO_ASAP;
629 purb->transfer_buffer =
630 peasycap->video_isoc_buffer[isbuf].pgo;
631 purb->transfer_buffer_length =
632 peasycap->video_isoc_buffer_size;
633 purb->complete = easycap_complete;
634 purb->context = peasycap;
635 purb->start_frame = 0;
636 purb->number_of_packets =
637 peasycap->video_isoc_framesperdesc;
639 for (j = 0; j < peasycap->
640 video_isoc_framesperdesc; j++) {
641 purb->iso_frame_desc[j].
644 video_isoc_maxframesize;
645 purb->iso_frame_desc[j].
647 video_isoc_maxframesize;
650 rc = usb_submit_urb(purb, GFP_KERNEL);
653 SAM("ERROR: usb_submit_urb() failed "
654 "for urb with rc:\n");
657 SAM("ERROR: -ENOMEM="
658 "usb_submit_urb()\n");
662 SAM("ERROR: -ENODEV="
663 "usb_submit_urb()\n");
668 "usb_submit_urb()\n");
672 SAM("ERROR: -EINVAL="
673 "usb_submit_urb()\n");
677 SAM("ERROR: -EAGAIN="
678 "usb_submit_urb()\n");
683 "usb_submit_urb()\n");
688 "usb_submit_urb()\n");
692 SAM("ERROR: -EMSGSIZE="
693 "usb_submit_urb()\n");
702 "usb_submit_urb()\n",
718 SAM("-ENOSPC=usb_submit_urb() for %i urbs\n", nospc);
719 SAM("..... possibly inadequate USB bandwidth\n");
720 peasycap->video_eof = 1;
724 JOM(4, "attempting cleanup instead of submitting\n");
725 list_for_each(plist_head, (peasycap->purb_video_head)) {
726 pdata_urb = list_entry(plist_head, struct data_urb,
728 if (NULL != pdata_urb) {
729 purb = pdata_urb->purb;
734 peasycap->video_isoc_streaming = 0;
736 peasycap->video_isoc_streaming = 1;
737 JOM(4, "submitted %i video urbs\n", m);
740 JOM(4, "already streaming video urbs\n");
744 /*****************************************************************************/
746 kill_video_urbs(struct easycap *peasycap)
749 struct list_head *plist_head;
750 struct data_urb *pdata_urb;
752 if (NULL == peasycap) {
753 SAY("ERROR: peasycap is NULL\n");
756 if (peasycap->video_isoc_streaming) {
757 if ((struct list_head *)NULL != peasycap->purb_video_head) {
758 peasycap->video_isoc_streaming = 0;
759 JOM(4, "killing video urbs\n");
761 list_for_each(plist_head, (peasycap->purb_video_head)) {
762 pdata_urb = list_entry(plist_head, struct data_urb,
764 if (NULL != pdata_urb) {
765 if (NULL != pdata_urb->purb) {
766 usb_kill_urb(pdata_urb->purb);
771 JOM(4, "%i video urbs killed\n", m);
773 SAM("ERROR: peasycap->purb_video_head is NULL\n");
777 JOM(8, "%i=video_isoc_streaming, no video urbs killed\n",
778 peasycap->video_isoc_streaming);
782 /****************************************************************************/
783 /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
784 #if defined(EASYCAP_IS_VIDEODEV_CLIENT)
786 easycap_release_noinode(struct file *file)
788 return easycap_release((struct inode *)NULL, file);
790 #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
791 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
792 /*--------------------------------------------------------------------------*/
794 easycap_release(struct inode *inode, struct file *file)
796 #if (!defined(EASYCAP_IS_VIDEODEV_CLIENT))
797 struct easycap *peasycap;
801 peasycap = file->private_data;
802 if (NULL == peasycap) {
803 SAY("ERROR: peasycap is NULL.\n");
804 SAY("ending unsuccessfully\n");
807 if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
808 SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap);
811 if (0 != kill_video_urbs(peasycap)) {
812 SAM("ERROR: kill_video_urbs() failed\n");
815 JOM(4, "ending successfully\n");
816 /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
819 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
820 #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
824 /****************************************************************************/
825 /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
826 #if defined(EASYCAP_IS_VIDEODEV_CLIENT)
828 videodev_release(struct video_device *pvideo_device)
830 struct easycap *peasycap;
834 peasycap = video_get_drvdata(pvideo_device);
835 if (NULL == peasycap) {
836 SAY("ERROR: peasycap is NULL\n");
837 SAY("ending unsuccessfully\n");
840 if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
841 SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap);
844 if (0 != kill_video_urbs(peasycap)) {
845 SAM("ERROR: kill_video_urbs() failed\n");
848 JOM(4, "ending successfully\n");
851 #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
852 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
853 /*****************************************************************************/
854 /*--------------------------------------------------------------------------*/
856 * THIS FUNCTION IS CALLED FROM WITHIN easycap_usb_disconnect() AND IS
857 * PROTECTED BY SEMAPHORES SET AND CLEARED BY easycap_usb_disconnect().
859 * BY THIS STAGE THE DEVICE HAS ALREADY BEEN PHYSICALLY UNPLUGGED, SO
860 * peasycap->pusb_device IS NO LONGER VALID.
862 /*---------------------------------------------------------------------------*/
864 easycap_delete(struct kref *pkref)
867 int allocation_video_urb, allocation_video_page, allocation_video_struct;
868 int allocation_audio_urb, allocation_audio_page, allocation_audio_struct;
869 int registered_video, registered_audio;
870 struct easycap *peasycap;
871 struct data_urb *pdata_urb;
872 struct list_head *plist_head, *plist_next;
876 peasycap = container_of(pkref, struct easycap, kref);
877 if (NULL == peasycap) {
878 SAM("ERROR: peasycap is NULL: cannot perform deletions\n");
881 if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
882 SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap);
885 kd = isdongle(peasycap);
886 /*---------------------------------------------------------------------------*/
890 /*---------------------------------------------------------------------------*/
891 if ((struct list_head *)NULL != peasycap->purb_video_head) {
892 JOM(4, "freeing video urbs\n");
894 list_for_each(plist_head, (peasycap->purb_video_head)) {
895 pdata_urb = list_entry(plist_head, struct data_urb, list_head);
896 if (NULL == pdata_urb)
897 JOM(4, "ERROR: pdata_urb is NULL\n");
899 if ((struct urb *)NULL != pdata_urb->purb) {
900 usb_free_urb(pdata_urb->purb);
901 pdata_urb->purb = (struct urb *)NULL;
902 peasycap->allocation_video_urb -= 1;
908 JOM(4, "%i video urbs freed\n", m);
909 /*---------------------------------------------------------------------------*/
910 JOM(4, "freeing video data_urb structures.\n");
912 list_for_each_safe(plist_head, plist_next, peasycap->purb_video_head) {
913 pdata_urb = list_entry(plist_head, struct data_urb, list_head);
914 if ((struct data_urb *)NULL != pdata_urb) {
915 kfree(pdata_urb); pdata_urb = (struct data_urb *)NULL;
916 peasycap->allocation_video_struct -=
917 sizeof(struct data_urb);
921 JOM(4, "%i video data_urb structures freed\n", m);
922 JOM(4, "setting peasycap->purb_video_head=NULL\n");
923 peasycap->purb_video_head = (struct list_head *)NULL;
925 /*---------------------------------------------------------------------------*/
926 JOM(4, "freeing video isoc buffers.\n");
928 for (k = 0; k < VIDEO_ISOC_BUFFER_MANY; k++) {
929 if ((void *)NULL != peasycap->video_isoc_buffer[k].pgo) {
930 free_pages((unsigned long)
931 (peasycap->video_isoc_buffer[k].pgo),
933 peasycap->video_isoc_buffer[k].pgo = (void *)NULL;
934 peasycap->allocation_video_page -=
935 ((unsigned int)(0x01 << VIDEO_ISOC_ORDER));
939 JOM(4, "isoc video buffers freed: %i pages\n", m * (0x01 << VIDEO_ISOC_ORDER));
940 /*---------------------------------------------------------------------------*/
941 JOM(4, "freeing video field buffers.\n");
943 for (k = 0; k < FIELD_BUFFER_MANY; k++) {
944 for (m = 0; m < FIELD_BUFFER_SIZE/PAGE_SIZE; m++) {
945 if ((void *)NULL != peasycap->field_buffer[k][m].pgo) {
946 free_page((unsigned long)
947 (peasycap->field_buffer[k][m].pgo));
948 peasycap->field_buffer[k][m].pgo = (void *)NULL;
949 peasycap->allocation_video_page -= 1;
954 JOM(4, "video field buffers freed: %i pages\n", gone);
955 /*---------------------------------------------------------------------------*/
956 JOM(4, "freeing video frame buffers.\n");
958 for (k = 0; k < FRAME_BUFFER_MANY; k++) {
959 for (m = 0; m < FRAME_BUFFER_SIZE/PAGE_SIZE; m++) {
960 if ((void *)NULL != peasycap->frame_buffer[k][m].pgo) {
961 free_page((unsigned long)
962 (peasycap->frame_buffer[k][m].pgo));
963 peasycap->frame_buffer[k][m].pgo = (void *)NULL;
964 peasycap->allocation_video_page -= 1;
969 JOM(4, "video frame buffers freed: %i pages\n", gone);
970 /*---------------------------------------------------------------------------*/
974 /*---------------------------------------------------------------------------*/
975 if ((struct list_head *)NULL != peasycap->purb_audio_head) {
976 JOM(4, "freeing audio urbs\n");
978 list_for_each(plist_head, (peasycap->purb_audio_head)) {
979 pdata_urb = list_entry(plist_head, struct data_urb, list_head);
980 if (NULL == pdata_urb)
981 JOM(4, "ERROR: pdata_urb is NULL\n");
983 if ((struct urb *)NULL != pdata_urb->purb) {
984 usb_free_urb(pdata_urb->purb);
985 pdata_urb->purb = (struct urb *)NULL;
986 peasycap->allocation_audio_urb -= 1;
991 JOM(4, "%i audio urbs freed\n", m);
992 /*---------------------------------------------------------------------------*/
993 JOM(4, "freeing audio data_urb structures.\n");
995 list_for_each_safe(plist_head, plist_next, peasycap->purb_audio_head) {
996 pdata_urb = list_entry(plist_head, struct data_urb, list_head);
997 if ((struct data_urb *)NULL != pdata_urb) {
998 kfree(pdata_urb); pdata_urb = (struct data_urb *)NULL;
999 peasycap->allocation_audio_struct -=
1000 sizeof(struct data_urb);
1004 JOM(4, "%i audio data_urb structures freed\n", m);
1005 JOM(4, "setting peasycap->purb_audio_head=NULL\n");
1006 peasycap->purb_audio_head = (struct list_head *)NULL;
1008 /*---------------------------------------------------------------------------*/
1009 JOM(4, "freeing audio isoc buffers.\n");
1011 for (k = 0; k < AUDIO_ISOC_BUFFER_MANY; k++) {
1012 if ((void *)NULL != peasycap->audio_isoc_buffer[k].pgo) {
1013 free_pages((unsigned long)
1014 (peasycap->audio_isoc_buffer[k].pgo),
1016 peasycap->audio_isoc_buffer[k].pgo = (void *)NULL;
1017 peasycap->allocation_audio_page -=
1018 ((unsigned int)(0x01 << AUDIO_ISOC_ORDER));
1022 JOM(4, "easyoss_delete(): isoc audio buffers freed: %i pages\n",
1023 m * (0x01 << AUDIO_ISOC_ORDER));
1024 /*---------------------------------------------------------------------------*/
1025 #if !defined(EASYCAP_NEEDS_ALSA)
1026 JOM(4, "freeing audio buffers.\n");
1028 for (k = 0; k < peasycap->audio_buffer_page_many; k++) {
1029 if ((void *)NULL != peasycap->audio_buffer[k].pgo) {
1030 free_page((unsigned long)(peasycap->audio_buffer[k].pgo));
1031 peasycap->audio_buffer[k].pgo = (void *)NULL;
1032 peasycap->allocation_audio_page -= 1;
1036 JOM(4, "easyoss_delete(): audio buffers freed: %i pages\n", gone);
1037 #endif /*!EASYCAP_NEEDS_ALSA*/
1038 /*---------------------------------------------------------------------------*/
1039 JOM(4, "freeing easycap structure.\n");
1040 allocation_video_urb = peasycap->allocation_video_urb;
1041 allocation_video_page = peasycap->allocation_video_page;
1042 allocation_video_struct = peasycap->allocation_video_struct;
1043 registered_video = peasycap->registered_video;
1044 allocation_audio_urb = peasycap->allocation_audio_urb;
1045 allocation_audio_page = peasycap->allocation_audio_page;
1046 allocation_audio_struct = peasycap->allocation_audio_struct;
1047 registered_audio = peasycap->registered_audio;
1051 if (0 <= kd && DONGLE_MANY > kd) {
1052 if (mutex_lock_interruptible(&mutex_dongle)) {
1053 SAY("ERROR: cannot down mutex_dongle\n");
1055 JOM(4, "locked mutex_dongle\n");
1056 easycapdc60_dongle[kd].peasycap = (struct easycap *)NULL;
1057 mutex_unlock(&mutex_dongle);
1058 JOM(4, "unlocked mutex_dongle\n");
1059 JOT(4, " null-->easycapdc60_dongle[%i].peasycap\n", kd);
1060 allocation_video_struct -= sizeof(struct easycap);
1063 SAY("ERROR: cannot purge easycapdc60_dongle[].peasycap");
1065 /*---------------------------------------------------------------------------*/
1066 SAY("%8i= video urbs after all deletions\n", allocation_video_urb);
1067 SAY("%8i= video pages after all deletions\n", allocation_video_page);
1068 SAY("%8i= video structs after all deletions\n", allocation_video_struct);
1069 SAY("%8i= video devices after all deletions\n", registered_video);
1070 SAY("%8i= audio urbs after all deletions\n", allocation_audio_urb);
1071 SAY("%8i= audio pages after all deletions\n", allocation_audio_page);
1072 SAY("%8i= audio structs after all deletions\n", allocation_audio_struct);
1073 SAY("%8i= audio devices after all deletions\n", registered_audio);
1075 JOT(4, "ending.\n");
1078 /*****************************************************************************/
1079 unsigned int easycap_poll(struct file *file, poll_table *wait)
1081 struct easycap *peasycap;
1086 if (NULL == ((poll_table *)wait))
1087 JOT(8, "WARNING: poll table pointer is NULL ... continuing\n");
1088 if ((struct file *)NULL == file) {
1089 SAY("ERROR: file pointer is NULL\n");
1090 return -ERESTARTSYS;
1092 peasycap = file->private_data;
1093 if (NULL == peasycap) {
1094 SAY("ERROR: peasycap is NULL\n");
1097 if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
1098 SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap);
1101 if (NULL == peasycap->pusb_device) {
1102 SAY("ERROR: peasycap->pusb_device is NULL\n");
1105 /*---------------------------------------------------------------------------*/
1106 kd = isdongle(peasycap);
1107 if (0 <= kd && DONGLE_MANY > kd) {
1108 if (mutex_lock_interruptible(&easycapdc60_dongle[kd].mutex_video)) {
1109 SAY("ERROR: cannot down "
1110 "easycapdc60_dongle[%i].mutex_video\n", kd);
1111 return -ERESTARTSYS;
1113 JOM(4, "locked easycapdc60_dongle[%i].mutex_video\n", kd);
1114 /*-------------------------------------------------------------------*/
1116 * MEANWHILE, easycap_usb_disconnect() MAY HAVE FREED POINTER
1117 * peasycap, IN WHICH CASE A REPEAT CALL TO isdongle() WILL FAIL.
1118 * IF NECESSARY, BAIL OUT.
1120 /*-------------------------------------------------------------------*/
1121 if (kd != isdongle(peasycap))
1122 return -ERESTARTSYS;
1124 SAY("ERROR: file is NULL\n");
1125 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1126 return -ERESTARTSYS;
1128 peasycap = file->private_data;
1129 if (NULL == peasycap) {
1130 SAY("ERROR: peasycap is NULL\n");
1131 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1132 return -ERESTARTSYS;
1134 if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
1135 SAY("ERROR: bad peasycap: 0x%08lX\n",
1136 (unsigned long int) peasycap);
1137 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1138 return -ERESTARTSYS;
1140 if (NULL == peasycap->pusb_device) {
1141 SAM("ERROR: peasycap->pusb_device is NULL\n");
1142 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1143 return -ERESTARTSYS;
1146 /*-------------------------------------------------------------------*/
1148 * IF easycap_usb_disconnect() HAS ALREADY FREED POINTER peasycap
1149 * BEFORE THE ATTEMPT TO ACQUIRE THE SEMAPHORE, isdongle() WILL
1150 * HAVE FAILED. BAIL OUT.
1152 /*-------------------------------------------------------------------*/
1153 return -ERESTARTSYS;
1154 /*---------------------------------------------------------------------------*/
1155 rc = easycap_dqbuf(peasycap, 0);
1156 peasycap->polled = 1;
1157 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1159 return POLLIN | POLLRDNORM;
1163 /*****************************************************************************/
1164 /*---------------------------------------------------------------------------*/
1166 * IF mode IS NONZERO THIS ROUTINE RETURNS -EAGAIN RATHER THAN BLOCKING.
1168 /*---------------------------------------------------------------------------*/
1170 easycap_dqbuf(struct easycap *peasycap, int mode)
1172 int input, ifield, miss, rc;
1176 if (NULL == peasycap) {
1177 SAY("ERROR: peasycap is NULL\n");
1180 if (NULL == peasycap->pusb_device) {
1181 SAY("ERROR: peasycap->pusb_device is NULL\n");
1185 JOM(8, "%i=ifield\n", ifield);
1186 /*---------------------------------------------------------------------------*/
1188 * CHECK FOR LOST INPUT SIGNAL.
1190 * FOR THE FOUR-CVBS EasyCAP, THIS DOES NOT WORK AS EXPECTED.
1191 * IF INPUT 0 IS PRESENT AND SYNC ACQUIRED, UNPLUGGING INPUT 4 DOES NOT
1192 * RESULT IN SETTING BIT 0x40 ON REGISTER 0x1F, PRESUMABLY BECAUSE THERE
1193 * IS FLYWHEELING ON INPUT 0. THE UPSHOT IS:
1195 * INPUT 0 PLUGGED, INPUT 4 PLUGGED => SCREEN 0 OK, SCREEN 4 OK
1196 * INPUT 0 PLUGGED, INPUT 4 UNPLUGGED => SCREEN 0 OK, SCREEN 4 BLACK
1197 * INPUT 0 UNPLUGGED, INPUT 4 PLUGGED => SCREEN 0 BARS, SCREEN 4 OK
1198 * INPUT 0 UNPLUGGED, INPUT 4 UNPLUGGED => SCREEN 0 BARS, SCREEN 4 BARS
1200 /*---------------------------------------------------------------------------*/
1201 input = peasycap->input;
1202 if (0 <= input && INPUT_MANY > input) {
1203 rc = read_saa(peasycap->pusb_device, 0x1F);
1206 peasycap->lost[input] += 1;
1208 peasycap->lost[input] -= 2;
1210 if (0 > peasycap->lost[input])
1211 peasycap->lost[input] = 0;
1212 else if ((2 * VIDEO_LOST_TOLERATE) < peasycap->lost[input])
1213 peasycap->lost[input] = (2 * VIDEO_LOST_TOLERATE);
1216 /*---------------------------------------------------------------------------*/
1218 * WAIT FOR FIELD ifield (0 => TOP, 1 => BOTTOM)
1220 /*---------------------------------------------------------------------------*/
1222 while ((peasycap->field_read == peasycap->field_fill) ||
1223 (0 != (0xFF00 & peasycap->field_buffer
1224 [peasycap->field_read][0].kount)) ||
1225 (ifield != (0x00FF & peasycap->field_buffer
1226 [peasycap->field_read][0].kount))) {
1230 JOM(8, "first wait on wq_video, "
1231 "%i=field_read %i=field_fill\n",
1232 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].kount))))))) {
1241 SAM("aborted by signal\n");
1244 if (peasycap->video_idle) {
1245 JOM(8, "%i=peasycap->video_idle ... returning -EAGAIN\n",
1246 peasycap->video_idle);
1249 if (peasycap->video_eof) {
1250 JOM(8, "%i=peasycap->video_eof\n", peasycap->video_eof);
1251 #if defined(PERSEVERE)
1252 if (1 == peasycap->status) {
1253 JOM(8, "persevering ...\n");
1254 peasycap->video_eof = 0;
1255 peasycap->audio_eof = 0;
1256 if (0 != reset(peasycap)) {
1257 JOM(8, " ... failed ... returning -EIO\n");
1258 peasycap->video_eof = 1;
1259 peasycap->audio_eof = 1;
1260 kill_video_urbs(peasycap);
1263 peasycap->status = 0;
1264 JOM(8, " ... OK ... returning -EAGAIN\n");
1267 #endif /*PERSEVERE*/
1268 peasycap->video_eof = 1;
1269 peasycap->audio_eof = 1;
1270 kill_video_urbs(peasycap);
1271 JOM(8, "returning -EIO\n");
1276 JOM(8, "first awakening on wq_video after %i waits\n", miss);
1278 rc = field2frame(peasycap);
1280 SAM("ERROR: field2frame() returned %i\n", rc);
1281 /*---------------------------------------------------------------------------*/
1283 * WAIT FOR THE OTHER FIELD
1285 /*---------------------------------------------------------------------------*/
1291 while ((peasycap->field_read == peasycap->field_fill) ||
1292 (0 != (0xFF00 & peasycap->field_buffer
1293 [peasycap->field_read][0].kount)) ||
1294 (ifield != (0x00FF & peasycap->field_buffer
1295 [peasycap->field_read][0].kount))) {
1299 JOM(8, "second wait on wq_video, "
1300 "%i=field_read %i=field_fill\n",
1301 peasycap->field_read, peasycap->field_fill);
1302 if (0 != (wait_event_interruptible(peasycap->wq_video,
1303 (peasycap->video_idle || peasycap->video_eof ||
1304 ((peasycap->field_read != peasycap->field_fill) &&
1305 (0 == (0xFF00 & peasycap->field_buffer
1306 [peasycap->field_read][0].kount)) &&
1307 (ifield == (0x00FF & peasycap->field_buffer
1308 [peasycap->field_read][0].
1310 SAM("aborted by signal\n");
1313 if (peasycap->video_idle) {
1314 JOM(8, "%i=peasycap->video_idle ... returning -EAGAIN\n",
1315 peasycap->video_idle);
1318 if (peasycap->video_eof) {
1319 JOM(8, "%i=peasycap->video_eof\n", peasycap->video_eof);
1320 #if defined(PERSEVERE)
1321 if (1 == peasycap->status) {
1322 JOM(8, "persevering ...\n");
1323 peasycap->video_eof = 0;
1324 peasycap->audio_eof = 0;
1325 if (0 != reset(peasycap)) {
1326 JOM(8, " ... failed ... returning -EIO\n");
1327 peasycap->video_eof = 1;
1328 peasycap->audio_eof = 1;
1329 kill_video_urbs(peasycap);
1332 peasycap->status = 0;
1333 JOM(8, " ... OK ... returning -EAGAIN\n");
1336 #endif /*PERSEVERE*/
1337 peasycap->video_eof = 1;
1338 peasycap->audio_eof = 1;
1339 kill_video_urbs(peasycap);
1340 JOM(8, "returning -EIO\n");
1345 JOM(8, "second awakening on wq_video after %i waits\n", miss);
1347 rc = field2frame(peasycap);
1349 SAM("ERROR: field2frame() returned %i\n", rc);
1350 /*---------------------------------------------------------------------------*/
1354 /*---------------------------------------------------------------------------*/
1355 if (0 != peasycap->skip) {
1356 peasycap->skipped++;
1357 if (peasycap->skip != peasycap->skipped)
1358 return peasycap->skip - peasycap->skipped;
1359 peasycap->skipped = 0;
1361 /*---------------------------------------------------------------------------*/
1362 peasycap->frame_read = peasycap->frame_fill;
1363 peasycap->queued[peasycap->frame_read] = 0;
1364 peasycap->done[peasycap->frame_read] = V4L2_BUF_FLAG_DONE;
1366 (peasycap->frame_fill)++;
1367 if (peasycap->frame_buffer_many <= peasycap->frame_fill)
1368 peasycap->frame_fill = 0;
1370 if (0x01 & easycap_standard[peasycap->standard_offset].mask) {
1371 peasycap->frame_buffer[peasycap->frame_read][0].kount =
1374 peasycap->frame_buffer[peasycap->frame_read][0].kount =
1378 JOM(8, "setting: %i=peasycap->frame_read\n", peasycap->frame_read);
1379 JOM(8, "bumped to: %i=peasycap->frame_fill\n", peasycap->frame_fill);
1383 /*****************************************************************************/
1384 /*---------------------------------------------------------------------------*/
1386 * BY DEFINITION, odd IS true FOR THE FIELD OCCUPYING LINES 1,3,5,...,479
1387 * odd IS false FOR THE FIELD OCCUPYING LINES 0,2,4,...,478
1389 * WHEN BOOLEAN PARAMETER decimatepixel IS true, ONLY THE FIELD FOR WHICH
1390 * odd==false IS TRANSFERRED TO THE FRAME BUFFER.
1392 * THE BOOLEAN PARAMETER offerfields IS true ONLY WHEN THE USER PROGRAM
1393 * CHOOSES THE OPTION V4L2_FIELD_INTERLACED.
1395 /*---------------------------------------------------------------------------*/
1397 field2frame(struct easycap *peasycap)
1399 struct timeval timeval;
1400 long long int above, below;
1402 struct signed_div_result sdr;
1405 int kex, kad, mex, mad, rex, rad, rad2;
1406 int c2, c3, w2, w3, cz, wz;
1407 int rc, bytesperpixel, multiplier, much, more, over, rump, caches, input;
1409 bool odd, isuy, decimatepixel, offerfields, badinput;
1411 if (NULL == peasycap) {
1412 SAY("ERROR: peasycap is NULL\n");
1417 input = 0x07 & peasycap->field_buffer[peasycap->field_read][0].input;
1419 JOM(8, "===== parity %i, input 0x%02X, field buffer %i --> "
1420 "frame buffer %i\n",
1421 peasycap->field_buffer[peasycap->field_read][0].kount,
1422 peasycap->field_buffer[peasycap->field_read][0].input,
1423 peasycap->field_read, peasycap->frame_fill);
1424 JOM(8, "===== %i=bytesperpixel\n", peasycap->bytesperpixel);
1425 if (true == peasycap->offerfields)
1426 JOM(8, "===== offerfields\n");
1428 /*---------------------------------------------------------------------------*/
1430 * REJECT OR CLEAN BAD FIELDS
1432 /*---------------------------------------------------------------------------*/
1433 if (peasycap->field_read == peasycap->field_fill) {
1434 SAM("ERROR: on entry, still filling field buffer %i\n",
1435 peasycap->field_read);
1438 #if defined(EASYCAP_TESTCARD)
1439 easycap_testcard(peasycap, peasycap->field_read);
1441 if (0 <= input && INPUT_MANY > input) {
1442 if (easycap_bars && VIDEO_LOST_TOLERATE <= peasycap->lost[input])
1443 easycap_testcard(peasycap, peasycap->field_read);
1445 #endif /*EASYCAP_TESTCARD*/
1446 /*---------------------------------------------------------------------------*/
1448 offerfields = peasycap->offerfields;
1449 bytesperpixel = peasycap->bytesperpixel;
1450 decimatepixel = peasycap->decimatepixel;
1452 if ((2 != bytesperpixel) &&
1453 (3 != bytesperpixel) &&
1454 (4 != bytesperpixel)) {
1455 SAM("MISTAKE: %i=bytesperpixel\n", bytesperpixel);
1458 if (true == decimatepixel)
1463 w2 = 2 * multiplier * (peasycap->width);
1464 w3 = bytesperpixel *
1468 (peasycap->height) *
1472 kex = peasycap->field_read; mex = 0;
1473 kad = peasycap->frame_fill; mad = 0;
1475 pex = peasycap->field_buffer[kex][0].pgo; rex = PAGE_SIZE;
1476 pad = peasycap->frame_buffer[kad][0].pgo; rad = PAGE_SIZE;
1477 if (peasycap->field_buffer[kex][0].kount)
1482 if ((true == odd) && (false == decimatepixel)) {
1483 JOM(8, " initial skipping %4i bytes p.%4i\n",
1484 w3/multiplier, mad);
1485 pad += (w3 / multiplier); rad -= (w3 / multiplier);
1488 mask = 0; rump = 0; caches = 0;
1492 /*-------------------------------------------------------------------*/
1494 ** PROCESS ONE LINE OF FRAME AT FULL RESOLUTION:
1495 ** READ w2 BYTES FROM FIELD BUFFER,
1496 ** WRITE w3 BYTES TO FRAME BUFFER
1498 /*-------------------------------------------------------------------*/
1499 if (false == decimatepixel) {
1502 much = over; more = 0; margin = 0; mask = 0x00;
1508 SAM("MISTAKE: much is odd\n");
1512 more = (bytesperpixel *
1514 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1515 if (1 < bytesperpixel) {
1516 if (rad * 2 < much * bytesperpixel) {
1518 ** INJUDICIOUS ALTERATION OF THIS
1519 ** STATEMENT BLOCK WILL CAUSE
1520 ** BREAKAGE. BEWARE.
1522 rad2 = rad + bytesperpixel - 1;
1524 rad2)/bytesperpixel)/2) * 2);
1525 rump = ((bytesperpixel *
1533 if ((mex + 1) < FIELD_BUFFER_SIZE/
1535 margin = *((__u8 *)(peasycap->
1537 [kex][mex + 1].pgo));
1541 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1543 SAM("MISTAKE: %i=bytesperpixel\n",
1547 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1550 if (true == badinput) {
1551 JOM(8, "ERROR: 0x%02X=->field_buffer"
1553 "0x%02X=(0x08|->input)\n",
1554 peasycap->field_buffer
1555 [kex][mex].input, kex, mex,
1556 (0x08|peasycap->input));
1558 rc = redaub(peasycap, pad, pex, much, more,
1559 mask, margin, isuy);
1561 SAM("ERROR: redaub() failed\n");
1570 over -= much; cz += much;
1571 pex += much; rex -= much;
1574 pex = peasycap->field_buffer[kex][mex].pgo;
1576 if (peasycap->field_buffer[kex][mex].input !=
1577 (0x08|peasycap->input))
1584 pad = peasycap->frame_buffer[kad][mad].pgo;
1592 /*---------------------------------------------------------------------------*/
1594 * SKIP w3 BYTES IN TARGET FRAME BUFFER,
1595 * UNLESS IT IS THE LAST LINE OF AN ODD FRAME
1597 /*---------------------------------------------------------------------------*/
1598 if ((false == odd) || (cz != wz)) {
1603 pad = peasycap->frame_buffer
1615 /*---------------------------------------------------------------------------*/
1617 * PROCESS ONE LINE OF FRAME AT REDUCED RESOLUTION:
1618 * ONLY IF false==odd,
1619 * READ w2 BYTES FROM FIELD BUFFER,
1620 * WRITE w3 / 2 BYTES TO FRAME BUFFER
1622 /*---------------------------------------------------------------------------*/
1623 } else if (false == odd) {
1626 much = over; more = 0; margin = 0; mask = 0x00;
1632 SAM("MISTAKE: much is odd\n");
1636 more = (bytesperpixel *
1638 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1639 if (1 < bytesperpixel) {
1640 if (rad * 4 < much * bytesperpixel) {
1642 ** INJUDICIOUS ALTERATION OF THIS
1643 ** STATEMENT BLOCK WILL CAUSE
1644 ** BREAKAGE. BEWARE.
1646 rad2 = rad + bytesperpixel - 1;
1647 much = ((((2 * rad2)/bytesperpixel)/2)
1649 rump = ((bytesperpixel *
1657 if ((mex + 1) < FIELD_BUFFER_SIZE/
1659 margin = *((__u8 *)(peasycap->
1661 [kex][mex + 1].pgo));
1666 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1668 SAM("MISTAKE: %i=bytesperpixel\n",
1672 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1676 if (true == badinput) {
1677 JOM(8, "ERROR: 0x%02X=->field_buffer"
1679 "0x%02X=(0x08|->input)\n",
1680 peasycap->field_buffer
1681 [kex][mex].input, kex, mex,
1682 (0x08|peasycap->input));
1684 rc = redaub(peasycap, pad, pex, much, more,
1685 mask, margin, isuy);
1687 SAM("ERROR: redaub() failed\n");
1690 over -= much; cz += much;
1691 pex += much; rex -= much;
1694 pex = peasycap->field_buffer[kex][mex].pgo;
1696 if (peasycap->field_buffer[kex][mex].input !=
1697 (0x08|peasycap->input))
1704 pad = peasycap->frame_buffer[kad][mad].pgo;
1712 /*---------------------------------------------------------------------------*/
1715 * READ w2 BYTES FROM FIELD BUFFER AND DISCARD THEM
1717 /*---------------------------------------------------------------------------*/
1723 pex = peasycap->field_buffer[kex][mex].pgo;
1725 if (peasycap->field_buffer[kex][mex].input !=
1726 (0x08|peasycap->input)) {
1727 JOM(8, "ERROR: 0x%02X=->field_buffer"
1729 "0x%02X=(0x08|->input)\n",
1730 peasycap->field_buffer
1731 [kex][mex].input, kex, mex,
1732 (0x08|peasycap->input));
1746 /*---------------------------------------------------------------------------*/
1750 /*---------------------------------------------------------------------------*/
1751 c2 = (mex + 1)*PAGE_SIZE - rex;
1753 SAM("ERROR: discrepancy %i in bytes read\n", c2 - cz);
1754 c3 = (mad + 1)*PAGE_SIZE - rad;
1756 if (false == decimatepixel) {
1759 SAM("ERROR: discrepancy %i in bytes written\n",
1760 c3 - (bytesperpixel *
1766 SAM("ERROR: discrepancy %i in bytes written\n",
1767 (2*c3)-(bytesperpixel *
1771 SAM("ERROR: discrepancy %i "
1772 "in bytes written\n", c3);
1776 SAM("WORRY: undischarged cache at end of line in frame buffer\n");
1778 JOM(8, "===== field2frame(): %i bytes --> %i bytes (incl skip)\n", c2, c3);
1779 JOM(8, "===== field2frame(): %i=mad %i=rad\n", mad, rad);
1782 JOM(8, "+++++ field2frame(): frame buffer %i is full\n", kad);
1784 if (peasycap->field_read == peasycap->field_fill)
1785 SAM("WARNING: on exit, filling field buffer %i\n",
1786 peasycap->field_read);
1787 /*---------------------------------------------------------------------------*/
1789 * CALCULATE VIDEO STREAMING RATE
1791 /*---------------------------------------------------------------------------*/
1792 do_gettimeofday(&timeval);
1793 if (peasycap->timeval6.tv_sec) {
1794 below = ((long long int)(1000000)) *
1795 ((long long int)(timeval.tv_sec -
1796 peasycap->timeval6.tv_sec)) +
1797 (long long int)(timeval.tv_usec - peasycap->timeval6.tv_usec);
1798 above = (long long int)1000000;
1800 sdr = signed_div(above, below);
1801 above = sdr.quotient;
1802 remainder = (__u32)sdr.remainder;
1804 JOM(8, "video streaming at %3lli.%03i fields per second\n", above,
1807 peasycap->timeval6 = timeval;
1810 JOM(8, "%i=caches\n", caches);
1813 /*****************************************************************************/
1814 struct signed_div_result
1815 signed_div(long long int above, long long int below)
1817 struct signed_div_result sdr;
1819 if (((0 <= above) && (0 <= below)) || ((0 > above) && (0 > below))) {
1820 sdr.remainder = (unsigned long long int) do_div(above, below);
1821 sdr.quotient = (long long int) above;
1827 sdr.remainder = (unsigned long long int) do_div(above, below);
1828 sdr.quotient = -((long long int) above);
1832 /*****************************************************************************/
1833 /*---------------------------------------------------------------------------*/
1835 * DECIMATION AND COLOURSPACE CONVERSION.
1837 * THIS ROUTINE REQUIRES THAT ALL THE DATA TO BE READ RESIDES ON ONE PAGE
1838 * AND THAT ALL THE DATA TO BE WRITTEN RESIDES ON ONE (DIFFERENT) PAGE.
1839 * THE CALLING ROUTINE MUST ENSURE THAT THIS REQUIREMENT IS MET, AND MUST
1840 * ALSO ENSURE THAT much IS EVEN.
1842 * much BYTES ARE READ, AT LEAST (bytesperpixel * much)/2 BYTES ARE WRITTEN
1843 * IF THERE IS NO DECIMATION, HALF THIS AMOUNT IF THERE IS DECIMATION.
1845 * mask IS ZERO WHEN NO SPECIAL BEHAVIOUR REQUIRED. OTHERWISE IT IS SET THUS:
1846 * 0x03 & mask = number of bytes to be written to cache instead of to
1848 * 0x04 & mask => use argument margin to set the chrominance for last pixel
1849 * 0x08 & mask => do not set the chrominance for last pixel
1851 * YUV to RGB CONVERSION IS (OR SHOULD BE) ITU-R BT 601.
1853 * THERE IS A LOT OF CODE REPETITION IN THIS ROUTINE IN ORDER TO AVOID
1854 * INEFFICIENT SWITCHING INSIDE INNER LOOPS. REARRANGING THE LOGIC TO
1855 * REDUCE CODE LENGTH WILL GENERALLY IMPAIR RUNTIME PERFORMANCE. BEWARE.
1857 /*---------------------------------------------------------------------------*/
1859 redaub(struct easycap *peasycap, void *pad, void *pex, int much, int more,
1860 __u8 mask, __u8 margin, bool isuy)
1862 static __s32 ay[256], bu[256], rv[256], gu[256], gv[256];
1864 __u8 r, g, b, y, u, v, c, *p2, *p3, *pz, *pr;
1866 bool byteswaporder, decimatepixel, last;
1871 SAM("MISTAKE: much is odd\n");
1874 bytesperpixel = peasycap->bytesperpixel;
1875 byteswaporder = peasycap->byteswaporder;
1876 decimatepixel = peasycap->decimatepixel;
1878 /*---------------------------------------------------------------------------*/
1880 for (j = 0; j < 112; j++) {
1881 s32 = (0xFF00 & (453 * j)) >> 8;
1882 bu[j + 128] = s32; bu[127 - j] = -s32;
1883 s32 = (0xFF00 & (359 * j)) >> 8;
1884 rv[j + 128] = s32; rv[127 - j] = -s32;
1885 s32 = (0xFF00 & (88 * j)) >> 8;
1886 gu[j + 128] = s32; gu[127 - j] = -s32;
1887 s32 = (0xFF00 & (183 * j)) >> 8;
1888 gv[j + 128] = s32; gv[127 - j] = -s32;
1890 for (j = 0; j < 16; j++) {
1891 bu[j] = bu[16]; rv[j] = rv[16];
1892 gu[j] = gu[16]; gv[j] = gv[16];
1894 for (j = 240; j < 256; j++) {
1895 bu[j] = bu[239]; rv[j] = rv[239];
1896 gu[j] = gu[239]; gv[j] = gv[239];
1898 for (j = 16; j < 236; j++)
1900 for (j = 0; j < 16; j++)
1902 for (j = 236; j < 256; j++)
1904 JOM(8, "lookup tables are prepared\n");
1906 pcache = peasycap->pcache;
1908 pcache = &peasycap->cache[0];
1909 /*---------------------------------------------------------------------------*/
1911 * TRANSFER CONTENTS OF CACHE TO THE FRAME BUFFER
1913 /*---------------------------------------------------------------------------*/
1915 SAM("MISTAKE: pcache is NULL\n");
1919 if (pcache != &peasycap->cache[0])
1920 JOM(16, "cache has %i bytes\n", (int)(pcache - &peasycap->cache[0]));
1921 p2 = &peasycap->cache[0];
1922 p3 = (__u8 *)pad - (int)(pcache - &peasycap->cache[0]);
1923 while (p2 < pcache) {
1926 pcache = &peasycap->cache[0];
1928 SAM("MISTAKE: pointer misalignment\n");
1931 /*---------------------------------------------------------------------------*/
1932 rump = (int)(0x03 & mask);
1934 p2 = (__u8 *)pex; pz = p2 + much; pr = p3 + more; last = false;
1943 JOM(16, "%4i=much %4i=more %i=rump\n", much, more, rump);
1945 /*---------------------------------------------------------------------------*/
1946 switch (bytesperpixel) {
1948 if (false == decimatepixel) {
1949 memcpy(pad, pex, (size_t)much);
1950 if (false == byteswaporder)
1951 /*---------------------------------------------------*/
1955 /*---------------------------------------------------*/
1958 /*---------------------------------------------------*/
1962 /*---------------------------------------------------*/
1963 p3 = (__u8 *)pad; pz = p3 + much;
1973 if (false == byteswaporder) {
1974 /*---------------------------------------------------*/
1978 /*---------------------------------------------------*/
1979 p2 = (__u8 *)pex; p3 = (__u8 *)pad; pz = p2 + much;
1982 *(p3 + 1) = *(p2 + 1);
1983 *(p3 + 2) = *(p2 + 2);
1984 *(p3 + 3) = *(p2 + 3);
1989 /*---------------------------------------------------*/
1993 /*---------------------------------------------------*/
1994 p2 = (__u8 *)pex; p3 = (__u8 *)pad; pz = p2 + much;
1998 *(p3 + 2) = *(p2 + 3);
1999 *(p3 + 3) = *(p2 + 2);
2009 if (false == decimatepixel) {
2010 if (false == byteswaporder) {
2011 /*---------------------------------------------------*/
2015 /*---------------------------------------------------*/
2017 if (pr <= (p3 + bytesperpixel))
2022 if ((true == last) && (0x0C & mask)) {
2038 s32 = ay[(int)y] + rv[(int)v];
2039 r = (255 < s32) ? 255 : ((0 > s32) ?
2041 s32 = ay[(int)y] - gu[(int)u] - gv[(int)v];
2042 g = (255 < s32) ? 255 : ((0 > s32) ?
2044 s32 = ay[(int)y] + bu[(int)u];
2045 b = (255 < s32) ? 255 : ((0 > s32) ?
2048 if ((true == last) && rump) {
2049 pcache = &peasycap->cache[0];
2050 switch (bytesperpixel - rump) {
2064 SAM("MISTAKE: %i=rump\n",
2065 bytesperpixel - rump);
2079 p3 += bytesperpixel;
2083 /*---------------------------------------------------*/
2087 /*---------------------------------------------------*/
2089 if (pr <= (p3 + bytesperpixel))
2094 if ((true == last) && (0x0C & mask)) {
2111 s32 = ay[(int)y] + rv[(int)v];
2112 r = (255 < s32) ? 255 : ((0 > s32) ?
2114 s32 = ay[(int)y] - gu[(int)u] - gv[(int)v];
2115 g = (255 < s32) ? 255 : ((0 > s32) ?
2117 s32 = ay[(int)y] + bu[(int)u];
2118 b = (255 < s32) ? 255 : ((0 > s32) ?
2121 if ((true == last) && rump) {
2122 pcache = &peasycap->cache[0];
2123 switch (bytesperpixel - rump) {
2137 SAM("MISTAKE: %i=rump\n",
2138 bytesperpixel - rump);
2152 p3 += bytesperpixel;
2157 if (false == byteswaporder) {
2158 /*---------------------------------------------------*/
2162 /*---------------------------------------------------*/
2164 if (pr <= (p3 + bytesperpixel))
2169 if ((true == last) && (0x0C & mask)) {
2186 s32 = ay[(int)y] + rv[(int)v];
2187 r = (255 < s32) ? 255 : ((0 > s32) ?
2189 s32 = ay[(int)y] - gu[(int)u] -
2191 g = (255 < s32) ? 255 : ((0 > s32) ?
2193 s32 = ay[(int)y] + bu[(int)u];
2194 b = (255 < s32) ? 255 : ((0 > s32) ?
2197 if ((true == last) && rump) {
2198 pcache = &peasycap->cache[0];
2199 switch (bytesperpixel - rump) {
2215 bytesperpixel - rump);
2225 p3 += bytesperpixel;
2233 /*---------------------------------------------------*/
2237 /*---------------------------------------------------*/
2239 if (pr <= (p3 + bytesperpixel))
2244 if ((true == last) && (0x0C & mask)) {
2262 s32 = ay[(int)y] + rv[(int)v];
2263 r = (255 < s32) ? 255 : ((0 > s32) ?
2265 s32 = ay[(int)y] - gu[(int)u] -
2267 g = (255 < s32) ? 255 : ((0 > s32) ?
2269 s32 = ay[(int)y] + bu[(int)u];
2270 b = (255 < s32) ? 255 : ((0 > s32) ?
2273 if ((true == last) && rump) {
2274 pcache = &peasycap->cache[0];
2275 switch (bytesperpixel - rump) {
2291 bytesperpixel - rump);
2301 p3 += bytesperpixel;
2314 if (false == decimatepixel) {
2315 if (false == byteswaporder) {
2316 /*---------------------------------------------------*/
2320 /*---------------------------------------------------*/
2322 if (pr <= (p3 + bytesperpixel))
2327 if ((true == last) && (0x0C & mask)) {
2343 s32 = ay[(int)y] + rv[(int)v];
2344 r = (255 < s32) ? 255 : ((0 > s32) ?
2346 s32 = ay[(int)y] - gu[(int)u] - gv[(int)v];
2347 g = (255 < s32) ? 255 : ((0 > s32) ?
2349 s32 = ay[(int)y] + bu[(int)u];
2350 b = (255 < s32) ? 255 : ((0 > s32) ?
2353 if ((true == last) && rump) {
2354 pcache = &peasycap->cache[0];
2355 switch (bytesperpixel - rump) {
2378 SAM("MISTAKE: %i=rump\n",
2379 bytesperpixel - rump);
2394 p3 += bytesperpixel;
2398 /*---------------------------------------------------*/
2402 /*---------------------------------------------------*/
2404 if (pr <= (p3 + bytesperpixel))
2409 if ((true == last) && (0x0C & mask)) {
2425 s32 = ay[(int)y] + rv[(int)v];
2426 r = (255 < s32) ? 255 : ((0 > s32) ?
2428 s32 = ay[(int)y] - gu[(int)u] - gv[(int)v];
2429 g = (255 < s32) ? 255 : ((0 > s32) ?
2431 s32 = ay[(int)y] + bu[(int)u];
2432 b = (255 < s32) ? 255 : ((0 > s32) ?
2435 if ((true == last) && rump) {
2436 pcache = &peasycap->cache[0];
2437 switch (bytesperpixel - rump) {
2460 SAM("MISTAKE: %i=rump\n",
2461 bytesperpixel - rump);
2476 p3 += bytesperpixel;
2481 if (false == byteswaporder) {
2482 /*---------------------------------------------------*/
2486 /*---------------------------------------------------*/
2488 if (pr <= (p3 + bytesperpixel))
2493 if ((true == last) && (0x0C & mask)) {
2511 s32 = ay[(int)y] + rv[(int)v];
2512 r = (255 < s32) ? 255 : ((0 > s32) ?
2514 s32 = ay[(int)y] - gu[(int)u] -
2516 g = (255 < s32) ? 255 : ((0 > s32) ?
2518 s32 = ay[(int)y] + bu[(int)u];
2519 b = (255 < s32) ? 255 : ((0 > s32) ?
2522 if ((true == last) && rump) {
2523 pcache = &peasycap->cache[0];
2524 switch (bytesperpixel - rump) {
2561 p3 += bytesperpixel;
2568 /*---------------------------------------------------*/
2572 /*---------------------------------------------------*/
2574 if (pr <= (p3 + bytesperpixel))
2579 if ((true == last) && (0x0C & mask)) {
2596 s32 = ay[(int)y] + rv[(int)v];
2597 r = (255 < s32) ? 255 : ((0 > s32) ?
2599 s32 = ay[(int)y] - gu[(int)u] -
2601 g = (255 < s32) ? 255 : ((0 > s32) ?
2603 s32 = ay[(int)y] + bu[(int)u];
2604 b = (255 < s32) ? 255 : ((0 > s32) ?
2607 if ((true == last) && rump) {
2608 pcache = &peasycap->cache[0];
2609 switch (bytesperpixel - rump) {
2634 bytesperpixel - rump);
2645 p3 += bytesperpixel;
2656 SAM("MISTAKE: %i=bytesperpixel\n", bytesperpixel);
2662 /*****************************************************************************/
2663 /*---------------------------------------------------------------------------*/
2665 * SEE CORBET ET AL. "LINUX DEVICE DRIVERS", 3rd EDITION, PAGES 430-434
2667 /*---------------------------------------------------------------------------*/
2668 int easycap_mmap(struct file *file, struct vm_area_struct *pvma)
2673 pvma->vm_ops = &easycap_vm_ops;
2674 pvma->vm_flags |= VM_RESERVED;
2676 pvma->vm_private_data = file->private_data;
2677 easycap_vma_open(pvma);
2680 /*****************************************************************************/
2682 easycap_vma_open(struct vm_area_struct *pvma)
2684 struct easycap *peasycap;
2686 peasycap = pvma->vm_private_data;
2687 if (NULL == peasycap) {
2688 SAY("ERROR: peasycap is NULL\n");
2691 if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
2692 SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap);
2695 peasycap->vma_many++;
2696 JOT(8, "%i=peasycap->vma_many\n", peasycap->vma_many);
2699 /*****************************************************************************/
2701 easycap_vma_close(struct vm_area_struct *pvma)
2703 struct easycap *peasycap;
2705 peasycap = pvma->vm_private_data;
2706 if (NULL == peasycap) {
2707 SAY("ERROR: peasycap is NULL\n");
2710 if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
2711 SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap);
2714 peasycap->vma_many--;
2715 JOT(8, "%i=peasycap->vma_many\n", peasycap->vma_many);
2718 /*****************************************************************************/
2720 easycap_vma_fault(struct vm_area_struct *pvma, struct vm_fault *pvmf)
2725 struct easycap *peasycap;
2727 retcode = VM_FAULT_NOPAGE;
2728 pbuf = (void *)NULL;
2729 page = (struct page *)NULL;
2732 SAY("pvma is NULL\n");
2736 SAY("pvmf is NULL\n");
2740 k = (pvmf->pgoff) / (FRAME_BUFFER_SIZE/PAGE_SIZE);
2741 m = (pvmf->pgoff) % (FRAME_BUFFER_SIZE/PAGE_SIZE);
2744 JOT(4, "%4i=k, %4i=m\n", k, m);
2746 JOT(16, "%4i=k, %4i=m\n", k, m);
2748 if ((0 > k) || (FRAME_BUFFER_MANY <= k)) {
2749 SAY("ERROR: buffer index %i out of range\n", k);
2752 if ((0 > m) || (FRAME_BUFFER_SIZE/PAGE_SIZE <= m)) {
2753 SAY("ERROR: page number %i out of range\n", m);
2756 peasycap = pvma->vm_private_data;
2757 if (NULL == peasycap) {
2758 SAY("ERROR: peasycap is NULL\n");
2761 /*---------------------------------------------------------------------------*/
2762 pbuf = peasycap->frame_buffer[k][m].pgo;
2764 SAM("ERROR: pbuf is NULL\n");
2767 page = virt_to_page(pbuf);
2769 SAM("ERROR: page is NULL\n");
2773 /*---------------------------------------------------------------------------*/
2776 SAM("ERROR: page is NULL after get_page(page)\n");
2779 retcode = VM_FAULT_MINOR;
2783 /*****************************************************************************/
2784 /*---------------------------------------------------------------------------*/
2786 * ON COMPLETION OF A VIDEO URB ITS DATA IS COPIED TO THE FIELD BUFFERS
2787 * PROVIDED peasycap->video_idle IS ZERO. REGARDLESS OF THIS BEING TRUE,
2788 * IT IS RESUBMITTED PROVIDED peasycap->video_isoc_streaming IS NOT ZERO.
2790 * THIS FUNCTION IS AN INTERRUPT SERVICE ROUTINE AND MUST NOT SLEEP.
2792 * INFORMATION ABOUT THE VALIDITY OF THE CONTENTS OF THE FIELD BUFFER ARE
2793 * STORED IN THE TWO-BYTE STATUS PARAMETER
2794 * peasycap->field_buffer[peasycap->field_fill][0].kount
2795 * NOTICE THAT THE INFORMATION IS STORED ONLY WITH PAGE 0 OF THE FIELD BUFFER.
2797 * THE LOWER BYTE CONTAINS THE FIELD PARITY BYTE FURNISHED BY THE SAA7113H
2800 * THE UPPER BYTE IS ZERO IF NO PROBLEMS, OTHERWISE:
2801 * 0 != (kount & 0x8000) => AT LEAST ONE URB COMPLETED WITH ERRORS
2802 * 0 != (kount & 0x4000) => BUFFER HAS TOO MUCH DATA
2803 * 0 != (kount & 0x2000) => BUFFER HAS NOT ENOUGH DATA
2804 * 0 != (kount & 0x1000) => BUFFER HAS DATA FROM DISPARATE INPUTS
2805 * 0 != (kount & 0x0400) => RESERVED
2806 * 0 != (kount & 0x0200) => FIELD BUFFER NOT YET CHECKED
2807 * 0 != (kount & 0x0100) => BUFFER HAS TWO EXTRA BYTES - WHY?
2809 /*---------------------------------------------------------------------------*/
2811 easycap_complete(struct urb *purb)
2813 struct easycap *peasycap;
2814 struct data_buffer *pfield_buffer;
2816 int i, more, much, leap, rc, last;
2817 int videofieldamount;
2818 unsigned int override, bad;
2819 int framestatus, framelength, frameactual, frameoffset;
2823 SAY("ERROR: easycap_complete(): purb is NULL\n");
2826 peasycap = purb->context;
2827 if (NULL == peasycap) {
2828 SAY("ERROR: easycap_complete(): peasycap is NULL\n");
2831 if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
2832 SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap);
2835 if (peasycap->video_eof)
2837 for (i = 0; i < VIDEO_ISOC_BUFFER_MANY; i++)
2838 if (purb->transfer_buffer == peasycap->video_isoc_buffer[i].pgo)
2840 JOM(16, "%2i=urb\n", i);
2841 last = peasycap->video_isoc_sequence;
2842 if ((((VIDEO_ISOC_BUFFER_MANY - 1) == last) &&
2844 (((VIDEO_ISOC_BUFFER_MANY - 1) != last) &&
2845 ((last + 1) != i))) {
2846 JOM(16, "ERROR: out-of-order urbs %i,%i ... continuing\n", last, i);
2848 peasycap->video_isoc_sequence = i;
2850 if (peasycap->video_idle) {
2851 JOM(16, "%i=video_idle %i=video_isoc_streaming\n",
2852 peasycap->video_idle, peasycap->video_isoc_streaming);
2853 if (peasycap->video_isoc_streaming) {
2854 rc = usb_submit_urb(purb, GFP_ATOMIC);
2894 SAM("0x%08X\n", rc);
2899 SAM("ERROR: while %i=video_idle, "
2901 "failed with rc:\n",
2902 peasycap->video_idle);
2908 /*---------------------------------------------------------------------------*/
2909 if (FIELD_BUFFER_MANY <= peasycap->field_fill) {
2910 SAM("ERROR: bad peasycap->field_fill\n");
2914 if ((-ESHUTDOWN == purb->status) || (-ENOENT == purb->status)) {
2915 JOM(8, "urb status -ESHUTDOWN or -ENOENT\n");
2919 (peasycap->field_buffer[peasycap->field_fill][0].kount) |= 0x8000 ;
2920 SAM("ERROR: bad urb status:\n");
2921 switch (purb->status) {
2922 case -EINPROGRESS: {
2923 SAM("-EINPROGRESS\n"); break;
2926 SAM("-ENOSR\n"); break;
2929 SAM("-EPIPE\n"); break;
2932 SAM("-EOVERFLOW\n"); break;
2935 SAM("-EPROTO\n"); break;
2938 SAM("-EILSEQ\n"); break;
2941 SAM("-ETIMEDOUT\n"); break;
2944 SAM("-EMSGSIZE\n"); break;
2947 SAM("-EOPNOTSUPP\n"); break;
2949 case -EPFNOSUPPORT: {
2950 SAM("-EPFNOSUPPORT\n"); break;
2952 case -EAFNOSUPPORT: {
2953 SAM("-EAFNOSUPPORT\n"); break;
2956 SAM("-EADDRINUSE\n"); break;
2958 case -EADDRNOTAVAIL: {
2959 SAM("-EADDRNOTAVAIL\n"); break;
2962 SAM("-ENOBUFS\n"); break;
2965 SAM("-EISCONN\n"); break;
2968 SAM("-ENOTCONN\n"); break;
2971 SAM("-ESHUTDOWN\n"); break;
2974 SAM("-ENOENT\n"); break;
2977 SAM("-ECONNRESET\n"); break;
2980 SAM("ENOSPC\n"); break;
2983 SAM("unknown error code 0x%08X\n", purb->status); break;
2986 /*---------------------------------------------------------------------------*/
2988 for (i = 0; i < purb->number_of_packets; i++) {
2989 if (0 != purb->iso_frame_desc[i].status) {
2990 (peasycap->field_buffer
2991 [peasycap->field_fill][0].kount) |= 0x8000 ;
2992 switch (purb->iso_frame_desc[i].status) {
2994 strcpy(&errbuf[0], "OK"); break;
2997 strcpy(&errbuf[0], "-ENOENT"); break;
2999 case -EINPROGRESS: {
3000 strcpy(&errbuf[0], "-EINPROGRESS"); break;
3003 strcpy(&errbuf[0], "-EPROTO"); break;
3006 strcpy(&errbuf[0], "-EILSEQ"); break;
3009 strcpy(&errbuf[0], "-ETIME"); break;
3012 strcpy(&errbuf[0], "-ETIMEDOUT"); break;
3015 strcpy(&errbuf[0], "-EPIPE"); break;
3018 strcpy(&errbuf[0], "-ECOMM"); break;
3021 strcpy(&errbuf[0], "-ENOSR"); break;
3024 strcpy(&errbuf[0], "-EOVERFLOW"); break;
3027 strcpy(&errbuf[0], "-EREMOTEIO"); break;
3030 strcpy(&errbuf[0], "-ENODEV"); break;
3033 strcpy(&errbuf[0], "-EXDEV"); break;
3036 strcpy(&errbuf[0], "-EINVAL"); break;
3039 strcpy(&errbuf[0], "-ECONNRESET"); break;
3042 SAM("ENOSPC\n"); break;
3045 strcpy(&errbuf[0], "-ESHUTDOWN"); break;
3048 strcpy(&errbuf[0], "unknown error"); break;
3052 framestatus = purb->iso_frame_desc[i].status;
3053 framelength = purb->iso_frame_desc[i].length;
3054 frameactual = purb->iso_frame_desc[i].actual_length;
3055 frameoffset = purb->iso_frame_desc[i].offset;
3057 JOM(16, "frame[%2i]:"
3062 i, framestatus, frameactual, framelength, frameoffset);
3063 if (!purb->iso_frame_desc[i].status) {
3064 more = purb->iso_frame_desc[i].actual_length;
3065 pfield_buffer = &peasycap->field_buffer
3066 [peasycap->field_fill][peasycap->field_page];
3067 videofieldamount = (peasycap->field_page *
3069 (int)(pfield_buffer->pto - pfield_buffer->pgo);
3071 peasycap->video_mt++;
3073 if (peasycap->video_mt) {
3074 JOM(8, "%4i empty video urb frames\n",
3075 peasycap->video_mt);
3076 peasycap->video_mt = 0;
3078 if (FIELD_BUFFER_MANY <= peasycap->field_fill) {
3079 SAM("ERROR: bad peasycap->field_fill\n");
3082 if (FIELD_BUFFER_SIZE/PAGE_SIZE <=
3083 peasycap->field_page) {
3084 SAM("ERROR: bad peasycap->field_page\n");
3087 pfield_buffer = &peasycap->field_buffer
3088 [peasycap->field_fill][peasycap->field_page];
3089 pu = (__u8 *)(purb->transfer_buffer +
3090 purb->iso_frame_desc[i].offset);
3095 /*--------------------------------------------------------------------------*/
3097 * EIGHT-BYTE END-OF-VIDEOFIELD MARKER.
3098 * NOTE: A SUCCESSION OF URB FRAMES FOLLOWING THIS ARE EMPTY,
3099 * CORRESPONDING TO THE FIELD FLYBACK (VERTICAL BLANKING) PERIOD.
3101 * PROVIDED THE FIELD BUFFER CONTAINS GOOD DATA AS INDICATED BY A ZERO UPPER
3103 * peasycap->field_buffer[peasycap->field_fill][0].kount
3104 * THE CONTENTS OF THE FIELD BUFFER ARE OFFERED TO dqbuf(), field_read IS
3105 * UPDATED AND field_fill IS BUMPED. IF THE FIELD BUFFER CONTAINS BAD DATA
3106 * NOTHING IS OFFERED TO dqbuf().
3108 * THE DECISION ON WHETHER THE PARITY OF THE OFFERED FIELD BUFFER IS RIGHT
3109 * RESTS WITH dqbuf().
3111 /*---------------------------------------------------------------------------*/
3112 if ((8 == more) || override) {
3113 if (videofieldamount >
3114 peasycap->videofieldamount) {
3115 if (2 == videofieldamount -
3118 (peasycap->field_buffer
3119 [peasycap->field_fill]
3120 [0].kount) |= 0x0100;
3121 peasycap->video_junk += (1 +
3122 VIDEO_JUNK_TOLERATE);
3124 (peasycap->field_buffer
3125 [peasycap->field_fill]
3126 [0].kount) |= 0x4000;
3127 } else if (videofieldamount <
3130 (peasycap->field_buffer
3131 [peasycap->field_fill]
3132 [0].kount) |= 0x2000;
3134 bad = 0xFF00 & peasycap->field_buffer
3135 [peasycap->field_fill]
3138 (peasycap->video_junk)--;
3139 if (-VIDEO_JUNK_TOLERATE >
3140 peasycap->video_junk)
3141 peasycap->video_junk =
3142 -VIDEO_JUNK_TOLERATE;
3143 peasycap->field_read =
3146 if (FIELD_BUFFER_MANY <=
3151 peasycap->field_page = 0;
3152 pfield_buffer = &peasycap->
3158 pfield_buffer->pto =
3160 JOM(8, "bumped to: %i="
3164 peasycap->field_fill,
3166 pfield_buffer->kount);
3167 JOM(8, "field buffer %i has "
3168 "%i bytes fit to be "
3170 peasycap->field_read,
3172 JOM(8, "wakeup call to "
3177 peasycap->field_read,
3178 peasycap->field_fill,
3182 field_read][0].kount);
3183 wake_up_interruptible
3187 (&peasycap->timeval7);
3189 peasycap->video_junk++;
3191 peasycap->video_junk +=
3192 (1 + VIDEO_JUNK_TOLERATE/2);
3193 JOM(8, "field buffer %i had %i "
3194 "bytes, now discarded: "
3196 peasycap->field_fill,
3199 peasycap->field_buffer
3200 [peasycap->field_fill][0].
3202 (peasycap->field_fill)++;
3204 if (FIELD_BUFFER_MANY <=
3205 peasycap->field_fill)
3206 peasycap->field_fill = 0;
3207 peasycap->field_page = 0;
3209 &peasycap->field_buffer
3210 [peasycap->field_fill]
3211 [peasycap->field_page];
3212 pfield_buffer->pto =
3215 JOM(8, "bumped to: %i=peasycap->"
3216 "field_fill %i=parity\n",
3217 peasycap->field_fill,
3218 0x00FF & pfield_buffer->kount);
3221 JOM(8, "end-of-field: received "
3222 "parity byte 0x%02X\n",
3225 pfield_buffer->kount = 0x0000;
3227 pfield_buffer->kount = 0x0001;
3228 pfield_buffer->input = 0x08 |
3229 (0x07 & peasycap->input);
3230 JOM(8, "end-of-field: 0x%02X=kount\n",
3231 0xFF & pfield_buffer->kount);
3234 /*---------------------------------------------------------------------------*/
3236 * COPY more BYTES FROM ISOC BUFFER TO FIELD BUFFER
3238 /*---------------------------------------------------------------------------*/
3242 if (FIELD_BUFFER_MANY <= peasycap->field_fill) {
3243 SAM("ERROR: bad peasycap->field_fill\n");
3246 if (FIELD_BUFFER_SIZE/PAGE_SIZE <=
3247 peasycap->field_page) {
3248 SAM("ERROR: bad peasycap->field_page\n");
3251 pfield_buffer = &peasycap->field_buffer
3252 [peasycap->field_fill][peasycap->field_page];
3254 pfield_buffer = &peasycap->field_buffer
3255 [peasycap->field_fill]
3256 [peasycap->field_page];
3257 if (PAGE_SIZE < (pfield_buffer->pto -
3258 pfield_buffer->pgo)) {
3259 SAM("ERROR: bad pfield_buffer->pto\n");
3262 if (PAGE_SIZE == (pfield_buffer->pto -
3263 pfield_buffer->pgo)) {
3264 (peasycap->field_page)++;
3265 if (FIELD_BUFFER_SIZE/PAGE_SIZE <=
3266 peasycap->field_page) {
3267 JOM(16, "wrapping peasycap->"
3269 peasycap->field_page = 0;
3271 pfield_buffer = &peasycap->
3273 [peasycap->field_fill]
3274 [peasycap->field_page];
3275 pfield_buffer->pto =
3277 pfield_buffer->input = 0x08 |
3278 (0x07 & peasycap->input);
3279 if ((peasycap->field_buffer[peasycap->
3282 pfield_buffer->input)
3283 (peasycap->field_buffer
3284 [peasycap->field_fill]
3285 [0]).kount |= 0x1000;
3288 much = PAGE_SIZE - (int)(pfield_buffer->pto -
3289 pfield_buffer->pgo);
3293 memcpy(pfield_buffer->pto, pu, much);
3295 (pfield_buffer->pto) += much;
3302 /*---------------------------------------------------------------------------*/
3304 * RESUBMIT THIS URB, UNLESS A SEVERE PERSISTENT ERROR CONDITION EXISTS.
3306 * IF THE WAIT QUEUES ARE NOT CLEARED IN RESPONSE TO AN ERROR CONDITION
3307 * THE USERSPACE PROGRAM, E.G. mplayer, MAY HANG ON EXIT. BEWARE.
3309 /*---------------------------------------------------------------------------*/
3310 if (VIDEO_ISOC_BUFFER_MANY <= peasycap->video_junk) {
3311 SAM("easycap driver shutting down on condition green\n");
3312 peasycap->status = 1;
3313 peasycap->video_eof = 1;
3314 peasycap->video_junk = 0;
3315 wake_up_interruptible(&peasycap->wq_video);
3316 #if !defined(PERSEVERE)
3317 peasycap->audio_eof = 1;
3318 wake_up_interruptible(&peasycap->wq_audio);
3319 #endif /*PERSEVERE*/
3322 if (peasycap->video_isoc_streaming) {
3323 rc = usb_submit_urb(purb, GFP_ATOMIC);
3327 SAM("ENOMEM\n"); break;
3330 SAM("ENODEV\n"); break;
3333 SAM("ENXIO\n"); break;
3336 SAM("EINVAL\n"); break;
3339 SAM("EAGAIN\n"); break;
3342 SAM("EFBIG\n"); break;
3345 SAM("EPIPE\n"); break;
3348 SAM("EMSGSIZE\n"); break;
3351 SAM("ENOSPC\n"); break;
3354 SAM("0x%08X\n", rc); break;
3358 SAM("ERROR: while %i=video_idle, "
3360 "failed with rc:\n",
3361 peasycap->video_idle);
3366 /*****************************************************************************/
3367 /*---------------------------------------------------------------------------*/
3369 * WHEN THE EasyCAP IS PHYSICALLY PLUGGED IN, THIS FUNCTION IS CALLED THREE
3370 * TIMES, ONCE FOR EACH OF THE THREE INTERFACES. BEWARE.
3372 /*---------------------------------------------------------------------------*/
3374 easycap_usb_probe(struct usb_interface *pusb_interface,
3375 const struct usb_device_id *pusb_device_id)
3377 struct usb_device *pusb_device, *pusb_device1;
3378 struct usb_host_interface *pusb_host_interface;
3379 struct usb_endpoint_descriptor *pepd;
3380 struct usb_interface_descriptor *pusb_interface_descriptor;
3381 struct usb_interface_assoc_descriptor *pusb_interface_assoc_descriptor;
3383 struct easycap *peasycap;
3385 struct data_urb *pdata_urb;
3386 size_t wMaxPacketSize;
3387 int ISOCwMaxPacketSize;
3388 int BULKwMaxPacketSize;
3389 int INTwMaxPacketSize;
3390 int CTRLwMaxPacketSize;
3391 __u8 bEndpointAddress;
3392 __u8 ISOCbEndpointAddress;
3393 __u8 INTbEndpointAddress;
3394 int isin, i, j, k, m, rc;
3395 __u8 bInterfaceNumber;
3396 __u8 bInterfaceClass;
3397 __u8 bInterfaceSubClass;
3399 int okalt[8], isokalt;
3405 struct easycap_format *peasycap_format;
3406 /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
3407 #if defined(EASYCAP_IS_VIDEODEV_CLIENT)
3408 #if defined(EASYCAP_NEEDS_V4L2_DEVICE_H)
3409 struct v4l2_device *pv4l2_device;
3410 #endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/
3411 #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
3412 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
3414 /* setup modules params */
3416 if ((struct usb_interface *)NULL == pusb_interface) {
3417 SAY("ERROR: pusb_interface is NULL\n");
3420 peasycap = (struct easycap *)NULL;
3421 /*---------------------------------------------------------------------------*/
3423 * GET POINTER TO STRUCTURE usb_device
3425 /*---------------------------------------------------------------------------*/
3426 pusb_device1 = container_of(pusb_interface->dev.parent,
3427 struct usb_device, dev);
3428 if ((struct usb_device *)NULL == pusb_device1) {
3429 SAY("ERROR: pusb_device1 is NULL\n");
3432 pusb_device = usb_get_dev(pusb_device1);
3433 if ((struct usb_device *)NULL == pusb_device) {
3434 SAY("ERROR: pusb_device is NULL\n");
3437 if ((unsigned long int)pusb_device1 != (unsigned long int)pusb_device) {
3438 JOT(4, "ERROR: pusb_device1 != pusb_device\n");
3441 JOT(4, "bNumConfigurations=%i\n", pusb_device->descriptor.bNumConfigurations);
3442 /*---------------------------------------------------------------------------*/
3443 pusb_host_interface = pusb_interface->cur_altsetting;
3444 if (NULL == pusb_host_interface) {
3445 SAY("ERROR: pusb_host_interface is NULL\n");
3448 pusb_interface_descriptor = &(pusb_host_interface->desc);
3449 if (NULL == pusb_interface_descriptor) {
3450 SAY("ERROR: pusb_interface_descriptor is NULL\n");
3453 /*---------------------------------------------------------------------------*/
3455 * GET PROPERTIES OF PROBED INTERFACE
3457 /*---------------------------------------------------------------------------*/
3458 bInterfaceNumber = pusb_interface_descriptor->bInterfaceNumber;
3459 bInterfaceClass = pusb_interface_descriptor->bInterfaceClass;
3460 bInterfaceSubClass = pusb_interface_descriptor->bInterfaceSubClass;
3462 JOT(4, "intf[%i]: pusb_interface->num_altsetting=%i\n",
3463 bInterfaceNumber, pusb_interface->num_altsetting);
3464 JOT(4, "intf[%i]: pusb_interface->cur_altsetting - "
3465 "pusb_interface->altsetting=%li\n", bInterfaceNumber,
3466 (long int)(pusb_interface->cur_altsetting -
3467 pusb_interface->altsetting));
3468 switch (bInterfaceClass) {
3469 case USB_CLASS_AUDIO: {
3470 JOT(4, "intf[%i]: bInterfaceClass=0x%02X=USB_CLASS_AUDIO\n",
3471 bInterfaceNumber, bInterfaceClass); break;
3473 case USB_CLASS_VIDEO: {
3474 JOT(4, "intf[%i]: bInterfaceClass=0x%02X=USB_CLASS_VIDEO\n",
3475 bInterfaceNumber, bInterfaceClass); break;
3477 case USB_CLASS_VENDOR_SPEC: {
3478 JOT(4, "intf[%i]: bInterfaceClass=0x%02X=USB_CLASS_VENDOR_SPEC\n",
3479 bInterfaceNumber, bInterfaceClass); break;
3484 switch (bInterfaceSubClass) {
3486 JOT(4, "intf[%i]: bInterfaceSubClass=0x%02X=AUDIOCONTROL\n",
3487 bInterfaceNumber, bInterfaceSubClass); break;
3490 JOT(4, "intf[%i]: bInterfaceSubClass=0x%02X=AUDIOSTREAMING\n",
3491 bInterfaceNumber, bInterfaceSubClass); break;
3494 JOT(4, "intf[%i]: bInterfaceSubClass=0x%02X=MIDISTREAMING\n",
3495 bInterfaceNumber, bInterfaceSubClass); break;
3500 /*---------------------------------------------------------------------------*/
3501 pusb_interface_assoc_descriptor = pusb_interface->intf_assoc;
3502 if (NULL != pusb_interface_assoc_descriptor) {
3503 JOT(4, "intf[%i]: bFirstInterface=0x%02X bInterfaceCount=0x%02X\n",
3505 pusb_interface_assoc_descriptor->bFirstInterface,
3506 pusb_interface_assoc_descriptor->bInterfaceCount);
3508 JOT(4, "intf[%i]: pusb_interface_assoc_descriptor is NULL\n",
3511 /*---------------------------------------------------------------------------*/
3513 * A NEW struct easycap IS ALWAYS ALLOCATED WHEN INTERFACE 0 IS PROBED.
3514 * IT IS NOT POSSIBLE HERE TO FREE ANY EXISTING struct easycap. THIS
3515 * SHOULD HAVE BEEN DONE BY easycap_delete() WHEN THE EasyCAP WAS
3516 * PHYSICALLY UNPLUGGED.
3518 * THE POINTER peasycap TO THE struct easycap IS REMEMBERED WHEN
3519 * INTERFACES 1 AND 2 ARE PROBED.
3521 /*---------------------------------------------------------------------------*/
3522 if (0 == bInterfaceNumber) {
3523 peasycap = kzalloc(sizeof(struct easycap), GFP_KERNEL);
3524 if (NULL == peasycap) {
3525 SAY("ERROR: Could not allocate peasycap\n");
3528 SAM("allocated 0x%08lX=peasycap\n", (unsigned long int) peasycap);
3529 /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
3530 #if defined(EASYCAP_IS_VIDEODEV_CLIENT)
3531 SAM("where 0x%08lX=&peasycap->video_device\n",
3532 (unsigned long int) &peasycap->video_device);
3533 #if defined(EASYCAP_NEEDS_V4L2_DEVICE_H)
3534 SAM("and 0x%08lX=&peasycap->v4l2_device\n",
3535 (unsigned long int) &peasycap->v4l2_device);
3536 #endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/
3537 #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
3538 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
3539 /*---------------------------------------------------------------------------*/
3541 * PERFORM URGENT INTIALIZATIONS ...
3543 /*---------------------------------------------------------------------------*/
3544 peasycap->minor = -1;
3545 strcpy(&peasycap->telltale[0], TELLTALE);
3546 kref_init(&peasycap->kref);
3547 JOM(8, "intf[%i]: after kref_init(..._video) "
3548 "%i=peasycap->kref.refcount.counter\n",
3549 bInterfaceNumber, peasycap->kref.refcount.counter);
3552 peasycap->gain = (s8)clamp(easycap_gain, 0, 31);
3554 init_waitqueue_head(&peasycap->wq_video);
3555 init_waitqueue_head(&peasycap->wq_audio);
3556 init_waitqueue_head(&peasycap->wq_trigger);
3558 if (mutex_lock_interruptible(&mutex_dongle)) {
3559 SAY("ERROR: cannot down mutex_dongle\n");
3560 return -ERESTARTSYS;
3562 /*---------------------------------------------------------------------------*/
3564 * FOR INTERFACES 1 AND 2 THE POINTER peasycap WILL NEED TO
3565 * TO BE THE SAME AS THAT ALLOCATED NOW FOR INTERFACE 0.
3567 * NORMALLY ndong WILL NOT HAVE CHANGED SINCE INTERFACE 0 WAS
3568 * PROBED, BUT THIS MAY NOT BE THE CASE IF, FOR EXAMPLE, TWO
3569 * EASYCAPs ARE PLUGGED IN SIMULTANEOUSLY.
3571 /*---------------------------------------------------------------------------*/
3572 for (ndong = 0; ndong < DONGLE_MANY; ndong++) {
3573 if ((NULL == easycapdc60_dongle[ndong].peasycap) &&
3574 (!mutex_is_locked(&easycapdc60_dongle
3575 [ndong].mutex_video)) &&
3576 (!mutex_is_locked(&easycapdc60_dongle
3577 [ndong].mutex_audio))) {
3578 easycapdc60_dongle[ndong].peasycap = peasycap;
3579 peasycap->isdongle = ndong;
3580 JOM(8, "intf[%i]: peasycap-->easycap"
3581 "_dongle[%i].peasycap\n",
3582 bInterfaceNumber, ndong);
3586 if (DONGLE_MANY <= ndong) {
3587 SAM("ERROR: too many dongles\n");
3588 mutex_unlock(&mutex_dongle);
3591 mutex_unlock(&mutex_dongle);
3593 peasycap->allocation_video_struct = sizeof(struct easycap);
3594 peasycap->allocation_video_page = 0;
3595 peasycap->allocation_video_urb = 0;
3596 peasycap->allocation_audio_struct = 0;
3597 peasycap->allocation_audio_page = 0;
3598 peasycap->allocation_audio_urb = 0;
3600 /*---------------------------------------------------------------------------*/
3602 * ... AND FURTHER INITIALIZE THE STRUCTURE
3604 /*---------------------------------------------------------------------------*/
3605 peasycap->pusb_device = pusb_device;
3606 peasycap->pusb_interface = pusb_interface;
3609 peasycap->microphone = false;
3611 peasycap->video_interface = -1;
3612 peasycap->video_altsetting_on = -1;
3613 peasycap->video_altsetting_off = -1;
3614 peasycap->video_endpointnumber = -1;
3615 peasycap->video_isoc_maxframesize = -1;
3616 peasycap->video_isoc_buffer_size = -1;
3618 peasycap->audio_interface = -1;
3619 peasycap->audio_altsetting_on = -1;
3620 peasycap->audio_altsetting_off = -1;
3621 peasycap->audio_endpointnumber = -1;
3622 peasycap->audio_isoc_maxframesize = -1;
3623 peasycap->audio_isoc_buffer_size = -1;
3625 peasycap->frame_buffer_many = FRAME_BUFFER_MANY;
3627 for (k = 0; k < INPUT_MANY; k++)
3628 peasycap->lost[k] = 0;
3630 peasycap->skipped = 0;
3631 peasycap->offerfields = 0;
3632 /*---------------------------------------------------------------------------*/
3634 * DYNAMICALLY FILL IN THE AVAILABLE FORMATS ...
3636 /*---------------------------------------------------------------------------*/
3637 rc = fillin_formats();
3639 SAM("ERROR: fillin_formats() returned %i\n", rc);
3642 JOM(4, "%i formats available\n", rc);
3643 /*---------------------------------------------------------------------------*/
3645 * ... AND POPULATE easycap.inputset[]
3647 /*---------------------------------------------------------------------------*/
3648 for (k = 0; k < INPUT_MANY; k++) {
3649 peasycap->inputset[k].input_ok = 0;
3650 peasycap->inputset[k].standard_offset_ok = 0;
3651 peasycap->inputset[k].format_offset_ok = 0;
3652 peasycap->inputset[k].brightness_ok = 0;
3653 peasycap->inputset[k].contrast_ok = 0;
3654 peasycap->inputset[k].saturation_ok = 0;
3655 peasycap->inputset[k].hue_ok = 0;
3657 if (true == peasycap->ntsc) {
3661 while (0xFFFF != easycap_standard[i].mask) {
3662 if (NTSC_M == easycap_standard[i].
3663 v4l2_standard.index) {
3665 for (k = 0; k < INPUT_MANY; k++) {
3666 peasycap->inputset[k].
3667 standard_offset = i;
3669 mask = easycap_standard[i].mask;
3677 while (0xFFFF != easycap_standard[i].mask) {
3678 if (PAL_BGHIN == easycap_standard[i].
3679 v4l2_standard.index) {
3681 for (k = 0; k < INPUT_MANY; k++) {
3682 peasycap->inputset[k].
3683 standard_offset = i;
3685 mask = easycap_standard[i].mask;
3692 SAM("MISTAKE: easycap.inputset[].standard_offset "
3693 "unpopulated, %i=m\n", m);
3697 peasycap_format = &easycap_format[0];
3700 while (0 != peasycap_format->v4l2_format.fmt.pix.width) {
3701 if (((peasycap_format->mask & 0x0F) == (mask & 0x0F)) &&
3703 v4l2_format.fmt.pix.field ==
3706 v4l2_format.fmt.pix.pixelformat ==
3707 V4L2_PIX_FMT_UYVY) &&
3709 v4l2_format.fmt.pix.width ==
3712 v4l2_format.fmt.pix.height == 480)) {
3714 for (k = 0; k < INPUT_MANY; k++)
3715 peasycap->inputset[k].format_offset = i;
3722 SAM("MISTAKE: easycap.inputset[].format_offset unpopulated\n");
3728 while (0xFFFFFFFF != easycap_control[i].id) {
3729 value = easycap_control[i].default_value;
3730 if (V4L2_CID_BRIGHTNESS == easycap_control[i].id) {
3732 for (k = 0; k < INPUT_MANY; k++)
3733 peasycap->inputset[k].brightness = value;
3734 } else if (V4L2_CID_CONTRAST == easycap_control[i].id) {
3736 for (k = 0; k < INPUT_MANY; k++)
3737 peasycap->inputset[k].contrast = value;
3738 } else if (V4L2_CID_SATURATION == easycap_control[i].id) {
3740 for (k = 0; k < INPUT_MANY; k++)
3741 peasycap->inputset[k].saturation = value;
3742 } else if (V4L2_CID_HUE == easycap_control[i].id) {
3744 for (k = 0; k < INPUT_MANY; k++)
3745 peasycap->inputset[k].hue = value;
3750 SAM("MISTAKE: easycap.inputset[].brightness,... "
3751 "underpopulated\n");
3754 for (k = 0; k < INPUT_MANY; k++)
3755 peasycap->inputset[k].input = k;
3756 JOM(4, "populated easycap.inputset[]\n");
3757 JOM(4, "finished initialization\n");
3759 /*---------------------------------------------------------------------------*/
3763 * IDENTIFY THE APPROPRIATE POINTER peasycap FOR INTERFACES 1 AND 2.
3764 * THE ADDRESS OF peasycap->pusb_device IS RELUCTANTLY USED FOR THIS PURPOSE.
3766 /*---------------------------------------------------------------------------*/
3767 for (ndong = 0; ndong < DONGLE_MANY; ndong++) {
3768 if (pusb_device == easycapdc60_dongle[ndong].peasycap->
3770 peasycap = easycapdc60_dongle[ndong].peasycap;
3771 JOT(8, "intf[%i]: easycapdc60_dongle[%i].peasycap-->"
3772 "peasycap\n", bInterfaceNumber, ndong);
3776 if (DONGLE_MANY <= ndong) {
3777 SAY("ERROR: peasycap is unknown when probing interface %i\n",
3781 if (NULL == peasycap) {
3782 SAY("ERROR: peasycap is NULL when probing interface %i\n",
3786 #if (!defined(EASYCAP_IS_VIDEODEV_CLIENT))
3788 /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
3790 #if defined(EASYCAP_NEEDS_V4L2_DEVICE_H)
3791 /*---------------------------------------------------------------------------*/
3793 * SOME VERSIONS OF THE videodev MODULE OVERWRITE THE DATA WHICH HAS
3794 * BEEN WRITTEN BY THE CALL TO usb_set_intfdata() IN easycap_usb_probe(),
3795 * REPLACING IT WITH A POINTER TO THE EMBEDDED v4l2_device STRUCTURE.
3796 * TO DETECT THIS, THE STRING IN THE easycap.telltale[] BUFFER IS CHECKED.
3798 /*---------------------------------------------------------------------------*/
3799 if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
3800 pv4l2_device = usb_get_intfdata(pusb_interface);
3801 if ((struct v4l2_device *)NULL == pv4l2_device) {
3802 SAY("ERROR: pv4l2_device is NULL\n");
3805 peasycap = (struct easycap *)
3806 container_of(pv4l2_device, struct easycap, v4l2_device);
3808 #endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/
3809 #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
3811 /*---------------------------------------------------------------------------*/
3812 if ((USB_CLASS_VIDEO == bInterfaceClass) ||
3813 (USB_CLASS_VENDOR_SPEC == bInterfaceClass)) {
3814 if (-1 == peasycap->video_interface) {
3815 peasycap->video_interface = bInterfaceNumber;
3816 JOM(4, "setting peasycap->video_interface=%i\n",
3817 peasycap->video_interface);
3819 if (peasycap->video_interface != bInterfaceNumber) {
3820 SAM("ERROR: attempting to reset "
3821 "peasycap->video_interface\n");
3822 SAM("...... continuing with "
3823 "%i=peasycap->video_interface\n",
3824 peasycap->video_interface);
3827 } else if ((USB_CLASS_AUDIO == bInterfaceClass) &&
3828 (0x02 == bInterfaceSubClass)) {
3829 if (-1 == peasycap->audio_interface) {
3830 peasycap->audio_interface = bInterfaceNumber;
3831 JOM(4, "setting peasycap->audio_interface=%i\n",
3832 peasycap->audio_interface);
3834 if (peasycap->audio_interface != bInterfaceNumber) {
3835 SAM("ERROR: attempting to reset "
3836 "peasycap->audio_interface\n");
3837 SAM("...... continuing with "
3838 "%i=peasycap->audio_interface\n",
3839 peasycap->audio_interface);
3843 /*---------------------------------------------------------------------------*/
3845 * INVESTIGATE ALL ALTSETTINGS.
3846 * DONE IN DETAIL BECAUSE USB DEVICE 05e1:0408 HAS DISPARATE INCARNATIONS.
3848 /*---------------------------------------------------------------------------*/
3851 for (i = 0; i < pusb_interface->num_altsetting; i++) {
3852 pusb_host_interface = &(pusb_interface->altsetting[i]);
3853 if ((struct usb_host_interface *)NULL == pusb_host_interface) {
3854 SAM("ERROR: pusb_host_interface is NULL\n");
3857 pusb_interface_descriptor = &(pusb_host_interface->desc);
3858 if ((struct usb_interface_descriptor *)NULL ==
3859 pusb_interface_descriptor) {
3860 SAM("ERROR: pusb_interface_descriptor is NULL\n");
3864 JOM(4, "intf[%i]alt[%i]: desc.bDescriptorType=0x%02X\n",
3865 bInterfaceNumber, i, pusb_interface_descriptor->bDescriptorType);
3866 JOM(4, "intf[%i]alt[%i]: desc.bInterfaceNumber=0x%02X\n",
3867 bInterfaceNumber, i, pusb_interface_descriptor->bInterfaceNumber);
3868 JOM(4, "intf[%i]alt[%i]: desc.bAlternateSetting=0x%02X\n",
3869 bInterfaceNumber, i, pusb_interface_descriptor->bAlternateSetting);
3870 JOM(4, "intf[%i]alt[%i]: desc.bNumEndpoints=0x%02X\n",
3871 bInterfaceNumber, i, pusb_interface_descriptor->bNumEndpoints);
3872 JOM(4, "intf[%i]alt[%i]: desc.bInterfaceClass=0x%02X\n",
3873 bInterfaceNumber, i, pusb_interface_descriptor->bInterfaceClass);
3874 JOM(4, "intf[%i]alt[%i]: desc.bInterfaceSubClass=0x%02X\n",
3875 bInterfaceNumber, i, pusb_interface_descriptor->bInterfaceSubClass);
3876 JOM(4, "intf[%i]alt[%i]: desc.bInterfaceProtocol=0x%02X\n",
3877 bInterfaceNumber, i, pusb_interface_descriptor->bInterfaceProtocol);
3878 JOM(4, "intf[%i]alt[%i]: desc.iInterface=0x%02X\n",
3879 bInterfaceNumber, i, pusb_interface_descriptor->iInterface);
3881 ISOCwMaxPacketSize = -1;
3882 BULKwMaxPacketSize = -1;
3883 INTwMaxPacketSize = -1;
3884 CTRLwMaxPacketSize = -1;
3885 ISOCbEndpointAddress = 0;
3886 INTbEndpointAddress = 0;
3888 if (0 == pusb_interface_descriptor->bNumEndpoints)
3889 JOM(4, "intf[%i]alt[%i] has no endpoints\n",
3890 bInterfaceNumber, i);
3891 /*---------------------------------------------------------------------------*/
3892 for (j = 0; j < pusb_interface_descriptor->bNumEndpoints; j++) {
3893 pepd = &(pusb_host_interface->endpoint[j].desc);
3894 if ((struct usb_endpoint_descriptor *)NULL == pepd) {
3895 SAM("ERROR: pepd is NULL.\n");
3896 SAM("...... skipping\n");
3899 wMaxPacketSize = le16_to_cpu(pepd->wMaxPacketSize);
3900 bEndpointAddress = pepd->bEndpointAddress;
3902 JOM(4, "intf[%i]alt[%i]end[%i]: bEndpointAddress=0x%X\n",
3903 bInterfaceNumber, i, j,
3904 pepd->bEndpointAddress);
3905 JOM(4, "intf[%i]alt[%i]end[%i]: bmAttributes=0x%X\n",
3906 bInterfaceNumber, i, j,
3907 pepd->bmAttributes);
3908 JOM(4, "intf[%i]alt[%i]end[%i]: wMaxPacketSize=%i\n",
3909 bInterfaceNumber, i, j,
3910 pepd->wMaxPacketSize);
3911 JOM(4, "intf[%i]alt[%i]end[%i]: bInterval=%i\n",
3912 bInterfaceNumber, i, j,
3915 if (pepd->bEndpointAddress & USB_DIR_IN) {
3916 JOM(4, "intf[%i]alt[%i]end[%i] is an IN endpoint\n",
3917 bInterfaceNumber, i, j);
3920 JOM(4, "intf[%i]alt[%i]end[%i] is an OUT endpoint\n",
3921 bInterfaceNumber, i, j);
3922 SAM("ERROR: OUT endpoint unexpected\n");
3923 SAM("...... continuing\n");
3926 if ((pepd->bmAttributes &
3927 USB_ENDPOINT_XFERTYPE_MASK) ==
3928 USB_ENDPOINT_XFER_ISOC) {
3929 JOM(4, "intf[%i]alt[%i]end[%i] is an ISOC endpoint\n",
3930 bInterfaceNumber, i, j);
3932 switch (bInterfaceClass) {
3933 case USB_CLASS_VIDEO:
3934 case USB_CLASS_VENDOR_SPEC: {
3937 "peasycap is NULL\n");
3940 if (pepd->wMaxPacketSize) {
3965 if (-1 == peasycap->
3966 video_altsetting_off) {
3968 video_altsetting_off =
3974 video_altsetting_off);
3976 SAM("ERROR: peasycap"
3977 "->video_altsetting_"
3978 "off already set\n");
3981 "%i=peasycap->video_"
3984 video_altsetting_off);
3989 case USB_CLASS_AUDIO: {
3990 if (0x02 != bInterfaceSubClass)
3994 "peasycap is NULL\n");
3997 if (pepd->wMaxPacketSize) {
3999 okalt[isokalt] = i ;
4022 if (-1 == peasycap->
4023 audio_altsetting_off) {
4025 audio_altsetting_off =
4031 audio_altsetting_off);
4033 SAM("ERROR: peasycap"
4034 "->audio_altsetting_"
4035 "off already set\n");
4042 audio_altsetting_off);
4051 } else if ((pepd->bmAttributes &
4052 USB_ENDPOINT_XFERTYPE_MASK) ==
4053 USB_ENDPOINT_XFER_BULK) {
4054 JOM(4, "intf[%i]alt[%i]end[%i] is a BULK endpoint\n",
4055 bInterfaceNumber, i, j);
4056 } else if ((pepd->bmAttributes &
4057 USB_ENDPOINT_XFERTYPE_MASK) ==
4058 USB_ENDPOINT_XFER_INT) {
4059 JOM(4, "intf[%i]alt[%i]end[%i] is an INT endpoint\n",
4060 bInterfaceNumber, i, j);
4062 JOM(4, "intf[%i]alt[%i]end[%i] is a CTRL endpoint\n",
4063 bInterfaceNumber, i, j);
4065 if (0 == pepd->wMaxPacketSize) {
4066 JOM(4, "intf[%i]alt[%i]end[%i] "
4067 "has zero packet size\n",
4068 bInterfaceNumber, i, j);
4072 /*---------------------------------------------------------------------------*/
4074 * PERFORM INITIALIZATION OF THE PROBED INTERFACE
4076 /*---------------------------------------------------------------------------*/
4077 JOM(4, "initialization begins for interface %i\n",
4078 pusb_interface_descriptor->bInterfaceNumber);
4079 switch (bInterfaceNumber) {
4080 /*---------------------------------------------------------------------------*/
4082 * INTERFACE 0 IS THE VIDEO INTERFACE
4084 /*---------------------------------------------------------------------------*/
4087 SAM("MISTAKE: peasycap is NULL\n");
4091 SAM("ERROR: no viable video_altsetting_on\n");
4094 peasycap->video_altsetting_on = okalt[isokalt - 1];
4095 JOM(4, "%i=video_altsetting_on <====\n",
4096 peasycap->video_altsetting_on);
4098 /*---------------------------------------------------------------------------*/
4100 * DECIDE THE VIDEO STREAMING PARAMETERS
4102 /*---------------------------------------------------------------------------*/
4103 peasycap->video_endpointnumber = okepn[isokalt - 1];
4104 JOM(4, "%i=video_endpointnumber\n", peasycap->video_endpointnumber);
4105 maxpacketsize = okmps[isokalt - 1];
4106 if (USB_2_0_MAXPACKETSIZE > maxpacketsize) {
4107 peasycap->video_isoc_maxframesize = maxpacketsize;
4109 peasycap->video_isoc_maxframesize =
4110 USB_2_0_MAXPACKETSIZE;
4112 JOM(4, "%i=video_isoc_maxframesize\n",
4113 peasycap->video_isoc_maxframesize);
4114 if (0 >= peasycap->video_isoc_maxframesize) {
4115 SAM("ERROR: bad video_isoc_maxframesize\n");
4116 SAM(" possibly because port is USB 1.1\n");
4119 peasycap->video_isoc_framesperdesc = VIDEO_ISOC_FRAMESPERDESC;
4120 JOM(4, "%i=video_isoc_framesperdesc\n",
4121 peasycap->video_isoc_framesperdesc);
4122 if (0 >= peasycap->video_isoc_framesperdesc) {
4123 SAM("ERROR: bad video_isoc_framesperdesc\n");
4126 peasycap->video_isoc_buffer_size =
4127 peasycap->video_isoc_maxframesize *
4128 peasycap->video_isoc_framesperdesc;
4129 JOM(4, "%i=video_isoc_buffer_size\n",
4130 peasycap->video_isoc_buffer_size);
4131 if ((PAGE_SIZE << VIDEO_ISOC_ORDER) <
4132 peasycap->video_isoc_buffer_size) {
4133 SAM("MISTAKE: peasycap->video_isoc_buffer_size too big\n");
4136 /*---------------------------------------------------------------------------*/
4137 if (-1 == peasycap->video_interface) {
4138 SAM("MISTAKE: video_interface is unset\n");
4141 if (-1 == peasycap->video_altsetting_on) {
4142 SAM("MISTAKE: video_altsetting_on is unset\n");
4145 if (-1 == peasycap->video_altsetting_off) {
4146 SAM("MISTAKE: video_interface_off is unset\n");
4149 if (-1 == peasycap->video_endpointnumber) {
4150 SAM("MISTAKE: video_endpointnumber is unset\n");
4153 if (-1 == peasycap->video_isoc_maxframesize) {
4154 SAM("MISTAKE: video_isoc_maxframesize is unset\n");
4157 if (-1 == peasycap->video_isoc_buffer_size) {
4158 SAM("MISTAKE: video_isoc_buffer_size is unset\n");
4161 /*---------------------------------------------------------------------------*/
4163 * ALLOCATE MEMORY FOR VIDEO BUFFERS. LISTS MUST BE INITIALIZED FIRST.
4165 /*---------------------------------------------------------------------------*/
4166 INIT_LIST_HEAD(&(peasycap->urb_video_head));
4167 peasycap->purb_video_head = &(peasycap->urb_video_head);
4168 /*---------------------------------------------------------------------------*/
4169 JOM(4, "allocating %i frame buffers of size %li\n",
4170 FRAME_BUFFER_MANY, (long int)FRAME_BUFFER_SIZE);
4171 JOM(4, ".... each scattered over %li pages\n",
4172 FRAME_BUFFER_SIZE/PAGE_SIZE);
4174 for (k = 0; k < FRAME_BUFFER_MANY; k++) {
4175 for (m = 0; m < FRAME_BUFFER_SIZE/PAGE_SIZE; m++) {
4176 if ((void *)NULL != peasycap->frame_buffer[k][m].pgo)
4177 SAM("attempting to reallocate frame "
4180 pbuf = (void *)__get_free_page(GFP_KERNEL);
4181 if ((void *)NULL == pbuf) {
4182 SAM("ERROR: Could not allocate frame "
4183 "buffer %i page %i\n", k, m);
4186 peasycap->allocation_video_page += 1;
4187 peasycap->frame_buffer[k][m].pgo = pbuf;
4189 peasycap->frame_buffer[k][m].pto =
4190 peasycap->frame_buffer[k][m].pgo;
4194 peasycap->frame_fill = 0;
4195 peasycap->frame_read = 0;
4196 JOM(4, "allocation of frame buffers done: %i pages\n", k *
4198 /*---------------------------------------------------------------------------*/
4199 JOM(4, "allocating %i field buffers of size %li\n",
4200 FIELD_BUFFER_MANY, (long int)FIELD_BUFFER_SIZE);
4201 JOM(4, ".... each scattered over %li pages\n",
4202 FIELD_BUFFER_SIZE/PAGE_SIZE);
4204 for (k = 0; k < FIELD_BUFFER_MANY; k++) {
4205 for (m = 0; m < FIELD_BUFFER_SIZE/PAGE_SIZE; m++) {
4206 if ((void *)NULL != peasycap->field_buffer[k][m].pgo) {
4207 SAM("ERROR: attempting to reallocate "
4210 pbuf = (void *) __get_free_page(GFP_KERNEL);
4211 if ((void *)NULL == pbuf) {
4212 SAM("ERROR: Could not allocate field"
4213 " buffer %i page %i\n", k, m);
4217 peasycap->allocation_video_page += 1;
4218 peasycap->field_buffer[k][m].pgo = pbuf;
4220 peasycap->field_buffer[k][m].pto =
4221 peasycap->field_buffer[k][m].pgo;
4223 peasycap->field_buffer[k][0].kount = 0x0200;
4225 peasycap->field_fill = 0;
4226 peasycap->field_page = 0;
4227 peasycap->field_read = 0;
4228 JOM(4, "allocation of field buffers done: %i pages\n", k *
4230 /*---------------------------------------------------------------------------*/
4231 JOM(4, "allocating %i isoc video buffers of size %i\n",
4232 VIDEO_ISOC_BUFFER_MANY,
4233 peasycap->video_isoc_buffer_size);
4234 JOM(4, ".... each occupying contiguous memory pages\n");
4236 for (k = 0; k < VIDEO_ISOC_BUFFER_MANY; k++) {
4237 pbuf = (void *)__get_free_pages(GFP_KERNEL, VIDEO_ISOC_ORDER);
4239 SAM("ERROR: Could not allocate isoc video buffer "
4243 peasycap->allocation_video_page +=
4244 ((unsigned int)(0x01 << VIDEO_ISOC_ORDER));
4246 peasycap->video_isoc_buffer[k].pgo = pbuf;
4247 peasycap->video_isoc_buffer[k].pto = pbuf +
4248 peasycap->video_isoc_buffer_size;
4249 peasycap->video_isoc_buffer[k].kount = k;
4251 JOM(4, "allocation of isoc video buffers done: %i pages\n",
4252 k * (0x01 << VIDEO_ISOC_ORDER));
4253 /*---------------------------------------------------------------------------*/
4255 * ALLOCATE AND INITIALIZE MULTIPLE struct urb ...
4257 /*---------------------------------------------------------------------------*/
4258 JOM(4, "allocating %i struct urb.\n", VIDEO_ISOC_BUFFER_MANY);
4259 JOM(4, "using %i=peasycap->video_isoc_framesperdesc\n",
4260 peasycap->video_isoc_framesperdesc);
4261 JOM(4, "using %i=peasycap->video_isoc_maxframesize\n",
4262 peasycap->video_isoc_maxframesize);
4263 JOM(4, "using %i=peasycap->video_isoc_buffer_sizen",
4264 peasycap->video_isoc_buffer_size);
4266 for (k = 0; k < VIDEO_ISOC_BUFFER_MANY; k++) {
4267 purb = usb_alloc_urb(peasycap->video_isoc_framesperdesc,
4270 SAM("ERROR: usb_alloc_urb returned NULL for buffer "
4274 peasycap->allocation_video_urb += 1;
4275 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
4276 pdata_urb = kzalloc(sizeof(struct data_urb), GFP_KERNEL);
4277 if (NULL == pdata_urb) {
4278 SAM("ERROR: Could not allocate struct data_urb.\n");
4281 peasycap->allocation_video_struct +=
4282 sizeof(struct data_urb);
4284 pdata_urb->purb = purb;
4285 pdata_urb->isbuf = k;
4286 pdata_urb->length = 0;
4287 list_add_tail(&(pdata_urb->list_head),
4288 peasycap->purb_video_head);
4289 /*---------------------------------------------------------------------------*/
4291 * ... AND INITIALIZE THEM
4293 /*---------------------------------------------------------------------------*/
4295 JOM(4, "initializing video urbs thus:\n");
4296 JOM(4, " purb->interval = 1;\n");
4297 JOM(4, " purb->dev = peasycap->pusb_device;\n");
4298 JOM(4, " purb->pipe = usb_rcvisocpipe"
4299 "(peasycap->pusb_device,%i);\n",
4300 peasycap->video_endpointnumber);
4301 JOM(4, " purb->transfer_flags = URB_ISO_ASAP;\n");
4302 JOM(4, " purb->transfer_buffer = peasycap->"
4303 "video_isoc_buffer[.].pgo;\n");
4304 JOM(4, " purb->transfer_buffer_length = %i;\n",
4305 peasycap->video_isoc_buffer_size);
4306 JOM(4, " purb->complete = easycap_complete;\n");
4307 JOM(4, " purb->context = peasycap;\n");
4308 JOM(4, " purb->start_frame = 0;\n");
4309 JOM(4, " purb->number_of_packets = %i;\n",
4310 peasycap->video_isoc_framesperdesc);
4311 JOM(4, " for (j = 0; j < %i; j++)\n",
4312 peasycap->video_isoc_framesperdesc);
4314 JOM(4, " purb->iso_frame_desc[j].offset = j*%i;\n",
4315 peasycap->video_isoc_maxframesize);
4316 JOM(4, " purb->iso_frame_desc[j].length = %i;\n",
4317 peasycap->video_isoc_maxframesize);
4322 purb->dev = peasycap->pusb_device;
4323 purb->pipe = usb_rcvisocpipe(peasycap->pusb_device,
4324 peasycap->video_endpointnumber);
4325 purb->transfer_flags = URB_ISO_ASAP;
4326 purb->transfer_buffer = peasycap->video_isoc_buffer[k].pgo;
4327 purb->transfer_buffer_length =
4328 peasycap->video_isoc_buffer_size;
4329 purb->complete = easycap_complete;
4330 purb->context = peasycap;
4331 purb->start_frame = 0;
4332 purb->number_of_packets = peasycap->video_isoc_framesperdesc;
4333 for (j = 0; j < peasycap->video_isoc_framesperdesc; j++) {
4334 purb->iso_frame_desc[j].offset = j *
4335 peasycap->video_isoc_maxframesize;
4336 purb->iso_frame_desc[j].length =
4337 peasycap->video_isoc_maxframesize;
4340 JOM(4, "allocation of %i struct urb done.\n", k);
4341 /*--------------------------------------------------------------------------*/
4343 * SAVE POINTER peasycap IN THIS INTERFACE.
4345 /*--------------------------------------------------------------------------*/
4346 usb_set_intfdata(pusb_interface, peasycap);
4347 /*---------------------------------------------------------------------------*/
4349 * IT IS ESSENTIAL TO INITIALIZE THE HARDWARE BEFORE, RATHER THAN AFTER,
4350 * THE DEVICE IS REGISTERED, BECAUSE SOME VERSIONS OF THE videodev MODULE
4351 * CALL easycap_open() IMMEDIATELY AFTER REGISTRATION, CAUSING A CLASH.
4354 /*---------------------------------------------------------------------------*/
4355 #if defined(PREFER_NTSC)
4356 peasycap->ntsc = true;
4357 JOM(8, "defaulting initially to NTSC\n");
4359 peasycap->ntsc = false;
4360 JOM(8, "defaulting initially to PAL\n");
4361 #endif /*PREFER_NTSC*/
4362 rc = reset(peasycap);
4364 SAM("ERROR: reset() returned %i\n", rc);
4367 /*--------------------------------------------------------------------------*/
4369 * THE VIDEO DEVICE CAN BE REGISTERED NOW, AS IT IS READY.
4371 /*--------------------------------------------------------------------------*/
4372 #if (!defined(EASYCAP_IS_VIDEODEV_CLIENT))
4373 if (0 != (usb_register_dev(pusb_interface, &easycap_class))) {
4374 err("Not able to get a minor for this device");
4375 usb_set_intfdata(pusb_interface, NULL);
4378 (peasycap->registered_video)++;
4379 SAM("easycap attached to minor #%d\n", pusb_interface->minor);
4380 peasycap->minor = pusb_interface->minor;
4383 /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
4385 #if defined(EASYCAP_NEEDS_V4L2_DEVICE_H)
4386 if (0 != (v4l2_device_register(&(pusb_interface->dev),
4387 &(peasycap->v4l2_device)))) {
4388 SAM("v4l2_device_register() failed\n");
4391 JOM(4, "registered device instance: %s\n",
4392 &(peasycap->v4l2_device.name[0]));
4394 /*---------------------------------------------------------------------------*/
4399 * THIS IS BELIEVED TO BE HARMLESS, BUT MAY WELL BE UNNECESSARY OR WRONG:
4401 /*---------------------------------------------------------------------------*/
4402 peasycap->video_device.v4l2_dev = (struct v4l2_device *)NULL;
4403 /*---------------------------------------------------------------------------*/
4405 #endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/
4407 strcpy(&peasycap->video_device.name[0], "easycapdc60");
4408 #if defined(EASYCAP_NEEDS_V4L2_FOPS)
4409 peasycap->video_device.fops = &v4l2_fops;
4411 peasycap->video_device.fops = &easycap_fops;
4412 #endif /*EASYCAP_NEEDS_V4L2_FOPS*/
4413 peasycap->video_device.minor = -1;
4414 peasycap->video_device.release = (void *)(&videodev_release);
4416 video_set_drvdata(&(peasycap->video_device), (void *)peasycap);
4418 if (0 != (video_register_device(&(peasycap->video_device),
4419 VFL_TYPE_GRABBER, -1))) {
4420 err("Not able to register with videodev");
4421 videodev_release(&(peasycap->video_device));
4424 (peasycap->registered_video)++;
4425 SAM("registered with videodev: %i=minor\n",
4426 peasycap->video_device.minor);
4427 peasycap->minor = peasycap->video_device.minor;
4429 #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
4430 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
4434 /*--------------------------------------------------------------------------*/
4436 * INTERFACE 1 IS THE AUDIO CONTROL INTERFACE
4437 * INTERFACE 2 IS THE AUDIO STREAMING INTERFACE
4439 /*--------------------------------------------------------------------------*/
4441 #if defined(EASYCAP_SILENT)
4443 #endif /*EASYCAP_SILENT*/
4445 SAM("MISTAKE: peasycap is NULL\n");
4448 /*--------------------------------------------------------------------------*/
4450 * SAVE POINTER peasycap IN INTERFACE 1
4452 /*--------------------------------------------------------------------------*/
4453 usb_set_intfdata(pusb_interface, peasycap);
4454 JOM(4, "no initialization required for interface %i\n",
4455 pusb_interface_descriptor->bInterfaceNumber);
4458 /*--------------------------------------------------------------------------*/
4460 #if defined(EASYCAP_SILENT)
4462 #endif /*EASYCAP_SILENT*/
4464 SAM("MISTAKE: peasycap is NULL\n");
4468 SAM("ERROR: no viable audio_altsetting_on\n");
4471 peasycap->audio_altsetting_on = okalt[isokalt - 1];
4472 JOM(4, "%i=audio_altsetting_on <====\n",
4473 peasycap->audio_altsetting_on);
4476 peasycap->audio_endpointnumber = okepn[isokalt - 1];
4477 JOM(4, "%i=audio_endpointnumber\n", peasycap->audio_endpointnumber);
4479 peasycap->audio_isoc_maxframesize = okmps[isokalt - 1];
4480 JOM(4, "%i=audio_isoc_maxframesize\n",
4481 peasycap->audio_isoc_maxframesize);
4482 if (0 >= peasycap->audio_isoc_maxframesize) {
4483 SAM("ERROR: bad audio_isoc_maxframesize\n");
4486 if (9 == peasycap->audio_isoc_maxframesize) {
4487 peasycap->ilk |= 0x02;
4488 SAM("audio hardware is microphone\n");
4489 peasycap->microphone = true;
4490 peasycap->audio_pages_per_fragment = PAGES_PER_AUDIO_FRAGMENT;
4491 } else if (256 == peasycap->audio_isoc_maxframesize) {
4492 peasycap->ilk &= ~0x02;
4493 SAM("audio hardware is AC'97\n");
4494 peasycap->microphone = false;
4495 peasycap->audio_pages_per_fragment = PAGES_PER_AUDIO_FRAGMENT;
4497 SAM("hardware is unidentified:\n");
4498 SAM("%i=audio_isoc_maxframesize\n",
4499 peasycap->audio_isoc_maxframesize);
4503 peasycap->audio_bytes_per_fragment =
4504 peasycap->audio_pages_per_fragment *
4506 peasycap->audio_buffer_page_many = (AUDIO_FRAGMENT_MANY *
4507 peasycap->audio_pages_per_fragment);
4509 JOM(4, "%6i=AUDIO_FRAGMENT_MANY\n", AUDIO_FRAGMENT_MANY);
4510 JOM(4, "%6i=audio_pages_per_fragment\n",
4511 peasycap->audio_pages_per_fragment);
4512 JOM(4, "%6i=audio_bytes_per_fragment\n",
4513 peasycap->audio_bytes_per_fragment);
4514 JOM(4, "%6i=audio_buffer_page_many\n",
4515 peasycap->audio_buffer_page_many);
4517 peasycap->audio_isoc_framesperdesc = AUDIO_ISOC_FRAMESPERDESC;
4519 JOM(4, "%i=audio_isoc_framesperdesc\n",
4520 peasycap->audio_isoc_framesperdesc);
4521 if (0 >= peasycap->audio_isoc_framesperdesc) {
4522 SAM("ERROR: bad audio_isoc_framesperdesc\n");
4526 peasycap->audio_isoc_buffer_size =
4527 peasycap->audio_isoc_maxframesize *
4528 peasycap->audio_isoc_framesperdesc;
4529 JOM(4, "%i=audio_isoc_buffer_size\n",
4530 peasycap->audio_isoc_buffer_size);
4531 if (AUDIO_ISOC_BUFFER_SIZE < peasycap->audio_isoc_buffer_size) {
4532 SAM("MISTAKE: audio_isoc_buffer_size bigger "
4533 "than %li=AUDIO_ISOC_BUFFER_SIZE\n",
4534 AUDIO_ISOC_BUFFER_SIZE);
4537 if (-1 == peasycap->audio_interface) {
4538 SAM("MISTAKE: audio_interface is unset\n");
4541 if (-1 == peasycap->audio_altsetting_on) {
4542 SAM("MISTAKE: audio_altsetting_on is unset\n");
4545 if (-1 == peasycap->audio_altsetting_off) {
4546 SAM("MISTAKE: audio_interface_off is unset\n");
4549 if (-1 == peasycap->audio_endpointnumber) {
4550 SAM("MISTAKE: audio_endpointnumber is unset\n");
4553 if (-1 == peasycap->audio_isoc_maxframesize) {
4554 SAM("MISTAKE: audio_isoc_maxframesize is unset\n");
4557 if (-1 == peasycap->audio_isoc_buffer_size) {
4558 SAM("MISTAKE: audio_isoc_buffer_size is unset\n");
4561 /*---------------------------------------------------------------------------*/
4563 * ALLOCATE MEMORY FOR AUDIO BUFFERS. LISTS MUST BE INITIALIZED FIRST.
4565 /*---------------------------------------------------------------------------*/
4566 INIT_LIST_HEAD(&(peasycap->urb_audio_head));
4567 peasycap->purb_audio_head = &(peasycap->urb_audio_head);
4569 #if !defined(EASYCAP_NEEDS_ALSA)
4570 JOM(4, "allocating an audio buffer\n");
4571 JOM(4, ".... scattered over %i pages\n",
4572 peasycap->audio_buffer_page_many);
4574 for (k = 0; k < peasycap->audio_buffer_page_many; k++) {
4575 if ((void *)NULL != peasycap->audio_buffer[k].pgo) {
4576 SAM("ERROR: attempting to reallocate audio buffers\n");
4578 pbuf = (void *) __get_free_page(GFP_KERNEL);
4579 if ((void *)NULL == pbuf) {
4580 SAM("ERROR: Could not allocate audio "
4581 "buffer page %i\n", k);
4584 peasycap->allocation_audio_page += 1;
4586 peasycap->audio_buffer[k].pgo = pbuf;
4588 peasycap->audio_buffer[k].pto = peasycap->audio_buffer[k].pgo;
4591 peasycap->audio_fill = 0;
4592 peasycap->audio_read = 0;
4593 JOM(4, "allocation of audio buffer done: %i pages\n", k);
4594 #endif /*!EASYCAP_NEEDS_ALSA*/
4595 /*---------------------------------------------------------------------------*/
4596 JOM(4, "allocating %i isoc audio buffers of size %i\n",
4597 AUDIO_ISOC_BUFFER_MANY, peasycap->audio_isoc_buffer_size);
4598 JOM(4, ".... each occupying contiguous memory pages\n");
4600 for (k = 0; k < AUDIO_ISOC_BUFFER_MANY; k++) {
4601 pbuf = (void *)__get_free_pages(GFP_KERNEL, AUDIO_ISOC_ORDER);
4603 SAM("ERROR: Could not allocate isoc audio buffer "
4607 peasycap->allocation_audio_page +=
4608 ((unsigned int)(0x01 << AUDIO_ISOC_ORDER));
4610 peasycap->audio_isoc_buffer[k].pgo = pbuf;
4611 peasycap->audio_isoc_buffer[k].pto = pbuf +
4612 peasycap->audio_isoc_buffer_size;
4613 peasycap->audio_isoc_buffer[k].kount = k;
4615 JOM(4, "allocation of isoc audio buffers done.\n");
4616 /*---------------------------------------------------------------------------*/
4618 * ALLOCATE AND INITIALIZE MULTIPLE struct urb ...
4620 /*---------------------------------------------------------------------------*/
4621 JOM(4, "allocating %i struct urb.\n", AUDIO_ISOC_BUFFER_MANY);
4622 JOM(4, "using %i=peasycap->audio_isoc_framesperdesc\n",
4623 peasycap->audio_isoc_framesperdesc);
4624 JOM(4, "using %i=peasycap->audio_isoc_maxframesize\n",
4625 peasycap->audio_isoc_maxframesize);
4626 JOM(4, "using %i=peasycap->audio_isoc_buffer_size\n",
4627 peasycap->audio_isoc_buffer_size);
4629 for (k = 0; k < AUDIO_ISOC_BUFFER_MANY; k++) {
4630 purb = usb_alloc_urb(peasycap->audio_isoc_framesperdesc,
4633 SAM("ERROR: usb_alloc_urb returned NULL for buffer "
4637 peasycap->allocation_audio_urb += 1 ;
4638 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
4639 pdata_urb = kzalloc(sizeof(struct data_urb), GFP_KERNEL);
4640 if (NULL == pdata_urb) {
4641 SAM("ERROR: Could not allocate struct data_urb.\n");
4644 peasycap->allocation_audio_struct +=
4645 sizeof(struct data_urb);
4647 pdata_urb->purb = purb;
4648 pdata_urb->isbuf = k;
4649 pdata_urb->length = 0;
4650 list_add_tail(&(pdata_urb->list_head),
4651 peasycap->purb_audio_head);
4652 /*---------------------------------------------------------------------------*/
4654 * ... AND INITIALIZE THEM
4656 /*---------------------------------------------------------------------------*/
4658 JOM(4, "initializing audio urbs thus:\n");
4659 JOM(4, " purb->interval = 1;\n");
4660 JOM(4, " purb->dev = peasycap->pusb_device;\n");
4661 JOM(4, " purb->pipe = usb_rcvisocpipe(peasycap->"
4662 "pusb_device,%i);\n",
4663 peasycap->audio_endpointnumber);
4664 JOM(4, " purb->transfer_flags = URB_ISO_ASAP;\n");
4665 JOM(4, " purb->transfer_buffer = "
4666 "peasycap->audio_isoc_buffer[.].pgo;\n");
4667 JOM(4, " purb->transfer_buffer_length = %i;\n",
4668 peasycap->audio_isoc_buffer_size);
4669 #if defined(EASYCAP_NEEDS_ALSA)
4670 JOM(4, " purb->complete = easycap_alsa_complete;\n");
4672 JOM(4, " purb->complete = easyoss_complete;\n");
4673 #endif /*EASYCAP_NEEDS_ALSA*/
4674 JOM(4, " purb->context = peasycap;\n");
4675 JOM(4, " purb->start_frame = 0;\n");
4676 JOM(4, " purb->number_of_packets = %i;\n",
4677 peasycap->audio_isoc_framesperdesc);
4678 JOM(4, " for (j = 0; j < %i; j++)\n",
4679 peasycap->audio_isoc_framesperdesc);
4681 JOM(4, " purb->iso_frame_desc[j].offset = j*%i;\n",
4682 peasycap->audio_isoc_maxframesize);
4683 JOM(4, " purb->iso_frame_desc[j].length = %i;\n",
4684 peasycap->audio_isoc_maxframesize);
4689 purb->dev = peasycap->pusb_device;
4690 purb->pipe = usb_rcvisocpipe(peasycap->pusb_device,
4691 peasycap->audio_endpointnumber);
4692 purb->transfer_flags = URB_ISO_ASAP;
4693 purb->transfer_buffer = peasycap->audio_isoc_buffer[k].pgo;
4694 purb->transfer_buffer_length =
4695 peasycap->audio_isoc_buffer_size;
4696 #if defined(EASYCAP_NEEDS_ALSA)
4697 purb->complete = easycap_alsa_complete;
4699 purb->complete = easyoss_complete;
4700 #endif /*EASYCAP_NEEDS_ALSA*/
4701 purb->context = peasycap;
4702 purb->start_frame = 0;
4703 purb->number_of_packets = peasycap->audio_isoc_framesperdesc;
4704 for (j = 0; j < peasycap->audio_isoc_framesperdesc; j++) {
4705 purb->iso_frame_desc[j].offset = j *
4706 peasycap->audio_isoc_maxframesize;
4707 purb->iso_frame_desc[j].length =
4708 peasycap->audio_isoc_maxframesize;
4711 JOM(4, "allocation of %i struct urb done.\n", k);
4712 /*---------------------------------------------------------------------------*/
4714 * SAVE POINTER peasycap IN THIS INTERFACE.
4716 /*---------------------------------------------------------------------------*/
4717 usb_set_intfdata(pusb_interface, peasycap);
4718 /*---------------------------------------------------------------------------*/
4720 * THE AUDIO DEVICE CAN BE REGISTERED NOW, AS IT IS READY.
4722 /*---------------------------------------------------------------------------*/
4723 #if defined(EASYCAP_NEEDS_ALSA)
4724 JOM(4, "initializing ALSA card\n");
4726 rc = easycap_alsa_probe(peasycap);
4728 err("easycap_alsa_probe() returned %i\n", rc);
4731 JOM(8, "kref_get() with %i=peasycap->kref.refcount.counter\n",
4732 (int)peasycap->kref.refcount.counter);
4733 kref_get(&peasycap->kref);
4734 (peasycap->registered_audio)++;
4737 #else /*EASYCAP_NEEDS_ALSA*/
4738 rc = usb_register_dev(pusb_interface, &easyoss_class);
4740 SAY("ERROR: usb_register_dev() failed\n");
4741 usb_set_intfdata(pusb_interface, NULL);
4744 JOM(8, "kref_get() with %i=peasycap->kref.refcount.counter\n",
4745 (int)peasycap->kref.refcount.counter);
4746 kref_get(&peasycap->kref);
4747 (peasycap->registered_audio)++;
4749 /*---------------------------------------------------------------------------*/
4751 * LET THE USER KNOW WHAT NODE THE AUDIO DEVICE IS ATTACHED TO.
4753 /*---------------------------------------------------------------------------*/
4754 SAM("easyoss attached to minor #%d\n", pusb_interface->minor);
4755 #endif /*EASYCAP_NEEDS_ALSA*/
4759 /*---------------------------------------------------------------------------*/
4761 * INTERFACES OTHER THAN 0, 1 AND 2 ARE UNEXPECTED
4763 /*---------------------------------------------------------------------------*/
4765 JOM(4, "ERROR: unexpected interface %i\n", bInterfaceNumber);
4769 SAM("ends successfully for interface %i\n",
4770 pusb_interface_descriptor->bInterfaceNumber);
4773 /*****************************************************************************/
4774 /*---------------------------------------------------------------------------*/
4776 * WHEN THIS FUNCTION IS CALLED THE EasyCAP HAS ALREADY BEEN PHYSICALLY
4777 * UNPLUGGED. HENCE peasycap->pusb_device IS NO LONGER VALID.
4779 * THIS FUNCTION AFFECTS BOTH OSS AND ALSA. BEWARE.
4781 /*---------------------------------------------------------------------------*/
4783 easycap_usb_disconnect(struct usb_interface *pusb_interface)
4785 struct usb_host_interface *pusb_host_interface;
4786 struct usb_interface_descriptor *pusb_interface_descriptor;
4787 __u8 bInterfaceNumber;
4788 struct easycap *peasycap;
4790 struct list_head *plist_head;
4791 struct data_urb *pdata_urb;
4793 /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
4794 #if defined(EASYCAP_IS_VIDEODEV_CLIENT)
4795 #if defined(EASYCAP_NEEDS_V4L2_DEVICE_H)
4796 struct v4l2_device *pv4l2_device;
4797 #endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/
4798 #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
4799 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
4803 if ((struct usb_interface *)NULL == pusb_interface) {
4804 JOT(4, "ERROR: pusb_interface is NULL\n");
4807 pusb_host_interface = pusb_interface->cur_altsetting;
4808 if ((struct usb_host_interface *)NULL == pusb_host_interface) {
4809 JOT(4, "ERROR: pusb_host_interface is NULL\n");
4812 pusb_interface_descriptor = &(pusb_host_interface->desc);
4813 if ((struct usb_interface_descriptor *)NULL == pusb_interface_descriptor) {
4814 JOT(4, "ERROR: pusb_interface_descriptor is NULL\n");
4817 bInterfaceNumber = pusb_interface_descriptor->bInterfaceNumber;
4818 minor = pusb_interface->minor;
4819 JOT(4, "intf[%i]: minor=%i\n", bInterfaceNumber, minor);
4821 if (1 == bInterfaceNumber)
4824 peasycap = usb_get_intfdata(pusb_interface);
4825 if (NULL == peasycap) {
4826 SAY("ERROR: peasycap is NULL\n");
4829 /*---------------------------------------------------------------------------*/
4830 #if (!defined(EASYCAP_IS_VIDEODEV_CLIENT))
4832 /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
4834 #if defined(EASYCAP_NEEDS_V4L2_DEVICE_H)
4835 /*---------------------------------------------------------------------------*/
4837 * SOME VERSIONS OF THE videodev MODULE OVERWRITE THE DATA WHICH HAS
4838 * BEEN WRITTEN BY THE CALL TO usb_set_intfdata() IN easycap_usb_probe(),
4839 * REPLACING IT WITH A POINTER TO THE EMBEDDED v4l2_device STRUCTURE.
4840 * TO DETECT THIS, THE STRING IN THE easycap.telltale[] BUFFER IS CHECKED.
4842 /*---------------------------------------------------------------------------*/
4843 if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
4844 pv4l2_device = usb_get_intfdata(pusb_interface);
4845 if ((struct v4l2_device *)NULL == pv4l2_device) {
4846 SAY("ERROR: pv4l2_device is NULL\n");
4849 peasycap = (struct easycap *)
4850 container_of(pv4l2_device, struct easycap, v4l2_device);
4852 #endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/
4854 #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
4855 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
4856 /*---------------------------------------------------------------------------*/
4857 if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
4858 SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap);
4861 /*---------------------------------------------------------------------------*/
4863 * IF THE WAIT QUEUES ARE NOT CLEARED A DEADLOCK IS POSSIBLE. BEWARE.
4865 /*---------------------------------------------------------------------------*/
4866 peasycap->video_eof = 1;
4867 peasycap->audio_eof = 1;
4868 wake_up_interruptible(&(peasycap->wq_video));
4869 wake_up_interruptible(&(peasycap->wq_audio));
4870 /*---------------------------------------------------------------------------*/
4871 switch (bInterfaceNumber) {
4873 if ((struct list_head *)NULL != peasycap->purb_video_head) {
4874 JOM(4, "killing video urbs\n");
4876 list_for_each(plist_head, (peasycap->purb_video_head))
4878 pdata_urb = list_entry(plist_head,
4879 struct data_urb, list_head);
4880 if ((struct data_urb *)NULL != pdata_urb) {
4881 if ((struct urb *)NULL !=
4883 usb_kill_urb(pdata_urb->purb);
4888 JOM(4, "%i video urbs killed\n", m);
4892 /*---------------------------------------------------------------------------*/
4894 if ((struct list_head *)NULL != peasycap->purb_audio_head) {
4895 JOM(4, "killing audio urbs\n");
4897 list_for_each(plist_head,
4898 (peasycap->purb_audio_head)) {
4899 pdata_urb = list_entry(plist_head,
4900 struct data_urb, list_head);
4901 if ((struct data_urb *)NULL != pdata_urb) {
4902 if ((struct urb *)NULL !=
4904 usb_kill_urb(pdata_urb->purb);
4909 JOM(4, "%i audio urbs killed\n", m);
4913 /*---------------------------------------------------------------------------*/
4917 /*--------------------------------------------------------------------------*/
4921 * THIS PROCEDURE WILL BLOCK UNTIL easycap_poll(), VIDEO IOCTL AND AUDIO
4922 * IOCTL ARE ALL UNLOCKED. IF THIS IS NOT DONE AN Oops CAN OCCUR WHEN
4923 * AN EasyCAP IS UNPLUGGED WHILE THE URBS ARE RUNNING. BEWARE.
4925 /*--------------------------------------------------------------------------*/
4926 kd = isdongle(peasycap);
4927 switch (bInterfaceNumber) {
4929 if (0 <= kd && DONGLE_MANY > kd) {
4930 wake_up_interruptible(&peasycap->wq_video);
4931 JOM(4, "about to lock easycapdc60_dongle[%i].mutex_video\n",
4933 if (mutex_lock_interruptible(&easycapdc60_dongle[kd].
4935 SAY("ERROR: cannot lock easycapdc60_dongle[%i]."
4936 "mutex_video\n", kd);
4939 JOM(4, "locked easycapdc60_dongle[%i].mutex_video\n", kd);
4941 SAY("ERROR: %i=kd is bad: cannot lock dongle\n", kd);
4942 /*---------------------------------------------------------------------------*/
4943 #if (!defined(EASYCAP_IS_VIDEODEV_CLIENT))
4944 if ((struct easycap *)NULL == peasycap) {
4945 SAM("ERROR: peasycap has become NULL\n");
4947 usb_deregister_dev(pusb_interface, &easycap_class);
4948 (peasycap->registered_video)--;
4949 JOM(4, "intf[%i]: usb_deregister_dev()\n", bInterfaceNumber);
4950 SAM("easycap detached from minor #%d\n", minor);
4952 /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
4954 #if defined(EASYCAP_NEEDS_V4L2_DEVICE_H)
4955 if (!peasycap->v4l2_device.name[0]) {
4956 SAM("ERROR: peasycap->v4l2_device.name is empty\n");
4957 if (0 <= kd && DONGLE_MANY > kd)
4958 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
4961 v4l2_device_disconnect(&peasycap->v4l2_device);
4962 JOM(4, "v4l2_device_disconnect() OK\n");
4963 v4l2_device_unregister(&peasycap->v4l2_device);
4964 JOM(4, "v4l2_device_unregister() OK\n");
4965 #endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/
4967 video_unregister_device(&peasycap->video_device);
4968 JOM(4, "intf[%i]: video_unregister_device() OK\n", bInterfaceNumber);
4969 (peasycap->registered_video)--;
4970 JOM(4, "unregistered with videodev: %i=minor\n", minor);
4971 #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
4972 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
4974 if (0 <= kd && DONGLE_MANY > kd) {
4975 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
4976 JOM(4, "unlocked easycapdc60_dongle[%i].mutex_video\n", kd);
4981 if (0 <= kd && DONGLE_MANY > kd) {
4982 wake_up_interruptible(&peasycap->wq_audio);
4983 JOM(4, "about to lock easycapdc60_dongle[%i].mutex_audio\n",
4985 if (mutex_lock_interruptible(&easycapdc60_dongle[kd].
4987 SAY("ERROR: cannot lock easycapdc60_dongle[%i]."
4988 "mutex_audio\n", kd);
4991 JOM(4, "locked easycapdc60_dongle[%i].mutex_audio\n", kd);
4993 SAY("ERROR: %i=kd is bad: cannot lock dongle\n", kd);
4994 #if defined(EASYCAP_NEEDS_ALSA)
4998 if (0 != snd_card_free(peasycap->psnd_card)) {
4999 SAY("ERROR: snd_card_free() failed\n");
5001 peasycap->psnd_card = (struct snd_card *)NULL;
5002 (peasycap->registered_audio)--;
5006 #else /*EASYCAP_NEEDS_ALSA*/
5007 usb_deregister_dev(pusb_interface, &easyoss_class);
5008 (peasycap->registered_audio)--;
5009 JOM(4, "intf[%i]: usb_deregister_dev()\n", bInterfaceNumber);
5010 SAM("easyoss detached from minor #%d\n", minor);
5011 #endif /*EASYCAP_NEEDS_ALSA*/
5013 if (0 <= kd && DONGLE_MANY > kd) {
5014 mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
5015 JOM(4, "unlocked easycapdc60_dongle[%i].mutex_audio\n", kd);
5022 /*---------------------------------------------------------------------------*/
5024 * CALL easycap_delete() IF NO REMAINING REFERENCES TO peasycap
5025 * (ALSO WHEN ALSA HAS BEEN IN USE)
5027 /*---------------------------------------------------------------------------*/
5028 if (!peasycap->kref.refcount.counter) {
5029 SAM("ERROR: peasycap->kref.refcount.counter is zero "
5030 "so cannot call kref_put()\n");
5031 SAM("ending unsuccessfully: may cause memory leak\n");
5034 if (0 <= kd && DONGLE_MANY > kd) {
5035 JOM(4, "about to lock easycapdc60_dongle[%i].mutex_video\n", kd);
5036 if (mutex_lock_interruptible(&easycapdc60_dongle[kd].mutex_video)) {
5037 SAY("ERROR: cannot down "
5038 "easycapdc60_dongle[%i].mutex_video\n", kd);
5039 SAM("ending unsuccessfully: may cause memory leak\n");
5042 JOM(4, "locked easycapdc60_dongle[%i].mutex_video\n", kd);
5043 JOM(4, "about to lock easycapdc60_dongle[%i].mutex_audio\n", kd);
5044 if (mutex_lock_interruptible(&easycapdc60_dongle[kd].mutex_audio)) {
5045 SAY("ERROR: cannot down "
5046 "easycapdc60_dongle[%i].mutex_audio\n", kd);
5047 mutex_unlock(&(easycapdc60_dongle[kd].mutex_video));
5048 JOM(4, "unlocked easycapdc60_dongle[%i].mutex_video\n", kd);
5049 SAM("ending unsuccessfully: may cause memory leak\n");
5052 JOM(4, "locked easycapdc60_dongle[%i].mutex_audio\n", kd);
5054 JOM(4, "intf[%i]: %i=peasycap->kref.refcount.counter\n",
5055 bInterfaceNumber, (int)peasycap->kref.refcount.counter);
5056 kref_put(&peasycap->kref, easycap_delete);
5057 JOT(4, "intf[%i]: kref_put() done.\n", bInterfaceNumber);
5058 if (0 <= kd && DONGLE_MANY > kd) {
5059 mutex_unlock(&(easycapdc60_dongle[kd].mutex_audio));
5060 JOT(4, "unlocked easycapdc60_dongle[%i].mutex_audio\n", kd);
5061 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
5062 JOT(4, "unlocked easycapdc60_dongle[%i].mutex_video\n", kd);
5064 /*---------------------------------------------------------------------------*/
5068 /*****************************************************************************/
5069 static int __init easycap_module_init(void)
5073 SAY("========easycap=======\n");
5074 JOT(4, "begins. %i=debug %i=bars %i=gain\n", easycap_debug, easycap_bars,
5076 SAY("version: " EASYCAP_DRIVER_VERSION "\n");
5078 mutex_init(&mutex_dongle);
5079 for (k = 0; k < DONGLE_MANY; k++) {
5080 easycapdc60_dongle[k].peasycap = (struct easycap *)NULL;
5081 mutex_init(&easycapdc60_dongle[k].mutex_video);
5082 mutex_init(&easycapdc60_dongle[k].mutex_audio);
5084 /*---------------------------------------------------------------------------*/
5086 * REGISTER THIS DRIVER WITH THE USB SUBSYTEM.
5088 /*---------------------------------------------------------------------------*/
5089 JOT(4, "registering driver easycap\n");
5090 rc = usb_register(&easycap_usb_driver);
5092 SAY("ERROR: usb_register returned %i\n", rc);
5097 /*****************************************************************************/
5098 static void __exit easycap_module_exit(void)
5102 /*---------------------------------------------------------------------------*/
5104 * DEREGISTER THIS DRIVER WITH THE USB SUBSYTEM.
5106 /*---------------------------------------------------------------------------*/
5107 usb_deregister(&easycap_usb_driver);
5111 /*****************************************************************************/
5113 module_init(easycap_module_init);
5114 module_exit(easycap_module_exit);
5116 MODULE_LICENSE("GPL");
5117 MODULE_AUTHOR("R.M. Thomas <rmthomas@sciolus.org>");
5118 MODULE_DESCRIPTION(EASYCAP_DRIVER_DESCRIPTION);
5119 MODULE_VERSION(EASYCAP_DRIVER_VERSION);
5120 #if defined(EASYCAP_DEBUG)
5121 MODULE_PARM_DESC(debug, "Debug level: 0(default),1,2,...,9");
5122 #endif /*EASYCAP_DEBUG*/
5123 MODULE_PARM_DESC(bars,
5124 "Testcard bars on input signal failure: 0=>no, 1=>yes(default)");
5125 MODULE_PARM_DESC(gain, "Audio gain: 0,...,16(default),...31");
5126 /*****************************************************************************/