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
, "NTCS 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 do_gettimeofday(&peasycap
->timeval7
);
274 /*---------------------------------------------------------------------------*/
276 * RESTORE INPUT AND FORCE REFRESH OF STANDARD, FORMAT, ETC.
278 * WHILE THIS PROCEDURE IS IN PROGRESS, SOME IOCTL COMMANDS WILL RETURN -EBUSY.
280 /*---------------------------------------------------------------------------*/
281 peasycap
->input
= -8192;
282 peasycap
->standard_offset
= -8192;
283 fmtidx
= ntsc
? NTSC_M
: PAL_BGHIN
;
285 peasycap_standard
= &easycap_standard
[0];
286 while (0xFFFF != peasycap_standard
->mask
) {
287 if (fmtidx
== peasycap_standard
->v4l2_standard
.index
) {
288 peasycap
->inputset
[input
].standard_offset
=
289 peasycap_standard
- easycap_standard
;
294 if (0xFFFF == peasycap_standard
->mask
) {
295 SAM("ERROR: standard not found\n");
298 JOM(8, "%i=peasycap->inputset[%i].standard_offset\n",
299 peasycap
->inputset
[input
].standard_offset
, input
);
301 peasycap
->format_offset
= -8192;
302 peasycap
->brightness
= -8192;
303 peasycap
->contrast
= -8192;
304 peasycap
->saturation
= -8192;
305 peasycap
->hue
= -8192;
307 rc
= newinput(peasycap
, input
);
310 SAM("ERROR: newinput(.,%i) rc = %i\n", rc
, input
);
313 JOM(4, "restored input, standard and format\n");
315 JOM(8, "true=peasycap->ntsc %d\n", peasycap
->ntsc
);
317 if (0 > peasycap
->input
) {
318 SAM("MISTAKE: %i=peasycap->input\n", peasycap
->input
);
321 if (0 > peasycap
->standard_offset
) {
322 SAM("MISTAKE: %i=peasycap->standard_offset\n",
323 peasycap
->standard_offset
);
326 if (0 > peasycap
->format_offset
) {
327 SAM("MISTAKE: %i=peasycap->format_offset\n",
328 peasycap
->format_offset
);
331 if (0 > peasycap
->brightness
) {
332 SAM("MISTAKE: %i=peasycap->brightness\n",
333 peasycap
->brightness
);
336 if (0 > peasycap
->contrast
) {
337 SAM("MISTAKE: %i=peasycap->contrast\n", peasycap
->contrast
);
340 if (0 > peasycap
->saturation
) {
341 SAM("MISTAKE: %i=peasycap->saturation\n",
342 peasycap
->saturation
);
345 if (0 > peasycap
->hue
) {
346 SAM("MISTAKE: %i=peasycap->hue\n", peasycap
->hue
);
351 /*****************************************************************************/
352 /*---------------------------------------------------------------------------*/
354 * IF THE REQUESTED INPUT IS THE SAME AS THE EXISTING INPUT, DO NOTHING.
356 * KILL URBS, CLEAR FIELD AND FRAME BUFFERS AND RESET THEIR
357 * _read AND _fill POINTERS.
358 * SELECT THE NEW INPUT.
359 * ADJUST THE STANDARD, FORMAT, BRIGHTNESS, CONTRAST, SATURATION AND HUE
360 * ON THE BASIS OF INFORMATION IN STRUCTURE easycap.inputset[input].
361 * RESUBMIT THE URBS IF STREAMING WAS ALREADY IN PROGRESS.
364 * THIS ROUTINE MAY BE CALLED FREQUENTLY BY ZONEMINDER VIA IOCTL,
365 * SO IT SHOULD WRITE ONLY SPARINGLY TO THE LOGFILE.
367 /*---------------------------------------------------------------------------*/
369 newinput(struct easycap
*peasycap
, int input
)
371 int rc
, k
, m
, mood
, off
;
372 int inputnow
, video_idlenow
, audio_idlenow
;
376 SAY("ERROR: peasycap is NULL\n");
379 JOM(8, "%i=input sought\n", input
);
381 if (0 > input
&& INPUT_MANY
<= input
)
383 inputnow
= peasycap
->input
;
384 if (input
== inputnow
)
386 /*---------------------------------------------------------------------------*/
388 * IF STREAMING IS IN PROGRESS THE URBS ARE KILLED AT THIS
389 * STAGE AND WILL BE RESUBMITTED PRIOR TO EXIT FROM THE ROUTINE.
390 * IF NO STREAMING IS IN PROGRESS NO URBS WILL BE SUBMITTED BY THE
393 /*---------------------------------------------------------------------------*/
394 video_idlenow
= peasycap
->video_idle
;
395 audio_idlenow
= peasycap
->audio_idle
;
397 peasycap
->video_idle
= 1;
398 peasycap
->audio_idle
= 1;
399 if (peasycap
->video_isoc_streaming
) {
401 kill_video_urbs(peasycap
);
405 /*---------------------------------------------------------------------------*/
406 if (!peasycap
->pusb_device
) {
407 SAM("ERROR: peasycap->pusb_device is NULL\n");
410 rc
= usb_set_interface(peasycap
->pusb_device
,
411 peasycap
->video_interface
,
412 peasycap
->video_altsetting_off
);
414 SAM("ERROR: usb_set_interface() rc = %i\n", rc
);
417 rc
= stop_100(peasycap
->pusb_device
);
419 SAM("ERROR: stop_100() rc = %i\n", rc
);
422 for (k
= 0; k
< FIELD_BUFFER_MANY
; k
++) {
423 for (m
= 0; m
< FIELD_BUFFER_SIZE
/PAGE_SIZE
; m
++)
424 memset(peasycap
->field_buffer
[k
][m
].pgo
, 0, PAGE_SIZE
);
426 for (k
= 0; k
< FRAME_BUFFER_MANY
; k
++) {
427 for (m
= 0; m
< FRAME_BUFFER_SIZE
/PAGE_SIZE
; m
++)
428 memset(peasycap
->frame_buffer
[k
][m
].pgo
, 0, PAGE_SIZE
);
430 peasycap
->field_page
= 0;
431 peasycap
->field_read
= 0;
432 peasycap
->field_fill
= 0;
434 peasycap
->frame_read
= 0;
435 peasycap
->frame_fill
= 0;
436 for (k
= 0; k
< peasycap
->input
; k
++) {
437 (peasycap
->frame_fill
)++;
438 if (peasycap
->frame_buffer_many
<= peasycap
->frame_fill
)
439 peasycap
->frame_fill
= 0;
441 peasycap
->input
= input
;
442 select_input(peasycap
->pusb_device
, peasycap
->input
, 9);
443 /*---------------------------------------------------------------------------*/
444 if (input
== peasycap
->inputset
[input
].input
) {
445 off
= peasycap
->inputset
[input
].standard_offset
;
446 if (off
!= peasycap
->standard_offset
) {
447 rc
= adjust_standard(peasycap
,
448 easycap_standard
[off
].v4l2_standard
.id
);
450 SAM("ERROR: adjust_standard() rc = %i\n", rc
);
453 JOM(8, "%i=peasycap->standard_offset\n",
454 peasycap
->standard_offset
);
456 JOM(8, "%i=peasycap->standard_offset unchanged\n",
457 peasycap
->standard_offset
);
459 off
= peasycap
->inputset
[input
].format_offset
;
460 if (off
!= peasycap
->format_offset
) {
461 struct v4l2_pix_format
*pix
=
462 &easycap_format
[off
].v4l2_format
.fmt
.pix
;
463 rc
= adjust_format(peasycap
,
464 pix
->width
, pix
->height
,
465 pix
->pixelformat
, pix
->field
, false);
467 SAM("ERROR: adjust_format() rc = %i\n", rc
);
470 JOM(8, "%i=peasycap->format_offset\n",
471 peasycap
->format_offset
);
473 JOM(8, "%i=peasycap->format_offset unchanged\n",
474 peasycap
->format_offset
);
476 mood
= peasycap
->inputset
[input
].brightness
;
477 if (mood
!= peasycap
->brightness
) {
478 rc
= adjust_brightness(peasycap
, mood
);
480 SAM("ERROR: adjust_brightness rc = %i\n", rc
);
483 JOM(8, "%i=peasycap->brightness\n",
484 peasycap
->brightness
);
486 mood
= peasycap
->inputset
[input
].contrast
;
487 if (mood
!= peasycap
->contrast
) {
488 rc
= adjust_contrast(peasycap
, mood
);
490 SAM("ERROR: adjust_contrast rc = %i\n", rc
);
493 JOM(8, "%i=peasycap->contrast\n", peasycap
->contrast
);
495 mood
= peasycap
->inputset
[input
].saturation
;
496 if (mood
!= peasycap
->saturation
) {
497 rc
= adjust_saturation(peasycap
, mood
);
499 SAM("ERROR: adjust_saturation rc = %i\n", rc
);
502 JOM(8, "%i=peasycap->saturation\n",
503 peasycap
->saturation
);
505 mood
= peasycap
->inputset
[input
].hue
;
506 if (mood
!= peasycap
->hue
) {
507 rc
= adjust_hue(peasycap
, mood
);
509 SAM("ERROR: adjust_hue rc = %i\n", rc
);
512 JOM(8, "%i=peasycap->hue\n", peasycap
->hue
);
515 SAM("MISTAKE: easycap.inputset[%i] unpopulated\n", input
);
518 /*---------------------------------------------------------------------------*/
519 if (!peasycap
->pusb_device
) {
520 SAM("ERROR: peasycap->pusb_device is NULL\n");
523 rc
= usb_set_interface(peasycap
->pusb_device
,
524 peasycap
->video_interface
,
525 peasycap
->video_altsetting_on
);
527 SAM("ERROR: usb_set_interface() rc = %i\n", rc
);
530 rc
= start_100(peasycap
->pusb_device
);
532 SAM("ERROR: start_100() rc = %i\n", rc
);
536 submit_video_urbs(peasycap
);
538 peasycap
->video_isoc_sequence
= VIDEO_ISOC_BUFFER_MANY
- 1;
539 peasycap
->video_idle
= video_idlenow
;
540 peasycap
->audio_idle
= audio_idlenow
;
541 peasycap
->video_junk
= 0;
545 /*****************************************************************************/
546 int submit_video_urbs(struct easycap
*peasycap
)
548 struct data_urb
*pdata_urb
;
550 struct list_head
*plist_head
;
551 int j
, isbad
, nospc
, m
, rc
;
555 SAY("ERROR: peasycap is NULL\n");
559 if (!peasycap
->purb_video_head
) {
560 SAY("ERROR: peasycap->urb_video_head uninitialized\n");
563 if (!peasycap
->pusb_device
) {
564 SAY("ERROR: peasycap->pusb_device is NULL\n");
567 if (!peasycap
->video_isoc_streaming
) {
568 JOM(4, "submission of all video urbs\n");
569 isbad
= 0; nospc
= 0; m
= 0;
570 list_for_each(plist_head
, (peasycap
->purb_video_head
)) {
571 pdata_urb
= list_entry(plist_head
,
572 struct data_urb
, list_head
);
573 if (pdata_urb
&& pdata_urb
->purb
) {
574 purb
= pdata_urb
->purb
;
575 isbuf
= pdata_urb
->isbuf
;
577 purb
->dev
= peasycap
->pusb_device
;
579 usb_rcvisocpipe(peasycap
->pusb_device
,
580 peasycap
->video_endpointnumber
);
581 purb
->transfer_flags
= URB_ISO_ASAP
;
582 purb
->transfer_buffer
=
583 peasycap
->video_isoc_buffer
[isbuf
].pgo
;
584 purb
->transfer_buffer_length
=
585 peasycap
->video_isoc_buffer_size
;
586 purb
->complete
= easycap_complete
;
587 purb
->context
= peasycap
;
588 purb
->start_frame
= 0;
589 purb
->number_of_packets
=
590 peasycap
->video_isoc_framesperdesc
;
592 for (j
= 0; j
< peasycap
->video_isoc_framesperdesc
; j
++) {
593 purb
->iso_frame_desc
[j
]. offset
=
594 j
* peasycap
->video_isoc_maxframesize
;
595 purb
->iso_frame_desc
[j
]. length
=
596 peasycap
->video_isoc_maxframesize
;
599 rc
= usb_submit_urb(purb
, GFP_KERNEL
);
602 SAM("ERROR: usb_submit_urb() failed "
603 "for urb with rc:-%s\n",
615 SAM("-ENOSPC=usb_submit_urb() for %i urbs\n", nospc
);
616 SAM("..... possibly inadequate USB bandwidth\n");
617 peasycap
->video_eof
= 1;
621 JOM(4, "attempting cleanup instead of submitting\n");
622 list_for_each(plist_head
, (peasycap
->purb_video_head
)) {
623 pdata_urb
= list_entry(plist_head
,
624 struct data_urb
, list_head
);
626 purb
= pdata_urb
->purb
;
631 peasycap
->video_isoc_streaming
= 0;
633 peasycap
->video_isoc_streaming
= 1;
634 JOM(4, "submitted %i video urbs\n", m
);
637 JOM(4, "already streaming video urbs\n");
641 /*****************************************************************************/
642 int kill_video_urbs(struct easycap
*peasycap
)
645 struct list_head
*plist_head
;
646 struct data_urb
*pdata_urb
;
649 SAY("ERROR: peasycap is NULL\n");
652 if (!peasycap
->video_isoc_streaming
) {
653 JOM(8, "%i=video_isoc_streaming, no video urbs killed\n",
654 peasycap
->video_isoc_streaming
);
657 if (!peasycap
->purb_video_head
) {
658 SAM("ERROR: peasycap->purb_video_head is NULL\n");
662 peasycap
->video_isoc_streaming
= 0;
663 JOM(4, "killing video urbs\n");
665 list_for_each(plist_head
, (peasycap
->purb_video_head
)) {
666 pdata_urb
= list_entry(plist_head
, struct data_urb
, list_head
);
667 if (pdata_urb
&& pdata_urb
->purb
) {
668 usb_kill_urb(pdata_urb
->purb
);
672 JOM(4, "%i video urbs killed\n", m
);
676 /****************************************************************************/
677 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
678 /*--------------------------------------------------------------------------*/
679 static int easycap_open_noinode(struct file
*file
)
681 return easycap_open(NULL
, file
);
684 static int videodev_release(struct video_device
*pvideo_device
)
686 struct easycap
*peasycap
;
688 peasycap
= video_get_drvdata(pvideo_device
);
690 SAY("ERROR: peasycap is NULL\n");
691 SAY("ending unsuccessfully\n");
694 if (0 != kill_video_urbs(peasycap
)) {
695 SAM("ERROR: kill_video_urbs() failed\n");
698 JOM(4, "ending successfully\n");
701 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
702 /*****************************************************************************/
703 /*--------------------------------------------------------------------------*/
705 * THIS FUNCTION IS CALLED FROM WITHIN easycap_usb_disconnect() AND IS
706 * PROTECTED BY SEMAPHORES SET AND CLEARED BY easycap_usb_disconnect().
708 * BY THIS STAGE THE DEVICE HAS ALREADY BEEN PHYSICALLY UNPLUGGED, SO
709 * peasycap->pusb_device IS NO LONGER VALID.
711 /*---------------------------------------------------------------------------*/
712 static void easycap_delete(struct kref
*pkref
)
714 struct easycap
*peasycap
;
715 struct data_urb
*pdata_urb
;
716 struct list_head
*plist_head
, *plist_next
;
718 int allocation_video_urb
;
719 int allocation_video_page
;
720 int allocation_video_struct
;
721 int allocation_audio_urb
;
722 int allocation_audio_page
;
723 int allocation_audio_struct
;
724 int registered_video
, registered_audio
;
726 peasycap
= container_of(pkref
, struct easycap
, kref
);
728 SAM("ERROR: peasycap is NULL: cannot perform deletions\n");
731 kd
= isdongle(peasycap
);
732 /*---------------------------------------------------------------------------*/
736 /*---------------------------------------------------------------------------*/
737 if (peasycap
->purb_video_head
) {
738 JOM(4, "freeing video urbs\n");
740 list_for_each(plist_head
, (peasycap
->purb_video_head
)) {
741 pdata_urb
= list_entry(plist_head
,
742 struct data_urb
, list_head
);
744 JOM(4, "ERROR: pdata_urb is NULL\n");
746 if (pdata_urb
->purb
) {
747 usb_free_urb(pdata_urb
->purb
);
748 pdata_urb
->purb
= NULL
;
749 peasycap
->allocation_video_urb
-= 1;
755 JOM(4, "%i video urbs freed\n", m
);
756 /*---------------------------------------------------------------------------*/
757 JOM(4, "freeing video data_urb structures.\n");
759 list_for_each_safe(plist_head
, plist_next
,
760 peasycap
->purb_video_head
) {
761 pdata_urb
= list_entry(plist_head
,
762 struct data_urb
, list_head
);
764 peasycap
->allocation_video_struct
-=
765 sizeof(struct data_urb
);
771 JOM(4, "%i video data_urb structures freed\n", m
);
772 JOM(4, "setting peasycap->purb_video_head=NULL\n");
773 peasycap
->purb_video_head
= NULL
;
775 /*---------------------------------------------------------------------------*/
776 JOM(4, "freeing video isoc buffers.\n");
778 for (k
= 0; k
< VIDEO_ISOC_BUFFER_MANY
; k
++) {
779 if (peasycap
->video_isoc_buffer
[k
].pgo
) {
780 free_pages((unsigned long)
781 peasycap
->video_isoc_buffer
[k
].pgo
,
783 peasycap
->video_isoc_buffer
[k
].pgo
= NULL
;
784 peasycap
->allocation_video_page
-=
785 BIT(VIDEO_ISOC_ORDER
);
789 JOM(4, "isoc video buffers freed: %i pages\n",
790 m
* (0x01 << VIDEO_ISOC_ORDER
));
791 /*---------------------------------------------------------------------------*/
792 JOM(4, "freeing video field buffers.\n");
794 for (k
= 0; k
< FIELD_BUFFER_MANY
; k
++) {
795 for (m
= 0; m
< FIELD_BUFFER_SIZE
/PAGE_SIZE
; m
++) {
796 if (peasycap
->field_buffer
[k
][m
].pgo
) {
797 free_page((unsigned long)
798 peasycap
->field_buffer
[k
][m
].pgo
);
799 peasycap
->field_buffer
[k
][m
].pgo
= NULL
;
800 peasycap
->allocation_video_page
-= 1;
805 JOM(4, "video field buffers freed: %i pages\n", gone
);
806 /*---------------------------------------------------------------------------*/
807 JOM(4, "freeing video frame buffers.\n");
809 for (k
= 0; k
< FRAME_BUFFER_MANY
; k
++) {
810 for (m
= 0; m
< FRAME_BUFFER_SIZE
/PAGE_SIZE
; m
++) {
811 if (peasycap
->frame_buffer
[k
][m
].pgo
) {
812 free_page((unsigned long)
813 peasycap
->frame_buffer
[k
][m
].pgo
);
814 peasycap
->frame_buffer
[k
][m
].pgo
= NULL
;
815 peasycap
->allocation_video_page
-= 1;
820 JOM(4, "video frame buffers freed: %i pages\n", gone
);
821 /*---------------------------------------------------------------------------*/
825 /*---------------------------------------------------------------------------*/
826 if (peasycap
->purb_audio_head
) {
827 JOM(4, "freeing audio urbs\n");
829 list_for_each(plist_head
, (peasycap
->purb_audio_head
)) {
830 pdata_urb
= list_entry(plist_head
,
831 struct data_urb
, list_head
);
833 JOM(4, "ERROR: pdata_urb is NULL\n");
835 if (pdata_urb
->purb
) {
836 usb_free_urb(pdata_urb
->purb
);
837 pdata_urb
->purb
= NULL
;
838 peasycap
->allocation_audio_urb
-= 1;
843 JOM(4, "%i audio urbs freed\n", m
);
844 /*---------------------------------------------------------------------------*/
845 JOM(4, "freeing audio data_urb structures.\n");
847 list_for_each_safe(plist_head
, plist_next
,
848 peasycap
->purb_audio_head
) {
849 pdata_urb
= list_entry(plist_head
,
850 struct data_urb
, list_head
);
852 peasycap
->allocation_audio_struct
-=
853 sizeof(struct data_urb
);
859 JOM(4, "%i audio data_urb structures freed\n", m
);
860 JOM(4, "setting peasycap->purb_audio_head=NULL\n");
861 peasycap
->purb_audio_head
= NULL
;
863 /*---------------------------------------------------------------------------*/
864 JOM(4, "freeing audio isoc buffers.\n");
866 for (k
= 0; k
< AUDIO_ISOC_BUFFER_MANY
; k
++) {
867 if (peasycap
->audio_isoc_buffer
[k
].pgo
) {
868 free_pages((unsigned long)
869 (peasycap
->audio_isoc_buffer
[k
].pgo
),
871 peasycap
->audio_isoc_buffer
[k
].pgo
= NULL
;
872 peasycap
->allocation_audio_page
-=
873 BIT(AUDIO_ISOC_ORDER
);
877 JOM(4, "easyoss_delete(): isoc audio buffers freed: %i pages\n",
878 m
* (0x01 << AUDIO_ISOC_ORDER
));
879 /*---------------------------------------------------------------------------*/
880 JOM(4, "freeing easycap structure.\n");
881 allocation_video_urb
= peasycap
->allocation_video_urb
;
882 allocation_video_page
= peasycap
->allocation_video_page
;
883 allocation_video_struct
= peasycap
->allocation_video_struct
;
884 registered_video
= peasycap
->registered_video
;
885 allocation_audio_urb
= peasycap
->allocation_audio_urb
;
886 allocation_audio_page
= peasycap
->allocation_audio_page
;
887 allocation_audio_struct
= peasycap
->allocation_audio_struct
;
888 registered_audio
= peasycap
->registered_audio
;
890 if (0 <= kd
&& DONGLE_MANY
> kd
) {
891 if (mutex_lock_interruptible(&mutex_dongle
)) {
892 SAY("ERROR: cannot down mutex_dongle\n");
894 JOM(4, "locked mutex_dongle\n");
895 easycapdc60_dongle
[kd
].peasycap
= NULL
;
896 mutex_unlock(&mutex_dongle
);
897 JOM(4, "unlocked mutex_dongle\n");
898 JOT(4, " null-->dongle[%i].peasycap\n", kd
);
899 allocation_video_struct
-= sizeof(struct easycap
);
902 SAY("ERROR: cannot purge dongle[].peasycap");
907 /*---------------------------------------------------------------------------*/
908 SAY("%8i=video urbs after all deletions\n", allocation_video_urb
);
909 SAY("%8i=video pages after all deletions\n", allocation_video_page
);
910 SAY("%8i=video structs after all deletions\n", allocation_video_struct
);
911 SAY("%8i=video devices after all deletions\n", registered_video
);
912 SAY("%8i=audio urbs after all deletions\n", allocation_audio_urb
);
913 SAY("%8i=audio pages after all deletions\n", allocation_audio_page
);
914 SAY("%8i=audio structs after all deletions\n", allocation_audio_struct
);
915 SAY("%8i=audio devices after all deletions\n", registered_audio
);
920 /*****************************************************************************/
921 static unsigned int easycap_poll(struct file
*file
, poll_table
*wait
)
923 struct easycap
*peasycap
;
928 if (NULL
== ((poll_table
*)wait
))
929 JOT(8, "WARNING: poll table pointer is NULL ... continuing\n");
931 SAY("ERROR: file pointer is NULL\n");
934 peasycap
= file
->private_data
;
936 SAY("ERROR: peasycap is NULL\n");
939 if (!peasycap
->pusb_device
) {
940 SAY("ERROR: peasycap->pusb_device is NULL\n");
943 /*---------------------------------------------------------------------------*/
944 kd
= isdongle(peasycap
);
945 if (0 <= kd
&& DONGLE_MANY
> kd
) {
946 if (mutex_lock_interruptible(&easycapdc60_dongle
[kd
].mutex_video
)) {
947 SAY("ERROR: cannot down dongle[%i].mutex_video\n", kd
);
950 JOM(4, "locked dongle[%i].mutex_video\n", kd
);
952 * MEANWHILE, easycap_usb_disconnect() MAY HAVE FREED POINTER
953 * peasycap, IN WHICH CASE A REPEAT CALL TO isdongle() WILL FAIL.
954 * IF NECESSARY, BAIL OUT.
956 if (kd
!= isdongle(peasycap
)) {
957 mutex_unlock(&easycapdc60_dongle
[kd
].mutex_video
);
961 SAY("ERROR: file is NULL\n");
962 mutex_unlock(&easycapdc60_dongle
[kd
].mutex_video
);
965 peasycap
= file
->private_data
;
967 SAY("ERROR: peasycap is NULL\n");
968 mutex_unlock(&easycapdc60_dongle
[kd
].mutex_video
);
971 if (!peasycap
->pusb_device
) {
972 SAM("ERROR: peasycap->pusb_device is NULL\n");
973 mutex_unlock(&easycapdc60_dongle
[kd
].mutex_video
);
978 * IF easycap_usb_disconnect() HAS ALREADY FREED POINTER peasycap
979 * BEFORE THE ATTEMPT TO ACQUIRE THE SEMAPHORE, isdongle() WILL
980 * HAVE FAILED. BAIL OUT.
983 /*---------------------------------------------------------------------------*/
984 rc
= easycap_dqbuf(peasycap
, 0);
985 peasycap
->polled
= 1;
986 mutex_unlock(&easycapdc60_dongle
[kd
].mutex_video
);
988 return POLLIN
| POLLRDNORM
;
992 /*****************************************************************************/
993 /*---------------------------------------------------------------------------*/
995 * IF mode IS NONZERO THIS ROUTINE RETURNS -EAGAIN RATHER THAN BLOCKING.
997 /*---------------------------------------------------------------------------*/
998 int easycap_dqbuf(struct easycap
*peasycap
, int mode
)
1000 int input
, ifield
, miss
, rc
;
1004 SAY("ERROR: peasycap is NULL\n");
1007 if (!peasycap
->pusb_device
) {
1008 SAY("ERROR: peasycap->pusb_device is NULL\n");
1012 JOM(8, "%i=ifield\n", ifield
);
1013 /*---------------------------------------------------------------------------*/
1015 * CHECK FOR LOST INPUT SIGNAL.
1017 * FOR THE FOUR-CVBS EasyCAP, THIS DOES NOT WORK AS EXPECTED.
1018 * IF INPUT 0 IS PRESENT AND SYNC ACQUIRED, UNPLUGGING INPUT 4 DOES NOT
1019 * RESULT IN SETTING BIT 0x40 ON REGISTER 0x1F, PRESUMABLY BECAUSE THERE
1020 * IS FLYWHEELING ON INPUT 0. THE UPSHOT IS:
1022 * INPUT 0 PLUGGED, INPUT 4 PLUGGED => SCREEN 0 OK, SCREEN 4 OK
1023 * INPUT 0 PLUGGED, INPUT 4 UNPLUGGED => SCREEN 0 OK, SCREEN 4 BLACK
1024 * INPUT 0 UNPLUGGED, INPUT 4 PLUGGED => SCREEN 0 BARS, SCREEN 4 OK
1025 * INPUT 0 UNPLUGGED, INPUT 4 UNPLUGGED => SCREEN 0 BARS, SCREEN 4 BARS
1027 /*---------------------------------------------------------------------------*/
1028 input
= peasycap
->input
;
1029 if (0 <= input
&& INPUT_MANY
> input
) {
1030 rc
= read_saa(peasycap
->pusb_device
, 0x1F);
1033 peasycap
->lost
[input
] += 1;
1035 peasycap
->lost
[input
] -= 2;
1037 if (0 > peasycap
->lost
[input
])
1038 peasycap
->lost
[input
] = 0;
1039 else if ((2 * VIDEO_LOST_TOLERATE
) < peasycap
->lost
[input
])
1040 peasycap
->lost
[input
] = (2 * VIDEO_LOST_TOLERATE
);
1043 /*---------------------------------------------------------------------------*/
1045 * WAIT FOR FIELD ifield (0 => TOP, 1 => BOTTOM)
1047 /*---------------------------------------------------------------------------*/
1049 while ((peasycap
->field_read
== peasycap
->field_fill
) ||
1050 (0 != (0xFF00 & peasycap
->field_buffer
1051 [peasycap
->field_read
][0].kount
)) ||
1052 (ifield
!= (0x00FF & peasycap
->field_buffer
1053 [peasycap
->field_read
][0].kount
))) {
1057 JOM(8, "first wait on wq_video, %i=field_read %i=field_fill\n",
1058 peasycap
->field_read
, peasycap
->field_fill
);
1060 if (0 != (wait_event_interruptible(peasycap
->wq_video
,
1061 (peasycap
->video_idle
|| peasycap
->video_eof
||
1062 ((peasycap
->field_read
!= peasycap
->field_fill
) &&
1063 (0 == (0xFF00 & peasycap
->field_buffer
[peasycap
->field_read
][0].kount
)) &&
1064 (ifield
== (0x00FF & peasycap
->field_buffer
[peasycap
->field_read
][0].kount
))))))) {
1065 SAM("aborted by signal\n");
1068 if (peasycap
->video_idle
) {
1069 JOM(8, "%i=peasycap->video_idle returning -EAGAIN\n",
1070 peasycap
->video_idle
);
1073 if (peasycap
->video_eof
) {
1074 JOM(8, "%i=peasycap->video_eof\n", peasycap
->video_eof
);
1075 #if defined(PERSEVERE)
1076 if (1 == peasycap
->status
) {
1077 JOM(8, "persevering ...\n");
1078 peasycap
->video_eof
= 0;
1079 peasycap
->audio_eof
= 0;
1080 if (0 != reset(peasycap
)) {
1081 JOM(8, " ... failed returning -EIO\n");
1082 peasycap
->video_eof
= 1;
1083 peasycap
->audio_eof
= 1;
1084 kill_video_urbs(peasycap
);
1087 peasycap
->status
= 0;
1088 JOM(8, " ... OK returning -EAGAIN\n");
1091 #endif /*PERSEVERE*/
1092 peasycap
->video_eof
= 1;
1093 peasycap
->audio_eof
= 1;
1094 kill_video_urbs(peasycap
);
1095 JOM(8, "returning -EIO\n");
1100 JOM(8, "first awakening on wq_video after %i waits\n", miss
);
1102 rc
= field2frame(peasycap
);
1104 SAM("ERROR: field2frame() rc = %i\n", rc
);
1105 /*---------------------------------------------------------------------------*/
1107 * WAIT FOR THE OTHER FIELD
1109 /*---------------------------------------------------------------------------*/
1115 while ((peasycap
->field_read
== peasycap
->field_fill
) ||
1116 (0 != (0xFF00 & peasycap
->field_buffer
[peasycap
->field_read
][0].kount
)) ||
1117 (ifield
!= (0x00FF & peasycap
->field_buffer
[peasycap
->field_read
][0].kount
))) {
1121 JOM(8, "second wait on wq_video %i=field_read %i=field_fill\n",
1122 peasycap
->field_read
, peasycap
->field_fill
);
1123 if (0 != (wait_event_interruptible(peasycap
->wq_video
,
1124 (peasycap
->video_idle
|| peasycap
->video_eof
||
1125 ((peasycap
->field_read
!= peasycap
->field_fill
) &&
1126 (0 == (0xFF00 & peasycap
->field_buffer
[peasycap
->field_read
][0].kount
)) &&
1127 (ifield
== (0x00FF & peasycap
->field_buffer
[peasycap
->field_read
][0].kount
))))))) {
1128 SAM("aborted by signal\n");
1131 if (peasycap
->video_idle
) {
1132 JOM(8, "%i=peasycap->video_idle returning -EAGAIN\n",
1133 peasycap
->video_idle
);
1136 if (peasycap
->video_eof
) {
1137 JOM(8, "%i=peasycap->video_eof\n", peasycap
->video_eof
);
1138 #if defined(PERSEVERE)
1139 if (1 == peasycap
->status
) {
1140 JOM(8, "persevering ...\n");
1141 peasycap
->video_eof
= 0;
1142 peasycap
->audio_eof
= 0;
1143 if (0 != reset(peasycap
)) {
1144 JOM(8, " ... failed returning -EIO\n");
1145 peasycap
->video_eof
= 1;
1146 peasycap
->audio_eof
= 1;
1147 kill_video_urbs(peasycap
);
1150 peasycap
->status
= 0;
1151 JOM(8, " ... OK ... returning -EAGAIN\n");
1154 #endif /*PERSEVERE*/
1155 peasycap
->video_eof
= 1;
1156 peasycap
->audio_eof
= 1;
1157 kill_video_urbs(peasycap
);
1158 JOM(8, "returning -EIO\n");
1163 JOM(8, "second awakening on wq_video after %i waits\n", miss
);
1165 rc
= field2frame(peasycap
);
1167 SAM("ERROR: field2frame() rc = %i\n", rc
);
1168 /*---------------------------------------------------------------------------*/
1172 /*---------------------------------------------------------------------------*/
1173 if (peasycap
->skip
) {
1174 peasycap
->skipped
++;
1175 if (peasycap
->skip
!= peasycap
->skipped
)
1176 return peasycap
->skip
- peasycap
->skipped
;
1178 peasycap
->skipped
= 0;
1180 /*---------------------------------------------------------------------------*/
1181 peasycap
->frame_read
= peasycap
->frame_fill
;
1182 peasycap
->queued
[peasycap
->frame_read
] = 0;
1183 peasycap
->done
[peasycap
->frame_read
] = V4L2_BUF_FLAG_DONE
;
1185 peasycap
->frame_fill
++;
1186 if (peasycap
->frame_buffer_many
<= peasycap
->frame_fill
)
1187 peasycap
->frame_fill
= 0;
1189 if (0x01 & easycap_standard
[peasycap
->standard_offset
].mask
)
1190 peasycap
->frame_buffer
[peasycap
->frame_read
][0].kount
=
1193 peasycap
->frame_buffer
[peasycap
->frame_read
][0].kount
=
1197 JOM(8, "setting: %i=peasycap->frame_read\n", peasycap
->frame_read
);
1198 JOM(8, "bumped to: %i=peasycap->frame_fill\n", peasycap
->frame_fill
);
1202 /*****************************************************************************/
1203 /*---------------------------------------------------------------------------*/
1205 * BY DEFINITION, odd IS true FOR THE FIELD OCCUPYING LINES 1,3,5,...,479
1206 * odd IS false FOR THE FIELD OCCUPYING LINES 0,2,4,...,478
1208 * WHEN BOOLEAN PARAMETER decimatepixel IS true, ONLY THE FIELD FOR WHICH
1209 * odd==false IS TRANSFERRED TO THE FRAME BUFFER.
1211 * THE BOOLEAN PARAMETER offerfields IS true ONLY WHEN THE USER PROGRAM
1212 * CHOOSES THE OPTION V4L2_FIELD_INTERLACED.
1214 /*---------------------------------------------------------------------------*/
1216 field2frame(struct easycap
*peasycap
)
1218 struct timeval timeval
;
1219 long long int above
, below
;
1221 struct signed_div_result sdr
;
1224 int kex
, kad
, mex
, mad
, rex
, rad
, rad2
;
1225 int c2
, c3
, w2
, w3
, cz
, wz
;
1226 int rc
, bytesperpixel
, multiplier
;
1227 int much
, more
, over
, rump
, caches
, input
;
1229 bool odd
, isuy
, decimatepixel
, offerfields
, badinput
;
1232 SAY("ERROR: peasycap is NULL\n");
1237 input
= 0x07 & peasycap
->field_buffer
[peasycap
->field_read
][0].input
;
1239 JOM(8, "===== parity %i, input 0x%02X, field buffer %i --> "
1240 "frame buffer %i\n",
1241 peasycap
->field_buffer
[peasycap
->field_read
][0].kount
,
1242 peasycap
->field_buffer
[peasycap
->field_read
][0].input
,
1243 peasycap
->field_read
, peasycap
->frame_fill
);
1244 JOM(8, "===== %i=bytesperpixel\n", peasycap
->bytesperpixel
);
1245 if (peasycap
->offerfields
)
1246 JOM(8, "===== offerfields\n");
1248 /*---------------------------------------------------------------------------*/
1250 * REJECT OR CLEAN BAD FIELDS
1252 /*---------------------------------------------------------------------------*/
1253 if (peasycap
->field_read
== peasycap
->field_fill
) {
1254 SAM("ERROR: on entry, still filling field buffer %i\n",
1255 peasycap
->field_read
);
1258 #ifdef EASYCAP_TESTCARD
1259 easycap_testcard(peasycap
, peasycap
->field_read
);
1261 if (0 <= input
&& INPUT_MANY
> input
) {
1262 if (easycap_bars
&& VIDEO_LOST_TOLERATE
<= peasycap
->lost
[input
])
1263 easycap_testcard(peasycap
, peasycap
->field_read
);
1265 #endif /*EASYCAP_TESTCARD*/
1266 /*---------------------------------------------------------------------------*/
1268 offerfields
= peasycap
->offerfields
;
1269 bytesperpixel
= peasycap
->bytesperpixel
;
1270 decimatepixel
= peasycap
->decimatepixel
;
1272 if ((2 != bytesperpixel
) &&
1273 (3 != bytesperpixel
) &&
1274 (4 != bytesperpixel
)) {
1275 SAM("MISTAKE: %i=bytesperpixel\n", bytesperpixel
);
1283 w2
= 2 * multiplier
* (peasycap
->width
);
1284 w3
= bytesperpixel
* multiplier
* (peasycap
->width
);
1285 wz
= multiplier
* (peasycap
->height
) *
1286 multiplier
* (peasycap
->width
);
1288 kex
= peasycap
->field_read
; mex
= 0;
1289 kad
= peasycap
->frame_fill
; mad
= 0;
1291 pex
= peasycap
->field_buffer
[kex
][0].pgo
; rex
= PAGE_SIZE
;
1292 pad
= peasycap
->frame_buffer
[kad
][0].pgo
; rad
= PAGE_SIZE
;
1293 odd
= !!(peasycap
->field_buffer
[kex
][0].kount
);
1295 if (odd
&& (!decimatepixel
)) {
1296 JOM(8, "initial skipping %4i bytes p.%4i\n",
1297 w3
/multiplier
, mad
);
1298 pad
+= (w3
/ multiplier
); rad
-= (w3
/ multiplier
);
1301 mask
= 0; rump
= 0; caches
= 0;
1306 * PROCESS ONE LINE OF FRAME AT FULL RESOLUTION:
1307 * READ w2 BYTES FROM FIELD BUFFER,
1308 * WRITE w3 BYTES TO FRAME BUFFER
1310 if (!decimatepixel
) {
1313 much
= over
; more
= 0;
1314 margin
= 0; mask
= 0x00;
1320 SAM("MISTAKE: much is odd\n");
1324 more
= (bytesperpixel
*
1326 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1327 if (1 < bytesperpixel
) {
1328 if (rad
* 2 < much
* bytesperpixel
) {
1330 * INJUDICIOUS ALTERATION OF
1331 * THIS STATEMENT BLOCK WILL
1332 * CAUSE BREAKAGE. BEWARE.
1334 rad2
= rad
+ bytesperpixel
- 1;
1335 much
= ((((2 * rad2
)/bytesperpixel
)/2) * 2);
1336 rump
= ((bytesperpixel
* much
) / 2) - rad
;
1343 if ((mex
+ 1) < FIELD_BUFFER_SIZE
/ PAGE_SIZE
)
1344 margin
= *((u8
*)(peasycap
->field_buffer
[kex
][mex
+ 1].pgo
));
1349 SAM("MISTAKE: %i=bytesperpixel\n",
1356 JOM(8, "ERROR: 0x%02X=->field_buffer"
1358 "0x%02X=(0x08|->input)\n",
1359 peasycap
->field_buffer
1360 [kex
][mex
].input
, kex
, mex
,
1361 (0x08|peasycap
->input
));
1363 rc
= redaub(peasycap
, pad
, pex
, much
, more
,
1364 mask
, margin
, isuy
);
1366 SAM("ERROR: redaub() failed\n");
1372 over
-= much
; cz
+= much
;
1373 pex
+= much
; rex
-= much
;
1376 pex
= peasycap
->field_buffer
[kex
][mex
].pgo
;
1378 if (peasycap
->field_buffer
[kex
][mex
].input
!= (0x08|peasycap
->input
))
1385 pad
= peasycap
->frame_buffer
[kad
][mad
].pgo
;
1393 /*---------------------------------------------------------------------------*/
1395 * SKIP w3 BYTES IN TARGET FRAME BUFFER,
1396 * UNLESS IT IS THE LAST LINE OF AN ODD FRAME
1398 /*---------------------------------------------------------------------------*/
1399 if (!odd
|| (cz
!= wz
)) {
1404 pad
= peasycap
->frame_buffer
1416 /*---------------------------------------------------------------------------*/
1418 * PROCESS ONE LINE OF FRAME AT REDUCED RESOLUTION:
1419 * ONLY IF false==odd,
1420 * READ w2 BYTES FROM FIELD BUFFER,
1421 * WRITE w3 / 2 BYTES TO FRAME BUFFER
1423 /*---------------------------------------------------------------------------*/
1427 much
= over
; more
= 0; margin
= 0; mask
= 0x00;
1433 SAM("MISTAKE: much is odd\n");
1437 more
= (bytesperpixel
* much
) / 4;
1438 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1439 if (1 < bytesperpixel
) {
1440 if (rad
* 4 < much
* bytesperpixel
) {
1442 * INJUDICIOUS ALTERATION OF
1443 * THIS STATEMENT BLOCK
1444 * WILL CAUSE BREAKAGE.
1447 rad2
= rad
+ bytesperpixel
- 1;
1448 much
= ((((2 * rad2
) / bytesperpixel
) / 2) * 4);
1449 rump
= ((bytesperpixel
* much
) / 4) - rad
;
1456 if ((mex
+ 1) < FIELD_BUFFER_SIZE
/ PAGE_SIZE
)
1457 margin
= *((u8
*)(peasycap
->field_buffer
[kex
][mex
+ 1].pgo
));
1461 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1463 SAM("MISTAKE: %i=bytesperpixel\n",
1467 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1472 JOM(8, "ERROR: 0x%02X=->field_buffer"
1474 "0x%02X=(0x08|->input)\n",
1475 peasycap
->field_buffer
1476 [kex
][mex
].input
, kex
, mex
,
1477 (0x08|peasycap
->input
));
1479 rc
= redaub(peasycap
, pad
, pex
, much
, more
,
1480 mask
, margin
, isuy
);
1482 SAM("ERROR: redaub() failed\n");
1485 over
-= much
; cz
+= much
;
1486 pex
+= much
; rex
-= much
;
1489 pex
= peasycap
->field_buffer
[kex
][mex
].pgo
;
1491 if (peasycap
->field_buffer
[kex
][mex
].input
!=
1492 (0x08|peasycap
->input
))
1499 pad
= peasycap
->frame_buffer
[kad
][mad
].pgo
;
1507 /*---------------------------------------------------------------------------*/
1510 * READ w2 BYTES FROM FIELD BUFFER AND DISCARD THEM
1512 /*---------------------------------------------------------------------------*/
1518 pex
= peasycap
->field_buffer
[kex
][mex
].pgo
;
1520 if (peasycap
->field_buffer
[kex
][mex
].input
!=
1521 (0x08|peasycap
->input
)) {
1522 JOM(8, "ERROR: 0x%02X=->field_buffer"
1524 "0x%02X=(0x08|->input)\n",
1525 peasycap
->field_buffer
1526 [kex
][mex
].input
, kex
, mex
,
1527 (0x08|peasycap
->input
));
1541 /*---------------------------------------------------------------------------*/
1545 /*---------------------------------------------------------------------------*/
1546 c2
= (mex
+ 1)*PAGE_SIZE
- rex
;
1548 SAM("ERROR: discrepancy %i in bytes read\n", c2
- cz
);
1549 c3
= (mad
+ 1)*PAGE_SIZE
- rad
;
1551 if (!decimatepixel
) {
1552 if (bytesperpixel
* cz
!= c3
)
1553 SAM("ERROR: discrepancy %i in bytes written\n",
1554 c3
- (bytesperpixel
* cz
));
1559 SAM("ERROR: discrepancy %i in bytes written\n",
1560 (2*c3
)-(bytesperpixel
* cz
));
1563 SAM("ERROR: discrepancy %i "
1564 "in bytes written\n", c3
);
1568 SAM("WORRY: undischarged cache at end of line in frame buffer\n");
1570 JOM(8, "===== field2frame(): %i bytes --> %i bytes (incl skip)\n", c2
, c3
);
1571 JOM(8, "===== field2frame(): %i=mad %i=rad\n", mad
, rad
);
1574 JOM(8, "+++++ field2frame(): frame buffer %i is full\n", kad
);
1576 if (peasycap
->field_read
== peasycap
->field_fill
)
1577 SAM("WARNING: on exit, filling field buffer %i\n",
1578 peasycap
->field_read
);
1579 /*---------------------------------------------------------------------------*/
1581 * CALCULATE VIDEO STREAMING RATE
1583 /*---------------------------------------------------------------------------*/
1584 do_gettimeofday(&timeval
);
1585 if (peasycap
->timeval6
.tv_sec
) {
1586 below
= ((long long int)(1000000)) *
1587 ((long long int)(timeval
.tv_sec
-
1588 peasycap
->timeval6
.tv_sec
)) +
1589 (long long int)(timeval
.tv_usec
- peasycap
->timeval6
.tv_usec
);
1590 above
= (long long int)1000000;
1592 sdr
= signed_div(above
, below
);
1593 above
= sdr
.quotient
;
1594 remainder
= (u32
)sdr
.remainder
;
1596 JOM(8, "video streaming at %3lli.%03i fields per second\n",
1597 above
, (remainder
/1000));
1599 peasycap
->timeval6
= timeval
;
1602 JOM(8, "%i=caches\n", caches
);
1605 /*****************************************************************************/
1606 struct signed_div_result
1607 signed_div(long long int above
, long long int below
)
1609 struct signed_div_result sdr
;
1611 if (((0 <= above
) && (0 <= below
)) || ((0 > above
) && (0 > below
))) {
1612 sdr
.remainder
= (unsigned long long int) do_div(above
, below
);
1613 sdr
.quotient
= (long long int) above
;
1619 sdr
.remainder
= (unsigned long long int) do_div(above
, below
);
1620 sdr
.quotient
= -((long long int) above
);
1624 /*****************************************************************************/
1625 /*---------------------------------------------------------------------------*/
1627 * DECIMATION AND COLOURSPACE CONVERSION.
1629 * THIS ROUTINE REQUIRES THAT ALL THE DATA TO BE READ RESIDES ON ONE PAGE
1630 * AND THAT ALL THE DATA TO BE WRITTEN RESIDES ON ONE (DIFFERENT) PAGE.
1631 * THE CALLING ROUTINE MUST ENSURE THAT THIS REQUIREMENT IS MET, AND MUST
1632 * ALSO ENSURE THAT much IS EVEN.
1634 * much BYTES ARE READ, AT LEAST (bytesperpixel * much)/2 BYTES ARE WRITTEN
1635 * IF THERE IS NO DECIMATION, HALF THIS AMOUNT IF THERE IS DECIMATION.
1637 * mask IS ZERO WHEN NO SPECIAL BEHAVIOUR REQUIRED. OTHERWISE IT IS SET THUS:
1638 * 0x03 & mask = number of bytes to be written to cache instead of to
1640 * 0x04 & mask => use argument margin to set the chrominance for last pixel
1641 * 0x08 & mask => do not set the chrominance for last pixel
1643 * YUV to RGB CONVERSION IS (OR SHOULD BE) ITU-R BT 601.
1645 * THERE IS A LOT OF CODE REPETITION IN THIS ROUTINE IN ORDER TO AVOID
1646 * INEFFICIENT SWITCHING INSIDE INNER LOOPS. REARRANGING THE LOGIC TO
1647 * REDUCE CODE LENGTH WILL GENERALLY IMPAIR RUNTIME PERFORMANCE. BEWARE.
1649 /*---------------------------------------------------------------------------*/
1651 redaub(struct easycap
*peasycap
, void *pad
, void *pex
, int much
, int more
,
1652 u8 mask
, u8 margin
, bool isuy
)
1654 static s32 ay
[256], bu
[256], rv
[256], gu
[256], gv
[256];
1656 u8 r
, g
, b
, y
, u
, v
, c
, *p2
, *p3
, *pz
, *pr
;
1658 bool byteswaporder
, decimatepixel
, last
;
1663 SAM("MISTAKE: much is odd\n");
1666 bytesperpixel
= peasycap
->bytesperpixel
;
1667 byteswaporder
= peasycap
->byteswaporder
;
1668 decimatepixel
= peasycap
->decimatepixel
;
1670 /*---------------------------------------------------------------------------*/
1672 for (j
= 0; j
< 112; j
++) {
1673 tmp
= (0xFF00 & (453 * j
)) >> 8;
1674 bu
[j
+ 128] = tmp
; bu
[127 - j
] = -tmp
;
1675 tmp
= (0xFF00 & (359 * j
)) >> 8;
1676 rv
[j
+ 128] = tmp
; rv
[127 - j
] = -tmp
;
1677 tmp
= (0xFF00 & (88 * j
)) >> 8;
1678 gu
[j
+ 128] = tmp
; gu
[127 - j
] = -tmp
;
1679 tmp
= (0xFF00 & (183 * j
)) >> 8;
1680 gv
[j
+ 128] = tmp
; gv
[127 - j
] = -tmp
;
1682 for (j
= 0; j
< 16; j
++) {
1683 bu
[j
] = bu
[16]; rv
[j
] = rv
[16];
1684 gu
[j
] = gu
[16]; gv
[j
] = gv
[16];
1686 for (j
= 240; j
< 256; j
++) {
1687 bu
[j
] = bu
[239]; rv
[j
] = rv
[239];
1688 gu
[j
] = gu
[239]; gv
[j
] = gv
[239];
1690 for (j
= 16; j
< 236; j
++)
1692 for (j
= 0; j
< 16; j
++)
1694 for (j
= 236; j
< 256; j
++)
1696 JOM(8, "lookup tables are prepared\n");
1698 pcache
= peasycap
->pcache
;
1700 pcache
= &peasycap
->cache
[0];
1701 /*---------------------------------------------------------------------------*/
1703 * TRANSFER CONTENTS OF CACHE TO THE FRAME BUFFER
1705 /*---------------------------------------------------------------------------*/
1707 SAM("MISTAKE: pcache is NULL\n");
1711 if (pcache
!= &peasycap
->cache
[0])
1712 JOM(16, "cache has %i bytes\n", (int)(pcache
- &peasycap
->cache
[0]));
1713 p2
= &peasycap
->cache
[0];
1714 p3
= (u8
*)pad
- (int)(pcache
- &peasycap
->cache
[0]);
1715 while (p2
< pcache
) {
1718 pcache
= &peasycap
->cache
[0];
1720 SAM("MISTAKE: pointer misalignment\n");
1723 /*---------------------------------------------------------------------------*/
1724 rump
= (int)(0x03 & mask
);
1726 p2
= (u8
*)pex
; pz
= p2
+ much
; pr
= p3
+ more
; last
= false;
1735 JOM(16, "%4i=much %4i=more %i=rump\n", much
, more
, rump
);
1737 /*---------------------------------------------------------------------------*/
1738 switch (bytesperpixel
) {
1740 if (!decimatepixel
) {
1741 memcpy(pad
, pex
, (size_t)much
);
1742 if (!byteswaporder
) {
1747 p3
= (u8
*)pad
; pz
= p3
+ much
;
1757 if (!byteswaporder
) {
1758 /* UYVY DECIMATED */
1759 p2
= (u8
*)pex
; p3
= (u8
*)pad
; pz
= p2
+ much
;
1762 *(p3
+ 1) = *(p2
+ 1);
1763 *(p3
+ 2) = *(p2
+ 2);
1764 *(p3
+ 3) = *(p2
+ 3);
1769 /* YUYV DECIMATED */
1770 p2
= (u8
*)pex
; p3
= (u8
*)pad
; pz
= p2
+ much
;
1774 *(p3
+ 2) = *(p2
+ 3);
1775 *(p3
+ 3) = *(p2
+ 2);
1785 if (!decimatepixel
) {
1786 if (!byteswaporder
) {
1789 if (pr
<= (p3
+ bytesperpixel
))
1794 if (last
&& (0x0C & mask
)) {
1810 tmp
= ay
[(int)y
] + rv
[(int)v
];
1811 r
= (255 < tmp
) ? 255 : ((0 > tmp
) ?
1813 tmp
= ay
[(int)y
] - gu
[(int)u
] - gv
[(int)v
];
1814 g
= (255 < tmp
) ? 255 : ((0 > tmp
) ?
1816 tmp
= ay
[(int)y
] + bu
[(int)u
];
1817 b
= (255 < tmp
) ? 255 : ((0 > tmp
) ?
1821 pcache
= &peasycap
->cache
[0];
1822 switch (bytesperpixel
- rump
) {
1836 SAM("MISTAKE: %i=rump\n",
1837 bytesperpixel
- rump
);
1851 p3
+= bytesperpixel
;
1857 if (pr
<= (p3
+ bytesperpixel
))
1862 if (last
&& (0x0C & mask
)) {
1879 tmp
= ay
[(int)y
] + rv
[(int)v
];
1880 r
= (255 < tmp
) ? 255 : ((0 > tmp
) ?
1882 tmp
= ay
[(int)y
] - gu
[(int)u
] - gv
[(int)v
];
1883 g
= (255 < tmp
) ? 255 : ((0 > tmp
) ?
1885 tmp
= ay
[(int)y
] + bu
[(int)u
];
1886 b
= (255 < tmp
) ? 255 : ((0 > tmp
) ?
1890 pcache
= &peasycap
->cache
[0];
1891 switch (bytesperpixel
- rump
) {
1905 SAM("MISTAKE: %i=rump\n",
1906 bytesperpixel
- rump
);
1920 p3
+= bytesperpixel
;
1925 if (!byteswaporder
) {
1928 if (pr
<= (p3
+ bytesperpixel
))
1933 if (last
&& (0x0C & mask
)) {
1950 tmp
= ay
[(int)y
] + rv
[(int)v
];
1951 r
= (255 < tmp
) ? 255 : ((0 > tmp
) ?
1953 tmp
= ay
[(int)y
] - gu
[(int)u
] -
1955 g
= (255 < tmp
) ? 255 : ((0 > tmp
) ?
1957 tmp
= ay
[(int)y
] + bu
[(int)u
];
1958 b
= (255 < tmp
) ? 255 : ((0 > tmp
) ?
1962 pcache
= &peasycap
->cache
[0];
1963 switch (bytesperpixel
- rump
) {
1979 bytesperpixel
- rump
);
1989 p3
+= bytesperpixel
;
1999 if (pr
<= (p3
+ bytesperpixel
))
2004 if (last
&& (0x0C & mask
)) {
2022 tmp
= ay
[(int)y
] + rv
[(int)v
];
2023 r
= (255 < tmp
) ? 255 : ((0 > tmp
) ?
2025 tmp
= ay
[(int)y
] - gu
[(int)u
] -
2027 g
= (255 < tmp
) ? 255 : ((0 > tmp
) ?
2029 tmp
= ay
[(int)y
] + bu
[(int)u
];
2030 b
= (255 < tmp
) ? 255 : ((0 > tmp
) ?
2034 pcache
= &peasycap
->cache
[0];
2035 switch (bytesperpixel
- rump
) {
2051 bytesperpixel
- rump
);
2061 p3
+= bytesperpixel
;
2074 if (!decimatepixel
) {
2075 if (!byteswaporder
) {
2078 if (pr
<= (p3
+ bytesperpixel
))
2083 if (last
&& (0x0C & mask
)) {
2099 tmp
= ay
[(int)y
] + rv
[(int)v
];
2100 r
= (255 < tmp
) ? 255 : ((0 > tmp
) ?
2102 tmp
= ay
[(int)y
] - gu
[(int)u
] - gv
[(int)v
];
2103 g
= (255 < tmp
) ? 255 : ((0 > tmp
) ?
2105 tmp
= ay
[(int)y
] + bu
[(int)u
];
2106 b
= (255 < tmp
) ? 255 : ((0 > tmp
) ?
2110 pcache
= &peasycap
->cache
[0];
2111 switch (bytesperpixel
- rump
) {
2134 SAM("MISTAKE: %i=rump\n",
2135 bytesperpixel
- rump
);
2150 p3
+= bytesperpixel
;
2158 if (pr
<= (p3
+ bytesperpixel
))
2163 if (last
&& (0x0C & mask
)) {
2179 tmp
= ay
[(int)y
] + rv
[(int)v
];
2180 r
= (255 < tmp
) ? 255 : ((0 > tmp
) ?
2182 tmp
= ay
[(int)y
] - gu
[(int)u
] - gv
[(int)v
];
2183 g
= (255 < tmp
) ? 255 : ((0 > tmp
) ?
2185 tmp
= ay
[(int)y
] + bu
[(int)u
];
2186 b
= (255 < tmp
) ? 255 : ((0 > tmp
) ?
2190 pcache
= &peasycap
->cache
[0];
2191 switch (bytesperpixel
- rump
) {
2214 SAM("MISTAKE: %i=rump\n",
2215 bytesperpixel
- rump
);
2229 p3
+= bytesperpixel
;
2234 if (!byteswaporder
) {
2239 if (pr
<= (p3
+ bytesperpixel
))
2244 if (last
&& (0x0C & mask
)) {
2262 tmp
= ay
[(int)y
] + rv
[(int)v
];
2263 r
= (255 < tmp
) ? 255 : ((0 > tmp
) ?
2265 tmp
= ay
[(int)y
] - gu
[(int)u
] -
2267 g
= (255 < tmp
) ? 255 : ((0 > tmp
) ?
2269 tmp
= ay
[(int)y
] + bu
[(int)u
];
2270 b
= (255 < tmp
) ? 255 : ((0 > tmp
) ?
2274 pcache
= &peasycap
->cache
[0];
2275 switch (bytesperpixel
- rump
) {
2312 p3
+= bytesperpixel
;
2323 if (pr
<= (p3
+ bytesperpixel
))
2328 if (last
&& (0x0C & mask
)) {
2345 tmp
= ay
[(int)y
] + rv
[(int)v
];
2346 r
= (255 < tmp
) ? 255 : ((0 > tmp
) ?
2348 tmp
= ay
[(int)y
] - gu
[(int)u
] -
2350 g
= (255 < tmp
) ? 255 : ((0 > tmp
) ?
2352 tmp
= ay
[(int)y
] + bu
[(int)u
];
2353 b
= (255 < tmp
) ? 255 : ((0 > tmp
) ?
2357 pcache
= &peasycap
->cache
[0];
2358 switch (bytesperpixel
- rump
) {
2383 bytesperpixel
- rump
);
2394 p3
+= bytesperpixel
;
2405 SAM("MISTAKE: %i=bytesperpixel\n", bytesperpixel
);
2411 /*****************************************************************************/
2413 * SEE CORBET ET AL. "LINUX DEVICE DRIVERS", 3rd EDITION, PAGES 430-434
2415 /*****************************************************************************/
2416 static void easycap_vma_open(struct vm_area_struct
*pvma
)
2418 struct easycap
*peasycap
;
2420 peasycap
= pvma
->vm_private_data
;
2422 SAY("ERROR: peasycap is NULL\n");
2425 peasycap
->vma_many
++;
2426 JOT(8, "%i=peasycap->vma_many\n", peasycap
->vma_many
);
2429 /*****************************************************************************/
2430 static void easycap_vma_close(struct vm_area_struct
*pvma
)
2432 struct easycap
*peasycap
;
2434 peasycap
= pvma
->vm_private_data
;
2436 SAY("ERROR: peasycap is NULL\n");
2439 peasycap
->vma_many
--;
2440 JOT(8, "%i=peasycap->vma_many\n", peasycap
->vma_many
);
2443 /*****************************************************************************/
2444 static int easycap_vma_fault(struct vm_area_struct
*pvma
, struct vm_fault
*pvmf
)
2449 struct easycap
*peasycap
;
2451 retcode
= VM_FAULT_NOPAGE
;
2454 SAY("pvma is NULL\n");
2458 SAY("pvmf is NULL\n");
2462 k
= (pvmf
->pgoff
) / (FRAME_BUFFER_SIZE
/PAGE_SIZE
);
2463 m
= (pvmf
->pgoff
) % (FRAME_BUFFER_SIZE
/PAGE_SIZE
);
2466 JOT(4, "%4i=k, %4i=m\n", k
, m
);
2468 JOT(16, "%4i=k, %4i=m\n", k
, m
);
2470 if ((0 > k
) || (FRAME_BUFFER_MANY
<= k
)) {
2471 SAY("ERROR: buffer index %i out of range\n", k
);
2474 if ((0 > m
) || (FRAME_BUFFER_SIZE
/PAGE_SIZE
<= m
)) {
2475 SAY("ERROR: page number %i out of range\n", m
);
2478 peasycap
= pvma
->vm_private_data
;
2480 SAY("ERROR: peasycap is NULL\n");
2483 /*---------------------------------------------------------------------------*/
2484 pbuf
= peasycap
->frame_buffer
[k
][m
].pgo
;
2486 SAM("ERROR: pbuf is NULL\n");
2489 page
= virt_to_page(pbuf
);
2491 SAM("ERROR: page is NULL\n");
2495 /*---------------------------------------------------------------------------*/
2497 SAM("ERROR: page is NULL after get_page(page)\n");
2500 retcode
= VM_FAULT_MINOR
;
2505 static const struct vm_operations_struct easycap_vm_ops
= {
2506 .open
= easycap_vma_open
,
2507 .close
= easycap_vma_close
,
2508 .fault
= easycap_vma_fault
,
2511 static int easycap_mmap(struct file
*file
, struct vm_area_struct
*pvma
)
2515 pvma
->vm_ops
= &easycap_vm_ops
;
2516 pvma
->vm_flags
|= VM_RESERVED
;
2518 pvma
->vm_private_data
= file
->private_data
;
2519 easycap_vma_open(pvma
);
2522 /*****************************************************************************/
2523 /*---------------------------------------------------------------------------*/
2525 * ON COMPLETION OF A VIDEO URB ITS DATA IS COPIED TO THE FIELD BUFFERS
2526 * PROVIDED peasycap->video_idle IS ZERO. REGARDLESS OF THIS BEING TRUE,
2527 * IT IS RESUBMITTED PROVIDED peasycap->video_isoc_streaming IS NOT ZERO.
2529 * THIS FUNCTION IS AN INTERRUPT SERVICE ROUTINE AND MUST NOT SLEEP.
2531 * INFORMATION ABOUT THE VALIDITY OF THE CONTENTS OF THE FIELD BUFFER ARE
2532 * STORED IN THE TWO-BYTE STATUS PARAMETER
2533 * peasycap->field_buffer[peasycap->field_fill][0].kount
2534 * NOTICE THAT THE INFORMATION IS STORED ONLY WITH PAGE 0 OF THE FIELD BUFFER.
2536 * THE LOWER BYTE CONTAINS THE FIELD PARITY BYTE FURNISHED BY THE SAA7113H
2539 * THE UPPER BYTE IS ZERO IF NO PROBLEMS, OTHERWISE:
2540 * 0 != (kount & 0x8000) => AT LEAST ONE URB COMPLETED WITH ERRORS
2541 * 0 != (kount & 0x4000) => BUFFER HAS TOO MUCH DATA
2542 * 0 != (kount & 0x2000) => BUFFER HAS NOT ENOUGH DATA
2543 * 0 != (kount & 0x1000) => BUFFER HAS DATA FROM DISPARATE INPUTS
2544 * 0 != (kount & 0x0400) => RESERVED
2545 * 0 != (kount & 0x0200) => FIELD BUFFER NOT YET CHECKED
2546 * 0 != (kount & 0x0100) => BUFFER HAS TWO EXTRA BYTES - WHY?
2548 /*---------------------------------------------------------------------------*/
2549 static void easycap_complete(struct urb
*purb
)
2551 struct easycap
*peasycap
;
2552 struct data_buffer
*pfield_buffer
;
2554 int i
, more
, much
, leap
, rc
, last
;
2555 int videofieldamount
;
2556 unsigned int override
, bad
;
2557 int framestatus
, framelength
, frameactual
, frameoffset
;
2561 SAY("ERROR: easycap_complete(): purb is NULL\n");
2564 peasycap
= purb
->context
;
2566 SAY("ERROR: easycap_complete(): peasycap is NULL\n");
2569 if (peasycap
->video_eof
)
2571 for (i
= 0; i
< VIDEO_ISOC_BUFFER_MANY
; i
++)
2572 if (purb
->transfer_buffer
== peasycap
->video_isoc_buffer
[i
].pgo
)
2574 JOM(16, "%2i=urb\n", i
);
2575 last
= peasycap
->video_isoc_sequence
;
2576 if ((((VIDEO_ISOC_BUFFER_MANY
- 1) == last
) && (0 != i
)) ||
2577 (((VIDEO_ISOC_BUFFER_MANY
- 1) != last
) && ((last
+ 1) != i
))) {
2578 JOM(16, "ERROR: out-of-order urbs %i,%i ... continuing\n",
2581 peasycap
->video_isoc_sequence
= i
;
2583 if (peasycap
->video_idle
) {
2584 JOM(16, "%i=video_idle %i=video_isoc_streaming\n",
2585 peasycap
->video_idle
, peasycap
->video_isoc_streaming
);
2586 if (peasycap
->video_isoc_streaming
) {
2587 rc
= usb_submit_urb(purb
, GFP_ATOMIC
);
2589 SAM("%s:%d ENOMEM\n", strerror(rc
), rc
);
2591 SAM("ERROR: while %i=video_idle, "
2593 "failed with rc:\n",
2594 peasycap
->video_idle
);
2600 /*---------------------------------------------------------------------------*/
2601 if (FIELD_BUFFER_MANY
<= peasycap
->field_fill
) {
2602 SAM("ERROR: bad peasycap->field_fill\n");
2606 if ((-ESHUTDOWN
== purb
->status
) || (-ENOENT
== purb
->status
)) {
2607 JOM(8, "urb status -ESHUTDOWN or -ENOENT\n");
2611 (peasycap
->field_buffer
[peasycap
->field_fill
][0].kount
) |= 0x8000 ;
2612 SAM("ERROR: bad urb status -%s: %d\n",
2613 strerror(purb
->status
), purb
->status
);
2614 /*---------------------------------------------------------------------------*/
2616 for (i
= 0; i
< purb
->number_of_packets
; i
++) {
2617 if (0 != purb
->iso_frame_desc
[i
].status
) {
2618 (peasycap
->field_buffer
2619 [peasycap
->field_fill
][0].kount
) |= 0x8000 ;
2620 /* FIXME: 1. missing '-' check boundaries */
2622 strerror(purb
->iso_frame_desc
[i
].status
));
2624 framestatus
= purb
->iso_frame_desc
[i
].status
;
2625 framelength
= purb
->iso_frame_desc
[i
].length
;
2626 frameactual
= purb
->iso_frame_desc
[i
].actual_length
;
2627 frameoffset
= purb
->iso_frame_desc
[i
].offset
;
2629 JOM(16, "frame[%2i]:"
2634 i
, framestatus
, frameactual
, framelength
, frameoffset
);
2635 if (!purb
->iso_frame_desc
[i
].status
) {
2636 more
= purb
->iso_frame_desc
[i
].actual_length
;
2637 pfield_buffer
= &peasycap
->field_buffer
2638 [peasycap
->field_fill
][peasycap
->field_page
];
2639 videofieldamount
= (peasycap
->field_page
*
2641 (int)(pfield_buffer
->pto
- pfield_buffer
->pgo
);
2643 peasycap
->video_mt
++;
2645 if (peasycap
->video_mt
) {
2646 JOM(8, "%4i empty video urb frames\n",
2647 peasycap
->video_mt
);
2648 peasycap
->video_mt
= 0;
2650 if (FIELD_BUFFER_MANY
<= peasycap
->field_fill
) {
2651 SAM("ERROR: bad peasycap->field_fill\n");
2654 if (FIELD_BUFFER_SIZE
/PAGE_SIZE
<=
2655 peasycap
->field_page
) {
2656 SAM("ERROR: bad peasycap->field_page\n");
2659 pfield_buffer
= &peasycap
->field_buffer
2660 [peasycap
->field_fill
][peasycap
->field_page
];
2661 pu
= (u8
*)(purb
->transfer_buffer
+
2662 purb
->iso_frame_desc
[i
].offset
);
2667 /*--------------------------------------------------------------------------*/
2669 * EIGHT-BYTE END-OF-VIDEOFIELD MARKER.
2670 * NOTE: A SUCCESSION OF URB FRAMES FOLLOWING THIS ARE EMPTY,
2671 * CORRESPONDING TO THE FIELD FLYBACK (VERTICAL BLANKING) PERIOD.
2673 * PROVIDED THE FIELD BUFFER CONTAINS GOOD DATA AS INDICATED BY A ZERO UPPER
2675 * peasycap->field_buffer[peasycap->field_fill][0].kount
2676 * THE CONTENTS OF THE FIELD BUFFER ARE OFFERED TO dqbuf(), field_read IS
2677 * UPDATED AND field_fill IS BUMPED. IF THE FIELD BUFFER CONTAINS BAD DATA
2678 * NOTHING IS OFFERED TO dqbuf().
2680 * THE DECISION ON WHETHER THE PARITY OF THE OFFERED FIELD BUFFER IS RIGHT
2681 * RESTS WITH dqbuf().
2683 /*---------------------------------------------------------------------------*/
2684 if ((8 == more
) || override
) {
2685 if (videofieldamount
>
2686 peasycap
->videofieldamount
) {
2687 if (2 == videofieldamount
-
2690 (peasycap
->field_buffer
2691 [peasycap
->field_fill
]
2692 [0].kount
) |= 0x0100;
2693 peasycap
->video_junk
+= (1 +
2694 VIDEO_JUNK_TOLERATE
);
2696 (peasycap
->field_buffer
2697 [peasycap
->field_fill
]
2698 [0].kount
) |= 0x4000;
2699 } else if (videofieldamount
<
2702 (peasycap
->field_buffer
2703 [peasycap
->field_fill
]
2704 [0].kount
) |= 0x2000;
2706 bad
= 0xFF00 & peasycap
->field_buffer
2707 [peasycap
->field_fill
]
2710 (peasycap
->video_junk
)--;
2711 if (-VIDEO_JUNK_TOLERATE
>
2712 peasycap
->video_junk
)
2713 peasycap
->video_junk
=
2714 -VIDEO_JUNK_TOLERATE
;
2715 peasycap
->field_read
=
2718 if (FIELD_BUFFER_MANY
<=
2723 peasycap
->field_page
= 0;
2724 pfield_buffer
= &peasycap
->
2730 pfield_buffer
->pto
=
2732 JOM(8, "bumped to: %i="
2736 peasycap
->field_fill
,
2738 pfield_buffer
->kount
);
2739 JOM(8, "field buffer %i has "
2740 "%i bytes fit to be "
2742 peasycap
->field_read
,
2744 JOM(8, "wakeup call to "
2749 peasycap
->field_read
,
2750 peasycap
->field_fill
,
2754 field_read
][0].kount
);
2755 wake_up_interruptible
2759 (&peasycap
->timeval7
);
2761 peasycap
->video_junk
++;
2763 peasycap
->video_junk
+=
2764 (1 + VIDEO_JUNK_TOLERATE
/2);
2765 JOM(8, "field buffer %i had %i "
2766 "bytes, now discarded: "
2768 peasycap
->field_fill
,
2771 peasycap
->field_buffer
2772 [peasycap
->field_fill
][0].
2774 (peasycap
->field_fill
)++;
2776 if (FIELD_BUFFER_MANY
<=
2777 peasycap
->field_fill
)
2778 peasycap
->field_fill
= 0;
2779 peasycap
->field_page
= 0;
2781 &peasycap
->field_buffer
2782 [peasycap
->field_fill
]
2783 [peasycap
->field_page
];
2784 pfield_buffer
->pto
=
2787 JOM(8, "bumped to: %i=peasycap->"
2788 "field_fill %i=parity\n",
2789 peasycap
->field_fill
,
2790 0x00FF & pfield_buffer
->kount
);
2793 JOM(8, "end-of-field: received "
2794 "parity byte 0x%02X\n",
2797 pfield_buffer
->kount
= 0x0000;
2799 pfield_buffer
->kount
= 0x0001;
2800 pfield_buffer
->input
= 0x08 |
2801 (0x07 & peasycap
->input
);
2802 JOM(8, "end-of-field: 0x%02X=kount\n",
2803 0xFF & pfield_buffer
->kount
);
2806 /*---------------------------------------------------------------------------*/
2808 * COPY more BYTES FROM ISOC BUFFER TO FIELD BUFFER
2810 /*---------------------------------------------------------------------------*/
2814 if (FIELD_BUFFER_MANY
<= peasycap
->field_fill
) {
2815 SAM("ERROR: bad peasycap->field_fill\n");
2818 if (FIELD_BUFFER_SIZE
/PAGE_SIZE
<= peasycap
->field_page
) {
2819 SAM("ERROR: bad peasycap->field_page\n");
2822 pfield_buffer
= &peasycap
->field_buffer
2823 [peasycap
->field_fill
][peasycap
->field_page
];
2825 pfield_buffer
= &peasycap
->field_buffer
2826 [peasycap
->field_fill
]
2827 [peasycap
->field_page
];
2828 if (PAGE_SIZE
< (pfield_buffer
->pto
-
2829 pfield_buffer
->pgo
)) {
2830 SAM("ERROR: bad pfield_buffer->pto\n");
2833 if (PAGE_SIZE
== (pfield_buffer
->pto
-
2834 pfield_buffer
->pgo
)) {
2835 (peasycap
->field_page
)++;
2836 if (FIELD_BUFFER_SIZE
/PAGE_SIZE
<=
2837 peasycap
->field_page
) {
2838 JOM(16, "wrapping peasycap->"
2840 peasycap
->field_page
= 0;
2842 pfield_buffer
= &peasycap
->
2844 [peasycap
->field_fill
]
2845 [peasycap
->field_page
];
2846 pfield_buffer
->pto
= pfield_buffer
->pgo
;
2847 pfield_buffer
->input
= 0x08 |
2848 (0x07 & peasycap
->input
);
2849 if ((peasycap
->field_buffer
[peasycap
->
2852 pfield_buffer
->input
)
2853 (peasycap
->field_buffer
2854 [peasycap
->field_fill
]
2855 [0]).kount
|= 0x1000;
2859 (int)(pfield_buffer
->pto
-
2860 pfield_buffer
->pgo
);
2864 memcpy(pfield_buffer
->pto
, pu
, much
);
2866 (pfield_buffer
->pto
) += much
;
2873 /*---------------------------------------------------------------------------*/
2875 * RESUBMIT THIS URB, UNLESS A SEVERE PERSISTENT ERROR CONDITION EXISTS.
2877 * IF THE WAIT QUEUES ARE NOT CLEARED IN RESPONSE TO AN ERROR CONDITION
2878 * THE USERSPACE PROGRAM, E.G. mplayer, MAY HANG ON EXIT. BEWARE.
2880 /*---------------------------------------------------------------------------*/
2881 if (VIDEO_ISOC_BUFFER_MANY
<= peasycap
->video_junk
) {
2882 SAM("easycap driver shutting down on condition green\n");
2883 peasycap
->status
= 1;
2884 peasycap
->video_eof
= 1;
2885 peasycap
->video_junk
= 0;
2886 wake_up_interruptible(&peasycap
->wq_video
);
2887 #if !defined(PERSEVERE)
2888 peasycap
->audio_eof
= 1;
2889 wake_up_interruptible(&peasycap
->wq_audio
);
2890 #endif /*PERSEVERE*/
2893 if (peasycap
->video_isoc_streaming
) {
2894 rc
= usb_submit_urb(purb
, GFP_ATOMIC
);
2896 SAM("%s: %d\n", strerror(rc
), rc
);
2898 SAM("ERROR: while %i=video_idle, "
2900 "failed with rc:\n",
2901 peasycap
->video_idle
);
2906 static const struct file_operations easycap_fops
= {
2907 .owner
= THIS_MODULE
,
2908 .open
= easycap_open
,
2909 .unlocked_ioctl
= easycap_unlocked_ioctl
,
2910 .poll
= easycap_poll
,
2911 .mmap
= easycap_mmap
,
2912 .llseek
= no_llseek
,
2914 static const struct usb_class_driver easycap_class
= {
2915 .name
= "usb/easycap%d",
2916 .fops
= &easycap_fops
,
2917 .minor_base
= USB_SKEL_MINOR_BASE
,
2919 /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
2920 static const struct v4l2_file_operations v4l2_fops
= {
2921 .owner
= THIS_MODULE
,
2922 .open
= easycap_open_noinode
,
2923 .unlocked_ioctl
= easycap_unlocked_ioctl
,
2924 .poll
= easycap_poll
,
2925 .mmap
= easycap_mmap
,
2927 /*****************************************************************************/
2928 /*---------------------------------------------------------------------------*/
2930 * WHEN THE EasyCAP IS PHYSICALLY PLUGGED IN, THIS FUNCTION IS CALLED THREE
2931 * TIMES, ONCE FOR EACH OF THE THREE INTERFACES. BEWARE.
2933 /*---------------------------------------------------------------------------*/
2934 static int easycap_usb_probe(struct usb_interface
*intf
,
2935 const struct usb_device_id
*id
)
2937 struct usb_device
*usbdev
;
2938 struct usb_host_interface
*alt
;
2939 struct usb_endpoint_descriptor
*ep
;
2940 struct usb_interface_descriptor
*interface
;
2942 struct easycap
*peasycap
;
2944 struct data_urb
*pdata_urb
;
2946 u8 bInterfaceNumber
;
2948 u8 bInterfaceSubClass
;
2950 int okalt
[8], isokalt
;
2956 struct easycap_format
*peasycap_format
;
2958 struct inputset
*inputset
;
2960 usbdev
= interface_to_usbdev(intf
);
2962 /*---------------------------------------------------------------------------*/
2963 alt
= usb_altnum_to_altsetting(intf
, 0);
2965 SAY("ERROR: usb_host_interface not found\n");
2968 interface
= &alt
->desc
;
2970 SAY("ERROR: intf_descriptor is NULL\n");
2973 /*---------------------------------------------------------------------------*/
2975 * GET PROPERTIES OF PROBED INTERFACE
2977 /*---------------------------------------------------------------------------*/
2978 bInterfaceNumber
= interface
->bInterfaceNumber
;
2979 bInterfaceClass
= interface
->bInterfaceClass
;
2980 bInterfaceSubClass
= interface
->bInterfaceSubClass
;
2982 JOT(4, "intf[%i]: num_altsetting=%i\n",
2983 bInterfaceNumber
, intf
->num_altsetting
);
2984 JOT(4, "intf[%i]: cur_altsetting - altsetting=%li\n",
2986 (long int)(intf
->cur_altsetting
- intf
->altsetting
));
2987 JOT(4, "intf[%i]: bInterfaceClass=0x%02X bInterfaceSubClass=0x%02X\n",
2988 bInterfaceNumber
, bInterfaceClass
, bInterfaceSubClass
);
2989 /*---------------------------------------------------------------------------*/
2991 * A NEW struct easycap IS ALWAYS ALLOCATED WHEN INTERFACE 0 IS PROBED.
2992 * IT IS NOT POSSIBLE HERE TO FREE ANY EXISTING struct easycap. THIS
2993 * SHOULD HAVE BEEN DONE BY easycap_delete() WHEN THE EasyCAP WAS
2994 * PHYSICALLY UNPLUGGED.
2996 * THE POINTER peasycap TO THE struct easycap IS REMEMBERED WHEN
2997 * INTERFACES 1 AND 2 ARE PROBED.
2999 /*---------------------------------------------------------------------------*/
3000 if (0 == bInterfaceNumber
) {
3001 peasycap
= kzalloc(sizeof(struct easycap
), GFP_KERNEL
);
3003 SAY("ERROR: Could not allocate peasycap\n");
3006 /*---------------------------------------------------------------------------*/
3008 * PERFORM URGENT INTIALIZATIONS ...
3010 /*---------------------------------------------------------------------------*/
3011 peasycap
->minor
= -1;
3012 kref_init(&peasycap
->kref
);
3013 JOM(8, "intf[%i]: after kref_init(..._video) "
3014 "%i=peasycap->kref.refcount.counter\n",
3015 bInterfaceNumber
, peasycap
->kref
.refcount
.counter
);
3018 peasycap
->gain
= (s8
)clamp(easycap_gain
, 0, 31);
3020 init_waitqueue_head(&peasycap
->wq_video
);
3021 init_waitqueue_head(&peasycap
->wq_audio
);
3022 init_waitqueue_head(&peasycap
->wq_trigger
);
3024 if (mutex_lock_interruptible(&mutex_dongle
)) {
3025 SAY("ERROR: cannot down mutex_dongle\n");
3026 return -ERESTARTSYS
;
3028 /*---------------------------------------------------------------------------*/
3030 * FOR INTERFACES 1 AND 2 THE POINTER peasycap WILL NEED TO
3031 * TO BE THE SAME AS THAT ALLOCATED NOW FOR INTERFACE 0.
3033 * NORMALLY ndong WILL NOT HAVE CHANGED SINCE INTERFACE 0 WAS
3034 * PROBED, BUT THIS MAY NOT BE THE CASE IF, FOR EXAMPLE, TWO
3035 * EASYCAPs ARE PLUGGED IN SIMULTANEOUSLY.
3037 /*---------------------------------------------------------------------------*/
3038 for (ndong
= 0; ndong
< DONGLE_MANY
; ndong
++) {
3039 if ((!easycapdc60_dongle
[ndong
].peasycap
) &&
3040 (!mutex_is_locked(&easycapdc60_dongle
3041 [ndong
].mutex_video
)) &&
3042 (!mutex_is_locked(&easycapdc60_dongle
3043 [ndong
].mutex_audio
))) {
3044 easycapdc60_dongle
[ndong
].peasycap
= peasycap
;
3045 peasycap
->isdongle
= ndong
;
3046 JOM(8, "intf[%i]: peasycap-->easycap"
3047 "_dongle[%i].peasycap\n",
3048 bInterfaceNumber
, ndong
);
3052 if (DONGLE_MANY
<= ndong
) {
3053 SAM("ERROR: too many dongles\n");
3054 mutex_unlock(&mutex_dongle
);
3057 mutex_unlock(&mutex_dongle
);
3059 peasycap
->allocation_video_struct
= sizeof(struct easycap
);
3060 peasycap
->allocation_video_page
= 0;
3061 peasycap
->allocation_video_urb
= 0;
3062 peasycap
->allocation_audio_struct
= 0;
3063 peasycap
->allocation_audio_page
= 0;
3064 peasycap
->allocation_audio_urb
= 0;
3066 /*---------------------------------------------------------------------------*/
3068 * ... AND FURTHER INITIALIZE THE STRUCTURE
3070 /*---------------------------------------------------------------------------*/
3071 peasycap
->pusb_device
= usbdev
;
3072 peasycap
->pusb_interface
= intf
;
3075 peasycap
->microphone
= false;
3077 peasycap
->video_interface
= -1;
3078 peasycap
->video_altsetting_on
= -1;
3079 peasycap
->video_altsetting_off
= -1;
3080 peasycap
->video_endpointnumber
= -1;
3081 peasycap
->video_isoc_maxframesize
= -1;
3082 peasycap
->video_isoc_buffer_size
= -1;
3084 peasycap
->audio_interface
= -1;
3085 peasycap
->audio_altsetting_on
= -1;
3086 peasycap
->audio_altsetting_off
= -1;
3087 peasycap
->audio_endpointnumber
= -1;
3088 peasycap
->audio_isoc_maxframesize
= -1;
3089 peasycap
->audio_isoc_buffer_size
= -1;
3091 peasycap
->frame_buffer_many
= FRAME_BUFFER_MANY
;
3093 for (k
= 0; k
< INPUT_MANY
; k
++)
3094 peasycap
->lost
[k
] = 0;
3096 peasycap
->skipped
= 0;
3097 peasycap
->offerfields
= 0;
3098 /*---------------------------------------------------------------------------*/
3100 * DYNAMICALLY FILL IN THE AVAILABLE FORMATS ...
3102 /*---------------------------------------------------------------------------*/
3103 rc
= fillin_formats();
3105 SAM("ERROR: fillin_formats() rc = %i\n", rc
);
3108 JOM(4, "%i formats available\n", rc
);
3109 /*---------------------------------------------------------------------------*/
3111 * ... AND POPULATE easycap.inputset[]
3113 /*---------------------------------------------------------------------------*/
3114 /* FIXME: maybe we just use memset 0 */
3115 inputset
= peasycap
->inputset
;
3116 for (k
= 0; k
< INPUT_MANY
; k
++) {
3117 inputset
[k
].input_ok
= 0;
3118 inputset
[k
].standard_offset_ok
= 0;
3119 inputset
[k
].format_offset_ok
= 0;
3120 inputset
[k
].brightness_ok
= 0;
3121 inputset
[k
].contrast_ok
= 0;
3122 inputset
[k
].saturation_ok
= 0;
3123 inputset
[k
].hue_ok
= 0;
3126 fmtidx
= peasycap
->ntsc
? NTSC_M
: PAL_BGHIN
;
3129 for (i
= 0; 0xFFFF != easycap_standard
[i
].mask
; i
++) {
3130 if (fmtidx
== easycap_standard
[i
].v4l2_standard
.index
) {
3132 for (k
= 0; k
< INPUT_MANY
; k
++)
3133 inputset
[k
].standard_offset
= i
;
3135 mask
= easycap_standard
[i
].mask
;
3141 "inputset->standard_offset unpopulated, %i=m\n", m
);
3145 peasycap_format
= &easycap_format
[0];
3147 for (i
= 0; peasycap_format
->v4l2_format
.fmt
.pix
.width
; i
++) {
3148 struct v4l2_pix_format
*pix
=
3149 &peasycap_format
->v4l2_format
.fmt
.pix
;
3150 if (((peasycap_format
->mask
& 0x0F) == (mask
& 0x0F)) &&
3151 pix
->field
== V4L2_FIELD_NONE
&&
3152 pix
->pixelformat
== V4L2_PIX_FMT_UYVY
&&
3153 pix
->width
== 640 && pix
->height
== 480) {
3155 for (k
= 0; k
< INPUT_MANY
; k
++)
3156 inputset
[k
].format_offset
= i
;
3162 SAM("ERROR: inputset[]->format_offset unpopulated\n");
3167 for (i
= 0; 0xFFFFFFFF != easycap_control
[i
].id
; i
++) {
3168 value
= easycap_control
[i
].default_value
;
3169 if (V4L2_CID_BRIGHTNESS
== easycap_control
[i
].id
) {
3171 for (k
= 0; k
< INPUT_MANY
; k
++)
3172 inputset
[k
].brightness
= value
;
3173 } else if (V4L2_CID_CONTRAST
== easycap_control
[i
].id
) {
3175 for (k
= 0; k
< INPUT_MANY
; k
++)
3176 inputset
[k
].contrast
= value
;
3177 } else if (V4L2_CID_SATURATION
== easycap_control
[i
].id
) {
3179 for (k
= 0; k
< INPUT_MANY
; k
++)
3180 inputset
[k
].saturation
= value
;
3181 } else if (V4L2_CID_HUE
== easycap_control
[i
].id
) {
3183 for (k
= 0; k
< INPUT_MANY
; k
++)
3184 inputset
[k
].hue
= value
;
3189 SAM("ERROR: inputset[]->brightness underpopulated\n");
3192 for (k
= 0; k
< INPUT_MANY
; k
++)
3193 inputset
[k
].input
= k
;
3194 JOM(4, "populated inputset[]\n");
3195 JOM(4, "finished initialization\n");
3197 /*---------------------------------------------------------------------------*/
3201 * IDENTIFY THE APPROPRIATE POINTER peasycap FOR INTERFACES 1 AND 2.
3202 * THE ADDRESS OF peasycap->pusb_device IS RELUCTANTLY USED FOR THIS PURPOSE.
3204 /*---------------------------------------------------------------------------*/
3205 for (ndong
= 0; ndong
< DONGLE_MANY
; ndong
++) {
3206 if (usbdev
== easycapdc60_dongle
[ndong
].peasycap
->
3208 peasycap
= easycapdc60_dongle
[ndong
].peasycap
;
3209 JOT(8, "intf[%i]: dongle[%i].peasycap\n",
3210 bInterfaceNumber
, ndong
);
3214 if (DONGLE_MANY
<= ndong
) {
3215 SAY("ERROR: peasycap is unknown when probing interface %i\n",
3220 SAY("ERROR: peasycap is NULL when probing interface %i\n",
3225 /*---------------------------------------------------------------------------*/
3226 if ((USB_CLASS_VIDEO
== bInterfaceClass
) ||
3227 (USB_CLASS_VENDOR_SPEC
== bInterfaceClass
)) {
3228 if (-1 == peasycap
->video_interface
) {
3229 peasycap
->video_interface
= bInterfaceNumber
;
3230 JOM(4, "setting peasycap->video_interface=%i\n",
3231 peasycap
->video_interface
);
3233 if (peasycap
->video_interface
!= bInterfaceNumber
) {
3234 SAM("ERROR: attempting to reset "
3235 "peasycap->video_interface\n");
3236 SAM("...... continuing with "
3237 "%i=peasycap->video_interface\n",
3238 peasycap
->video_interface
);
3241 } else if ((USB_CLASS_AUDIO
== bInterfaceClass
) &&
3242 (USB_SUBCLASS_AUDIOSTREAMING
== bInterfaceSubClass
)) {
3243 if (-1 == peasycap
->audio_interface
) {
3244 peasycap
->audio_interface
= bInterfaceNumber
;
3245 JOM(4, "setting peasycap->audio_interface=%i\n",
3246 peasycap
->audio_interface
);
3248 if (peasycap
->audio_interface
!= bInterfaceNumber
) {
3249 SAM("ERROR: attempting to reset "
3250 "peasycap->audio_interface\n");
3251 SAM("...... continuing with "
3252 "%i=peasycap->audio_interface\n",
3253 peasycap
->audio_interface
);
3257 /*---------------------------------------------------------------------------*/
3259 * INVESTIGATE ALL ALTSETTINGS.
3260 * DONE IN DETAIL BECAUSE USB DEVICE 05e1:0408 HAS DISPARATE INCARNATIONS.
3262 /*---------------------------------------------------------------------------*/
3265 for (i
= 0; i
< intf
->num_altsetting
; i
++) {
3266 alt
= usb_altnum_to_altsetting(intf
, i
);
3268 SAM("ERROR: alt is NULL\n");
3271 interface
= &alt
->desc
;
3273 SAM("ERROR: intf_descriptor is NULL\n");
3277 if (0 == interface
->bNumEndpoints
)
3278 JOM(4, "intf[%i]alt[%i] has no endpoints\n",
3279 bInterfaceNumber
, i
);
3280 /*---------------------------------------------------------------------------*/
3281 for (j
= 0; j
< interface
->bNumEndpoints
; j
++) {
3282 ep
= &alt
->endpoint
[j
].desc
;
3284 SAM("ERROR: ep is NULL.\n");
3285 SAM("...... skipping\n");
3289 if (!usb_endpoint_is_isoc_in(ep
)) {
3290 JOM(4, "intf[%i]alt[%i]end[%i] is a %d endpoint\n",
3292 i
, j
, ep
->bmAttributes
);
3293 if (usb_endpoint_dir_out(ep
)) {
3294 SAM("ERROR: OUT endpoint unexpected\n");
3295 SAM("...... continuing\n");
3299 switch (bInterfaceClass
) {
3300 case USB_CLASS_VIDEO
:
3301 case USB_CLASS_VENDOR_SPEC
: {
3302 if (ep
->wMaxPacketSize
) {
3327 if (-1 == peasycap
->
3328 video_altsetting_off
) {
3330 video_altsetting_off
=
3336 video_altsetting_off
);
3338 SAM("ERROR: peasycap"
3339 "->video_altsetting_"
3340 "off already set\n");
3343 "%i=peasycap->video_"
3346 video_altsetting_off
);
3351 case USB_CLASS_AUDIO
: {
3352 if (bInterfaceSubClass
!=
3353 USB_SUBCLASS_AUDIOSTREAMING
)
3357 "peasycap is NULL\n");
3360 if (ep
->wMaxPacketSize
) {
3362 okalt
[isokalt
] = i
;
3385 if (-1 == peasycap
->
3386 audio_altsetting_off
) {
3388 audio_altsetting_off
=
3394 audio_altsetting_off
);
3396 SAM("ERROR: peasycap"
3397 "->audio_altsetting_"
3398 "off already set\n");
3405 audio_altsetting_off
);
3413 if (0 == ep
->wMaxPacketSize
) {
3414 JOM(4, "intf[%i]alt[%i]end[%i] "
3415 "has zero packet size\n",
3416 bInterfaceNumber
, i
, j
);
3420 /*---------------------------------------------------------------------------*/
3422 * PERFORM INITIALIZATION OF THE PROBED INTERFACE
3424 /*---------------------------------------------------------------------------*/
3425 JOM(4, "initialization begins for interface %i\n",
3426 interface
->bInterfaceNumber
);
3427 switch (bInterfaceNumber
) {
3428 /*---------------------------------------------------------------------------*/
3430 * INTERFACE 0 IS THE VIDEO INTERFACE
3432 /*---------------------------------------------------------------------------*/
3435 SAM("MISTAKE: peasycap is NULL\n");
3439 SAM("ERROR: no viable video_altsetting_on\n");
3442 peasycap
->video_altsetting_on
= okalt
[isokalt
- 1];
3443 JOM(4, "%i=video_altsetting_on <====\n",
3444 peasycap
->video_altsetting_on
);
3446 /*---------------------------------------------------------------------------*/
3448 * DECIDE THE VIDEO STREAMING PARAMETERS
3450 /*---------------------------------------------------------------------------*/
3451 peasycap
->video_endpointnumber
= okepn
[isokalt
- 1];
3452 JOM(4, "%i=video_endpointnumber\n", peasycap
->video_endpointnumber
);
3453 maxpacketsize
= okmps
[isokalt
- 1];
3455 peasycap
->video_isoc_maxframesize
=
3456 min(maxpacketsize
, USB_2_0_MAXPACKETSIZE
);
3457 if (0 >= peasycap
->video_isoc_maxframesize
) {
3458 SAM("ERROR: bad video_isoc_maxframesize\n");
3459 SAM(" possibly because port is USB 1.1\n");
3462 JOM(4, "%i=video_isoc_maxframesize\n",
3463 peasycap
->video_isoc_maxframesize
);
3465 peasycap
->video_isoc_framesperdesc
= VIDEO_ISOC_FRAMESPERDESC
;
3466 JOM(4, "%i=video_isoc_framesperdesc\n",
3467 peasycap
->video_isoc_framesperdesc
);
3468 if (0 >= peasycap
->video_isoc_framesperdesc
) {
3469 SAM("ERROR: bad video_isoc_framesperdesc\n");
3472 peasycap
->video_isoc_buffer_size
=
3473 peasycap
->video_isoc_maxframesize
*
3474 peasycap
->video_isoc_framesperdesc
;
3475 JOM(4, "%i=video_isoc_buffer_size\n",
3476 peasycap
->video_isoc_buffer_size
);
3477 if ((PAGE_SIZE
<< VIDEO_ISOC_ORDER
) <
3478 peasycap
->video_isoc_buffer_size
) {
3479 SAM("MISTAKE: peasycap->video_isoc_buffer_size too big\n");
3482 /*---------------------------------------------------------------------------*/
3483 if (-1 == peasycap
->video_interface
) {
3484 SAM("MISTAKE: video_interface is unset\n");
3487 if (-1 == peasycap
->video_altsetting_on
) {
3488 SAM("MISTAKE: video_altsetting_on is unset\n");
3491 if (-1 == peasycap
->video_altsetting_off
) {
3492 SAM("MISTAKE: video_interface_off is unset\n");
3495 if (-1 == peasycap
->video_endpointnumber
) {
3496 SAM("MISTAKE: video_endpointnumber is unset\n");
3499 if (-1 == peasycap
->video_isoc_maxframesize
) {
3500 SAM("MISTAKE: video_isoc_maxframesize is unset\n");
3503 if (-1 == peasycap
->video_isoc_buffer_size
) {
3504 SAM("MISTAKE: video_isoc_buffer_size is unset\n");
3507 /*---------------------------------------------------------------------------*/
3509 * ALLOCATE MEMORY FOR VIDEO BUFFERS. LISTS MUST BE INITIALIZED FIRST.
3511 /*---------------------------------------------------------------------------*/
3512 INIT_LIST_HEAD(&(peasycap
->urb_video_head
));
3513 peasycap
->purb_video_head
= &(peasycap
->urb_video_head
);
3514 /*---------------------------------------------------------------------------*/
3515 JOM(4, "allocating %i frame buffers of size %li\n",
3516 FRAME_BUFFER_MANY
, (long int)FRAME_BUFFER_SIZE
);
3517 JOM(4, ".... each scattered over %li pages\n",
3518 FRAME_BUFFER_SIZE
/PAGE_SIZE
);
3520 for (k
= 0; k
< FRAME_BUFFER_MANY
; k
++) {
3521 for (m
= 0; m
< FRAME_BUFFER_SIZE
/PAGE_SIZE
; m
++) {
3522 if (peasycap
->frame_buffer
[k
][m
].pgo
)
3523 SAM("attempting to reallocate frame "
3526 pbuf
= (void *)__get_free_page(GFP_KERNEL
);
3528 SAM("ERROR: Could not allocate frame "
3529 "buffer %i page %i\n", k
, m
);
3532 peasycap
->allocation_video_page
+= 1;
3533 peasycap
->frame_buffer
[k
][m
].pgo
= pbuf
;
3535 peasycap
->frame_buffer
[k
][m
].pto
=
3536 peasycap
->frame_buffer
[k
][m
].pgo
;
3540 peasycap
->frame_fill
= 0;
3541 peasycap
->frame_read
= 0;
3542 JOM(4, "allocation of frame buffers done: %i pages\n", k
*
3544 /*---------------------------------------------------------------------------*/
3545 JOM(4, "allocating %i field buffers of size %li\n",
3546 FIELD_BUFFER_MANY
, (long int)FIELD_BUFFER_SIZE
);
3547 JOM(4, ".... each scattered over %li pages\n",
3548 FIELD_BUFFER_SIZE
/PAGE_SIZE
);
3550 for (k
= 0; k
< FIELD_BUFFER_MANY
; k
++) {
3551 for (m
= 0; m
< FIELD_BUFFER_SIZE
/PAGE_SIZE
; m
++) {
3552 if (peasycap
->field_buffer
[k
][m
].pgo
) {
3553 SAM("ERROR: attempting to reallocate "
3556 pbuf
= (void *) __get_free_page(GFP_KERNEL
);
3558 SAM("ERROR: Could not allocate field"
3559 " buffer %i page %i\n", k
, m
);
3563 peasycap
->allocation_video_page
+= 1;
3564 peasycap
->field_buffer
[k
][m
].pgo
= pbuf
;
3566 peasycap
->field_buffer
[k
][m
].pto
=
3567 peasycap
->field_buffer
[k
][m
].pgo
;
3569 peasycap
->field_buffer
[k
][0].kount
= 0x0200;
3571 peasycap
->field_fill
= 0;
3572 peasycap
->field_page
= 0;
3573 peasycap
->field_read
= 0;
3574 JOM(4, "allocation of field buffers done: %i pages\n", k
*
3576 /*---------------------------------------------------------------------------*/
3577 JOM(4, "allocating %i isoc video buffers of size %i\n",
3578 VIDEO_ISOC_BUFFER_MANY
,
3579 peasycap
->video_isoc_buffer_size
);
3580 JOM(4, ".... each occupying contiguous memory pages\n");
3582 for (k
= 0; k
< VIDEO_ISOC_BUFFER_MANY
; k
++) {
3583 pbuf
= (void *)__get_free_pages(GFP_KERNEL
,
3586 SAM("ERROR: Could not allocate isoc video buffer "
3590 peasycap
->allocation_video_page
+=
3591 BIT(VIDEO_ISOC_ORDER
);
3593 peasycap
->video_isoc_buffer
[k
].pgo
= pbuf
;
3594 peasycap
->video_isoc_buffer
[k
].pto
=
3595 pbuf
+ peasycap
->video_isoc_buffer_size
;
3596 peasycap
->video_isoc_buffer
[k
].kount
= k
;
3598 JOM(4, "allocation of isoc video buffers done: %i pages\n",
3599 k
* (0x01 << VIDEO_ISOC_ORDER
));
3600 /*---------------------------------------------------------------------------*/
3602 * ALLOCATE AND INITIALIZE MULTIPLE struct urb ...
3604 /*---------------------------------------------------------------------------*/
3605 JOM(4, "allocating %i struct urb.\n", VIDEO_ISOC_BUFFER_MANY
);
3606 JOM(4, "using %i=peasycap->video_isoc_framesperdesc\n",
3607 peasycap
->video_isoc_framesperdesc
);
3608 JOM(4, "using %i=peasycap->video_isoc_maxframesize\n",
3609 peasycap
->video_isoc_maxframesize
);
3610 JOM(4, "using %i=peasycap->video_isoc_buffer_sizen",
3611 peasycap
->video_isoc_buffer_size
);
3613 for (k
= 0; k
< VIDEO_ISOC_BUFFER_MANY
; k
++) {
3614 purb
= usb_alloc_urb(peasycap
->video_isoc_framesperdesc
,
3617 SAM("ERROR: usb_alloc_urb returned NULL for buffer "
3621 peasycap
->allocation_video_urb
+= 1;
3622 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
3623 pdata_urb
= kzalloc(sizeof(struct data_urb
), GFP_KERNEL
);
3625 SAM("ERROR: Could not allocate struct data_urb.\n");
3628 peasycap
->allocation_video_struct
+=
3629 sizeof(struct data_urb
);
3631 pdata_urb
->purb
= purb
;
3632 pdata_urb
->isbuf
= k
;
3633 pdata_urb
->length
= 0;
3634 list_add_tail(&(pdata_urb
->list_head
),
3635 peasycap
->purb_video_head
);
3636 /*---------------------------------------------------------------------------*/
3638 * ... AND INITIALIZE THEM
3640 /*---------------------------------------------------------------------------*/
3642 JOM(4, "initializing video urbs thus:\n");
3643 JOM(4, " purb->interval = 1;\n");
3644 JOM(4, " purb->dev = peasycap->pusb_device;\n");
3645 JOM(4, " purb->pipe = usb_rcvisocpipe"
3646 "(peasycap->pusb_device,%i);\n",
3647 peasycap
->video_endpointnumber
);
3648 JOM(4, " purb->transfer_flags = URB_ISO_ASAP;\n");
3649 JOM(4, " purb->transfer_buffer = peasycap->"
3650 "video_isoc_buffer[.].pgo;\n");
3651 JOM(4, " purb->transfer_buffer_length = %i;\n",
3652 peasycap
->video_isoc_buffer_size
);
3653 JOM(4, " purb->complete = easycap_complete;\n");
3654 JOM(4, " purb->context = peasycap;\n");
3655 JOM(4, " purb->start_frame = 0;\n");
3656 JOM(4, " purb->number_of_packets = %i;\n",
3657 peasycap
->video_isoc_framesperdesc
);
3658 JOM(4, " for (j = 0; j < %i; j++)\n",
3659 peasycap
->video_isoc_framesperdesc
);
3661 JOM(4, " purb->iso_frame_desc[j].offset = j*%i;\n",
3662 peasycap
->video_isoc_maxframesize
);
3663 JOM(4, " purb->iso_frame_desc[j].length = %i;\n",
3664 peasycap
->video_isoc_maxframesize
);
3669 purb
->dev
= peasycap
->pusb_device
;
3670 purb
->pipe
= usb_rcvisocpipe(peasycap
->pusb_device
,
3671 peasycap
->video_endpointnumber
);
3672 purb
->transfer_flags
= URB_ISO_ASAP
;
3673 purb
->transfer_buffer
= peasycap
->video_isoc_buffer
[k
].pgo
;
3674 purb
->transfer_buffer_length
=
3675 peasycap
->video_isoc_buffer_size
;
3676 purb
->complete
= easycap_complete
;
3677 purb
->context
= peasycap
;
3678 purb
->start_frame
= 0;
3679 purb
->number_of_packets
= peasycap
->video_isoc_framesperdesc
;
3680 for (j
= 0; j
< peasycap
->video_isoc_framesperdesc
; j
++) {
3681 purb
->iso_frame_desc
[j
].offset
= j
*
3682 peasycap
->video_isoc_maxframesize
;
3683 purb
->iso_frame_desc
[j
].length
=
3684 peasycap
->video_isoc_maxframesize
;
3687 JOM(4, "allocation of %i struct urb done.\n", k
);
3688 /*--------------------------------------------------------------------------*/
3690 * SAVE POINTER peasycap IN THIS INTERFACE.
3692 /*--------------------------------------------------------------------------*/
3693 usb_set_intfdata(intf
, peasycap
);
3694 /*---------------------------------------------------------------------------*/
3696 * IT IS ESSENTIAL TO INITIALIZE THE HARDWARE BEFORE, RATHER THAN AFTER,
3697 * THE DEVICE IS REGISTERED, BECAUSE SOME VERSIONS OF THE videodev MODULE
3698 * CALL easycap_open() IMMEDIATELY AFTER REGISTRATION, CAUSING A CLASH.
3701 /*---------------------------------------------------------------------------*/
3702 peasycap
->ntsc
= easycap_ntsc
;
3703 JOM(8, "defaulting initially to %s\n",
3704 easycap_ntsc
? "NTSC" : "PAL");
3705 rc
= reset(peasycap
);
3707 SAM("ERROR: reset() rc = %i\n", rc
);
3710 /*--------------------------------------------------------------------------*/
3712 * THE VIDEO DEVICE CAN BE REGISTERED NOW, AS IT IS READY.
3714 /*--------------------------------------------------------------------------*/
3715 if (v4l2_device_register(&intf
->dev
, &peasycap
->v4l2_device
)) {
3716 SAM("v4l2_device_register() failed\n");
3719 JOM(4, "registered device instance: %s\n",
3720 peasycap
->v4l2_device
.name
);
3721 /*---------------------------------------------------------------------------*/
3726 * THIS IS BELIEVED TO BE HARMLESS, BUT MAY WELL BE UNNECESSARY OR WRONG:
3728 /*---------------------------------------------------------------------------*/
3729 peasycap
->video_device
.v4l2_dev
= NULL
;
3730 /*---------------------------------------------------------------------------*/
3733 strcpy(&peasycap
->video_device
.name
[0], "easycapdc60");
3734 peasycap
->video_device
.fops
= &v4l2_fops
;
3735 peasycap
->video_device
.minor
= -1;
3736 peasycap
->video_device
.release
= (void *)(&videodev_release
);
3738 video_set_drvdata(&(peasycap
->video_device
), (void *)peasycap
);
3740 if (0 != (video_register_device(&(peasycap
->video_device
),
3741 VFL_TYPE_GRABBER
, -1))) {
3742 err("Not able to register with videodev");
3743 videodev_release(&(peasycap
->video_device
));
3746 (peasycap
->registered_video
)++;
3747 SAM("registered with videodev: %i=minor\n",
3748 peasycap
->video_device
.minor
);
3749 peasycap
->minor
= peasycap
->video_device
.minor
;
3751 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
3755 /*--------------------------------------------------------------------------*/
3757 * INTERFACE 1 IS THE AUDIO CONTROL INTERFACE
3758 * INTERFACE 2 IS THE AUDIO STREAMING INTERFACE
3760 /*--------------------------------------------------------------------------*/
3763 SAM("MISTAKE: peasycap is NULL\n");
3766 /*--------------------------------------------------------------------------*/
3768 * SAVE POINTER peasycap IN INTERFACE 1
3770 /*--------------------------------------------------------------------------*/
3771 usb_set_intfdata(intf
, peasycap
);
3772 JOM(4, "no initialization required for interface %i\n",
3773 interface
->bInterfaceNumber
);
3776 /*--------------------------------------------------------------------------*/
3779 SAM("MISTAKE: peasycap is NULL\n");
3783 SAM("ERROR: no viable audio_altsetting_on\n");
3786 peasycap
->audio_altsetting_on
= okalt
[isokalt
- 1];
3787 JOM(4, "%i=audio_altsetting_on <====\n",
3788 peasycap
->audio_altsetting_on
);
3791 peasycap
->audio_endpointnumber
= okepn
[isokalt
- 1];
3792 JOM(4, "%i=audio_endpointnumber\n", peasycap
->audio_endpointnumber
);
3794 peasycap
->audio_isoc_maxframesize
= okmps
[isokalt
- 1];
3795 JOM(4, "%i=audio_isoc_maxframesize\n",
3796 peasycap
->audio_isoc_maxframesize
);
3797 if (0 >= peasycap
->audio_isoc_maxframesize
) {
3798 SAM("ERROR: bad audio_isoc_maxframesize\n");
3801 if (9 == peasycap
->audio_isoc_maxframesize
) {
3802 peasycap
->ilk
|= 0x02;
3803 SAM("audio hardware is microphone\n");
3804 peasycap
->microphone
= true;
3805 peasycap
->audio_pages_per_fragment
=
3806 PAGES_PER_AUDIO_FRAGMENT
;
3807 } else if (256 == peasycap
->audio_isoc_maxframesize
) {
3808 peasycap
->ilk
&= ~0x02;
3809 SAM("audio hardware is AC'97\n");
3810 peasycap
->microphone
= false;
3811 peasycap
->audio_pages_per_fragment
=
3812 PAGES_PER_AUDIO_FRAGMENT
;
3814 SAM("hardware is unidentified:\n");
3815 SAM("%i=audio_isoc_maxframesize\n",
3816 peasycap
->audio_isoc_maxframesize
);
3820 peasycap
->audio_bytes_per_fragment
=
3821 peasycap
->audio_pages_per_fragment
* PAGE_SIZE
;
3822 peasycap
->audio_buffer_page_many
= (AUDIO_FRAGMENT_MANY
*
3823 peasycap
->audio_pages_per_fragment
);
3825 JOM(4, "%6i=AUDIO_FRAGMENT_MANY\n", AUDIO_FRAGMENT_MANY
);
3826 JOM(4, "%6i=audio_pages_per_fragment\n",
3827 peasycap
->audio_pages_per_fragment
);
3828 JOM(4, "%6i=audio_bytes_per_fragment\n",
3829 peasycap
->audio_bytes_per_fragment
);
3830 JOM(4, "%6i=audio_buffer_page_many\n",
3831 peasycap
->audio_buffer_page_many
);
3833 peasycap
->audio_isoc_framesperdesc
= AUDIO_ISOC_FRAMESPERDESC
;
3835 JOM(4, "%i=audio_isoc_framesperdesc\n",
3836 peasycap
->audio_isoc_framesperdesc
);
3837 if (0 >= peasycap
->audio_isoc_framesperdesc
) {
3838 SAM("ERROR: bad audio_isoc_framesperdesc\n");
3842 peasycap
->audio_isoc_buffer_size
=
3843 peasycap
->audio_isoc_maxframesize
*
3844 peasycap
->audio_isoc_framesperdesc
;
3845 JOM(4, "%i=audio_isoc_buffer_size\n",
3846 peasycap
->audio_isoc_buffer_size
);
3847 if (AUDIO_ISOC_BUFFER_SIZE
< peasycap
->audio_isoc_buffer_size
) {
3848 SAM("MISTAKE: audio_isoc_buffer_size bigger "
3849 "than %li=AUDIO_ISOC_BUFFER_SIZE\n",
3850 AUDIO_ISOC_BUFFER_SIZE
);
3853 if (-1 == peasycap
->audio_interface
) {
3854 SAM("MISTAKE: audio_interface is unset\n");
3857 if (-1 == peasycap
->audio_altsetting_on
) {
3858 SAM("MISTAKE: audio_altsetting_on is unset\n");
3861 if (-1 == peasycap
->audio_altsetting_off
) {
3862 SAM("MISTAKE: audio_interface_off is unset\n");
3865 if (-1 == peasycap
->audio_endpointnumber
) {
3866 SAM("MISTAKE: audio_endpointnumber is unset\n");
3869 if (-1 == peasycap
->audio_isoc_maxframesize
) {
3870 SAM("MISTAKE: audio_isoc_maxframesize is unset\n");
3873 if (-1 == peasycap
->audio_isoc_buffer_size
) {
3874 SAM("MISTAKE: audio_isoc_buffer_size is unset\n");
3877 /*---------------------------------------------------------------------------*/
3879 * ALLOCATE MEMORY FOR AUDIO BUFFERS. LISTS MUST BE INITIALIZED FIRST.
3881 /*---------------------------------------------------------------------------*/
3882 INIT_LIST_HEAD(&(peasycap
->urb_audio_head
));
3883 peasycap
->purb_audio_head
= &(peasycap
->urb_audio_head
);
3885 /*---------------------------------------------------------------------------*/
3886 JOM(4, "allocating %i isoc audio buffers of size %i\n",
3887 AUDIO_ISOC_BUFFER_MANY
,
3888 peasycap
->audio_isoc_buffer_size
);
3889 JOM(4, ".... each occupying contiguous memory pages\n");
3891 for (k
= 0; k
< AUDIO_ISOC_BUFFER_MANY
; k
++) {
3892 pbuf
= (void *)__get_free_pages(GFP_KERNEL
,
3895 SAM("ERROR: Could not allocate isoc audio buffer "
3899 peasycap
->allocation_audio_page
+=
3900 BIT(AUDIO_ISOC_ORDER
);
3902 peasycap
->audio_isoc_buffer
[k
].pgo
= pbuf
;
3903 peasycap
->audio_isoc_buffer
[k
].pto
= pbuf
+
3904 peasycap
->audio_isoc_buffer_size
;
3905 peasycap
->audio_isoc_buffer
[k
].kount
= k
;
3907 JOM(4, "allocation of isoc audio buffers done.\n");
3908 /*---------------------------------------------------------------------------*/
3910 * ALLOCATE AND INITIALIZE MULTIPLE struct urb ...
3912 /*---------------------------------------------------------------------------*/
3913 JOM(4, "allocating %i struct urb.\n", AUDIO_ISOC_BUFFER_MANY
);
3914 JOM(4, "using %i=peasycap->audio_isoc_framesperdesc\n",
3915 peasycap
->audio_isoc_framesperdesc
);
3916 JOM(4, "using %i=peasycap->audio_isoc_maxframesize\n",
3917 peasycap
->audio_isoc_maxframesize
);
3918 JOM(4, "using %i=peasycap->audio_isoc_buffer_size\n",
3919 peasycap
->audio_isoc_buffer_size
);
3921 for (k
= 0; k
< AUDIO_ISOC_BUFFER_MANY
; k
++) {
3922 purb
= usb_alloc_urb(peasycap
->audio_isoc_framesperdesc
,
3925 SAM("ERROR: usb_alloc_urb returned NULL for buffer "
3929 peasycap
->allocation_audio_urb
+= 1 ;
3930 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
3931 pdata_urb
= kzalloc(sizeof(struct data_urb
), GFP_KERNEL
);
3933 SAM("ERROR: Could not allocate struct data_urb.\n");
3936 peasycap
->allocation_audio_struct
+=
3937 sizeof(struct data_urb
);
3939 pdata_urb
->purb
= purb
;
3940 pdata_urb
->isbuf
= k
;
3941 pdata_urb
->length
= 0;
3942 list_add_tail(&(pdata_urb
->list_head
),
3943 peasycap
->purb_audio_head
);
3944 /*---------------------------------------------------------------------------*/
3946 * ... AND INITIALIZE THEM
3948 /*---------------------------------------------------------------------------*/
3950 JOM(4, "initializing audio urbs thus:\n");
3951 JOM(4, " purb->interval = 1;\n");
3952 JOM(4, " purb->dev = peasycap->pusb_device;\n");
3953 JOM(4, " purb->pipe = usb_rcvisocpipe(peasycap->"
3954 "pusb_device,%i);\n",
3955 peasycap
->audio_endpointnumber
);
3956 JOM(4, " purb->transfer_flags = URB_ISO_ASAP;\n");
3957 JOM(4, " purb->transfer_buffer = "
3958 "peasycap->audio_isoc_buffer[.].pgo;\n");
3959 JOM(4, " purb->transfer_buffer_length = %i;\n",
3960 peasycap
->audio_isoc_buffer_size
);
3961 JOM(4, " purb->complete = easycap_alsa_complete;\n");
3962 JOM(4, " purb->context = peasycap;\n");
3963 JOM(4, " purb->start_frame = 0;\n");
3964 JOM(4, " purb->number_of_packets = %i;\n",
3965 peasycap
->audio_isoc_framesperdesc
);
3966 JOM(4, " for (j = 0; j < %i; j++)\n",
3967 peasycap
->audio_isoc_framesperdesc
);
3969 JOM(4, " purb->iso_frame_desc[j].offset = j*%i;\n",
3970 peasycap
->audio_isoc_maxframesize
);
3971 JOM(4, " purb->iso_frame_desc[j].length = %i;\n",
3972 peasycap
->audio_isoc_maxframesize
);
3977 purb
->dev
= peasycap
->pusb_device
;
3978 purb
->pipe
= usb_rcvisocpipe(peasycap
->pusb_device
,
3979 peasycap
->audio_endpointnumber
);
3980 purb
->transfer_flags
= URB_ISO_ASAP
;
3981 purb
->transfer_buffer
= peasycap
->audio_isoc_buffer
[k
].pgo
;
3982 purb
->transfer_buffer_length
=
3983 peasycap
->audio_isoc_buffer_size
;
3984 purb
->complete
= easycap_alsa_complete
;
3985 purb
->context
= peasycap
;
3986 purb
->start_frame
= 0;
3987 purb
->number_of_packets
= peasycap
->audio_isoc_framesperdesc
;
3988 for (j
= 0; j
< peasycap
->audio_isoc_framesperdesc
; j
++) {
3989 purb
->iso_frame_desc
[j
].offset
= j
*
3990 peasycap
->audio_isoc_maxframesize
;
3991 purb
->iso_frame_desc
[j
].length
=
3992 peasycap
->audio_isoc_maxframesize
;
3995 JOM(4, "allocation of %i struct urb done.\n", k
);
3996 /*---------------------------------------------------------------------------*/
3998 * SAVE POINTER peasycap IN THIS INTERFACE.
4000 /*---------------------------------------------------------------------------*/
4001 usb_set_intfdata(intf
, peasycap
);
4002 /*---------------------------------------------------------------------------*/
4004 * THE AUDIO DEVICE CAN BE REGISTERED NOW, AS IT IS READY.
4006 /*---------------------------------------------------------------------------*/
4007 JOM(4, "initializing ALSA card\n");
4009 rc
= easycap_alsa_probe(peasycap
);
4011 err("easycap_alsa_probe() rc = %i\n", rc
);
4016 JOM(8, "kref_get() with %i=kref.refcount.counter\n",
4017 peasycap
->kref
.refcount
.counter
);
4018 kref_get(&peasycap
->kref
);
4019 peasycap
->registered_audio
++;
4022 /*---------------------------------------------------------------------------*/
4024 * INTERFACES OTHER THAN 0, 1 AND 2 ARE UNEXPECTED
4026 /*---------------------------------------------------------------------------*/
4028 JOM(4, "ERROR: unexpected interface %i\n", bInterfaceNumber
);
4031 SAM("ends successfully for interface %i\n", bInterfaceNumber
);
4034 /*****************************************************************************/
4035 /*---------------------------------------------------------------------------*/
4037 * WHEN THIS FUNCTION IS CALLED THE EasyCAP HAS ALREADY BEEN PHYSICALLY
4038 * UNPLUGGED. HENCE peasycap->pusb_device IS NO LONGER VALID.
4040 * THIS FUNCTION AFFECTS ALSA. BEWARE.
4042 /*---------------------------------------------------------------------------*/
4043 static void easycap_usb_disconnect(struct usb_interface
*pusb_interface
)
4045 struct usb_host_interface
*pusb_host_interface
;
4046 struct usb_interface_descriptor
*pusb_interface_descriptor
;
4047 u8 bInterfaceNumber
;
4048 struct easycap
*peasycap
;
4050 struct list_head
*plist_head
;
4051 struct data_urb
*pdata_urb
;
4056 pusb_host_interface
= pusb_interface
->cur_altsetting
;
4057 if (!pusb_host_interface
) {
4058 JOT(4, "ERROR: pusb_host_interface is NULL\n");
4061 pusb_interface_descriptor
= &(pusb_host_interface
->desc
);
4062 if (!pusb_interface_descriptor
) {
4063 JOT(4, "ERROR: pusb_interface_descriptor is NULL\n");
4066 bInterfaceNumber
= pusb_interface_descriptor
->bInterfaceNumber
;
4067 minor
= pusb_interface
->minor
;
4068 JOT(4, "intf[%i]: minor=%i\n", bInterfaceNumber
, minor
);
4070 if (1 == bInterfaceNumber
)
4073 peasycap
= usb_get_intfdata(pusb_interface
);
4075 SAY("ERROR: peasycap is NULL\n");
4078 /*---------------------------------------------------------------------------*/
4080 * IF THE WAIT QUEUES ARE NOT CLEARED A DEADLOCK IS POSSIBLE. BEWARE.
4082 /*---------------------------------------------------------------------------*/
4083 peasycap
->video_eof
= 1;
4084 peasycap
->audio_eof
= 1;
4085 wake_up_interruptible(&(peasycap
->wq_video
));
4086 wake_up_interruptible(&(peasycap
->wq_audio
));
4087 /*---------------------------------------------------------------------------*/
4088 switch (bInterfaceNumber
) {
4090 if (peasycap
->purb_video_head
) {
4091 JOM(4, "killing video urbs\n");
4093 list_for_each(plist_head
, peasycap
->purb_video_head
) {
4094 pdata_urb
= list_entry(plist_head
,
4095 struct data_urb
, list_head
);
4097 if (pdata_urb
->purb
) {
4098 usb_kill_urb(pdata_urb
->purb
);
4103 JOM(4, "%i video urbs killed\n", m
);
4107 /*---------------------------------------------------------------------------*/
4109 if (peasycap
->purb_audio_head
) {
4110 JOM(4, "killing audio urbs\n");
4112 list_for_each(plist_head
, peasycap
->purb_audio_head
) {
4113 pdata_urb
= list_entry(plist_head
,
4114 struct data_urb
, list_head
);
4116 if (pdata_urb
->purb
) {
4117 usb_kill_urb(pdata_urb
->purb
);
4122 JOM(4, "%i audio urbs killed\n", m
);
4129 /*--------------------------------------------------------------------------*/
4133 * THIS PROCEDURE WILL BLOCK UNTIL easycap_poll(), VIDEO IOCTL AND AUDIO
4134 * IOCTL ARE ALL UNLOCKED. IF THIS IS NOT DONE AN Oops CAN OCCUR WHEN
4135 * AN EasyCAP IS UNPLUGGED WHILE THE URBS ARE RUNNING. BEWARE.
4137 /*--------------------------------------------------------------------------*/
4138 kd
= isdongle(peasycap
);
4139 switch (bInterfaceNumber
) {
4141 if (0 <= kd
&& DONGLE_MANY
> kd
) {
4142 wake_up_interruptible(&peasycap
->wq_video
);
4143 JOM(4, "about to lock dongle[%i].mutex_video\n", kd
);
4144 if (mutex_lock_interruptible(&easycapdc60_dongle
[kd
].
4147 "cannot lock dongle[%i].mutex_video\n", kd
);
4150 JOM(4, "locked dongle[%i].mutex_video\n", kd
);
4152 SAY("ERROR: %i=kd is bad: cannot lock dongle\n", kd
);
4154 /*---------------------------------------------------------------------------*/
4155 if (!peasycap
->v4l2_device
.name
[0]) {
4156 SAM("ERROR: peasycap->v4l2_device.name is empty\n");
4157 if (0 <= kd
&& DONGLE_MANY
> kd
)
4158 mutex_unlock(&easycapdc60_dongle
[kd
].mutex_video
);
4161 v4l2_device_disconnect(&peasycap
->v4l2_device
);
4162 JOM(4, "v4l2_device_disconnect() OK\n");
4163 v4l2_device_unregister(&peasycap
->v4l2_device
);
4164 JOM(4, "v4l2_device_unregister() OK\n");
4166 video_unregister_device(&peasycap
->video_device
);
4167 JOM(4, "intf[%i]: video_unregister_device() minor=%i\n",
4168 bInterfaceNumber
, minor
);
4169 peasycap
->registered_video
--;
4170 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
4172 if (0 <= kd
&& DONGLE_MANY
> kd
) {
4173 mutex_unlock(&easycapdc60_dongle
[kd
].mutex_video
);
4174 JOM(4, "unlocked dongle[%i].mutex_video\n", kd
);
4179 if (0 <= kd
&& DONGLE_MANY
> kd
) {
4180 wake_up_interruptible(&peasycap
->wq_audio
);
4181 JOM(4, "about to lock dongle[%i].mutex_audio\n", kd
);
4182 if (mutex_lock_interruptible(&easycapdc60_dongle
[kd
].
4185 "cannot lock dongle[%i].mutex_audio\n", kd
);
4188 JOM(4, "locked dongle[%i].mutex_audio\n", kd
);
4190 SAY("ERROR: %i=kd is bad: cannot lock dongle\n", kd
);
4191 if (0 != snd_card_free(peasycap
->psnd_card
)) {
4192 SAY("ERROR: snd_card_free() failed\n");
4194 peasycap
->psnd_card
= NULL
;
4195 (peasycap
->registered_audio
)--;
4197 if (0 <= kd
&& DONGLE_MANY
> kd
) {
4198 mutex_unlock(&easycapdc60_dongle
[kd
].mutex_audio
);
4199 JOM(4, "unlocked dongle[%i].mutex_audio\n", kd
);
4206 /*---------------------------------------------------------------------------*/
4208 * CALL easycap_delete() IF NO REMAINING REFERENCES TO peasycap
4209 * (ALSO WHEN ALSA HAS BEEN IN USE)
4211 /*---------------------------------------------------------------------------*/
4212 if (!peasycap
->kref
.refcount
.counter
) {
4213 SAM("ERROR: peasycap->kref.refcount.counter is zero "
4214 "so cannot call kref_put()\n");
4215 SAM("ending unsuccessfully: may cause memory leak\n");
4218 if (0 <= kd
&& DONGLE_MANY
> kd
) {
4219 JOM(4, "about to lock dongle[%i].mutex_video\n", kd
);
4220 if (mutex_lock_interruptible(&easycapdc60_dongle
[kd
].mutex_video
)) {
4221 SAY("ERROR: cannot lock dongle[%i].mutex_video\n", kd
);
4222 SAM("ending unsuccessfully: may cause memory leak\n");
4225 JOM(4, "locked dongle[%i].mutex_video\n", kd
);
4226 JOM(4, "about to lock dongle[%i].mutex_audio\n", kd
);
4227 if (mutex_lock_interruptible(&easycapdc60_dongle
[kd
].mutex_audio
)) {
4228 SAY("ERROR: cannot lock dongle[%i].mutex_audio\n", kd
);
4229 mutex_unlock(&(easycapdc60_dongle
[kd
].mutex_video
));
4230 JOM(4, "unlocked dongle[%i].mutex_video\n", kd
);
4231 SAM("ending unsuccessfully: may cause memory leak\n");
4234 JOM(4, "locked dongle[%i].mutex_audio\n", kd
);
4236 JOM(4, "intf[%i]: %i=peasycap->kref.refcount.counter\n",
4237 bInterfaceNumber
, (int)peasycap
->kref
.refcount
.counter
);
4238 kref_put(&peasycap
->kref
, easycap_delete
);
4239 JOT(4, "intf[%i]: kref_put() done.\n", bInterfaceNumber
);
4240 if (0 <= kd
&& DONGLE_MANY
> kd
) {
4241 mutex_unlock(&(easycapdc60_dongle
[kd
].mutex_audio
));
4242 JOT(4, "unlocked dongle[%i].mutex_audio\n", kd
);
4243 mutex_unlock(&easycapdc60_dongle
[kd
].mutex_video
);
4244 JOT(4, "unlocked dongle[%i].mutex_video\n", kd
);
4246 /*---------------------------------------------------------------------------*/
4250 /*****************************************************************************/
4252 /*---------------------------------------------------------------------------*/
4254 * PARAMETERS APPLICABLE TO ENTIRE DRIVER, I.E. BOTH VIDEO AND AUDIO
4256 /*---------------------------------------------------------------------------*/
4257 static struct usb_device_id easycap_usb_device_id_table
[] = {
4258 {USB_DEVICE(USB_EASYCAP_VENDOR_ID
, USB_EASYCAP_PRODUCT_ID
)},
4262 MODULE_DEVICE_TABLE(usb
, easycap_usb_device_id_table
);
4263 struct usb_driver easycap_usb_driver
= {
4265 .id_table
= easycap_usb_device_id_table
,
4266 .probe
= easycap_usb_probe
,
4267 .disconnect
= easycap_usb_disconnect
,
4270 static int __init
easycap_module_init(void)
4274 printk(KERN_INFO
"Easycap version: "EASYCAP_DRIVER_VERSION
"\n");
4276 JOT(4, "begins. %i=debug %i=bars %i=gain\n",
4277 easycap_debug
, easycap_bars
, easycap_gain
);
4279 mutex_init(&mutex_dongle
);
4280 for (k
= 0; k
< DONGLE_MANY
; k
++) {
4281 easycapdc60_dongle
[k
].peasycap
= NULL
;
4282 mutex_init(&easycapdc60_dongle
[k
].mutex_video
);
4283 mutex_init(&easycapdc60_dongle
[k
].mutex_audio
);
4285 rc
= usb_register(&easycap_usb_driver
);
4287 printk(KERN_ERR
"Easycap: usb_register failed rc=%d\n", rc
);
4291 /*****************************************************************************/
4292 static void __exit
easycap_module_exit(void)
4294 usb_deregister(&easycap_usb_driver
);
4296 /*****************************************************************************/
4298 module_init(easycap_module_init
);
4299 module_exit(easycap_module_exit
);
4301 /*****************************************************************************/