1 /******************************************************************************
5 * Video driver for EasyCAP USB2.0 Video Capture Device DC60 *
8 ******************************************************************************/
11 * Copyright (C) 2010 R.M. Thomas <rmthomas@sciolus.org>
14 * This is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
19 * The software is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this software; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 /*****************************************************************************/
32 #include <linux/usb/audio.h>
35 MODULE_LICENSE("GPL");
36 MODULE_AUTHOR("R.M. Thomas <rmthomas@sciolus.org>");
37 MODULE_DESCRIPTION(EASYCAP_DRIVER_DESCRIPTION
);
38 MODULE_VERSION(EASYCAP_DRIVER_VERSION
);
40 #ifdef CONFIG_EASYCAP_DEBUG
42 module_param_named(debug
, easycap_debug
, int, S_IRUGO
| S_IWUSR
);
43 MODULE_PARM_DESC(debug
, "Debug level: 0(default),1,2,...,9");
44 #endif /* CONFIG_EASYCAP_DEBUG */
46 bool easycap_readback
;
47 module_param_named(readback
, easycap_readback
, bool, S_IRUGO
| S_IWUSR
);
48 MODULE_PARM_DESC(readback
, "read back written registers: (default false)");
50 static int easycap_bars
= 1;
51 module_param_named(bars
, easycap_bars
, int, S_IRUGO
| S_IWUSR
);
52 MODULE_PARM_DESC(bars
,
53 "Testcard bars on input signal failure: 0=>no, 1=>yes(default)");
55 static int easycap_gain
= 16;
56 module_param_named(gain
, easycap_gain
, int, S_IRUGO
| S_IWUSR
);
57 MODULE_PARM_DESC(gain
, "Audio gain: 0,...,16(default),...31");
59 static bool easycap_ntsc
;
60 module_param_named(ntsc
, easycap_ntsc
, bool, S_IRUGO
| S_IWUSR
);
61 MODULE_PARM_DESC(ntsc
, "NTSC default encoding (default PAL)");
65 struct easycap_dongle easycapdc60_dongle
[DONGLE_MANY
];
66 static struct mutex mutex_dongle
;
67 static void easycap_complete(struct urb
*purb
);
68 static int reset(struct easycap
*peasycap
);
70 const char *strerror(int err
)
72 #define ERRNOSTR(_e) case _e: return # _e
84 ERRNOSTR(EINPROGRESS
);
91 ERRNOSTR(EPFNOSUPPORT
);
92 ERRNOSTR(EAFNOSUPPORT
);
94 ERRNOSTR(EADDRNOTAVAIL
);
100 ERRNOSTR(ECONNRESET
);
106 default: return "unknown";
112 /*---------------------------------------------------------------------------*/
114 * PARAMETERS USED WHEN REGISTERING THE VIDEO INTERFACE
116 * NOTE: SOME KERNELS IGNORE usb_class_driver.minor_base, AS MENTIONED BY
117 * CORBET ET AL. "LINUX DEVICE DRIVERS", 3rd EDITION, PAGE 253.
118 * THIS IS THE CASE FOR OpenSUSE.
120 /*---------------------------------------------------------------------------*/
121 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
122 /****************************************************************************/
123 /*---------------------------------------------------------------------------*/
125 * THIS ROUTINE DOES NOT DETECT DUPLICATE OCCURRENCES OF POINTER peasycap
127 /*---------------------------------------------------------------------------*/
128 int isdongle(struct easycap
*peasycap
)
133 for (k
= 0; k
< DONGLE_MANY
; k
++) {
134 if (easycapdc60_dongle
[k
].peasycap
== peasycap
) {
135 peasycap
->isdongle
= k
;
141 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
142 static int easycap_open(struct inode
*inode
, struct file
*file
)
144 struct video_device
*pvideo_device
;
145 struct easycap
*peasycap
;
149 SAY("==========OPEN=========\n");
151 pvideo_device
= video_devdata(file
);
152 if (!pvideo_device
) {
153 SAY("ERROR: pvideo_device is NULL.\n");
156 peasycap
= (struct easycap
*)video_get_drvdata(pvideo_device
);
158 SAY("ERROR: peasycap is NULL\n");
161 if (!peasycap
->pusb_device
) {
162 SAM("ERROR: peasycap->pusb_device is NULL\n");
165 JOM(16, "peasycap->pusb_device=%p\n", peasycap
->pusb_device
);
167 file
->private_data
= peasycap
;
168 rc
= wakeup_device(peasycap
->pusb_device
);
170 JOM(8, "wakeup_device() OK\n");
172 SAM("ERROR: wakeup_device() rc = %i\n", rc
);
174 SAM("ERROR: wakeup_device() returned -ENODEV\n");
176 SAM("ERROR: wakeup_device() rc = %i\n", rc
);
180 rc
= reset(peasycap
);
182 SAM("ERROR: reset() rc = %i\n", rc
);
188 /*****************************************************************************/
189 /*---------------------------------------------------------------------------*/
191 * RESET THE HARDWARE TO ITS REFERENCE STATE.
193 * THIS ROUTINE MAY BE CALLED REPEATEDLY IF easycap_complete() DETECTS
194 * A BAD VIDEO FRAME SIZE.
196 /*---------------------------------------------------------------------------*/
197 static int reset(struct easycap
*peasycap
)
199 struct easycap_standard
const *peasycap_standard
;
200 int fmtidx
, input
, rate
;
205 SAY("ERROR: peasycap is NULL\n");
208 input
= peasycap
->input
;
210 /*---------------------------------------------------------------------------*/
212 * IF THE SAA7113H HAS ALREADY ACQUIRED SYNC, USE ITS HARDWARE-DETECTED
213 * FIELD FREQUENCY TO DISTINGUISH NTSC FROM PAL. THIS IS ESSENTIAL FOR
214 * gstreamer AND OTHER USERSPACE PROGRAMS WHICH MAY NOT ATTEMPT TO INITIATE
215 * A SWITCH BETWEEN PAL AND NTSC.
217 * FUNCTION ready_saa() MAY REQUIRE A SUBSTANTIAL FRACTION OF A SECOND TO
218 * COMPLETE, SO SHOULD NOT BE INVOKED WITHOUT GOOD REASON.
220 /*---------------------------------------------------------------------------*/
222 JOM(8, "peasycap->ntsc=%d\n", peasycap
->ntsc
);
224 rate
= ready_saa(peasycap
->pusb_device
);
226 JOM(8, "not ready to capture after %i ms ...\n", PATIENCE
);
227 ntsc
= !peasycap
->ntsc
;
228 JOM(8, "... trying %s ..\n", ntsc
? "NTSC" : "PAL");
229 rc
= setup_stk(peasycap
->pusb_device
, ntsc
);
231 SAM("ERROR: setup_stk() rc = %i\n", rc
);
234 rc
= setup_saa(peasycap
->pusb_device
, ntsc
);
236 SAM("ERROR: setup_saa() rc = %i\n", rc
);
240 rate
= ready_saa(peasycap
->pusb_device
);
242 JOM(8, "not ready to capture after %i ms\n", PATIENCE
);
243 JOM(8, "... saa register 0x1F has 0x%02X\n",
244 read_saa(peasycap
->pusb_device
, 0x1F));
245 ntsc
= peasycap
->ntsc
;
247 JOM(8, "... success at second try: %i=rate\n", rate
);
248 ntsc
= (0 < (rate
/2)) ? true : false ;
252 JOM(8, "... success at first try: %i=rate\n", rate
);
253 ntsc
= (0 < rate
/2) ? true : false ;
255 JOM(8, "ntsc=%d\n", ntsc
);
256 /*---------------------------------------------------------------------------*/
258 rc
= setup_stk(peasycap
->pusb_device
, ntsc
);
260 SAM("ERROR: setup_stk() rc = %i\n", rc
);
263 rc
= setup_saa(peasycap
->pusb_device
, ntsc
);
265 SAM("ERROR: setup_saa() rc = %i\n", rc
);
269 memset(peasycap
->merit
, 0, sizeof(peasycap
->merit
));
271 peasycap
->video_eof
= 0;
272 peasycap
->audio_eof
= 0;
273 /*---------------------------------------------------------------------------*/
275 * RESTORE INPUT AND FORCE REFRESH OF STANDARD, FORMAT, ETC.
277 * WHILE THIS PROCEDURE IS IN PROGRESS, SOME IOCTL COMMANDS WILL RETURN -EBUSY.
279 /*---------------------------------------------------------------------------*/
280 peasycap
->input
= -8192;
281 peasycap
->standard_offset
= -8192;
282 fmtidx
= ntsc
? NTSC_M
: PAL_BGHIN
;
284 peasycap_standard
= &easycap_standard
[0];
285 while (0xFFFF != peasycap_standard
->mask
) {
286 if (fmtidx
== peasycap_standard
->v4l2_standard
.index
) {
287 peasycap
->inputset
[input
].standard_offset
=
288 peasycap_standard
- easycap_standard
;
293 if (0xFFFF == peasycap_standard
->mask
) {
294 SAM("ERROR: standard not found\n");
297 JOM(8, "%i=peasycap->inputset[%i].standard_offset\n",
298 peasycap
->inputset
[input
].standard_offset
, input
);
300 peasycap
->format_offset
= -8192;
301 peasycap
->brightness
= -8192;
302 peasycap
->contrast
= -8192;
303 peasycap
->saturation
= -8192;
304 peasycap
->hue
= -8192;
306 rc
= newinput(peasycap
, input
);
309 SAM("ERROR: newinput(.,%i) rc = %i\n", rc
, input
);
312 JOM(4, "restored input, standard and format\n");
314 JOM(8, "true=peasycap->ntsc %d\n", peasycap
->ntsc
);
316 if (0 > peasycap
->input
) {
317 SAM("MISTAKE: %i=peasycap->input\n", peasycap
->input
);
320 if (0 > peasycap
->standard_offset
) {
321 SAM("MISTAKE: %i=peasycap->standard_offset\n",
322 peasycap
->standard_offset
);
325 if (0 > peasycap
->format_offset
) {
326 SAM("MISTAKE: %i=peasycap->format_offset\n",
327 peasycap
->format_offset
);
330 if (0 > peasycap
->brightness
) {
331 SAM("MISTAKE: %i=peasycap->brightness\n",
332 peasycap
->brightness
);
335 if (0 > peasycap
->contrast
) {
336 SAM("MISTAKE: %i=peasycap->contrast\n", peasycap
->contrast
);
339 if (0 > peasycap
->saturation
) {
340 SAM("MISTAKE: %i=peasycap->saturation\n",
341 peasycap
->saturation
);
344 if (0 > peasycap
->hue
) {
345 SAM("MISTAKE: %i=peasycap->hue\n", peasycap
->hue
);
350 /*****************************************************************************/
351 /*---------------------------------------------------------------------------*/
353 * IF THE REQUESTED INPUT IS THE SAME AS THE EXISTING INPUT, DO NOTHING.
355 * KILL URBS, CLEAR FIELD AND FRAME BUFFERS AND RESET THEIR
356 * _read AND _fill POINTERS.
357 * SELECT THE NEW INPUT.
358 * ADJUST THE STANDARD, FORMAT, BRIGHTNESS, CONTRAST, SATURATION AND HUE
359 * ON THE BASIS OF INFORMATION IN STRUCTURE easycap.inputset[input].
360 * RESUBMIT THE URBS IF STREAMING WAS ALREADY IN PROGRESS.
363 * THIS ROUTINE MAY BE CALLED FREQUENTLY BY ZONEMINDER VIA IOCTL,
364 * SO IT SHOULD WRITE ONLY SPARINGLY TO THE LOGFILE.
366 /*---------------------------------------------------------------------------*/
368 newinput(struct easycap
*peasycap
, int input
)
370 int rc
, k
, m
, mood
, off
;
371 int inputnow
, video_idlenow
, audio_idlenow
;
375 SAY("ERROR: peasycap is NULL\n");
378 JOM(8, "%i=input sought\n", input
);
380 if (0 > input
&& INPUT_MANY
<= input
)
382 inputnow
= peasycap
->input
;
383 if (input
== inputnow
)
385 /*---------------------------------------------------------------------------*/
387 * IF STREAMING IS IN PROGRESS THE URBS ARE KILLED AT THIS
388 * STAGE AND WILL BE RESUBMITTED PRIOR TO EXIT FROM THE ROUTINE.
389 * IF NO STREAMING IS IN PROGRESS NO URBS WILL BE SUBMITTED BY THE
392 /*---------------------------------------------------------------------------*/
393 video_idlenow
= peasycap
->video_idle
;
394 audio_idlenow
= peasycap
->audio_idle
;
396 peasycap
->video_idle
= 1;
397 peasycap
->audio_idle
= 1;
398 if (peasycap
->video_isoc_streaming
) {
400 kill_video_urbs(peasycap
);
404 /*---------------------------------------------------------------------------*/
405 if (!peasycap
->pusb_device
) {
406 SAM("ERROR: peasycap->pusb_device is NULL\n");
409 rc
= usb_set_interface(peasycap
->pusb_device
,
410 peasycap
->video_interface
,
411 peasycap
->video_altsetting_off
);
413 SAM("ERROR: usb_set_interface() rc = %i\n", rc
);
416 rc
= stop_100(peasycap
->pusb_device
);
418 SAM("ERROR: stop_100() rc = %i\n", rc
);
421 for (k
= 0; k
< FIELD_BUFFER_MANY
; k
++) {
422 for (m
= 0; m
< FIELD_BUFFER_SIZE
/PAGE_SIZE
; m
++)
423 memset(peasycap
->field_buffer
[k
][m
].pgo
, 0, PAGE_SIZE
);
425 for (k
= 0; k
< FRAME_BUFFER_MANY
; k
++) {
426 for (m
= 0; m
< FRAME_BUFFER_SIZE
/PAGE_SIZE
; m
++)
427 memset(peasycap
->frame_buffer
[k
][m
].pgo
, 0, PAGE_SIZE
);
429 peasycap
->field_page
= 0;
430 peasycap
->field_read
= 0;
431 peasycap
->field_fill
= 0;
433 peasycap
->frame_read
= 0;
434 peasycap
->frame_fill
= 0;
435 for (k
= 0; k
< peasycap
->input
; k
++) {
436 (peasycap
->frame_fill
)++;
437 if (peasycap
->frame_buffer_many
<= peasycap
->frame_fill
)
438 peasycap
->frame_fill
= 0;
440 peasycap
->input
= input
;
441 select_input(peasycap
->pusb_device
, peasycap
->input
, 9);
442 /*---------------------------------------------------------------------------*/
443 if (input
== peasycap
->inputset
[input
].input
) {
444 off
= peasycap
->inputset
[input
].standard_offset
;
445 if (off
!= peasycap
->standard_offset
) {
446 rc
= adjust_standard(peasycap
,
447 easycap_standard
[off
].v4l2_standard
.id
);
449 SAM("ERROR: adjust_standard() rc = %i\n", rc
);
452 JOM(8, "%i=peasycap->standard_offset\n",
453 peasycap
->standard_offset
);
455 JOM(8, "%i=peasycap->standard_offset unchanged\n",
456 peasycap
->standard_offset
);
458 off
= peasycap
->inputset
[input
].format_offset
;
459 if (off
!= peasycap
->format_offset
) {
460 struct v4l2_pix_format
*pix
=
461 &easycap_format
[off
].v4l2_format
.fmt
.pix
;
462 rc
= adjust_format(peasycap
,
463 pix
->width
, pix
->height
,
464 pix
->pixelformat
, pix
->field
, false);
466 SAM("ERROR: adjust_format() rc = %i\n", rc
);
469 JOM(8, "%i=peasycap->format_offset\n",
470 peasycap
->format_offset
);
472 JOM(8, "%i=peasycap->format_offset unchanged\n",
473 peasycap
->format_offset
);
475 mood
= peasycap
->inputset
[input
].brightness
;
476 if (mood
!= peasycap
->brightness
) {
477 rc
= adjust_brightness(peasycap
, mood
);
479 SAM("ERROR: adjust_brightness rc = %i\n", rc
);
482 JOM(8, "%i=peasycap->brightness\n",
483 peasycap
->brightness
);
485 mood
= peasycap
->inputset
[input
].contrast
;
486 if (mood
!= peasycap
->contrast
) {
487 rc
= adjust_contrast(peasycap
, mood
);
489 SAM("ERROR: adjust_contrast rc = %i\n", rc
);
492 JOM(8, "%i=peasycap->contrast\n", peasycap
->contrast
);
494 mood
= peasycap
->inputset
[input
].saturation
;
495 if (mood
!= peasycap
->saturation
) {
496 rc
= adjust_saturation(peasycap
, mood
);
498 SAM("ERROR: adjust_saturation rc = %i\n", rc
);
501 JOM(8, "%i=peasycap->saturation\n",
502 peasycap
->saturation
);
504 mood
= peasycap
->inputset
[input
].hue
;
505 if (mood
!= peasycap
->hue
) {
506 rc
= adjust_hue(peasycap
, mood
);
508 SAM("ERROR: adjust_hue rc = %i\n", rc
);
511 JOM(8, "%i=peasycap->hue\n", peasycap
->hue
);
514 SAM("MISTAKE: easycap.inputset[%i] unpopulated\n", input
);
517 /*---------------------------------------------------------------------------*/
518 if (!peasycap
->pusb_device
) {
519 SAM("ERROR: peasycap->pusb_device is NULL\n");
522 rc
= usb_set_interface(peasycap
->pusb_device
,
523 peasycap
->video_interface
,
524 peasycap
->video_altsetting_on
);
526 SAM("ERROR: usb_set_interface() rc = %i\n", rc
);
529 rc
= start_100(peasycap
->pusb_device
);
531 SAM("ERROR: start_100() rc = %i\n", rc
);
535 submit_video_urbs(peasycap
);
537 peasycap
->video_isoc_sequence
= VIDEO_ISOC_BUFFER_MANY
- 1;
538 peasycap
->video_idle
= video_idlenow
;
539 peasycap
->audio_idle
= audio_idlenow
;
540 peasycap
->video_junk
= 0;
544 /*****************************************************************************/
545 int submit_video_urbs(struct easycap
*peasycap
)
547 struct data_urb
*pdata_urb
;
549 struct list_head
*plist_head
;
550 int j
, isbad
, nospc
, m
, rc
;
554 SAY("ERROR: peasycap is NULL\n");
558 if (!peasycap
->purb_video_head
) {
559 SAY("ERROR: peasycap->urb_video_head uninitialized\n");
562 if (!peasycap
->pusb_device
) {
563 SAY("ERROR: peasycap->pusb_device is NULL\n");
566 if (!peasycap
->video_isoc_streaming
) {
567 JOM(4, "submission of all video urbs\n");
568 isbad
= 0; nospc
= 0; m
= 0;
569 list_for_each(plist_head
, (peasycap
->purb_video_head
)) {
570 pdata_urb
= list_entry(plist_head
,
571 struct data_urb
, list_head
);
572 if (pdata_urb
&& pdata_urb
->purb
) {
573 purb
= pdata_urb
->purb
;
574 isbuf
= pdata_urb
->isbuf
;
576 purb
->dev
= peasycap
->pusb_device
;
578 usb_rcvisocpipe(peasycap
->pusb_device
,
579 peasycap
->video_endpointnumber
);
580 purb
->transfer_flags
= URB_ISO_ASAP
;
581 purb
->transfer_buffer
=
582 peasycap
->video_isoc_buffer
[isbuf
].pgo
;
583 purb
->transfer_buffer_length
=
584 peasycap
->video_isoc_buffer_size
;
585 purb
->complete
= easycap_complete
;
586 purb
->context
= peasycap
;
587 purb
->start_frame
= 0;
588 purb
->number_of_packets
=
589 peasycap
->video_isoc_framesperdesc
;
591 for (j
= 0; j
< peasycap
->video_isoc_framesperdesc
; j
++) {
592 purb
->iso_frame_desc
[j
]. offset
=
593 j
* peasycap
->video_isoc_maxframesize
;
594 purb
->iso_frame_desc
[j
]. length
=
595 peasycap
->video_isoc_maxframesize
;
598 rc
= usb_submit_urb(purb
, GFP_KERNEL
);
601 SAM("ERROR: usb_submit_urb() failed "
602 "for urb with rc:-%s\n",
614 SAM("-ENOSPC=usb_submit_urb() for %i urbs\n", nospc
);
615 SAM("..... possibly inadequate USB bandwidth\n");
616 peasycap
->video_eof
= 1;
620 JOM(4, "attempting cleanup instead of submitting\n");
621 list_for_each(plist_head
, (peasycap
->purb_video_head
)) {
622 pdata_urb
= list_entry(plist_head
,
623 struct data_urb
, list_head
);
625 purb
= pdata_urb
->purb
;
630 peasycap
->video_isoc_streaming
= 0;
632 peasycap
->video_isoc_streaming
= 1;
633 JOM(4, "submitted %i video urbs\n", m
);
636 JOM(4, "already streaming video urbs\n");
640 /*****************************************************************************/
641 int kill_video_urbs(struct easycap
*peasycap
)
644 struct list_head
*plist_head
;
645 struct data_urb
*pdata_urb
;
648 SAY("ERROR: peasycap is NULL\n");
651 if (!peasycap
->video_isoc_streaming
) {
652 JOM(8, "%i=video_isoc_streaming, no video urbs killed\n",
653 peasycap
->video_isoc_streaming
);
656 if (!peasycap
->purb_video_head
) {
657 SAM("ERROR: peasycap->purb_video_head is NULL\n");
661 peasycap
->video_isoc_streaming
= 0;
662 JOM(4, "killing video urbs\n");
664 list_for_each(plist_head
, (peasycap
->purb_video_head
)) {
665 pdata_urb
= list_entry(plist_head
, struct data_urb
, list_head
);
666 if (pdata_urb
&& pdata_urb
->purb
) {
667 usb_kill_urb(pdata_urb
->purb
);
671 JOM(4, "%i video urbs killed\n", m
);
675 /****************************************************************************/
676 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
677 /*--------------------------------------------------------------------------*/
678 static int easycap_open_noinode(struct file
*file
)
680 return easycap_open(NULL
, file
);
683 static int videodev_release(struct video_device
*pvideo_device
)
685 struct easycap
*peasycap
;
687 peasycap
= video_get_drvdata(pvideo_device
);
689 SAY("ERROR: peasycap is NULL\n");
690 SAY("ending unsuccessfully\n");
693 if (0 != kill_video_urbs(peasycap
)) {
694 SAM("ERROR: kill_video_urbs() failed\n");
697 JOM(4, "ending successfully\n");
700 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
701 /*****************************************************************************/
702 /*--------------------------------------------------------------------------*/
704 * THIS FUNCTION IS CALLED FROM WITHIN easycap_usb_disconnect() AND IS
705 * PROTECTED BY SEMAPHORES SET AND CLEARED BY easycap_usb_disconnect().
707 * BY THIS STAGE THE DEVICE HAS ALREADY BEEN PHYSICALLY UNPLUGGED, SO
708 * peasycap->pusb_device IS NO LONGER VALID.
710 /*---------------------------------------------------------------------------*/
711 static void easycap_delete(struct kref
*pkref
)
713 struct easycap
*peasycap
;
714 struct data_urb
*pdata_urb
;
715 struct list_head
*plist_head
, *plist_next
;
717 int allocation_video_urb
;
718 int allocation_video_page
;
719 int allocation_video_struct
;
720 int allocation_audio_urb
;
721 int allocation_audio_page
;
722 int allocation_audio_struct
;
723 int registered_video
, registered_audio
;
725 peasycap
= container_of(pkref
, struct easycap
, kref
);
727 SAM("ERROR: peasycap is NULL: cannot perform deletions\n");
730 kd
= isdongle(peasycap
);
731 /*---------------------------------------------------------------------------*/
735 /*---------------------------------------------------------------------------*/
736 if (peasycap
->purb_video_head
) {
737 JOM(4, "freeing video urbs\n");
739 list_for_each(plist_head
, (peasycap
->purb_video_head
)) {
740 pdata_urb
= list_entry(plist_head
,
741 struct data_urb
, list_head
);
743 JOM(4, "ERROR: pdata_urb is NULL\n");
745 if (pdata_urb
->purb
) {
746 usb_free_urb(pdata_urb
->purb
);
747 pdata_urb
->purb
= NULL
;
748 peasycap
->allocation_video_urb
-= 1;
754 JOM(4, "%i video urbs freed\n", m
);
755 /*---------------------------------------------------------------------------*/
756 JOM(4, "freeing video data_urb structures.\n");
758 list_for_each_safe(plist_head
, plist_next
,
759 peasycap
->purb_video_head
) {
760 pdata_urb
= list_entry(plist_head
,
761 struct data_urb
, list_head
);
763 peasycap
->allocation_video_struct
-=
764 sizeof(struct data_urb
);
770 JOM(4, "%i video data_urb structures freed\n", m
);
771 JOM(4, "setting peasycap->purb_video_head=NULL\n");
772 peasycap
->purb_video_head
= NULL
;
774 /*---------------------------------------------------------------------------*/
775 JOM(4, "freeing video isoc buffers.\n");
777 for (k
= 0; k
< VIDEO_ISOC_BUFFER_MANY
; k
++) {
778 if (peasycap
->video_isoc_buffer
[k
].pgo
) {
779 free_pages((unsigned long)
780 peasycap
->video_isoc_buffer
[k
].pgo
,
782 peasycap
->video_isoc_buffer
[k
].pgo
= NULL
;
783 peasycap
->allocation_video_page
-=
784 BIT(VIDEO_ISOC_ORDER
);
788 JOM(4, "isoc video buffers freed: %i pages\n",
789 m
* (0x01 << VIDEO_ISOC_ORDER
));
790 /*---------------------------------------------------------------------------*/
791 JOM(4, "freeing video field buffers.\n");
793 for (k
= 0; k
< FIELD_BUFFER_MANY
; k
++) {
794 for (m
= 0; m
< FIELD_BUFFER_SIZE
/PAGE_SIZE
; m
++) {
795 if (peasycap
->field_buffer
[k
][m
].pgo
) {
796 free_page((unsigned long)
797 peasycap
->field_buffer
[k
][m
].pgo
);
798 peasycap
->field_buffer
[k
][m
].pgo
= NULL
;
799 peasycap
->allocation_video_page
-= 1;
804 JOM(4, "video field buffers freed: %i pages\n", gone
);
805 /*---------------------------------------------------------------------------*/
806 JOM(4, "freeing video frame buffers.\n");
808 for (k
= 0; k
< FRAME_BUFFER_MANY
; k
++) {
809 for (m
= 0; m
< FRAME_BUFFER_SIZE
/PAGE_SIZE
; m
++) {
810 if (peasycap
->frame_buffer
[k
][m
].pgo
) {
811 free_page((unsigned long)
812 peasycap
->frame_buffer
[k
][m
].pgo
);
813 peasycap
->frame_buffer
[k
][m
].pgo
= NULL
;
814 peasycap
->allocation_video_page
-= 1;
819 JOM(4, "video frame buffers freed: %i pages\n", gone
);
820 /*---------------------------------------------------------------------------*/
824 /*---------------------------------------------------------------------------*/
825 if (peasycap
->purb_audio_head
) {
826 JOM(4, "freeing audio urbs\n");
828 list_for_each(plist_head
, (peasycap
->purb_audio_head
)) {
829 pdata_urb
= list_entry(plist_head
,
830 struct data_urb
, list_head
);
832 JOM(4, "ERROR: pdata_urb is NULL\n");
834 if (pdata_urb
->purb
) {
835 usb_free_urb(pdata_urb
->purb
);
836 pdata_urb
->purb
= NULL
;
837 peasycap
->allocation_audio_urb
-= 1;
842 JOM(4, "%i audio urbs freed\n", m
);
843 /*---------------------------------------------------------------------------*/
844 JOM(4, "freeing audio data_urb structures.\n");
846 list_for_each_safe(plist_head
, plist_next
,
847 peasycap
->purb_audio_head
) {
848 pdata_urb
= list_entry(plist_head
,
849 struct data_urb
, list_head
);
851 peasycap
->allocation_audio_struct
-=
852 sizeof(struct data_urb
);
858 JOM(4, "%i audio data_urb structures freed\n", m
);
859 JOM(4, "setting peasycap->purb_audio_head=NULL\n");
860 peasycap
->purb_audio_head
= NULL
;
862 /*---------------------------------------------------------------------------*/
863 JOM(4, "freeing audio isoc buffers.\n");
865 for (k
= 0; k
< AUDIO_ISOC_BUFFER_MANY
; k
++) {
866 if (peasycap
->audio_isoc_buffer
[k
].pgo
) {
867 free_pages((unsigned long)
868 (peasycap
->audio_isoc_buffer
[k
].pgo
),
870 peasycap
->audio_isoc_buffer
[k
].pgo
= NULL
;
871 peasycap
->allocation_audio_page
-=
872 BIT(AUDIO_ISOC_ORDER
);
876 JOM(4, "easyoss_delete(): isoc audio buffers freed: %i pages\n",
877 m
* (0x01 << AUDIO_ISOC_ORDER
));
878 /*---------------------------------------------------------------------------*/
879 JOM(4, "freeing easycap structure.\n");
880 allocation_video_urb
= peasycap
->allocation_video_urb
;
881 allocation_video_page
= peasycap
->allocation_video_page
;
882 allocation_video_struct
= peasycap
->allocation_video_struct
;
883 registered_video
= peasycap
->registered_video
;
884 allocation_audio_urb
= peasycap
->allocation_audio_urb
;
885 allocation_audio_page
= peasycap
->allocation_audio_page
;
886 allocation_audio_struct
= peasycap
->allocation_audio_struct
;
887 registered_audio
= peasycap
->registered_audio
;
889 if (0 <= kd
&& DONGLE_MANY
> kd
) {
890 if (mutex_lock_interruptible(&mutex_dongle
)) {
891 SAY("ERROR: cannot down mutex_dongle\n");
893 JOM(4, "locked mutex_dongle\n");
894 easycapdc60_dongle
[kd
].peasycap
= NULL
;
895 mutex_unlock(&mutex_dongle
);
896 JOM(4, "unlocked mutex_dongle\n");
897 JOT(4, " null-->dongle[%i].peasycap\n", kd
);
898 allocation_video_struct
-= sizeof(struct easycap
);
901 SAY("ERROR: cannot purge dongle[].peasycap");
906 /*---------------------------------------------------------------------------*/
907 SAY("%8i=video urbs after all deletions\n", allocation_video_urb
);
908 SAY("%8i=video pages after all deletions\n", allocation_video_page
);
909 SAY("%8i=video structs after all deletions\n", allocation_video_struct
);
910 SAY("%8i=video devices after all deletions\n", registered_video
);
911 SAY("%8i=audio urbs after all deletions\n", allocation_audio_urb
);
912 SAY("%8i=audio pages after all deletions\n", allocation_audio_page
);
913 SAY("%8i=audio structs after all deletions\n", allocation_audio_struct
);
914 SAY("%8i=audio devices after all deletions\n", registered_audio
);
919 /*****************************************************************************/
920 static unsigned int easycap_poll(struct file
*file
, poll_table
*wait
)
922 struct easycap
*peasycap
;
927 if (NULL
== ((poll_table
*)wait
))
928 JOT(8, "WARNING: poll table pointer is NULL ... continuing\n");
930 SAY("ERROR: file pointer is NULL\n");
933 peasycap
= file
->private_data
;
935 SAY("ERROR: peasycap is NULL\n");
938 if (!peasycap
->pusb_device
) {
939 SAY("ERROR: peasycap->pusb_device is NULL\n");
942 /*---------------------------------------------------------------------------*/
943 kd
= isdongle(peasycap
);
944 if (0 <= kd
&& DONGLE_MANY
> kd
) {
945 if (mutex_lock_interruptible(&easycapdc60_dongle
[kd
].mutex_video
)) {
946 SAY("ERROR: cannot down dongle[%i].mutex_video\n", kd
);
949 JOM(4, "locked dongle[%i].mutex_video\n", kd
);
951 * MEANWHILE, easycap_usb_disconnect() MAY HAVE FREED POINTER
952 * peasycap, IN WHICH CASE A REPEAT CALL TO isdongle() WILL FAIL.
953 * IF NECESSARY, BAIL OUT.
955 if (kd
!= isdongle(peasycap
)) {
956 mutex_unlock(&easycapdc60_dongle
[kd
].mutex_video
);
960 SAY("ERROR: file is NULL\n");
961 mutex_unlock(&easycapdc60_dongle
[kd
].mutex_video
);
964 peasycap
= file
->private_data
;
966 SAY("ERROR: peasycap is NULL\n");
967 mutex_unlock(&easycapdc60_dongle
[kd
].mutex_video
);
970 if (!peasycap
->pusb_device
) {
971 SAM("ERROR: peasycap->pusb_device is NULL\n");
972 mutex_unlock(&easycapdc60_dongle
[kd
].mutex_video
);
977 * IF easycap_usb_disconnect() HAS ALREADY FREED POINTER peasycap
978 * BEFORE THE ATTEMPT TO ACQUIRE THE SEMAPHORE, isdongle() WILL
979 * HAVE FAILED. BAIL OUT.
982 /*---------------------------------------------------------------------------*/
983 rc
= easycap_dqbuf(peasycap
, 0);
984 peasycap
->polled
= 1;
985 mutex_unlock(&easycapdc60_dongle
[kd
].mutex_video
);
987 return POLLIN
| POLLRDNORM
;
991 /*****************************************************************************/
992 /*---------------------------------------------------------------------------*/
994 * IF mode IS NONZERO THIS ROUTINE RETURNS -EAGAIN RATHER THAN BLOCKING.
996 /*---------------------------------------------------------------------------*/
997 int easycap_dqbuf(struct easycap
*peasycap
, int mode
)
999 int input
, ifield
, miss
, rc
;
1003 SAY("ERROR: peasycap is NULL\n");
1006 if (!peasycap
->pusb_device
) {
1007 SAY("ERROR: peasycap->pusb_device is NULL\n");
1011 JOM(8, "%i=ifield\n", ifield
);
1012 /*---------------------------------------------------------------------------*/
1014 * CHECK FOR LOST INPUT SIGNAL.
1016 * FOR THE FOUR-CVBS EasyCAP, THIS DOES NOT WORK AS EXPECTED.
1017 * IF INPUT 0 IS PRESENT AND SYNC ACQUIRED, UNPLUGGING INPUT 4 DOES NOT
1018 * RESULT IN SETTING BIT 0x40 ON REGISTER 0x1F, PRESUMABLY BECAUSE THERE
1019 * IS FLYWHEELING ON INPUT 0. THE UPSHOT IS:
1021 * INPUT 0 PLUGGED, INPUT 4 PLUGGED => SCREEN 0 OK, SCREEN 4 OK
1022 * INPUT 0 PLUGGED, INPUT 4 UNPLUGGED => SCREEN 0 OK, SCREEN 4 BLACK
1023 * INPUT 0 UNPLUGGED, INPUT 4 PLUGGED => SCREEN 0 BARS, SCREEN 4 OK
1024 * INPUT 0 UNPLUGGED, INPUT 4 UNPLUGGED => SCREEN 0 BARS, SCREEN 4 BARS
1026 /*---------------------------------------------------------------------------*/
1027 input
= peasycap
->input
;
1028 if (0 <= input
&& INPUT_MANY
> input
) {
1029 rc
= read_saa(peasycap
->pusb_device
, 0x1F);
1032 peasycap
->lost
[input
] += 1;
1034 peasycap
->lost
[input
] -= 2;
1036 if (0 > peasycap
->lost
[input
])
1037 peasycap
->lost
[input
] = 0;
1038 else if ((2 * VIDEO_LOST_TOLERATE
) < peasycap
->lost
[input
])
1039 peasycap
->lost
[input
] = (2 * VIDEO_LOST_TOLERATE
);
1042 /*---------------------------------------------------------------------------*/
1044 * WAIT FOR FIELD ifield (0 => TOP, 1 => BOTTOM)
1046 /*---------------------------------------------------------------------------*/
1048 while ((peasycap
->field_read
== peasycap
->field_fill
) ||
1049 (0 != (0xFF00 & peasycap
->field_buffer
1050 [peasycap
->field_read
][0].kount
)) ||
1051 (ifield
!= (0x00FF & peasycap
->field_buffer
1052 [peasycap
->field_read
][0].kount
))) {
1056 JOM(8, "first wait on wq_video, %i=field_read %i=field_fill\n",
1057 peasycap
->field_read
, peasycap
->field_fill
);
1059 if (0 != (wait_event_interruptible(peasycap
->wq_video
,
1060 (peasycap
->video_idle
|| peasycap
->video_eof
||
1061 ((peasycap
->field_read
!= peasycap
->field_fill
) &&
1062 (0 == (0xFF00 & peasycap
->field_buffer
[peasycap
->field_read
][0].kount
)) &&
1063 (ifield
== (0x00FF & peasycap
->field_buffer
[peasycap
->field_read
][0].kount
))))))) {
1064 SAM("aborted by signal\n");
1067 if (peasycap
->video_idle
) {
1068 JOM(8, "%i=peasycap->video_idle returning -EAGAIN\n",
1069 peasycap
->video_idle
);
1072 if (peasycap
->video_eof
) {
1073 JOM(8, "%i=peasycap->video_eof\n", peasycap
->video_eof
);
1074 #if defined(PERSEVERE)
1075 if (1 == peasycap
->status
) {
1076 JOM(8, "persevering ...\n");
1077 peasycap
->video_eof
= 0;
1078 peasycap
->audio_eof
= 0;
1079 if (0 != reset(peasycap
)) {
1080 JOM(8, " ... failed returning -EIO\n");
1081 peasycap
->video_eof
= 1;
1082 peasycap
->audio_eof
= 1;
1083 kill_video_urbs(peasycap
);
1086 peasycap
->status
= 0;
1087 JOM(8, " ... OK returning -EAGAIN\n");
1090 #endif /*PERSEVERE*/
1091 peasycap
->video_eof
= 1;
1092 peasycap
->audio_eof
= 1;
1093 kill_video_urbs(peasycap
);
1094 JOM(8, "returning -EIO\n");
1099 JOM(8, "first awakening on wq_video after %i waits\n", miss
);
1101 rc
= field2frame(peasycap
);
1103 SAM("ERROR: field2frame() rc = %i\n", rc
);
1104 /*---------------------------------------------------------------------------*/
1106 * WAIT FOR THE OTHER FIELD
1108 /*---------------------------------------------------------------------------*/
1114 while ((peasycap
->field_read
== peasycap
->field_fill
) ||
1115 (0 != (0xFF00 & peasycap
->field_buffer
[peasycap
->field_read
][0].kount
)) ||
1116 (ifield
!= (0x00FF & peasycap
->field_buffer
[peasycap
->field_read
][0].kount
))) {
1120 JOM(8, "second wait on wq_video %i=field_read %i=field_fill\n",
1121 peasycap
->field_read
, peasycap
->field_fill
);
1122 if (0 != (wait_event_interruptible(peasycap
->wq_video
,
1123 (peasycap
->video_idle
|| peasycap
->video_eof
||
1124 ((peasycap
->field_read
!= peasycap
->field_fill
) &&
1125 (0 == (0xFF00 & peasycap
->field_buffer
[peasycap
->field_read
][0].kount
)) &&
1126 (ifield
== (0x00FF & peasycap
->field_buffer
[peasycap
->field_read
][0].kount
))))))) {
1127 SAM("aborted by signal\n");
1130 if (peasycap
->video_idle
) {
1131 JOM(8, "%i=peasycap->video_idle returning -EAGAIN\n",
1132 peasycap
->video_idle
);
1135 if (peasycap
->video_eof
) {
1136 JOM(8, "%i=peasycap->video_eof\n", peasycap
->video_eof
);
1137 #if defined(PERSEVERE)
1138 if (1 == peasycap
->status
) {
1139 JOM(8, "persevering ...\n");
1140 peasycap
->video_eof
= 0;
1141 peasycap
->audio_eof
= 0;
1142 if (0 != reset(peasycap
)) {
1143 JOM(8, " ... failed returning -EIO\n");
1144 peasycap
->video_eof
= 1;
1145 peasycap
->audio_eof
= 1;
1146 kill_video_urbs(peasycap
);
1149 peasycap
->status
= 0;
1150 JOM(8, " ... OK ... returning -EAGAIN\n");
1153 #endif /*PERSEVERE*/
1154 peasycap
->video_eof
= 1;
1155 peasycap
->audio_eof
= 1;
1156 kill_video_urbs(peasycap
);
1157 JOM(8, "returning -EIO\n");
1162 JOM(8, "second awakening on wq_video after %i waits\n", miss
);
1164 rc
= field2frame(peasycap
);
1166 SAM("ERROR: field2frame() rc = %i\n", rc
);
1167 /*---------------------------------------------------------------------------*/
1171 /*---------------------------------------------------------------------------*/
1172 if (peasycap
->skip
) {
1173 peasycap
->skipped
++;
1174 if (peasycap
->skip
!= peasycap
->skipped
)
1175 return peasycap
->skip
- peasycap
->skipped
;
1177 peasycap
->skipped
= 0;
1179 /*---------------------------------------------------------------------------*/
1180 peasycap
->frame_read
= peasycap
->frame_fill
;
1181 peasycap
->queued
[peasycap
->frame_read
] = 0;
1182 peasycap
->done
[peasycap
->frame_read
] = V4L2_BUF_FLAG_DONE
;
1184 peasycap
->frame_fill
++;
1185 if (peasycap
->frame_buffer_many
<= peasycap
->frame_fill
)
1186 peasycap
->frame_fill
= 0;
1188 if (0x01 & easycap_standard
[peasycap
->standard_offset
].mask
)
1189 peasycap
->frame_buffer
[peasycap
->frame_read
][0].kount
=
1192 peasycap
->frame_buffer
[peasycap
->frame_read
][0].kount
=
1196 JOM(8, "setting: %i=peasycap->frame_read\n", peasycap
->frame_read
);
1197 JOM(8, "bumped to: %i=peasycap->frame_fill\n", peasycap
->frame_fill
);
1201 /*****************************************************************************/
1202 /*---------------------------------------------------------------------------*/
1204 * BY DEFINITION, odd IS true FOR THE FIELD OCCUPYING LINES 1,3,5,...,479
1205 * odd IS false FOR THE FIELD OCCUPYING LINES 0,2,4,...,478
1207 * WHEN BOOLEAN PARAMETER decimatepixel IS true, ONLY THE FIELD FOR WHICH
1208 * odd==false IS TRANSFERRED TO THE FRAME BUFFER.
1210 * THE BOOLEAN PARAMETER offerfields IS true ONLY WHEN THE USER PROGRAM
1211 * CHOOSES THE OPTION V4L2_FIELD_INTERLACED.
1213 /*---------------------------------------------------------------------------*/
1215 field2frame(struct easycap
*peasycap
)
1219 int kex
, kad
, mex
, mad
, rex
, rad
, rad2
;
1220 int c2
, c3
, w2
, w3
, cz
, wz
;
1221 int rc
, bytesperpixel
, multiplier
;
1222 int much
, more
, over
, rump
, caches
, input
;
1224 bool odd
, isuy
, decimatepixel
, offerfields
, badinput
;
1227 SAY("ERROR: peasycap is NULL\n");
1232 input
= 0x07 & peasycap
->field_buffer
[peasycap
->field_read
][0].input
;
1234 JOM(8, "===== parity %i, input 0x%02X, field buffer %i --> "
1235 "frame buffer %i\n",
1236 peasycap
->field_buffer
[peasycap
->field_read
][0].kount
,
1237 peasycap
->field_buffer
[peasycap
->field_read
][0].input
,
1238 peasycap
->field_read
, peasycap
->frame_fill
);
1239 JOM(8, "===== %i=bytesperpixel\n", peasycap
->bytesperpixel
);
1240 if (peasycap
->offerfields
)
1241 JOM(8, "===== offerfields\n");
1243 /*---------------------------------------------------------------------------*/
1245 * REJECT OR CLEAN BAD FIELDS
1247 /*---------------------------------------------------------------------------*/
1248 if (peasycap
->field_read
== peasycap
->field_fill
) {
1249 SAM("ERROR: on entry, still filling field buffer %i\n",
1250 peasycap
->field_read
);
1253 #ifdef EASYCAP_TESTCARD
1254 easycap_testcard(peasycap
, peasycap
->field_read
);
1256 if (0 <= input
&& INPUT_MANY
> input
) {
1257 if (easycap_bars
&& VIDEO_LOST_TOLERATE
<= peasycap
->lost
[input
])
1258 easycap_testcard(peasycap
, peasycap
->field_read
);
1260 #endif /*EASYCAP_TESTCARD*/
1261 /*---------------------------------------------------------------------------*/
1263 offerfields
= peasycap
->offerfields
;
1264 bytesperpixel
= peasycap
->bytesperpixel
;
1265 decimatepixel
= peasycap
->decimatepixel
;
1267 if ((2 != bytesperpixel
) &&
1268 (3 != bytesperpixel
) &&
1269 (4 != bytesperpixel
)) {
1270 SAM("MISTAKE: %i=bytesperpixel\n", bytesperpixel
);
1278 w2
= 2 * multiplier
* (peasycap
->width
);
1279 w3
= bytesperpixel
* multiplier
* (peasycap
->width
);
1280 wz
= multiplier
* (peasycap
->height
) *
1281 multiplier
* (peasycap
->width
);
1283 kex
= peasycap
->field_read
; mex
= 0;
1284 kad
= peasycap
->frame_fill
; mad
= 0;
1286 pex
= peasycap
->field_buffer
[kex
][0].pgo
; rex
= PAGE_SIZE
;
1287 pad
= peasycap
->frame_buffer
[kad
][0].pgo
; rad
= PAGE_SIZE
;
1288 odd
= !!(peasycap
->field_buffer
[kex
][0].kount
);
1290 if (odd
&& (!decimatepixel
)) {
1291 JOM(8, "initial skipping %4i bytes p.%4i\n",
1292 w3
/multiplier
, mad
);
1293 pad
+= (w3
/ multiplier
); rad
-= (w3
/ multiplier
);
1296 mask
= 0; rump
= 0; caches
= 0;
1301 * PROCESS ONE LINE OF FRAME AT FULL RESOLUTION:
1302 * READ w2 BYTES FROM FIELD BUFFER,
1303 * WRITE w3 BYTES TO FRAME BUFFER
1305 if (!decimatepixel
) {
1308 much
= over
; more
= 0;
1309 margin
= 0; mask
= 0x00;
1315 SAM("MISTAKE: much is odd\n");
1319 more
= (bytesperpixel
*
1321 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1322 if (1 < bytesperpixel
) {
1323 if (rad
* 2 < much
* bytesperpixel
) {
1325 * INJUDICIOUS ALTERATION OF
1326 * THIS STATEMENT BLOCK WILL
1327 * CAUSE BREAKAGE. BEWARE.
1329 rad2
= rad
+ bytesperpixel
- 1;
1330 much
= ((((2 * rad2
)/bytesperpixel
)/2) * 2);
1331 rump
= ((bytesperpixel
* much
) / 2) - rad
;
1338 if ((mex
+ 1) < FIELD_BUFFER_SIZE
/ PAGE_SIZE
)
1339 margin
= *((u8
*)(peasycap
->field_buffer
[kex
][mex
+ 1].pgo
));
1344 SAM("MISTAKE: %i=bytesperpixel\n",
1351 JOM(8, "ERROR: 0x%02X=->field_buffer"
1353 "0x%02X=(0x08|->input)\n",
1354 peasycap
->field_buffer
1355 [kex
][mex
].input
, kex
, mex
,
1356 (0x08|peasycap
->input
));
1358 rc
= redaub(peasycap
, pad
, pex
, much
, more
,
1359 mask
, margin
, isuy
);
1361 SAM("ERROR: redaub() failed\n");
1367 over
-= much
; cz
+= much
;
1368 pex
+= much
; rex
-= much
;
1371 pex
= peasycap
->field_buffer
[kex
][mex
].pgo
;
1373 if (peasycap
->field_buffer
[kex
][mex
].input
!= (0x08|peasycap
->input
))
1380 pad
= peasycap
->frame_buffer
[kad
][mad
].pgo
;
1388 /*---------------------------------------------------------------------------*/
1390 * SKIP w3 BYTES IN TARGET FRAME BUFFER,
1391 * UNLESS IT IS THE LAST LINE OF AN ODD FRAME
1393 /*---------------------------------------------------------------------------*/
1394 if (!odd
|| (cz
!= wz
)) {
1399 pad
= peasycap
->frame_buffer
1411 /*---------------------------------------------------------------------------*/
1413 * PROCESS ONE LINE OF FRAME AT REDUCED RESOLUTION:
1414 * ONLY IF false==odd,
1415 * READ w2 BYTES FROM FIELD BUFFER,
1416 * WRITE w3 / 2 BYTES TO FRAME BUFFER
1418 /*---------------------------------------------------------------------------*/
1422 much
= over
; more
= 0; margin
= 0; mask
= 0x00;
1428 SAM("MISTAKE: much is odd\n");
1432 more
= (bytesperpixel
* much
) / 4;
1433 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1434 if (1 < bytesperpixel
) {
1435 if (rad
* 4 < much
* bytesperpixel
) {
1437 * INJUDICIOUS ALTERATION OF
1438 * THIS STATEMENT BLOCK
1439 * WILL CAUSE BREAKAGE.
1442 rad2
= rad
+ bytesperpixel
- 1;
1443 much
= ((((2 * rad2
) / bytesperpixel
) / 2) * 4);
1444 rump
= ((bytesperpixel
* much
) / 4) - rad
;
1451 if ((mex
+ 1) < FIELD_BUFFER_SIZE
/ PAGE_SIZE
)
1452 margin
= *((u8
*)(peasycap
->field_buffer
[kex
][mex
+ 1].pgo
));
1456 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1458 SAM("MISTAKE: %i=bytesperpixel\n",
1462 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1467 JOM(8, "ERROR: 0x%02X=->field_buffer"
1469 "0x%02X=(0x08|->input)\n",
1470 peasycap
->field_buffer
1471 [kex
][mex
].input
, kex
, mex
,
1472 (0x08|peasycap
->input
));
1474 rc
= redaub(peasycap
, pad
, pex
, much
, more
,
1475 mask
, margin
, isuy
);
1477 SAM("ERROR: redaub() failed\n");
1480 over
-= much
; cz
+= much
;
1481 pex
+= much
; rex
-= much
;
1484 pex
= peasycap
->field_buffer
[kex
][mex
].pgo
;
1486 if (peasycap
->field_buffer
[kex
][mex
].input
!=
1487 (0x08|peasycap
->input
))
1494 pad
= peasycap
->frame_buffer
[kad
][mad
].pgo
;
1502 /*---------------------------------------------------------------------------*/
1505 * READ w2 BYTES FROM FIELD BUFFER AND DISCARD THEM
1507 /*---------------------------------------------------------------------------*/
1513 pex
= peasycap
->field_buffer
[kex
][mex
].pgo
;
1515 if (peasycap
->field_buffer
[kex
][mex
].input
!=
1516 (0x08|peasycap
->input
)) {
1517 JOM(8, "ERROR: 0x%02X=->field_buffer"
1519 "0x%02X=(0x08|->input)\n",
1520 peasycap
->field_buffer
1521 [kex
][mex
].input
, kex
, mex
,
1522 (0x08|peasycap
->input
));
1536 /*---------------------------------------------------------------------------*/
1540 /*---------------------------------------------------------------------------*/
1541 c2
= (mex
+ 1)*PAGE_SIZE
- rex
;
1543 SAM("ERROR: discrepancy %i in bytes read\n", c2
- cz
);
1544 c3
= (mad
+ 1)*PAGE_SIZE
- rad
;
1546 if (!decimatepixel
) {
1547 if (bytesperpixel
* cz
!= c3
)
1548 SAM("ERROR: discrepancy %i in bytes written\n",
1549 c3
- (bytesperpixel
* cz
));
1554 SAM("ERROR: discrepancy %i in bytes written\n",
1555 (2*c3
)-(bytesperpixel
* cz
));
1558 SAM("ERROR: discrepancy %i "
1559 "in bytes written\n", c3
);
1563 SAM("WORRY: undischarged cache at end of line in frame buffer\n");
1565 JOM(8, "===== field2frame(): %i bytes --> %i bytes (incl skip)\n", c2
, c3
);
1566 JOM(8, "===== field2frame(): %i=mad %i=rad\n", mad
, rad
);
1569 JOM(8, "+++++ field2frame(): frame buffer %i is full\n", kad
);
1571 if (peasycap
->field_read
== peasycap
->field_fill
)
1572 SAM("WARNING: on exit, filling field buffer %i\n",
1573 peasycap
->field_read
);
1576 JOM(8, "%i=caches\n", caches
);
1579 /*---------------------------------------------------------------------------*/
1581 * DECIMATION AND COLOURSPACE CONVERSION.
1583 * THIS ROUTINE REQUIRES THAT ALL THE DATA TO BE READ RESIDES ON ONE PAGE
1584 * AND THAT ALL THE DATA TO BE WRITTEN RESIDES ON ONE (DIFFERENT) PAGE.
1585 * THE CALLING ROUTINE MUST ENSURE THAT THIS REQUIREMENT IS MET, AND MUST
1586 * ALSO ENSURE THAT much IS EVEN.
1588 * much BYTES ARE READ, AT LEAST (bytesperpixel * much)/2 BYTES ARE WRITTEN
1589 * IF THERE IS NO DECIMATION, HALF THIS AMOUNT IF THERE IS DECIMATION.
1591 * mask IS ZERO WHEN NO SPECIAL BEHAVIOUR REQUIRED. OTHERWISE IT IS SET THUS:
1592 * 0x03 & mask = number of bytes to be written to cache instead of to
1594 * 0x04 & mask => use argument margin to set the chrominance for last pixel
1595 * 0x08 & mask => do not set the chrominance for last pixel
1597 * YUV to RGB CONVERSION IS (OR SHOULD BE) ITU-R BT 601.
1599 * THERE IS A LOT OF CODE REPETITION IN THIS ROUTINE IN ORDER TO AVOID
1600 * INEFFICIENT SWITCHING INSIDE INNER LOOPS. REARRANGING THE LOGIC TO
1601 * REDUCE CODE LENGTH WILL GENERALLY IMPAIR RUNTIME PERFORMANCE. BEWARE.
1603 /*---------------------------------------------------------------------------*/
1605 redaub(struct easycap
*peasycap
, void *pad
, void *pex
, int much
, int more
,
1606 u8 mask
, u8 margin
, bool isuy
)
1608 static s32 ay
[256], bu
[256], rv
[256], gu
[256], gv
[256];
1610 u8 r
, g
, b
, y
, u
, v
, c
, *p2
, *p3
, *pz
, *pr
;
1612 bool byteswaporder
, decimatepixel
, last
;
1617 SAM("MISTAKE: much is odd\n");
1620 bytesperpixel
= peasycap
->bytesperpixel
;
1621 byteswaporder
= peasycap
->byteswaporder
;
1622 decimatepixel
= peasycap
->decimatepixel
;
1624 /*---------------------------------------------------------------------------*/
1626 for (j
= 0; j
< 112; j
++) {
1627 tmp
= (0xFF00 & (453 * j
)) >> 8;
1628 bu
[j
+ 128] = tmp
; bu
[127 - j
] = -tmp
;
1629 tmp
= (0xFF00 & (359 * j
)) >> 8;
1630 rv
[j
+ 128] = tmp
; rv
[127 - j
] = -tmp
;
1631 tmp
= (0xFF00 & (88 * j
)) >> 8;
1632 gu
[j
+ 128] = tmp
; gu
[127 - j
] = -tmp
;
1633 tmp
= (0xFF00 & (183 * j
)) >> 8;
1634 gv
[j
+ 128] = tmp
; gv
[127 - j
] = -tmp
;
1636 for (j
= 0; j
< 16; j
++) {
1637 bu
[j
] = bu
[16]; rv
[j
] = rv
[16];
1638 gu
[j
] = gu
[16]; gv
[j
] = gv
[16];
1640 for (j
= 240; j
< 256; j
++) {
1641 bu
[j
] = bu
[239]; rv
[j
] = rv
[239];
1642 gu
[j
] = gu
[239]; gv
[j
] = gv
[239];
1644 for (j
= 16; j
< 236; j
++)
1646 for (j
= 0; j
< 16; j
++)
1648 for (j
= 236; j
< 256; j
++)
1650 JOM(8, "lookup tables are prepared\n");
1652 pcache
= peasycap
->pcache
;
1654 pcache
= &peasycap
->cache
[0];
1655 /*---------------------------------------------------------------------------*/
1657 * TRANSFER CONTENTS OF CACHE TO THE FRAME BUFFER
1659 /*---------------------------------------------------------------------------*/
1661 SAM("MISTAKE: pcache is NULL\n");
1665 if (pcache
!= &peasycap
->cache
[0])
1666 JOM(16, "cache has %i bytes\n", (int)(pcache
- &peasycap
->cache
[0]));
1667 p2
= &peasycap
->cache
[0];
1668 p3
= (u8
*)pad
- (int)(pcache
- &peasycap
->cache
[0]);
1669 while (p2
< pcache
) {
1672 pcache
= &peasycap
->cache
[0];
1674 SAM("MISTAKE: pointer misalignment\n");
1677 /*---------------------------------------------------------------------------*/
1678 rump
= (int)(0x03 & mask
);
1680 p2
= (u8
*)pex
; pz
= p2
+ much
; pr
= p3
+ more
; last
= false;
1689 JOM(16, "%4i=much %4i=more %i=rump\n", much
, more
, rump
);
1691 /*---------------------------------------------------------------------------*/
1692 switch (bytesperpixel
) {
1694 if (!decimatepixel
) {
1695 memcpy(pad
, pex
, (size_t)much
);
1696 if (!byteswaporder
) {
1701 p3
= (u8
*)pad
; pz
= p3
+ much
;
1711 if (!byteswaporder
) {
1712 /* UYVY DECIMATED */
1713 p2
= (u8
*)pex
; p3
= (u8
*)pad
; pz
= p2
+ much
;
1716 *(p3
+ 1) = *(p2
+ 1);
1717 *(p3
+ 2) = *(p2
+ 2);
1718 *(p3
+ 3) = *(p2
+ 3);
1723 /* YUYV DECIMATED */
1724 p2
= (u8
*)pex
; p3
= (u8
*)pad
; pz
= p2
+ much
;
1728 *(p3
+ 2) = *(p2
+ 3);
1729 *(p3
+ 3) = *(p2
+ 2);
1739 if (!decimatepixel
) {
1740 if (!byteswaporder
) {
1743 if (pr
<= (p3
+ bytesperpixel
))
1748 if (last
&& (0x0C & mask
)) {
1764 tmp
= ay
[(int)y
] + rv
[(int)v
];
1765 r
= (255 < tmp
) ? 255 : ((0 > tmp
) ?
1767 tmp
= ay
[(int)y
] - gu
[(int)u
] - gv
[(int)v
];
1768 g
= (255 < tmp
) ? 255 : ((0 > tmp
) ?
1770 tmp
= ay
[(int)y
] + bu
[(int)u
];
1771 b
= (255 < tmp
) ? 255 : ((0 > tmp
) ?
1775 pcache
= &peasycap
->cache
[0];
1776 switch (bytesperpixel
- rump
) {
1790 SAM("MISTAKE: %i=rump\n",
1791 bytesperpixel
- rump
);
1805 p3
+= bytesperpixel
;
1811 if (pr
<= (p3
+ bytesperpixel
))
1816 if (last
&& (0x0C & mask
)) {
1833 tmp
= ay
[(int)y
] + rv
[(int)v
];
1834 r
= (255 < tmp
) ? 255 : ((0 > tmp
) ?
1836 tmp
= ay
[(int)y
] - gu
[(int)u
] - gv
[(int)v
];
1837 g
= (255 < tmp
) ? 255 : ((0 > tmp
) ?
1839 tmp
= ay
[(int)y
] + bu
[(int)u
];
1840 b
= (255 < tmp
) ? 255 : ((0 > tmp
) ?
1844 pcache
= &peasycap
->cache
[0];
1845 switch (bytesperpixel
- rump
) {
1859 SAM("MISTAKE: %i=rump\n",
1860 bytesperpixel
- rump
);
1874 p3
+= bytesperpixel
;
1879 if (!byteswaporder
) {
1882 if (pr
<= (p3
+ bytesperpixel
))
1887 if (last
&& (0x0C & mask
)) {
1904 tmp
= ay
[(int)y
] + rv
[(int)v
];
1905 r
= (255 < tmp
) ? 255 : ((0 > tmp
) ?
1907 tmp
= ay
[(int)y
] - gu
[(int)u
] -
1909 g
= (255 < tmp
) ? 255 : ((0 > tmp
) ?
1911 tmp
= ay
[(int)y
] + bu
[(int)u
];
1912 b
= (255 < tmp
) ? 255 : ((0 > tmp
) ?
1916 pcache
= &peasycap
->cache
[0];
1917 switch (bytesperpixel
- rump
) {
1933 bytesperpixel
- rump
);
1943 p3
+= bytesperpixel
;
1953 if (pr
<= (p3
+ bytesperpixel
))
1958 if (last
&& (0x0C & mask
)) {
1976 tmp
= ay
[(int)y
] + rv
[(int)v
];
1977 r
= (255 < tmp
) ? 255 : ((0 > tmp
) ?
1979 tmp
= ay
[(int)y
] - gu
[(int)u
] -
1981 g
= (255 < tmp
) ? 255 : ((0 > tmp
) ?
1983 tmp
= ay
[(int)y
] + bu
[(int)u
];
1984 b
= (255 < tmp
) ? 255 : ((0 > tmp
) ?
1988 pcache
= &peasycap
->cache
[0];
1989 switch (bytesperpixel
- rump
) {
2005 bytesperpixel
- rump
);
2015 p3
+= bytesperpixel
;
2028 if (!decimatepixel
) {
2029 if (!byteswaporder
) {
2032 if (pr
<= (p3
+ bytesperpixel
))
2037 if (last
&& (0x0C & mask
)) {
2053 tmp
= ay
[(int)y
] + rv
[(int)v
];
2054 r
= (255 < tmp
) ? 255 : ((0 > tmp
) ?
2056 tmp
= ay
[(int)y
] - gu
[(int)u
] - gv
[(int)v
];
2057 g
= (255 < tmp
) ? 255 : ((0 > tmp
) ?
2059 tmp
= ay
[(int)y
] + bu
[(int)u
];
2060 b
= (255 < tmp
) ? 255 : ((0 > tmp
) ?
2064 pcache
= &peasycap
->cache
[0];
2065 switch (bytesperpixel
- rump
) {
2088 SAM("MISTAKE: %i=rump\n",
2089 bytesperpixel
- rump
);
2104 p3
+= bytesperpixel
;
2112 if (pr
<= (p3
+ bytesperpixel
))
2117 if (last
&& (0x0C & mask
)) {
2133 tmp
= ay
[(int)y
] + rv
[(int)v
];
2134 r
= (255 < tmp
) ? 255 : ((0 > tmp
) ?
2136 tmp
= ay
[(int)y
] - gu
[(int)u
] - gv
[(int)v
];
2137 g
= (255 < tmp
) ? 255 : ((0 > tmp
) ?
2139 tmp
= ay
[(int)y
] + bu
[(int)u
];
2140 b
= (255 < tmp
) ? 255 : ((0 > tmp
) ?
2144 pcache
= &peasycap
->cache
[0];
2145 switch (bytesperpixel
- rump
) {
2168 SAM("MISTAKE: %i=rump\n",
2169 bytesperpixel
- rump
);
2183 p3
+= bytesperpixel
;
2188 if (!byteswaporder
) {
2193 if (pr
<= (p3
+ bytesperpixel
))
2198 if (last
&& (0x0C & mask
)) {
2216 tmp
= ay
[(int)y
] + rv
[(int)v
];
2217 r
= (255 < tmp
) ? 255 : ((0 > tmp
) ?
2219 tmp
= ay
[(int)y
] - gu
[(int)u
] -
2221 g
= (255 < tmp
) ? 255 : ((0 > tmp
) ?
2223 tmp
= ay
[(int)y
] + bu
[(int)u
];
2224 b
= (255 < tmp
) ? 255 : ((0 > tmp
) ?
2228 pcache
= &peasycap
->cache
[0];
2229 switch (bytesperpixel
- rump
) {
2266 p3
+= bytesperpixel
;
2277 if (pr
<= (p3
+ bytesperpixel
))
2282 if (last
&& (0x0C & mask
)) {
2299 tmp
= ay
[(int)y
] + rv
[(int)v
];
2300 r
= (255 < tmp
) ? 255 : ((0 > tmp
) ?
2302 tmp
= ay
[(int)y
] - gu
[(int)u
] -
2304 g
= (255 < tmp
) ? 255 : ((0 > tmp
) ?
2306 tmp
= ay
[(int)y
] + bu
[(int)u
];
2307 b
= (255 < tmp
) ? 255 : ((0 > tmp
) ?
2311 pcache
= &peasycap
->cache
[0];
2312 switch (bytesperpixel
- rump
) {
2337 bytesperpixel
- rump
);
2348 p3
+= bytesperpixel
;
2359 SAM("MISTAKE: %i=bytesperpixel\n", bytesperpixel
);
2365 /*****************************************************************************/
2367 * SEE CORBET ET AL. "LINUX DEVICE DRIVERS", 3rd EDITION, PAGES 430-434
2369 /*****************************************************************************/
2370 static void easycap_vma_open(struct vm_area_struct
*pvma
)
2372 struct easycap
*peasycap
;
2374 peasycap
= pvma
->vm_private_data
;
2376 SAY("ERROR: peasycap is NULL\n");
2379 peasycap
->vma_many
++;
2380 JOT(8, "%i=peasycap->vma_many\n", peasycap
->vma_many
);
2383 /*****************************************************************************/
2384 static void easycap_vma_close(struct vm_area_struct
*pvma
)
2386 struct easycap
*peasycap
;
2388 peasycap
= pvma
->vm_private_data
;
2390 SAY("ERROR: peasycap is NULL\n");
2393 peasycap
->vma_many
--;
2394 JOT(8, "%i=peasycap->vma_many\n", peasycap
->vma_many
);
2397 /*****************************************************************************/
2398 static int easycap_vma_fault(struct vm_area_struct
*pvma
, struct vm_fault
*pvmf
)
2403 struct easycap
*peasycap
;
2405 retcode
= VM_FAULT_NOPAGE
;
2408 SAY("pvma is NULL\n");
2412 SAY("pvmf is NULL\n");
2416 k
= (pvmf
->pgoff
) / (FRAME_BUFFER_SIZE
/PAGE_SIZE
);
2417 m
= (pvmf
->pgoff
) % (FRAME_BUFFER_SIZE
/PAGE_SIZE
);
2420 JOT(4, "%4i=k, %4i=m\n", k
, m
);
2422 JOT(16, "%4i=k, %4i=m\n", k
, m
);
2424 if ((0 > k
) || (FRAME_BUFFER_MANY
<= k
)) {
2425 SAY("ERROR: buffer index %i out of range\n", k
);
2428 if ((0 > m
) || (FRAME_BUFFER_SIZE
/PAGE_SIZE
<= m
)) {
2429 SAY("ERROR: page number %i out of range\n", m
);
2432 peasycap
= pvma
->vm_private_data
;
2434 SAY("ERROR: peasycap is NULL\n");
2437 /*---------------------------------------------------------------------------*/
2438 pbuf
= peasycap
->frame_buffer
[k
][m
].pgo
;
2440 SAM("ERROR: pbuf is NULL\n");
2443 page
= virt_to_page(pbuf
);
2445 SAM("ERROR: page is NULL\n");
2449 /*---------------------------------------------------------------------------*/
2451 SAM("ERROR: page is NULL after get_page(page)\n");
2454 retcode
= VM_FAULT_MINOR
;
2459 static const struct vm_operations_struct easycap_vm_ops
= {
2460 .open
= easycap_vma_open
,
2461 .close
= easycap_vma_close
,
2462 .fault
= easycap_vma_fault
,
2465 static int easycap_mmap(struct file
*file
, struct vm_area_struct
*pvma
)
2469 pvma
->vm_ops
= &easycap_vm_ops
;
2470 pvma
->vm_flags
|= VM_RESERVED
;
2472 pvma
->vm_private_data
= file
->private_data
;
2473 easycap_vma_open(pvma
);
2476 /*****************************************************************************/
2477 /*---------------------------------------------------------------------------*/
2479 * ON COMPLETION OF A VIDEO URB ITS DATA IS COPIED TO THE FIELD BUFFERS
2480 * PROVIDED peasycap->video_idle IS ZERO. REGARDLESS OF THIS BEING TRUE,
2481 * IT IS RESUBMITTED PROVIDED peasycap->video_isoc_streaming IS NOT ZERO.
2483 * THIS FUNCTION IS AN INTERRUPT SERVICE ROUTINE AND MUST NOT SLEEP.
2485 * INFORMATION ABOUT THE VALIDITY OF THE CONTENTS OF THE FIELD BUFFER ARE
2486 * STORED IN THE TWO-BYTE STATUS PARAMETER
2487 * peasycap->field_buffer[peasycap->field_fill][0].kount
2488 * NOTICE THAT THE INFORMATION IS STORED ONLY WITH PAGE 0 OF THE FIELD BUFFER.
2490 * THE LOWER BYTE CONTAINS THE FIELD PARITY BYTE FURNISHED BY THE SAA7113H
2493 * THE UPPER BYTE IS ZERO IF NO PROBLEMS, OTHERWISE:
2494 * 0 != (kount & 0x8000) => AT LEAST ONE URB COMPLETED WITH ERRORS
2495 * 0 != (kount & 0x4000) => BUFFER HAS TOO MUCH DATA
2496 * 0 != (kount & 0x2000) => BUFFER HAS NOT ENOUGH DATA
2497 * 0 != (kount & 0x1000) => BUFFER HAS DATA FROM DISPARATE INPUTS
2498 * 0 != (kount & 0x0400) => RESERVED
2499 * 0 != (kount & 0x0200) => FIELD BUFFER NOT YET CHECKED
2500 * 0 != (kount & 0x0100) => BUFFER HAS TWO EXTRA BYTES - WHY?
2502 /*---------------------------------------------------------------------------*/
2503 static void easycap_complete(struct urb
*purb
)
2505 struct easycap
*peasycap
;
2506 struct data_buffer
*pfield_buffer
;
2508 int i
, more
, much
, leap
, rc
, last
;
2509 int videofieldamount
;
2510 unsigned int override
, bad
;
2511 int framestatus
, framelength
, frameactual
, frameoffset
;
2515 SAY("ERROR: easycap_complete(): purb is NULL\n");
2518 peasycap
= purb
->context
;
2520 SAY("ERROR: easycap_complete(): peasycap is NULL\n");
2523 if (peasycap
->video_eof
)
2525 for (i
= 0; i
< VIDEO_ISOC_BUFFER_MANY
; i
++)
2526 if (purb
->transfer_buffer
== peasycap
->video_isoc_buffer
[i
].pgo
)
2528 JOM(16, "%2i=urb\n", i
);
2529 last
= peasycap
->video_isoc_sequence
;
2530 if ((((VIDEO_ISOC_BUFFER_MANY
- 1) == last
) && (0 != i
)) ||
2531 (((VIDEO_ISOC_BUFFER_MANY
- 1) != last
) && ((last
+ 1) != i
))) {
2532 JOM(16, "ERROR: out-of-order urbs %i,%i ... continuing\n",
2535 peasycap
->video_isoc_sequence
= i
;
2537 if (peasycap
->video_idle
) {
2538 JOM(16, "%i=video_idle %i=video_isoc_streaming\n",
2539 peasycap
->video_idle
, peasycap
->video_isoc_streaming
);
2540 if (peasycap
->video_isoc_streaming
) {
2541 rc
= usb_submit_urb(purb
, GFP_ATOMIC
);
2543 SAM("%s:%d ENOMEM\n", strerror(rc
), rc
);
2545 SAM("ERROR: while %i=video_idle, "
2547 "failed with rc:\n",
2548 peasycap
->video_idle
);
2554 /*---------------------------------------------------------------------------*/
2555 if (FIELD_BUFFER_MANY
<= peasycap
->field_fill
) {
2556 SAM("ERROR: bad peasycap->field_fill\n");
2560 if ((-ESHUTDOWN
== purb
->status
) || (-ENOENT
== purb
->status
)) {
2561 JOM(8, "urb status -ESHUTDOWN or -ENOENT\n");
2565 (peasycap
->field_buffer
[peasycap
->field_fill
][0].kount
) |= 0x8000 ;
2566 SAM("ERROR: bad urb status -%s: %d\n",
2567 strerror(purb
->status
), purb
->status
);
2568 /*---------------------------------------------------------------------------*/
2570 for (i
= 0; i
< purb
->number_of_packets
; i
++) {
2571 if (0 != purb
->iso_frame_desc
[i
].status
) {
2572 (peasycap
->field_buffer
2573 [peasycap
->field_fill
][0].kount
) |= 0x8000 ;
2574 /* FIXME: 1. missing '-' check boundaries */
2576 strerror(purb
->iso_frame_desc
[i
].status
));
2578 framestatus
= purb
->iso_frame_desc
[i
].status
;
2579 framelength
= purb
->iso_frame_desc
[i
].length
;
2580 frameactual
= purb
->iso_frame_desc
[i
].actual_length
;
2581 frameoffset
= purb
->iso_frame_desc
[i
].offset
;
2583 JOM(16, "frame[%2i]:"
2588 i
, framestatus
, frameactual
, framelength
, frameoffset
);
2589 if (!purb
->iso_frame_desc
[i
].status
) {
2590 more
= purb
->iso_frame_desc
[i
].actual_length
;
2591 pfield_buffer
= &peasycap
->field_buffer
2592 [peasycap
->field_fill
][peasycap
->field_page
];
2593 videofieldamount
= (peasycap
->field_page
*
2595 (int)(pfield_buffer
->pto
- pfield_buffer
->pgo
);
2597 peasycap
->video_mt
++;
2599 if (peasycap
->video_mt
) {
2600 JOM(8, "%4i empty video urb frames\n",
2601 peasycap
->video_mt
);
2602 peasycap
->video_mt
= 0;
2604 if (FIELD_BUFFER_MANY
<= peasycap
->field_fill
) {
2605 SAM("ERROR: bad peasycap->field_fill\n");
2608 if (FIELD_BUFFER_SIZE
/PAGE_SIZE
<=
2609 peasycap
->field_page
) {
2610 SAM("ERROR: bad peasycap->field_page\n");
2613 pfield_buffer
= &peasycap
->field_buffer
2614 [peasycap
->field_fill
][peasycap
->field_page
];
2615 pu
= (u8
*)(purb
->transfer_buffer
+
2616 purb
->iso_frame_desc
[i
].offset
);
2621 /*--------------------------------------------------------------------------*/
2623 * EIGHT-BYTE END-OF-VIDEOFIELD MARKER.
2624 * NOTE: A SUCCESSION OF URB FRAMES FOLLOWING THIS ARE EMPTY,
2625 * CORRESPONDING TO THE FIELD FLYBACK (VERTICAL BLANKING) PERIOD.
2627 * PROVIDED THE FIELD BUFFER CONTAINS GOOD DATA AS INDICATED BY A ZERO UPPER
2629 * peasycap->field_buffer[peasycap->field_fill][0].kount
2630 * THE CONTENTS OF THE FIELD BUFFER ARE OFFERED TO dqbuf(), field_read IS
2631 * UPDATED AND field_fill IS BUMPED. IF THE FIELD BUFFER CONTAINS BAD DATA
2632 * NOTHING IS OFFERED TO dqbuf().
2634 * THE DECISION ON WHETHER THE PARITY OF THE OFFERED FIELD BUFFER IS RIGHT
2635 * RESTS WITH dqbuf().
2637 /*---------------------------------------------------------------------------*/
2638 if ((8 == more
) || override
) {
2639 if (videofieldamount
>
2640 peasycap
->videofieldamount
) {
2641 if (2 == videofieldamount
-
2644 (peasycap
->field_buffer
2645 [peasycap
->field_fill
]
2646 [0].kount
) |= 0x0100;
2647 peasycap
->video_junk
+= (1 +
2648 VIDEO_JUNK_TOLERATE
);
2650 (peasycap
->field_buffer
2651 [peasycap
->field_fill
]
2652 [0].kount
) |= 0x4000;
2653 } else if (videofieldamount
<
2656 (peasycap
->field_buffer
2657 [peasycap
->field_fill
]
2658 [0].kount
) |= 0x2000;
2660 bad
= 0xFF00 & peasycap
->field_buffer
2661 [peasycap
->field_fill
]
2664 (peasycap
->video_junk
)--;
2665 if (-VIDEO_JUNK_TOLERATE
>
2666 peasycap
->video_junk
)
2667 peasycap
->video_junk
=
2668 -VIDEO_JUNK_TOLERATE
;
2669 peasycap
->field_read
=
2672 if (FIELD_BUFFER_MANY
<=
2677 peasycap
->field_page
= 0;
2678 pfield_buffer
= &peasycap
->
2684 pfield_buffer
->pto
=
2686 JOM(8, "bumped to: %i="
2690 peasycap
->field_fill
,
2692 pfield_buffer
->kount
);
2693 JOM(8, "field buffer %i has "
2694 "%i bytes fit to be "
2696 peasycap
->field_read
,
2698 JOM(8, "wakeup call to "
2703 peasycap
->field_read
,
2704 peasycap
->field_fill
,
2708 field_read
][0].kount
);
2709 wake_up_interruptible
2713 peasycap
->video_junk
++;
2715 peasycap
->video_junk
+=
2716 (1 + VIDEO_JUNK_TOLERATE
/2);
2717 JOM(8, "field buffer %i had %i "
2718 "bytes, now discarded: "
2720 peasycap
->field_fill
,
2723 peasycap
->field_buffer
2724 [peasycap
->field_fill
][0].
2726 (peasycap
->field_fill
)++;
2728 if (FIELD_BUFFER_MANY
<=
2729 peasycap
->field_fill
)
2730 peasycap
->field_fill
= 0;
2731 peasycap
->field_page
= 0;
2733 &peasycap
->field_buffer
2734 [peasycap
->field_fill
]
2735 [peasycap
->field_page
];
2736 pfield_buffer
->pto
=
2739 JOM(8, "bumped to: %i=peasycap->"
2740 "field_fill %i=parity\n",
2741 peasycap
->field_fill
,
2742 0x00FF & pfield_buffer
->kount
);
2745 JOM(8, "end-of-field: received "
2746 "parity byte 0x%02X\n",
2749 pfield_buffer
->kount
= 0x0000;
2751 pfield_buffer
->kount
= 0x0001;
2752 pfield_buffer
->input
= 0x08 |
2753 (0x07 & peasycap
->input
);
2754 JOM(8, "end-of-field: 0x%02X=kount\n",
2755 0xFF & pfield_buffer
->kount
);
2758 /*---------------------------------------------------------------------------*/
2760 * COPY more BYTES FROM ISOC BUFFER TO FIELD BUFFER
2762 /*---------------------------------------------------------------------------*/
2766 if (FIELD_BUFFER_MANY
<= peasycap
->field_fill
) {
2767 SAM("ERROR: bad peasycap->field_fill\n");
2770 if (FIELD_BUFFER_SIZE
/PAGE_SIZE
<= peasycap
->field_page
) {
2771 SAM("ERROR: bad peasycap->field_page\n");
2774 pfield_buffer
= &peasycap
->field_buffer
2775 [peasycap
->field_fill
][peasycap
->field_page
];
2777 pfield_buffer
= &peasycap
->field_buffer
2778 [peasycap
->field_fill
]
2779 [peasycap
->field_page
];
2780 if (PAGE_SIZE
< (pfield_buffer
->pto
-
2781 pfield_buffer
->pgo
)) {
2782 SAM("ERROR: bad pfield_buffer->pto\n");
2785 if (PAGE_SIZE
== (pfield_buffer
->pto
-
2786 pfield_buffer
->pgo
)) {
2787 (peasycap
->field_page
)++;
2788 if (FIELD_BUFFER_SIZE
/PAGE_SIZE
<=
2789 peasycap
->field_page
) {
2790 JOM(16, "wrapping peasycap->"
2792 peasycap
->field_page
= 0;
2794 pfield_buffer
= &peasycap
->
2796 [peasycap
->field_fill
]
2797 [peasycap
->field_page
];
2798 pfield_buffer
->pto
= pfield_buffer
->pgo
;
2799 pfield_buffer
->input
= 0x08 |
2800 (0x07 & peasycap
->input
);
2801 if ((peasycap
->field_buffer
[peasycap
->
2804 pfield_buffer
->input
)
2805 (peasycap
->field_buffer
2806 [peasycap
->field_fill
]
2807 [0]).kount
|= 0x1000;
2811 (int)(pfield_buffer
->pto
-
2812 pfield_buffer
->pgo
);
2816 memcpy(pfield_buffer
->pto
, pu
, much
);
2818 (pfield_buffer
->pto
) += much
;
2825 /*---------------------------------------------------------------------------*/
2827 * RESUBMIT THIS URB, UNLESS A SEVERE PERSISTENT ERROR CONDITION EXISTS.
2829 * IF THE WAIT QUEUES ARE NOT CLEARED IN RESPONSE TO AN ERROR CONDITION
2830 * THE USERSPACE PROGRAM, E.G. mplayer, MAY HANG ON EXIT. BEWARE.
2832 /*---------------------------------------------------------------------------*/
2833 if (VIDEO_ISOC_BUFFER_MANY
<= peasycap
->video_junk
) {
2834 SAM("easycap driver shutting down on condition green\n");
2835 peasycap
->status
= 1;
2836 peasycap
->video_eof
= 1;
2837 peasycap
->video_junk
= 0;
2838 wake_up_interruptible(&peasycap
->wq_video
);
2839 #if !defined(PERSEVERE)
2840 peasycap
->audio_eof
= 1;
2841 wake_up_interruptible(&peasycap
->wq_audio
);
2842 #endif /*PERSEVERE*/
2845 if (peasycap
->video_isoc_streaming
) {
2846 rc
= usb_submit_urb(purb
, GFP_ATOMIC
);
2848 SAM("%s: %d\n", strerror(rc
), rc
);
2850 SAM("ERROR: while %i=video_idle, "
2852 "failed with rc:\n",
2853 peasycap
->video_idle
);
2858 static const struct file_operations easycap_fops
= {
2859 .owner
= THIS_MODULE
,
2860 .open
= easycap_open
,
2861 .unlocked_ioctl
= easycap_unlocked_ioctl
,
2862 .poll
= easycap_poll
,
2863 .mmap
= easycap_mmap
,
2864 .llseek
= no_llseek
,
2866 static const struct usb_class_driver easycap_class
= {
2867 .name
= "usb/easycap%d",
2868 .fops
= &easycap_fops
,
2869 .minor_base
= USB_SKEL_MINOR_BASE
,
2871 /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
2872 static const struct v4l2_file_operations v4l2_fops
= {
2873 .owner
= THIS_MODULE
,
2874 .open
= easycap_open_noinode
,
2875 .unlocked_ioctl
= easycap_unlocked_ioctl
,
2876 .poll
= easycap_poll
,
2877 .mmap
= easycap_mmap
,
2879 /*****************************************************************************/
2880 /*---------------------------------------------------------------------------*/
2882 * WHEN THE EasyCAP IS PHYSICALLY PLUGGED IN, THIS FUNCTION IS CALLED THREE
2883 * TIMES, ONCE FOR EACH OF THE THREE INTERFACES. BEWARE.
2885 /*---------------------------------------------------------------------------*/
2886 static int easycap_usb_probe(struct usb_interface
*intf
,
2887 const struct usb_device_id
*id
)
2889 struct usb_device
*usbdev
;
2890 struct usb_host_interface
*alt
;
2891 struct usb_endpoint_descriptor
*ep
;
2892 struct usb_interface_descriptor
*interface
;
2894 struct easycap
*peasycap
;
2896 struct data_urb
*pdata_urb
;
2898 u8 bInterfaceNumber
;
2900 u8 bInterfaceSubClass
;
2902 int okalt
[8], isokalt
;
2908 struct easycap_format
*peasycap_format
;
2910 struct inputset
*inputset
;
2912 usbdev
= interface_to_usbdev(intf
);
2914 /*---------------------------------------------------------------------------*/
2915 alt
= usb_altnum_to_altsetting(intf
, 0);
2917 SAY("ERROR: usb_host_interface not found\n");
2920 interface
= &alt
->desc
;
2922 SAY("ERROR: intf_descriptor is NULL\n");
2925 /*---------------------------------------------------------------------------*/
2927 * GET PROPERTIES OF PROBED INTERFACE
2929 /*---------------------------------------------------------------------------*/
2930 bInterfaceNumber
= interface
->bInterfaceNumber
;
2931 bInterfaceClass
= interface
->bInterfaceClass
;
2932 bInterfaceSubClass
= interface
->bInterfaceSubClass
;
2934 JOT(4, "intf[%i]: num_altsetting=%i\n",
2935 bInterfaceNumber
, intf
->num_altsetting
);
2936 JOT(4, "intf[%i]: cur_altsetting - altsetting=%li\n",
2938 (long int)(intf
->cur_altsetting
- intf
->altsetting
));
2939 JOT(4, "intf[%i]: bInterfaceClass=0x%02X bInterfaceSubClass=0x%02X\n",
2940 bInterfaceNumber
, bInterfaceClass
, bInterfaceSubClass
);
2941 /*---------------------------------------------------------------------------*/
2943 * A NEW struct easycap IS ALWAYS ALLOCATED WHEN INTERFACE 0 IS PROBED.
2944 * IT IS NOT POSSIBLE HERE TO FREE ANY EXISTING struct easycap. THIS
2945 * SHOULD HAVE BEEN DONE BY easycap_delete() WHEN THE EasyCAP WAS
2946 * PHYSICALLY UNPLUGGED.
2948 * THE POINTER peasycap TO THE struct easycap IS REMEMBERED WHEN
2949 * INTERFACES 1 AND 2 ARE PROBED.
2951 /*---------------------------------------------------------------------------*/
2952 if (0 == bInterfaceNumber
) {
2953 peasycap
= kzalloc(sizeof(struct easycap
), GFP_KERNEL
);
2955 SAY("ERROR: Could not allocate peasycap\n");
2958 /*---------------------------------------------------------------------------*/
2960 * PERFORM URGENT INTIALIZATIONS ...
2962 /*---------------------------------------------------------------------------*/
2963 peasycap
->minor
= -1;
2964 kref_init(&peasycap
->kref
);
2965 JOM(8, "intf[%i]: after kref_init(..._video) "
2966 "%i=peasycap->kref.refcount.counter\n",
2967 bInterfaceNumber
, peasycap
->kref
.refcount
.counter
);
2970 peasycap
->gain
= (s8
)clamp(easycap_gain
, 0, 31);
2972 init_waitqueue_head(&peasycap
->wq_video
);
2973 init_waitqueue_head(&peasycap
->wq_audio
);
2974 init_waitqueue_head(&peasycap
->wq_trigger
);
2976 if (mutex_lock_interruptible(&mutex_dongle
)) {
2977 SAY("ERROR: cannot down mutex_dongle\n");
2978 return -ERESTARTSYS
;
2980 /*---------------------------------------------------------------------------*/
2982 * FOR INTERFACES 1 AND 2 THE POINTER peasycap WILL NEED TO
2983 * TO BE THE SAME AS THAT ALLOCATED NOW FOR INTERFACE 0.
2985 * NORMALLY ndong WILL NOT HAVE CHANGED SINCE INTERFACE 0 WAS
2986 * PROBED, BUT THIS MAY NOT BE THE CASE IF, FOR EXAMPLE, TWO
2987 * EASYCAPs ARE PLUGGED IN SIMULTANEOUSLY.
2989 /*---------------------------------------------------------------------------*/
2990 for (ndong
= 0; ndong
< DONGLE_MANY
; ndong
++) {
2991 if ((!easycapdc60_dongle
[ndong
].peasycap
) &&
2992 (!mutex_is_locked(&easycapdc60_dongle
2993 [ndong
].mutex_video
)) &&
2994 (!mutex_is_locked(&easycapdc60_dongle
2995 [ndong
].mutex_audio
))) {
2996 easycapdc60_dongle
[ndong
].peasycap
= peasycap
;
2997 peasycap
->isdongle
= ndong
;
2998 JOM(8, "intf[%i]: peasycap-->easycap"
2999 "_dongle[%i].peasycap\n",
3000 bInterfaceNumber
, ndong
);
3004 if (DONGLE_MANY
<= ndong
) {
3005 SAM("ERROR: too many dongles\n");
3006 mutex_unlock(&mutex_dongle
);
3009 mutex_unlock(&mutex_dongle
);
3011 peasycap
->allocation_video_struct
= sizeof(struct easycap
);
3012 peasycap
->allocation_video_page
= 0;
3013 peasycap
->allocation_video_urb
= 0;
3014 peasycap
->allocation_audio_struct
= 0;
3015 peasycap
->allocation_audio_page
= 0;
3016 peasycap
->allocation_audio_urb
= 0;
3018 /*---------------------------------------------------------------------------*/
3020 * ... AND FURTHER INITIALIZE THE STRUCTURE
3022 /*---------------------------------------------------------------------------*/
3023 peasycap
->pusb_device
= usbdev
;
3024 peasycap
->pusb_interface
= intf
;
3027 peasycap
->microphone
= false;
3029 peasycap
->video_interface
= -1;
3030 peasycap
->video_altsetting_on
= -1;
3031 peasycap
->video_altsetting_off
= -1;
3032 peasycap
->video_endpointnumber
= -1;
3033 peasycap
->video_isoc_maxframesize
= -1;
3034 peasycap
->video_isoc_buffer_size
= -1;
3036 peasycap
->audio_interface
= -1;
3037 peasycap
->audio_altsetting_on
= -1;
3038 peasycap
->audio_altsetting_off
= -1;
3039 peasycap
->audio_endpointnumber
= -1;
3040 peasycap
->audio_isoc_maxframesize
= -1;
3041 peasycap
->audio_isoc_buffer_size
= -1;
3043 peasycap
->frame_buffer_many
= FRAME_BUFFER_MANY
;
3045 for (k
= 0; k
< INPUT_MANY
; k
++)
3046 peasycap
->lost
[k
] = 0;
3048 peasycap
->skipped
= 0;
3049 peasycap
->offerfields
= 0;
3050 /*---------------------------------------------------------------------------*/
3052 * DYNAMICALLY FILL IN THE AVAILABLE FORMATS ...
3054 /*---------------------------------------------------------------------------*/
3055 rc
= fillin_formats();
3057 SAM("ERROR: fillin_formats() rc = %i\n", rc
);
3060 JOM(4, "%i formats available\n", rc
);
3061 /*---------------------------------------------------------------------------*/
3063 * ... AND POPULATE easycap.inputset[]
3065 /*---------------------------------------------------------------------------*/
3066 /* FIXME: maybe we just use memset 0 */
3067 inputset
= peasycap
->inputset
;
3068 for (k
= 0; k
< INPUT_MANY
; k
++) {
3069 inputset
[k
].input_ok
= 0;
3070 inputset
[k
].standard_offset_ok
= 0;
3071 inputset
[k
].format_offset_ok
= 0;
3072 inputset
[k
].brightness_ok
= 0;
3073 inputset
[k
].contrast_ok
= 0;
3074 inputset
[k
].saturation_ok
= 0;
3075 inputset
[k
].hue_ok
= 0;
3078 fmtidx
= peasycap
->ntsc
? NTSC_M
: PAL_BGHIN
;
3081 for (i
= 0; 0xFFFF != easycap_standard
[i
].mask
; i
++) {
3082 if (fmtidx
== easycap_standard
[i
].v4l2_standard
.index
) {
3084 for (k
= 0; k
< INPUT_MANY
; k
++)
3085 inputset
[k
].standard_offset
= i
;
3087 mask
= easycap_standard
[i
].mask
;
3093 "inputset->standard_offset unpopulated, %i=m\n", m
);
3097 peasycap_format
= &easycap_format
[0];
3099 for (i
= 0; peasycap_format
->v4l2_format
.fmt
.pix
.width
; i
++) {
3100 struct v4l2_pix_format
*pix
=
3101 &peasycap_format
->v4l2_format
.fmt
.pix
;
3102 if (((peasycap_format
->mask
& 0x0F) == (mask
& 0x0F)) &&
3103 pix
->field
== V4L2_FIELD_NONE
&&
3104 pix
->pixelformat
== V4L2_PIX_FMT_UYVY
&&
3105 pix
->width
== 640 && pix
->height
== 480) {
3107 for (k
= 0; k
< INPUT_MANY
; k
++)
3108 inputset
[k
].format_offset
= i
;
3114 SAM("ERROR: inputset[]->format_offset unpopulated\n");
3119 for (i
= 0; 0xFFFFFFFF != easycap_control
[i
].id
; i
++) {
3120 value
= easycap_control
[i
].default_value
;
3121 if (V4L2_CID_BRIGHTNESS
== easycap_control
[i
].id
) {
3123 for (k
= 0; k
< INPUT_MANY
; k
++)
3124 inputset
[k
].brightness
= value
;
3125 } else if (V4L2_CID_CONTRAST
== easycap_control
[i
].id
) {
3127 for (k
= 0; k
< INPUT_MANY
; k
++)
3128 inputset
[k
].contrast
= value
;
3129 } else if (V4L2_CID_SATURATION
== easycap_control
[i
].id
) {
3131 for (k
= 0; k
< INPUT_MANY
; k
++)
3132 inputset
[k
].saturation
= value
;
3133 } else if (V4L2_CID_HUE
== easycap_control
[i
].id
) {
3135 for (k
= 0; k
< INPUT_MANY
; k
++)
3136 inputset
[k
].hue
= value
;
3141 SAM("ERROR: inputset[]->brightness underpopulated\n");
3144 for (k
= 0; k
< INPUT_MANY
; k
++)
3145 inputset
[k
].input
= k
;
3146 JOM(4, "populated inputset[]\n");
3147 JOM(4, "finished initialization\n");
3149 /*---------------------------------------------------------------------------*/
3153 * IDENTIFY THE APPROPRIATE POINTER peasycap FOR INTERFACES 1 AND 2.
3154 * THE ADDRESS OF peasycap->pusb_device IS RELUCTANTLY USED FOR THIS PURPOSE.
3156 /*---------------------------------------------------------------------------*/
3157 for (ndong
= 0; ndong
< DONGLE_MANY
; ndong
++) {
3158 if (usbdev
== easycapdc60_dongle
[ndong
].peasycap
->
3160 peasycap
= easycapdc60_dongle
[ndong
].peasycap
;
3161 JOT(8, "intf[%i]: dongle[%i].peasycap\n",
3162 bInterfaceNumber
, ndong
);
3166 if (DONGLE_MANY
<= ndong
) {
3167 SAY("ERROR: peasycap is unknown when probing interface %i\n",
3172 SAY("ERROR: peasycap is NULL when probing interface %i\n",
3177 /*---------------------------------------------------------------------------*/
3178 if ((USB_CLASS_VIDEO
== bInterfaceClass
) ||
3179 (USB_CLASS_VENDOR_SPEC
== bInterfaceClass
)) {
3180 if (-1 == peasycap
->video_interface
) {
3181 peasycap
->video_interface
= bInterfaceNumber
;
3182 JOM(4, "setting peasycap->video_interface=%i\n",
3183 peasycap
->video_interface
);
3185 if (peasycap
->video_interface
!= bInterfaceNumber
) {
3186 SAM("ERROR: attempting to reset "
3187 "peasycap->video_interface\n");
3188 SAM("...... continuing with "
3189 "%i=peasycap->video_interface\n",
3190 peasycap
->video_interface
);
3193 } else if ((USB_CLASS_AUDIO
== bInterfaceClass
) &&
3194 (USB_SUBCLASS_AUDIOSTREAMING
== bInterfaceSubClass
)) {
3195 if (-1 == peasycap
->audio_interface
) {
3196 peasycap
->audio_interface
= bInterfaceNumber
;
3197 JOM(4, "setting peasycap->audio_interface=%i\n",
3198 peasycap
->audio_interface
);
3200 if (peasycap
->audio_interface
!= bInterfaceNumber
) {
3201 SAM("ERROR: attempting to reset "
3202 "peasycap->audio_interface\n");
3203 SAM("...... continuing with "
3204 "%i=peasycap->audio_interface\n",
3205 peasycap
->audio_interface
);
3209 /*---------------------------------------------------------------------------*/
3211 * INVESTIGATE ALL ALTSETTINGS.
3212 * DONE IN DETAIL BECAUSE USB DEVICE 05e1:0408 HAS DISPARATE INCARNATIONS.
3214 /*---------------------------------------------------------------------------*/
3217 for (i
= 0; i
< intf
->num_altsetting
; i
++) {
3218 alt
= usb_altnum_to_altsetting(intf
, i
);
3220 SAM("ERROR: alt is NULL\n");
3223 interface
= &alt
->desc
;
3225 SAM("ERROR: intf_descriptor is NULL\n");
3229 if (0 == interface
->bNumEndpoints
)
3230 JOM(4, "intf[%i]alt[%i] has no endpoints\n",
3231 bInterfaceNumber
, i
);
3232 /*---------------------------------------------------------------------------*/
3233 for (j
= 0; j
< interface
->bNumEndpoints
; j
++) {
3234 ep
= &alt
->endpoint
[j
].desc
;
3236 SAM("ERROR: ep is NULL.\n");
3237 SAM("...... skipping\n");
3241 if (!usb_endpoint_is_isoc_in(ep
)) {
3242 JOM(4, "intf[%i]alt[%i]end[%i] is a %d endpoint\n",
3244 i
, j
, ep
->bmAttributes
);
3245 if (usb_endpoint_dir_out(ep
)) {
3246 SAM("ERROR: OUT endpoint unexpected\n");
3247 SAM("...... continuing\n");
3251 switch (bInterfaceClass
) {
3252 case USB_CLASS_VIDEO
:
3253 case USB_CLASS_VENDOR_SPEC
: {
3254 if (ep
->wMaxPacketSize
) {
3279 if (-1 == peasycap
->
3280 video_altsetting_off
) {
3282 video_altsetting_off
=
3288 video_altsetting_off
);
3290 SAM("ERROR: peasycap"
3291 "->video_altsetting_"
3292 "off already set\n");
3295 "%i=peasycap->video_"
3298 video_altsetting_off
);
3303 case USB_CLASS_AUDIO
: {
3304 if (bInterfaceSubClass
!=
3305 USB_SUBCLASS_AUDIOSTREAMING
)
3309 "peasycap is NULL\n");
3312 if (ep
->wMaxPacketSize
) {
3314 okalt
[isokalt
] = i
;
3337 if (-1 == peasycap
->
3338 audio_altsetting_off
) {
3340 audio_altsetting_off
=
3346 audio_altsetting_off
);
3348 SAM("ERROR: peasycap"
3349 "->audio_altsetting_"
3350 "off already set\n");
3357 audio_altsetting_off
);
3365 if (0 == ep
->wMaxPacketSize
) {
3366 JOM(4, "intf[%i]alt[%i]end[%i] "
3367 "has zero packet size\n",
3368 bInterfaceNumber
, i
, j
);
3372 /*---------------------------------------------------------------------------*/
3374 * PERFORM INITIALIZATION OF THE PROBED INTERFACE
3376 /*---------------------------------------------------------------------------*/
3377 JOM(4, "initialization begins for interface %i\n",
3378 interface
->bInterfaceNumber
);
3379 switch (bInterfaceNumber
) {
3380 /*---------------------------------------------------------------------------*/
3382 * INTERFACE 0 IS THE VIDEO INTERFACE
3384 /*---------------------------------------------------------------------------*/
3387 SAM("MISTAKE: peasycap is NULL\n");
3391 SAM("ERROR: no viable video_altsetting_on\n");
3394 peasycap
->video_altsetting_on
= okalt
[isokalt
- 1];
3395 JOM(4, "%i=video_altsetting_on <====\n",
3396 peasycap
->video_altsetting_on
);
3398 /*---------------------------------------------------------------------------*/
3400 * DECIDE THE VIDEO STREAMING PARAMETERS
3402 /*---------------------------------------------------------------------------*/
3403 peasycap
->video_endpointnumber
= okepn
[isokalt
- 1];
3404 JOM(4, "%i=video_endpointnumber\n", peasycap
->video_endpointnumber
);
3405 maxpacketsize
= okmps
[isokalt
- 1];
3407 peasycap
->video_isoc_maxframesize
=
3408 min(maxpacketsize
, USB_2_0_MAXPACKETSIZE
);
3409 if (0 >= peasycap
->video_isoc_maxframesize
) {
3410 SAM("ERROR: bad video_isoc_maxframesize\n");
3411 SAM(" possibly because port is USB 1.1\n");
3414 JOM(4, "%i=video_isoc_maxframesize\n",
3415 peasycap
->video_isoc_maxframesize
);
3417 peasycap
->video_isoc_framesperdesc
= VIDEO_ISOC_FRAMESPERDESC
;
3418 JOM(4, "%i=video_isoc_framesperdesc\n",
3419 peasycap
->video_isoc_framesperdesc
);
3420 if (0 >= peasycap
->video_isoc_framesperdesc
) {
3421 SAM("ERROR: bad video_isoc_framesperdesc\n");
3424 peasycap
->video_isoc_buffer_size
=
3425 peasycap
->video_isoc_maxframesize
*
3426 peasycap
->video_isoc_framesperdesc
;
3427 JOM(4, "%i=video_isoc_buffer_size\n",
3428 peasycap
->video_isoc_buffer_size
);
3429 if ((PAGE_SIZE
<< VIDEO_ISOC_ORDER
) <
3430 peasycap
->video_isoc_buffer_size
) {
3431 SAM("MISTAKE: peasycap->video_isoc_buffer_size too big\n");
3434 /*---------------------------------------------------------------------------*/
3435 if (-1 == peasycap
->video_interface
) {
3436 SAM("MISTAKE: video_interface is unset\n");
3439 if (-1 == peasycap
->video_altsetting_on
) {
3440 SAM("MISTAKE: video_altsetting_on is unset\n");
3443 if (-1 == peasycap
->video_altsetting_off
) {
3444 SAM("MISTAKE: video_interface_off is unset\n");
3447 if (-1 == peasycap
->video_endpointnumber
) {
3448 SAM("MISTAKE: video_endpointnumber is unset\n");
3451 if (-1 == peasycap
->video_isoc_maxframesize
) {
3452 SAM("MISTAKE: video_isoc_maxframesize is unset\n");
3455 if (-1 == peasycap
->video_isoc_buffer_size
) {
3456 SAM("MISTAKE: video_isoc_buffer_size is unset\n");
3459 /*---------------------------------------------------------------------------*/
3461 * ALLOCATE MEMORY FOR VIDEO BUFFERS. LISTS MUST BE INITIALIZED FIRST.
3463 /*---------------------------------------------------------------------------*/
3464 INIT_LIST_HEAD(&(peasycap
->urb_video_head
));
3465 peasycap
->purb_video_head
= &(peasycap
->urb_video_head
);
3466 /*---------------------------------------------------------------------------*/
3467 JOM(4, "allocating %i frame buffers of size %li\n",
3468 FRAME_BUFFER_MANY
, (long int)FRAME_BUFFER_SIZE
);
3469 JOM(4, ".... each scattered over %li pages\n",
3470 FRAME_BUFFER_SIZE
/PAGE_SIZE
);
3472 for (k
= 0; k
< FRAME_BUFFER_MANY
; k
++) {
3473 for (m
= 0; m
< FRAME_BUFFER_SIZE
/PAGE_SIZE
; m
++) {
3474 if (peasycap
->frame_buffer
[k
][m
].pgo
)
3475 SAM("attempting to reallocate frame "
3478 pbuf
= (void *)__get_free_page(GFP_KERNEL
);
3480 SAM("ERROR: Could not allocate frame "
3481 "buffer %i page %i\n", k
, m
);
3484 peasycap
->allocation_video_page
+= 1;
3485 peasycap
->frame_buffer
[k
][m
].pgo
= pbuf
;
3487 peasycap
->frame_buffer
[k
][m
].pto
=
3488 peasycap
->frame_buffer
[k
][m
].pgo
;
3492 peasycap
->frame_fill
= 0;
3493 peasycap
->frame_read
= 0;
3494 JOM(4, "allocation of frame buffers done: %i pages\n", k
*
3496 /*---------------------------------------------------------------------------*/
3497 JOM(4, "allocating %i field buffers of size %li\n",
3498 FIELD_BUFFER_MANY
, (long int)FIELD_BUFFER_SIZE
);
3499 JOM(4, ".... each scattered over %li pages\n",
3500 FIELD_BUFFER_SIZE
/PAGE_SIZE
);
3502 for (k
= 0; k
< FIELD_BUFFER_MANY
; k
++) {
3503 for (m
= 0; m
< FIELD_BUFFER_SIZE
/PAGE_SIZE
; m
++) {
3504 if (peasycap
->field_buffer
[k
][m
].pgo
) {
3505 SAM("ERROR: attempting to reallocate "
3508 pbuf
= (void *) __get_free_page(GFP_KERNEL
);
3510 SAM("ERROR: Could not allocate field"
3511 " buffer %i page %i\n", k
, m
);
3515 peasycap
->allocation_video_page
+= 1;
3516 peasycap
->field_buffer
[k
][m
].pgo
= pbuf
;
3518 peasycap
->field_buffer
[k
][m
].pto
=
3519 peasycap
->field_buffer
[k
][m
].pgo
;
3521 peasycap
->field_buffer
[k
][0].kount
= 0x0200;
3523 peasycap
->field_fill
= 0;
3524 peasycap
->field_page
= 0;
3525 peasycap
->field_read
= 0;
3526 JOM(4, "allocation of field buffers done: %i pages\n", k
*
3528 /*---------------------------------------------------------------------------*/
3529 JOM(4, "allocating %i isoc video buffers of size %i\n",
3530 VIDEO_ISOC_BUFFER_MANY
,
3531 peasycap
->video_isoc_buffer_size
);
3532 JOM(4, ".... each occupying contiguous memory pages\n");
3534 for (k
= 0; k
< VIDEO_ISOC_BUFFER_MANY
; k
++) {
3535 pbuf
= (void *)__get_free_pages(GFP_KERNEL
,
3538 SAM("ERROR: Could not allocate isoc video buffer "
3542 peasycap
->allocation_video_page
+=
3543 BIT(VIDEO_ISOC_ORDER
);
3545 peasycap
->video_isoc_buffer
[k
].pgo
= pbuf
;
3546 peasycap
->video_isoc_buffer
[k
].pto
=
3547 pbuf
+ peasycap
->video_isoc_buffer_size
;
3548 peasycap
->video_isoc_buffer
[k
].kount
= k
;
3550 JOM(4, "allocation of isoc video buffers done: %i pages\n",
3551 k
* (0x01 << VIDEO_ISOC_ORDER
));
3552 /*---------------------------------------------------------------------------*/
3554 * ALLOCATE AND INITIALIZE MULTIPLE struct urb ...
3556 /*---------------------------------------------------------------------------*/
3557 JOM(4, "allocating %i struct urb.\n", VIDEO_ISOC_BUFFER_MANY
);
3558 JOM(4, "using %i=peasycap->video_isoc_framesperdesc\n",
3559 peasycap
->video_isoc_framesperdesc
);
3560 JOM(4, "using %i=peasycap->video_isoc_maxframesize\n",
3561 peasycap
->video_isoc_maxframesize
);
3562 JOM(4, "using %i=peasycap->video_isoc_buffer_sizen",
3563 peasycap
->video_isoc_buffer_size
);
3565 for (k
= 0; k
< VIDEO_ISOC_BUFFER_MANY
; k
++) {
3566 purb
= usb_alloc_urb(peasycap
->video_isoc_framesperdesc
,
3569 SAM("ERROR: usb_alloc_urb returned NULL for buffer "
3573 peasycap
->allocation_video_urb
+= 1;
3574 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
3575 pdata_urb
= kzalloc(sizeof(struct data_urb
), GFP_KERNEL
);
3577 SAM("ERROR: Could not allocate struct data_urb.\n");
3580 peasycap
->allocation_video_struct
+=
3581 sizeof(struct data_urb
);
3583 pdata_urb
->purb
= purb
;
3584 pdata_urb
->isbuf
= k
;
3585 pdata_urb
->length
= 0;
3586 list_add_tail(&(pdata_urb
->list_head
),
3587 peasycap
->purb_video_head
);
3588 /*---------------------------------------------------------------------------*/
3590 * ... AND INITIALIZE THEM
3592 /*---------------------------------------------------------------------------*/
3594 JOM(4, "initializing video urbs thus:\n");
3595 JOM(4, " purb->interval = 1;\n");
3596 JOM(4, " purb->dev = peasycap->pusb_device;\n");
3597 JOM(4, " purb->pipe = usb_rcvisocpipe"
3598 "(peasycap->pusb_device,%i);\n",
3599 peasycap
->video_endpointnumber
);
3600 JOM(4, " purb->transfer_flags = URB_ISO_ASAP;\n");
3601 JOM(4, " purb->transfer_buffer = peasycap->"
3602 "video_isoc_buffer[.].pgo;\n");
3603 JOM(4, " purb->transfer_buffer_length = %i;\n",
3604 peasycap
->video_isoc_buffer_size
);
3605 JOM(4, " purb->complete = easycap_complete;\n");
3606 JOM(4, " purb->context = peasycap;\n");
3607 JOM(4, " purb->start_frame = 0;\n");
3608 JOM(4, " purb->number_of_packets = %i;\n",
3609 peasycap
->video_isoc_framesperdesc
);
3610 JOM(4, " for (j = 0; j < %i; j++)\n",
3611 peasycap
->video_isoc_framesperdesc
);
3613 JOM(4, " purb->iso_frame_desc[j].offset = j*%i;\n",
3614 peasycap
->video_isoc_maxframesize
);
3615 JOM(4, " purb->iso_frame_desc[j].length = %i;\n",
3616 peasycap
->video_isoc_maxframesize
);
3621 purb
->dev
= peasycap
->pusb_device
;
3622 purb
->pipe
= usb_rcvisocpipe(peasycap
->pusb_device
,
3623 peasycap
->video_endpointnumber
);
3624 purb
->transfer_flags
= URB_ISO_ASAP
;
3625 purb
->transfer_buffer
= peasycap
->video_isoc_buffer
[k
].pgo
;
3626 purb
->transfer_buffer_length
=
3627 peasycap
->video_isoc_buffer_size
;
3628 purb
->complete
= easycap_complete
;
3629 purb
->context
= peasycap
;
3630 purb
->start_frame
= 0;
3631 purb
->number_of_packets
= peasycap
->video_isoc_framesperdesc
;
3632 for (j
= 0; j
< peasycap
->video_isoc_framesperdesc
; j
++) {
3633 purb
->iso_frame_desc
[j
].offset
= j
*
3634 peasycap
->video_isoc_maxframesize
;
3635 purb
->iso_frame_desc
[j
].length
=
3636 peasycap
->video_isoc_maxframesize
;
3639 JOM(4, "allocation of %i struct urb done.\n", k
);
3640 /*--------------------------------------------------------------------------*/
3642 * SAVE POINTER peasycap IN THIS INTERFACE.
3644 /*--------------------------------------------------------------------------*/
3645 usb_set_intfdata(intf
, peasycap
);
3646 /*---------------------------------------------------------------------------*/
3648 * IT IS ESSENTIAL TO INITIALIZE THE HARDWARE BEFORE, RATHER THAN AFTER,
3649 * THE DEVICE IS REGISTERED, BECAUSE SOME VERSIONS OF THE videodev MODULE
3650 * CALL easycap_open() IMMEDIATELY AFTER REGISTRATION, CAUSING A CLASH.
3653 /*---------------------------------------------------------------------------*/
3654 peasycap
->ntsc
= easycap_ntsc
;
3655 JOM(8, "defaulting initially to %s\n",
3656 easycap_ntsc
? "NTSC" : "PAL");
3657 rc
= reset(peasycap
);
3659 SAM("ERROR: reset() rc = %i\n", rc
);
3662 /*--------------------------------------------------------------------------*/
3664 * THE VIDEO DEVICE CAN BE REGISTERED NOW, AS IT IS READY.
3666 /*--------------------------------------------------------------------------*/
3667 if (v4l2_device_register(&intf
->dev
, &peasycap
->v4l2_device
)) {
3668 SAM("v4l2_device_register() failed\n");
3671 JOM(4, "registered device instance: %s\n",
3672 peasycap
->v4l2_device
.name
);
3673 /*---------------------------------------------------------------------------*/
3678 * THIS IS BELIEVED TO BE HARMLESS, BUT MAY WELL BE UNNECESSARY OR WRONG:
3680 /*---------------------------------------------------------------------------*/
3681 peasycap
->video_device
.v4l2_dev
= NULL
;
3682 /*---------------------------------------------------------------------------*/
3685 strcpy(&peasycap
->video_device
.name
[0], "easycapdc60");
3686 peasycap
->video_device
.fops
= &v4l2_fops
;
3687 peasycap
->video_device
.minor
= -1;
3688 peasycap
->video_device
.release
= (void *)(&videodev_release
);
3690 video_set_drvdata(&(peasycap
->video_device
), (void *)peasycap
);
3692 if (0 != (video_register_device(&(peasycap
->video_device
),
3693 VFL_TYPE_GRABBER
, -1))) {
3694 err("Not able to register with videodev");
3695 videodev_release(&(peasycap
->video_device
));
3698 (peasycap
->registered_video
)++;
3699 SAM("registered with videodev: %i=minor\n",
3700 peasycap
->video_device
.minor
);
3701 peasycap
->minor
= peasycap
->video_device
.minor
;
3703 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
3707 /*--------------------------------------------------------------------------*/
3709 * INTERFACE 1 IS THE AUDIO CONTROL INTERFACE
3710 * INTERFACE 2 IS THE AUDIO STREAMING INTERFACE
3712 /*--------------------------------------------------------------------------*/
3715 SAM("MISTAKE: peasycap is NULL\n");
3718 /*--------------------------------------------------------------------------*/
3720 * SAVE POINTER peasycap IN INTERFACE 1
3722 /*--------------------------------------------------------------------------*/
3723 usb_set_intfdata(intf
, peasycap
);
3724 JOM(4, "no initialization required for interface %i\n",
3725 interface
->bInterfaceNumber
);
3728 /*--------------------------------------------------------------------------*/
3731 SAM("MISTAKE: peasycap is NULL\n");
3735 SAM("ERROR: no viable audio_altsetting_on\n");
3738 peasycap
->audio_altsetting_on
= okalt
[isokalt
- 1];
3739 JOM(4, "%i=audio_altsetting_on <====\n",
3740 peasycap
->audio_altsetting_on
);
3743 peasycap
->audio_endpointnumber
= okepn
[isokalt
- 1];
3744 JOM(4, "%i=audio_endpointnumber\n", peasycap
->audio_endpointnumber
);
3746 peasycap
->audio_isoc_maxframesize
= okmps
[isokalt
- 1];
3747 JOM(4, "%i=audio_isoc_maxframesize\n",
3748 peasycap
->audio_isoc_maxframesize
);
3749 if (0 >= peasycap
->audio_isoc_maxframesize
) {
3750 SAM("ERROR: bad audio_isoc_maxframesize\n");
3753 if (9 == peasycap
->audio_isoc_maxframesize
) {
3754 peasycap
->ilk
|= 0x02;
3755 SAM("audio hardware is microphone\n");
3756 peasycap
->microphone
= true;
3757 peasycap
->audio_pages_per_fragment
=
3758 PAGES_PER_AUDIO_FRAGMENT
;
3759 } else if (256 == peasycap
->audio_isoc_maxframesize
) {
3760 peasycap
->ilk
&= ~0x02;
3761 SAM("audio hardware is AC'97\n");
3762 peasycap
->microphone
= false;
3763 peasycap
->audio_pages_per_fragment
=
3764 PAGES_PER_AUDIO_FRAGMENT
;
3766 SAM("hardware is unidentified:\n");
3767 SAM("%i=audio_isoc_maxframesize\n",
3768 peasycap
->audio_isoc_maxframesize
);
3772 peasycap
->audio_bytes_per_fragment
=
3773 peasycap
->audio_pages_per_fragment
* PAGE_SIZE
;
3774 peasycap
->audio_buffer_page_many
= (AUDIO_FRAGMENT_MANY
*
3775 peasycap
->audio_pages_per_fragment
);
3777 JOM(4, "%6i=AUDIO_FRAGMENT_MANY\n", AUDIO_FRAGMENT_MANY
);
3778 JOM(4, "%6i=audio_pages_per_fragment\n",
3779 peasycap
->audio_pages_per_fragment
);
3780 JOM(4, "%6i=audio_bytes_per_fragment\n",
3781 peasycap
->audio_bytes_per_fragment
);
3782 JOM(4, "%6i=audio_buffer_page_many\n",
3783 peasycap
->audio_buffer_page_many
);
3785 peasycap
->audio_isoc_framesperdesc
= AUDIO_ISOC_FRAMESPERDESC
;
3787 JOM(4, "%i=audio_isoc_framesperdesc\n",
3788 peasycap
->audio_isoc_framesperdesc
);
3789 if (0 >= peasycap
->audio_isoc_framesperdesc
) {
3790 SAM("ERROR: bad audio_isoc_framesperdesc\n");
3794 peasycap
->audio_isoc_buffer_size
=
3795 peasycap
->audio_isoc_maxframesize
*
3796 peasycap
->audio_isoc_framesperdesc
;
3797 JOM(4, "%i=audio_isoc_buffer_size\n",
3798 peasycap
->audio_isoc_buffer_size
);
3799 if (AUDIO_ISOC_BUFFER_SIZE
< peasycap
->audio_isoc_buffer_size
) {
3800 SAM("MISTAKE: audio_isoc_buffer_size bigger "
3801 "than %li=AUDIO_ISOC_BUFFER_SIZE\n",
3802 AUDIO_ISOC_BUFFER_SIZE
);
3805 if (-1 == peasycap
->audio_interface
) {
3806 SAM("MISTAKE: audio_interface is unset\n");
3809 if (-1 == peasycap
->audio_altsetting_on
) {
3810 SAM("MISTAKE: audio_altsetting_on is unset\n");
3813 if (-1 == peasycap
->audio_altsetting_off
) {
3814 SAM("MISTAKE: audio_interface_off is unset\n");
3817 if (-1 == peasycap
->audio_endpointnumber
) {
3818 SAM("MISTAKE: audio_endpointnumber is unset\n");
3821 if (-1 == peasycap
->audio_isoc_maxframesize
) {
3822 SAM("MISTAKE: audio_isoc_maxframesize is unset\n");
3825 if (-1 == peasycap
->audio_isoc_buffer_size
) {
3826 SAM("MISTAKE: audio_isoc_buffer_size is unset\n");
3829 /*---------------------------------------------------------------------------*/
3831 * ALLOCATE MEMORY FOR AUDIO BUFFERS. LISTS MUST BE INITIALIZED FIRST.
3833 /*---------------------------------------------------------------------------*/
3834 INIT_LIST_HEAD(&(peasycap
->urb_audio_head
));
3835 peasycap
->purb_audio_head
= &(peasycap
->urb_audio_head
);
3837 /*---------------------------------------------------------------------------*/
3838 JOM(4, "allocating %i isoc audio buffers of size %i\n",
3839 AUDIO_ISOC_BUFFER_MANY
,
3840 peasycap
->audio_isoc_buffer_size
);
3841 JOM(4, ".... each occupying contiguous memory pages\n");
3843 for (k
= 0; k
< AUDIO_ISOC_BUFFER_MANY
; k
++) {
3844 pbuf
= (void *)__get_free_pages(GFP_KERNEL
,
3847 SAM("ERROR: Could not allocate isoc audio buffer "
3851 peasycap
->allocation_audio_page
+=
3852 BIT(AUDIO_ISOC_ORDER
);
3854 peasycap
->audio_isoc_buffer
[k
].pgo
= pbuf
;
3855 peasycap
->audio_isoc_buffer
[k
].pto
= pbuf
+
3856 peasycap
->audio_isoc_buffer_size
;
3857 peasycap
->audio_isoc_buffer
[k
].kount
= k
;
3859 JOM(4, "allocation of isoc audio buffers done.\n");
3860 /*---------------------------------------------------------------------------*/
3862 * ALLOCATE AND INITIALIZE MULTIPLE struct urb ...
3864 /*---------------------------------------------------------------------------*/
3865 JOM(4, "allocating %i struct urb.\n", AUDIO_ISOC_BUFFER_MANY
);
3866 JOM(4, "using %i=peasycap->audio_isoc_framesperdesc\n",
3867 peasycap
->audio_isoc_framesperdesc
);
3868 JOM(4, "using %i=peasycap->audio_isoc_maxframesize\n",
3869 peasycap
->audio_isoc_maxframesize
);
3870 JOM(4, "using %i=peasycap->audio_isoc_buffer_size\n",
3871 peasycap
->audio_isoc_buffer_size
);
3873 for (k
= 0; k
< AUDIO_ISOC_BUFFER_MANY
; k
++) {
3874 purb
= usb_alloc_urb(peasycap
->audio_isoc_framesperdesc
,
3877 SAM("ERROR: usb_alloc_urb returned NULL for buffer "
3881 peasycap
->allocation_audio_urb
+= 1 ;
3882 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
3883 pdata_urb
= kzalloc(sizeof(struct data_urb
), GFP_KERNEL
);
3885 SAM("ERROR: Could not allocate struct data_urb.\n");
3888 peasycap
->allocation_audio_struct
+=
3889 sizeof(struct data_urb
);
3891 pdata_urb
->purb
= purb
;
3892 pdata_urb
->isbuf
= k
;
3893 pdata_urb
->length
= 0;
3894 list_add_tail(&(pdata_urb
->list_head
),
3895 peasycap
->purb_audio_head
);
3896 /*---------------------------------------------------------------------------*/
3898 * ... AND INITIALIZE THEM
3900 /*---------------------------------------------------------------------------*/
3902 JOM(4, "initializing audio urbs thus:\n");
3903 JOM(4, " purb->interval = 1;\n");
3904 JOM(4, " purb->dev = peasycap->pusb_device;\n");
3905 JOM(4, " purb->pipe = usb_rcvisocpipe(peasycap->"
3906 "pusb_device,%i);\n",
3907 peasycap
->audio_endpointnumber
);
3908 JOM(4, " purb->transfer_flags = URB_ISO_ASAP;\n");
3909 JOM(4, " purb->transfer_buffer = "
3910 "peasycap->audio_isoc_buffer[.].pgo;\n");
3911 JOM(4, " purb->transfer_buffer_length = %i;\n",
3912 peasycap
->audio_isoc_buffer_size
);
3913 JOM(4, " purb->complete = easycap_alsa_complete;\n");
3914 JOM(4, " purb->context = peasycap;\n");
3915 JOM(4, " purb->start_frame = 0;\n");
3916 JOM(4, " purb->number_of_packets = %i;\n",
3917 peasycap
->audio_isoc_framesperdesc
);
3918 JOM(4, " for (j = 0; j < %i; j++)\n",
3919 peasycap
->audio_isoc_framesperdesc
);
3921 JOM(4, " purb->iso_frame_desc[j].offset = j*%i;\n",
3922 peasycap
->audio_isoc_maxframesize
);
3923 JOM(4, " purb->iso_frame_desc[j].length = %i;\n",
3924 peasycap
->audio_isoc_maxframesize
);
3929 purb
->dev
= peasycap
->pusb_device
;
3930 purb
->pipe
= usb_rcvisocpipe(peasycap
->pusb_device
,
3931 peasycap
->audio_endpointnumber
);
3932 purb
->transfer_flags
= URB_ISO_ASAP
;
3933 purb
->transfer_buffer
= peasycap
->audio_isoc_buffer
[k
].pgo
;
3934 purb
->transfer_buffer_length
=
3935 peasycap
->audio_isoc_buffer_size
;
3936 purb
->complete
= easycap_alsa_complete
;
3937 purb
->context
= peasycap
;
3938 purb
->start_frame
= 0;
3939 purb
->number_of_packets
= peasycap
->audio_isoc_framesperdesc
;
3940 for (j
= 0; j
< peasycap
->audio_isoc_framesperdesc
; j
++) {
3941 purb
->iso_frame_desc
[j
].offset
= j
*
3942 peasycap
->audio_isoc_maxframesize
;
3943 purb
->iso_frame_desc
[j
].length
=
3944 peasycap
->audio_isoc_maxframesize
;
3947 JOM(4, "allocation of %i struct urb done.\n", k
);
3948 /*---------------------------------------------------------------------------*/
3950 * SAVE POINTER peasycap IN THIS INTERFACE.
3952 /*---------------------------------------------------------------------------*/
3953 usb_set_intfdata(intf
, peasycap
);
3954 /*---------------------------------------------------------------------------*/
3956 * THE AUDIO DEVICE CAN BE REGISTERED NOW, AS IT IS READY.
3958 /*---------------------------------------------------------------------------*/
3959 JOM(4, "initializing ALSA card\n");
3961 rc
= easycap_alsa_probe(peasycap
);
3963 err("easycap_alsa_probe() rc = %i\n", rc
);
3968 JOM(8, "kref_get() with %i=kref.refcount.counter\n",
3969 peasycap
->kref
.refcount
.counter
);
3970 kref_get(&peasycap
->kref
);
3971 peasycap
->registered_audio
++;
3974 /*---------------------------------------------------------------------------*/
3976 * INTERFACES OTHER THAN 0, 1 AND 2 ARE UNEXPECTED
3978 /*---------------------------------------------------------------------------*/
3980 JOM(4, "ERROR: unexpected interface %i\n", bInterfaceNumber
);
3983 SAM("ends successfully for interface %i\n", bInterfaceNumber
);
3986 /*****************************************************************************/
3987 /*---------------------------------------------------------------------------*/
3989 * WHEN THIS FUNCTION IS CALLED THE EasyCAP HAS ALREADY BEEN PHYSICALLY
3990 * UNPLUGGED. HENCE peasycap->pusb_device IS NO LONGER VALID.
3992 * THIS FUNCTION AFFECTS ALSA. BEWARE.
3994 /*---------------------------------------------------------------------------*/
3995 static void easycap_usb_disconnect(struct usb_interface
*pusb_interface
)
3997 struct usb_host_interface
*pusb_host_interface
;
3998 struct usb_interface_descriptor
*pusb_interface_descriptor
;
3999 u8 bInterfaceNumber
;
4000 struct easycap
*peasycap
;
4002 struct list_head
*plist_head
;
4003 struct data_urb
*pdata_urb
;
4008 pusb_host_interface
= pusb_interface
->cur_altsetting
;
4009 if (!pusb_host_interface
) {
4010 JOT(4, "ERROR: pusb_host_interface is NULL\n");
4013 pusb_interface_descriptor
= &(pusb_host_interface
->desc
);
4014 if (!pusb_interface_descriptor
) {
4015 JOT(4, "ERROR: pusb_interface_descriptor is NULL\n");
4018 bInterfaceNumber
= pusb_interface_descriptor
->bInterfaceNumber
;
4019 minor
= pusb_interface
->minor
;
4020 JOT(4, "intf[%i]: minor=%i\n", bInterfaceNumber
, minor
);
4022 if (1 == bInterfaceNumber
)
4025 peasycap
= usb_get_intfdata(pusb_interface
);
4027 SAY("ERROR: peasycap is NULL\n");
4030 /*---------------------------------------------------------------------------*/
4032 * IF THE WAIT QUEUES ARE NOT CLEARED A DEADLOCK IS POSSIBLE. BEWARE.
4034 /*---------------------------------------------------------------------------*/
4035 peasycap
->video_eof
= 1;
4036 peasycap
->audio_eof
= 1;
4037 wake_up_interruptible(&(peasycap
->wq_video
));
4038 wake_up_interruptible(&(peasycap
->wq_audio
));
4039 /*---------------------------------------------------------------------------*/
4040 switch (bInterfaceNumber
) {
4042 if (peasycap
->purb_video_head
) {
4043 JOM(4, "killing video urbs\n");
4045 list_for_each(plist_head
, peasycap
->purb_video_head
) {
4046 pdata_urb
= list_entry(plist_head
,
4047 struct data_urb
, list_head
);
4049 if (pdata_urb
->purb
) {
4050 usb_kill_urb(pdata_urb
->purb
);
4055 JOM(4, "%i video urbs killed\n", m
);
4059 /*---------------------------------------------------------------------------*/
4061 if (peasycap
->purb_audio_head
) {
4062 JOM(4, "killing audio urbs\n");
4064 list_for_each(plist_head
, peasycap
->purb_audio_head
) {
4065 pdata_urb
= list_entry(plist_head
,
4066 struct data_urb
, list_head
);
4068 if (pdata_urb
->purb
) {
4069 usb_kill_urb(pdata_urb
->purb
);
4074 JOM(4, "%i audio urbs killed\n", m
);
4081 /*--------------------------------------------------------------------------*/
4085 * THIS PROCEDURE WILL BLOCK UNTIL easycap_poll(), VIDEO IOCTL AND AUDIO
4086 * IOCTL ARE ALL UNLOCKED. IF THIS IS NOT DONE AN Oops CAN OCCUR WHEN
4087 * AN EasyCAP IS UNPLUGGED WHILE THE URBS ARE RUNNING. BEWARE.
4089 /*--------------------------------------------------------------------------*/
4090 kd
= isdongle(peasycap
);
4091 switch (bInterfaceNumber
) {
4093 if (0 <= kd
&& DONGLE_MANY
> kd
) {
4094 wake_up_interruptible(&peasycap
->wq_video
);
4095 JOM(4, "about to lock dongle[%i].mutex_video\n", kd
);
4096 if (mutex_lock_interruptible(&easycapdc60_dongle
[kd
].
4099 "cannot lock dongle[%i].mutex_video\n", kd
);
4102 JOM(4, "locked dongle[%i].mutex_video\n", kd
);
4104 SAY("ERROR: %i=kd is bad: cannot lock dongle\n", kd
);
4106 /*---------------------------------------------------------------------------*/
4107 if (!peasycap
->v4l2_device
.name
[0]) {
4108 SAM("ERROR: peasycap->v4l2_device.name is empty\n");
4109 if (0 <= kd
&& DONGLE_MANY
> kd
)
4110 mutex_unlock(&easycapdc60_dongle
[kd
].mutex_video
);
4113 v4l2_device_disconnect(&peasycap
->v4l2_device
);
4114 JOM(4, "v4l2_device_disconnect() OK\n");
4115 v4l2_device_unregister(&peasycap
->v4l2_device
);
4116 JOM(4, "v4l2_device_unregister() OK\n");
4118 video_unregister_device(&peasycap
->video_device
);
4119 JOM(4, "intf[%i]: video_unregister_device() minor=%i\n",
4120 bInterfaceNumber
, minor
);
4121 peasycap
->registered_video
--;
4122 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
4124 if (0 <= kd
&& DONGLE_MANY
> kd
) {
4125 mutex_unlock(&easycapdc60_dongle
[kd
].mutex_video
);
4126 JOM(4, "unlocked dongle[%i].mutex_video\n", kd
);
4131 if (0 <= kd
&& DONGLE_MANY
> kd
) {
4132 wake_up_interruptible(&peasycap
->wq_audio
);
4133 JOM(4, "about to lock dongle[%i].mutex_audio\n", kd
);
4134 if (mutex_lock_interruptible(&easycapdc60_dongle
[kd
].
4137 "cannot lock dongle[%i].mutex_audio\n", kd
);
4140 JOM(4, "locked dongle[%i].mutex_audio\n", kd
);
4142 SAY("ERROR: %i=kd is bad: cannot lock dongle\n", kd
);
4143 if (0 != snd_card_free(peasycap
->psnd_card
)) {
4144 SAY("ERROR: snd_card_free() failed\n");
4146 peasycap
->psnd_card
= NULL
;
4147 (peasycap
->registered_audio
)--;
4149 if (0 <= kd
&& DONGLE_MANY
> kd
) {
4150 mutex_unlock(&easycapdc60_dongle
[kd
].mutex_audio
);
4151 JOM(4, "unlocked dongle[%i].mutex_audio\n", kd
);
4158 /*---------------------------------------------------------------------------*/
4160 * CALL easycap_delete() IF NO REMAINING REFERENCES TO peasycap
4161 * (ALSO WHEN ALSA HAS BEEN IN USE)
4163 /*---------------------------------------------------------------------------*/
4164 if (!peasycap
->kref
.refcount
.counter
) {
4165 SAM("ERROR: peasycap->kref.refcount.counter is zero "
4166 "so cannot call kref_put()\n");
4167 SAM("ending unsuccessfully: may cause memory leak\n");
4170 if (0 <= kd
&& DONGLE_MANY
> kd
) {
4171 JOM(4, "about to lock dongle[%i].mutex_video\n", kd
);
4172 if (mutex_lock_interruptible(&easycapdc60_dongle
[kd
].mutex_video
)) {
4173 SAY("ERROR: cannot lock dongle[%i].mutex_video\n", kd
);
4174 SAM("ending unsuccessfully: may cause memory leak\n");
4177 JOM(4, "locked dongle[%i].mutex_video\n", kd
);
4178 JOM(4, "about to lock dongle[%i].mutex_audio\n", kd
);
4179 if (mutex_lock_interruptible(&easycapdc60_dongle
[kd
].mutex_audio
)) {
4180 SAY("ERROR: cannot lock dongle[%i].mutex_audio\n", kd
);
4181 mutex_unlock(&(easycapdc60_dongle
[kd
].mutex_video
));
4182 JOM(4, "unlocked dongle[%i].mutex_video\n", kd
);
4183 SAM("ending unsuccessfully: may cause memory leak\n");
4186 JOM(4, "locked dongle[%i].mutex_audio\n", kd
);
4188 JOM(4, "intf[%i]: %i=peasycap->kref.refcount.counter\n",
4189 bInterfaceNumber
, (int)peasycap
->kref
.refcount
.counter
);
4190 kref_put(&peasycap
->kref
, easycap_delete
);
4191 JOT(4, "intf[%i]: kref_put() done.\n", bInterfaceNumber
);
4192 if (0 <= kd
&& DONGLE_MANY
> kd
) {
4193 mutex_unlock(&(easycapdc60_dongle
[kd
].mutex_audio
));
4194 JOT(4, "unlocked dongle[%i].mutex_audio\n", kd
);
4195 mutex_unlock(&easycapdc60_dongle
[kd
].mutex_video
);
4196 JOT(4, "unlocked dongle[%i].mutex_video\n", kd
);
4198 /*---------------------------------------------------------------------------*/
4202 /*****************************************************************************/
4204 /*---------------------------------------------------------------------------*/
4206 * PARAMETERS APPLICABLE TO ENTIRE DRIVER, I.E. BOTH VIDEO AND AUDIO
4208 /*---------------------------------------------------------------------------*/
4209 static struct usb_device_id easycap_usb_device_id_table
[] = {
4210 {USB_DEVICE(USB_EASYCAP_VENDOR_ID
, USB_EASYCAP_PRODUCT_ID
)},
4214 MODULE_DEVICE_TABLE(usb
, easycap_usb_device_id_table
);
4215 struct usb_driver easycap_usb_driver
= {
4217 .id_table
= easycap_usb_device_id_table
,
4218 .probe
= easycap_usb_probe
,
4219 .disconnect
= easycap_usb_disconnect
,
4222 static int __init
easycap_module_init(void)
4226 printk(KERN_INFO
"Easycap version: "EASYCAP_DRIVER_VERSION
"\n");
4228 JOT(4, "begins. %i=debug %i=bars %i=gain\n",
4229 easycap_debug
, easycap_bars
, easycap_gain
);
4231 mutex_init(&mutex_dongle
);
4232 for (k
= 0; k
< DONGLE_MANY
; k
++) {
4233 easycapdc60_dongle
[k
].peasycap
= NULL
;
4234 mutex_init(&easycapdc60_dongle
[k
].mutex_video
);
4235 mutex_init(&easycapdc60_dongle
[k
].mutex_audio
);
4237 rc
= usb_register(&easycap_usb_driver
);
4239 printk(KERN_ERR
"Easycap: usb_register failed rc=%d\n", rc
);
4243 /*****************************************************************************/
4244 static void __exit
easycap_module_exit(void)
4246 usb_deregister(&easycap_usb_driver
);
4248 /*****************************************************************************/
4250 module_init(easycap_module_init
);
4251 module_exit(easycap_module_exit
);
4253 /*****************************************************************************/