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 (memcmp(&peasycap
->telltale
[0], TELLTALE
, strlen(TELLTALE
))) {
162 SAY("ERROR: bad peasycap: %p\n", peasycap
);
165 if (!peasycap
->pusb_device
) {
166 SAM("ERROR: peasycap->pusb_device is NULL\n");
169 JOM(16, "peasycap->pusb_device=%p\n", peasycap
->pusb_device
);
171 file
->private_data
= peasycap
;
172 rc
= wakeup_device(peasycap
->pusb_device
);
174 JOM(8, "wakeup_device() OK\n");
176 SAM("ERROR: wakeup_device() rc = %i\n", rc
);
178 SAM("ERROR: wakeup_device() returned -ENODEV\n");
180 SAM("ERROR: wakeup_device() rc = %i\n", rc
);
184 rc
= reset(peasycap
);
186 SAM("ERROR: reset() rc = %i\n", rc
);
192 /*****************************************************************************/
193 /*---------------------------------------------------------------------------*/
195 * RESET THE HARDWARE TO ITS REFERENCE STATE.
197 * THIS ROUTINE MAY BE CALLED REPEATEDLY IF easycap_complete() DETECTS
198 * A BAD VIDEO FRAME SIZE.
200 /*---------------------------------------------------------------------------*/
201 static int reset(struct easycap
*peasycap
)
203 struct easycap_standard
const *peasycap_standard
;
204 int fmtidx
, input
, rate
;
209 SAY("ERROR: peasycap is NULL\n");
212 input
= peasycap
->input
;
214 /*---------------------------------------------------------------------------*/
216 * IF THE SAA7113H HAS ALREADY ACQUIRED SYNC, USE ITS HARDWARE-DETECTED
217 * FIELD FREQUENCY TO DISTINGUISH NTSC FROM PAL. THIS IS ESSENTIAL FOR
218 * gstreamer AND OTHER USERSPACE PROGRAMS WHICH MAY NOT ATTEMPT TO INITIATE
219 * A SWITCH BETWEEN PAL AND NTSC.
221 * FUNCTION ready_saa() MAY REQUIRE A SUBSTANTIAL FRACTION OF A SECOND TO
222 * COMPLETE, SO SHOULD NOT BE INVOKED WITHOUT GOOD REASON.
224 /*---------------------------------------------------------------------------*/
226 JOM(8, "peasycap->ntsc=%d\n", peasycap
->ntsc
);
228 rate
= ready_saa(peasycap
->pusb_device
);
230 JOM(8, "not ready to capture after %i ms ...\n", PATIENCE
);
231 ntsc
= !peasycap
->ntsc
;
232 JOM(8, "... trying %s ..\n", ntsc
? "NTSC" : "PAL");
233 rc
= setup_stk(peasycap
->pusb_device
, ntsc
);
235 SAM("ERROR: setup_stk() rc = %i\n", rc
);
238 rc
= setup_saa(peasycap
->pusb_device
, ntsc
);
240 SAM("ERROR: setup_saa() rc = %i\n", rc
);
244 rate
= ready_saa(peasycap
->pusb_device
);
246 JOM(8, "not ready to capture after %i ms\n", PATIENCE
);
247 JOM(8, "... saa register 0x1F has 0x%02X\n",
248 read_saa(peasycap
->pusb_device
, 0x1F));
249 ntsc
= peasycap
->ntsc
;
251 JOM(8, "... success at second try: %i=rate\n", rate
);
252 ntsc
= (0 < (rate
/2)) ? true : false ;
256 JOM(8, "... success at first try: %i=rate\n", rate
);
257 ntsc
= (0 < rate
/2) ? true : false ;
259 JOM(8, "ntsc=%d\n", ntsc
);
260 /*---------------------------------------------------------------------------*/
262 rc
= setup_stk(peasycap
->pusb_device
, ntsc
);
264 SAM("ERROR: setup_stk() rc = %i\n", rc
);
267 rc
= setup_saa(peasycap
->pusb_device
, ntsc
);
269 SAM("ERROR: setup_saa() rc = %i\n", rc
);
273 memset(peasycap
->merit
, 0, sizeof(peasycap
->merit
));
275 peasycap
->video_eof
= 0;
276 peasycap
->audio_eof
= 0;
277 do_gettimeofday(&peasycap
->timeval7
);
278 /*---------------------------------------------------------------------------*/
280 * RESTORE INPUT AND FORCE REFRESH OF STANDARD, FORMAT, ETC.
282 * WHILE THIS PROCEDURE IS IN PROGRESS, SOME IOCTL COMMANDS WILL RETURN -EBUSY.
284 /*---------------------------------------------------------------------------*/
285 peasycap
->input
= -8192;
286 peasycap
->standard_offset
= -8192;
287 fmtidx
= ntsc
? NTSC_M
: PAL_BGHIN
;
289 peasycap_standard
= &easycap_standard
[0];
290 while (0xFFFF != peasycap_standard
->mask
) {
291 if (fmtidx
== peasycap_standard
->v4l2_standard
.index
) {
292 peasycap
->inputset
[input
].standard_offset
=
293 peasycap_standard
- easycap_standard
;
298 if (0xFFFF == peasycap_standard
->mask
) {
299 SAM("ERROR: standard not found\n");
302 JOM(8, "%i=peasycap->inputset[%i].standard_offset\n",
303 peasycap
->inputset
[input
].standard_offset
, input
);
305 peasycap
->format_offset
= -8192;
306 peasycap
->brightness
= -8192;
307 peasycap
->contrast
= -8192;
308 peasycap
->saturation
= -8192;
309 peasycap
->hue
= -8192;
311 rc
= newinput(peasycap
, input
);
314 SAM("ERROR: newinput(.,%i) rc = %i\n", rc
, input
);
317 JOM(4, "restored input, standard and format\n");
319 JOM(8, "true=peasycap->ntsc %d\n", peasycap
->ntsc
);
321 if (0 > peasycap
->input
) {
322 SAM("MISTAKE: %i=peasycap->input\n", peasycap
->input
);
325 if (0 > peasycap
->standard_offset
) {
326 SAM("MISTAKE: %i=peasycap->standard_offset\n",
327 peasycap
->standard_offset
);
330 if (0 > peasycap
->format_offset
) {
331 SAM("MISTAKE: %i=peasycap->format_offset\n",
332 peasycap
->format_offset
);
335 if (0 > peasycap
->brightness
) {
336 SAM("MISTAKE: %i=peasycap->brightness\n",
337 peasycap
->brightness
);
340 if (0 > peasycap
->contrast
) {
341 SAM("MISTAKE: %i=peasycap->contrast\n", peasycap
->contrast
);
344 if (0 > peasycap
->saturation
) {
345 SAM("MISTAKE: %i=peasycap->saturation\n",
346 peasycap
->saturation
);
349 if (0 > peasycap
->hue
) {
350 SAM("MISTAKE: %i=peasycap->hue\n", peasycap
->hue
);
355 /*****************************************************************************/
356 /*---------------------------------------------------------------------------*/
358 * IF THE REQUESTED INPUT IS THE SAME AS THE EXISTING INPUT, DO NOTHING.
360 * KILL URBS, CLEAR FIELD AND FRAME BUFFERS AND RESET THEIR
361 * _read AND _fill POINTERS.
362 * SELECT THE NEW INPUT.
363 * ADJUST THE STANDARD, FORMAT, BRIGHTNESS, CONTRAST, SATURATION AND HUE
364 * ON THE BASIS OF INFORMATION IN STRUCTURE easycap.inputset[input].
365 * RESUBMIT THE URBS IF STREAMING WAS ALREADY IN PROGRESS.
368 * THIS ROUTINE MAY BE CALLED FREQUENTLY BY ZONEMINDER VIA IOCTL,
369 * SO IT SHOULD WRITE ONLY SPARINGLY TO THE LOGFILE.
371 /*---------------------------------------------------------------------------*/
373 newinput(struct easycap
*peasycap
, int input
)
375 int rc
, k
, m
, mood
, off
;
376 int inputnow
, video_idlenow
, audio_idlenow
;
380 SAY("ERROR: peasycap is NULL\n");
383 JOM(8, "%i=input sought\n", input
);
385 if (0 > input
&& INPUT_MANY
<= input
)
387 inputnow
= peasycap
->input
;
388 if (input
== inputnow
)
390 /*---------------------------------------------------------------------------*/
392 * IF STREAMING IS IN PROGRESS THE URBS ARE KILLED AT THIS
393 * STAGE AND WILL BE RESUBMITTED PRIOR TO EXIT FROM THE ROUTINE.
394 * IF NO STREAMING IS IN PROGRESS NO URBS WILL BE SUBMITTED BY THE
397 /*---------------------------------------------------------------------------*/
398 video_idlenow
= peasycap
->video_idle
;
399 audio_idlenow
= peasycap
->audio_idle
;
401 peasycap
->video_idle
= 1;
402 peasycap
->audio_idle
= 1;
403 if (peasycap
->video_isoc_streaming
) {
405 kill_video_urbs(peasycap
);
409 /*---------------------------------------------------------------------------*/
410 if (!peasycap
->pusb_device
) {
411 SAM("ERROR: peasycap->pusb_device is NULL\n");
414 rc
= usb_set_interface(peasycap
->pusb_device
,
415 peasycap
->video_interface
,
416 peasycap
->video_altsetting_off
);
418 SAM("ERROR: usb_set_interface() rc = %i\n", rc
);
421 rc
= stop_100(peasycap
->pusb_device
);
423 SAM("ERROR: stop_100() rc = %i\n", rc
);
426 for (k
= 0; k
< FIELD_BUFFER_MANY
; k
++) {
427 for (m
= 0; m
< FIELD_BUFFER_SIZE
/PAGE_SIZE
; m
++)
428 memset(peasycap
->field_buffer
[k
][m
].pgo
, 0, PAGE_SIZE
);
430 for (k
= 0; k
< FRAME_BUFFER_MANY
; k
++) {
431 for (m
= 0; m
< FRAME_BUFFER_SIZE
/PAGE_SIZE
; m
++)
432 memset(peasycap
->frame_buffer
[k
][m
].pgo
, 0, PAGE_SIZE
);
434 peasycap
->field_page
= 0;
435 peasycap
->field_read
= 0;
436 peasycap
->field_fill
= 0;
438 peasycap
->frame_read
= 0;
439 peasycap
->frame_fill
= 0;
440 for (k
= 0; k
< peasycap
->input
; k
++) {
441 (peasycap
->frame_fill
)++;
442 if (peasycap
->frame_buffer_many
<= peasycap
->frame_fill
)
443 peasycap
->frame_fill
= 0;
445 peasycap
->input
= input
;
446 select_input(peasycap
->pusb_device
, peasycap
->input
, 9);
447 /*---------------------------------------------------------------------------*/
448 if (input
== peasycap
->inputset
[input
].input
) {
449 off
= peasycap
->inputset
[input
].standard_offset
;
450 if (off
!= peasycap
->standard_offset
) {
451 rc
= adjust_standard(peasycap
,
452 easycap_standard
[off
].v4l2_standard
.id
);
454 SAM("ERROR: adjust_standard() rc = %i\n", rc
);
457 JOM(8, "%i=peasycap->standard_offset\n",
458 peasycap
->standard_offset
);
460 JOM(8, "%i=peasycap->standard_offset unchanged\n",
461 peasycap
->standard_offset
);
463 off
= peasycap
->inputset
[input
].format_offset
;
464 if (off
!= peasycap
->format_offset
) {
465 struct v4l2_pix_format
*pix
=
466 &easycap_format
[off
].v4l2_format
.fmt
.pix
;
467 rc
= adjust_format(peasycap
,
468 pix
->width
, pix
->height
,
469 pix
->pixelformat
, pix
->field
, false);
471 SAM("ERROR: adjust_format() rc = %i\n", rc
);
474 JOM(8, "%i=peasycap->format_offset\n",
475 peasycap
->format_offset
);
477 JOM(8, "%i=peasycap->format_offset unchanged\n",
478 peasycap
->format_offset
);
480 mood
= peasycap
->inputset
[input
].brightness
;
481 if (mood
!= peasycap
->brightness
) {
482 rc
= adjust_brightness(peasycap
, mood
);
484 SAM("ERROR: adjust_brightness rc = %i\n", rc
);
487 JOM(8, "%i=peasycap->brightness\n",
488 peasycap
->brightness
);
490 mood
= peasycap
->inputset
[input
].contrast
;
491 if (mood
!= peasycap
->contrast
) {
492 rc
= adjust_contrast(peasycap
, mood
);
494 SAM("ERROR: adjust_contrast rc = %i\n", rc
);
497 JOM(8, "%i=peasycap->contrast\n", peasycap
->contrast
);
499 mood
= peasycap
->inputset
[input
].saturation
;
500 if (mood
!= peasycap
->saturation
) {
501 rc
= adjust_saturation(peasycap
, mood
);
503 SAM("ERROR: adjust_saturation rc = %i\n", rc
);
506 JOM(8, "%i=peasycap->saturation\n",
507 peasycap
->saturation
);
509 mood
= peasycap
->inputset
[input
].hue
;
510 if (mood
!= peasycap
->hue
) {
511 rc
= adjust_hue(peasycap
, mood
);
513 SAM("ERROR: adjust_hue rc = %i\n", rc
);
516 JOM(8, "%i=peasycap->hue\n", peasycap
->hue
);
519 SAM("MISTAKE: easycap.inputset[%i] unpopulated\n", input
);
522 /*---------------------------------------------------------------------------*/
523 if (!peasycap
->pusb_device
) {
524 SAM("ERROR: peasycap->pusb_device is NULL\n");
527 rc
= usb_set_interface(peasycap
->pusb_device
,
528 peasycap
->video_interface
,
529 peasycap
->video_altsetting_on
);
531 SAM("ERROR: usb_set_interface() rc = %i\n", rc
);
534 rc
= start_100(peasycap
->pusb_device
);
536 SAM("ERROR: start_100() rc = %i\n", rc
);
540 submit_video_urbs(peasycap
);
542 peasycap
->video_isoc_sequence
= VIDEO_ISOC_BUFFER_MANY
- 1;
543 peasycap
->video_idle
= video_idlenow
;
544 peasycap
->audio_idle
= audio_idlenow
;
545 peasycap
->video_junk
= 0;
549 /*****************************************************************************/
550 int submit_video_urbs(struct easycap
*peasycap
)
552 struct data_urb
*pdata_urb
;
554 struct list_head
*plist_head
;
555 int j
, isbad
, nospc
, m
, rc
;
559 SAY("ERROR: peasycap is NULL\n");
563 if (!peasycap
->purb_video_head
) {
564 SAY("ERROR: peasycap->urb_video_head uninitialized\n");
567 if (!peasycap
->pusb_device
) {
568 SAY("ERROR: peasycap->pusb_device is NULL\n");
571 if (!peasycap
->video_isoc_streaming
) {
572 JOM(4, "submission of all video urbs\n");
573 isbad
= 0; nospc
= 0; m
= 0;
574 list_for_each(plist_head
, (peasycap
->purb_video_head
)) {
575 pdata_urb
= list_entry(plist_head
,
576 struct data_urb
, list_head
);
577 if (pdata_urb
&& pdata_urb
->purb
) {
578 purb
= pdata_urb
->purb
;
579 isbuf
= pdata_urb
->isbuf
;
581 purb
->dev
= peasycap
->pusb_device
;
583 usb_rcvisocpipe(peasycap
->pusb_device
,
584 peasycap
->video_endpointnumber
);
585 purb
->transfer_flags
= URB_ISO_ASAP
;
586 purb
->transfer_buffer
=
587 peasycap
->video_isoc_buffer
[isbuf
].pgo
;
588 purb
->transfer_buffer_length
=
589 peasycap
->video_isoc_buffer_size
;
590 purb
->complete
= easycap_complete
;
591 purb
->context
= peasycap
;
592 purb
->start_frame
= 0;
593 purb
->number_of_packets
=
594 peasycap
->video_isoc_framesperdesc
;
596 for (j
= 0; j
< peasycap
->video_isoc_framesperdesc
; j
++) {
597 purb
->iso_frame_desc
[j
]. offset
=
598 j
* peasycap
->video_isoc_maxframesize
;
599 purb
->iso_frame_desc
[j
]. length
=
600 peasycap
->video_isoc_maxframesize
;
603 rc
= usb_submit_urb(purb
, GFP_KERNEL
);
606 SAM("ERROR: usb_submit_urb() failed "
607 "for urb with rc:-%s\n",
619 SAM("-ENOSPC=usb_submit_urb() for %i urbs\n", nospc
);
620 SAM("..... possibly inadequate USB bandwidth\n");
621 peasycap
->video_eof
= 1;
625 JOM(4, "attempting cleanup instead of submitting\n");
626 list_for_each(plist_head
, (peasycap
->purb_video_head
)) {
627 pdata_urb
= list_entry(plist_head
,
628 struct data_urb
, list_head
);
630 purb
= pdata_urb
->purb
;
635 peasycap
->video_isoc_streaming
= 0;
637 peasycap
->video_isoc_streaming
= 1;
638 JOM(4, "submitted %i video urbs\n", m
);
641 JOM(4, "already streaming video urbs\n");
645 /*****************************************************************************/
646 int kill_video_urbs(struct easycap
*peasycap
)
649 struct list_head
*plist_head
;
650 struct data_urb
*pdata_urb
;
653 SAY("ERROR: peasycap is NULL\n");
656 if (!peasycap
->video_isoc_streaming
) {
657 JOM(8, "%i=video_isoc_streaming, no video urbs killed\n",
658 peasycap
->video_isoc_streaming
);
661 if (!peasycap
->purb_video_head
) {
662 SAM("ERROR: peasycap->purb_video_head is NULL\n");
666 peasycap
->video_isoc_streaming
= 0;
667 JOM(4, "killing video urbs\n");
669 list_for_each(plist_head
, (peasycap
->purb_video_head
)) {
670 pdata_urb
= list_entry(plist_head
, struct data_urb
, list_head
);
671 if (pdata_urb
&& pdata_urb
->purb
) {
672 usb_kill_urb(pdata_urb
->purb
);
676 JOM(4, "%i video urbs killed\n", m
);
680 /****************************************************************************/
681 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
682 /*--------------------------------------------------------------------------*/
683 static int easycap_open_noinode(struct file
*file
)
685 return easycap_open(NULL
, file
);
688 static int videodev_release(struct video_device
*pvideo_device
)
690 struct easycap
*peasycap
;
692 peasycap
= video_get_drvdata(pvideo_device
);
694 SAY("ERROR: peasycap is NULL\n");
695 SAY("ending unsuccessfully\n");
698 if (memcmp(&peasycap
->telltale
[0], TELLTALE
, strlen(TELLTALE
))) {
699 SAY("ERROR: bad peasycap: %p\n", peasycap
);
702 if (0 != kill_video_urbs(peasycap
)) {
703 SAM("ERROR: kill_video_urbs() failed\n");
706 JOM(4, "ending successfully\n");
709 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
710 /*****************************************************************************/
711 /*--------------------------------------------------------------------------*/
713 * THIS FUNCTION IS CALLED FROM WITHIN easycap_usb_disconnect() AND IS
714 * PROTECTED BY SEMAPHORES SET AND CLEARED BY easycap_usb_disconnect().
716 * BY THIS STAGE THE DEVICE HAS ALREADY BEEN PHYSICALLY UNPLUGGED, SO
717 * peasycap->pusb_device IS NO LONGER VALID.
719 /*---------------------------------------------------------------------------*/
720 static void easycap_delete(struct kref
*pkref
)
722 struct easycap
*peasycap
;
723 struct data_urb
*pdata_urb
;
724 struct list_head
*plist_head
, *plist_next
;
726 int allocation_video_urb
;
727 int allocation_video_page
;
728 int allocation_video_struct
;
729 int allocation_audio_urb
;
730 int allocation_audio_page
;
731 int allocation_audio_struct
;
732 int registered_video
, registered_audio
;
734 peasycap
= container_of(pkref
, struct easycap
, kref
);
736 SAM("ERROR: peasycap is NULL: cannot perform deletions\n");
739 if (memcmp(&peasycap
->telltale
[0], TELLTALE
, strlen(TELLTALE
))) {
740 SAY("ERROR: bad peasycap: %p\n", peasycap
);
743 kd
= isdongle(peasycap
);
744 /*---------------------------------------------------------------------------*/
748 /*---------------------------------------------------------------------------*/
749 if (peasycap
->purb_video_head
) {
750 JOM(4, "freeing video urbs\n");
752 list_for_each(plist_head
, (peasycap
->purb_video_head
)) {
753 pdata_urb
= list_entry(plist_head
,
754 struct data_urb
, list_head
);
756 JOM(4, "ERROR: pdata_urb is NULL\n");
758 if (pdata_urb
->purb
) {
759 usb_free_urb(pdata_urb
->purb
);
760 pdata_urb
->purb
= NULL
;
761 peasycap
->allocation_video_urb
-= 1;
767 JOM(4, "%i video urbs freed\n", m
);
768 /*---------------------------------------------------------------------------*/
769 JOM(4, "freeing video data_urb structures.\n");
771 list_for_each_safe(plist_head
, plist_next
,
772 peasycap
->purb_video_head
) {
773 pdata_urb
= list_entry(plist_head
,
774 struct data_urb
, list_head
);
776 peasycap
->allocation_video_struct
-=
777 sizeof(struct data_urb
);
783 JOM(4, "%i video data_urb structures freed\n", m
);
784 JOM(4, "setting peasycap->purb_video_head=NULL\n");
785 peasycap
->purb_video_head
= NULL
;
787 /*---------------------------------------------------------------------------*/
788 JOM(4, "freeing video isoc buffers.\n");
790 for (k
= 0; k
< VIDEO_ISOC_BUFFER_MANY
; k
++) {
791 if (peasycap
->video_isoc_buffer
[k
].pgo
) {
792 free_pages((unsigned long)
793 peasycap
->video_isoc_buffer
[k
].pgo
,
795 peasycap
->video_isoc_buffer
[k
].pgo
= NULL
;
796 peasycap
->allocation_video_page
-=
797 BIT(VIDEO_ISOC_ORDER
);
801 JOM(4, "isoc video buffers freed: %i pages\n",
802 m
* (0x01 << VIDEO_ISOC_ORDER
));
803 /*---------------------------------------------------------------------------*/
804 JOM(4, "freeing video field buffers.\n");
806 for (k
= 0; k
< FIELD_BUFFER_MANY
; k
++) {
807 for (m
= 0; m
< FIELD_BUFFER_SIZE
/PAGE_SIZE
; m
++) {
808 if (peasycap
->field_buffer
[k
][m
].pgo
) {
809 free_page((unsigned long)
810 peasycap
->field_buffer
[k
][m
].pgo
);
811 peasycap
->field_buffer
[k
][m
].pgo
= NULL
;
812 peasycap
->allocation_video_page
-= 1;
817 JOM(4, "video field buffers freed: %i pages\n", gone
);
818 /*---------------------------------------------------------------------------*/
819 JOM(4, "freeing video frame buffers.\n");
821 for (k
= 0; k
< FRAME_BUFFER_MANY
; k
++) {
822 for (m
= 0; m
< FRAME_BUFFER_SIZE
/PAGE_SIZE
; m
++) {
823 if (peasycap
->frame_buffer
[k
][m
].pgo
) {
824 free_page((unsigned long)
825 peasycap
->frame_buffer
[k
][m
].pgo
);
826 peasycap
->frame_buffer
[k
][m
].pgo
= NULL
;
827 peasycap
->allocation_video_page
-= 1;
832 JOM(4, "video frame buffers freed: %i pages\n", gone
);
833 /*---------------------------------------------------------------------------*/
837 /*---------------------------------------------------------------------------*/
838 if (peasycap
->purb_audio_head
) {
839 JOM(4, "freeing audio urbs\n");
841 list_for_each(plist_head
, (peasycap
->purb_audio_head
)) {
842 pdata_urb
= list_entry(plist_head
,
843 struct data_urb
, list_head
);
845 JOM(4, "ERROR: pdata_urb is NULL\n");
847 if (pdata_urb
->purb
) {
848 usb_free_urb(pdata_urb
->purb
);
849 pdata_urb
->purb
= NULL
;
850 peasycap
->allocation_audio_urb
-= 1;
855 JOM(4, "%i audio urbs freed\n", m
);
856 /*---------------------------------------------------------------------------*/
857 JOM(4, "freeing audio data_urb structures.\n");
859 list_for_each_safe(plist_head
, plist_next
,
860 peasycap
->purb_audio_head
) {
861 pdata_urb
= list_entry(plist_head
,
862 struct data_urb
, list_head
);
864 peasycap
->allocation_audio_struct
-=
865 sizeof(struct data_urb
);
871 JOM(4, "%i audio data_urb structures freed\n", m
);
872 JOM(4, "setting peasycap->purb_audio_head=NULL\n");
873 peasycap
->purb_audio_head
= NULL
;
875 /*---------------------------------------------------------------------------*/
876 JOM(4, "freeing audio isoc buffers.\n");
878 for (k
= 0; k
< AUDIO_ISOC_BUFFER_MANY
; k
++) {
879 if (peasycap
->audio_isoc_buffer
[k
].pgo
) {
880 free_pages((unsigned long)
881 (peasycap
->audio_isoc_buffer
[k
].pgo
),
883 peasycap
->audio_isoc_buffer
[k
].pgo
= NULL
;
884 peasycap
->allocation_audio_page
-=
885 BIT(AUDIO_ISOC_ORDER
);
889 JOM(4, "easyoss_delete(): isoc audio buffers freed: %i pages\n",
890 m
* (0x01 << AUDIO_ISOC_ORDER
));
891 /*---------------------------------------------------------------------------*/
892 #ifdef CONFIG_EASYCAP_OSS
893 JOM(4, "freeing audio buffers.\n");
895 for (k
= 0; k
< peasycap
->audio_buffer_page_many
; k
++) {
896 if (peasycap
->audio_buffer
[k
].pgo
) {
897 free_page((unsigned long)peasycap
->audio_buffer
[k
].pgo
);
898 peasycap
->audio_buffer
[k
].pgo
= NULL
;
899 peasycap
->allocation_audio_page
-= 1;
903 JOM(4, "easyoss_delete(): audio buffers freed: %i pages\n", gone
);
904 #endif /* CONFIG_EASYCAP_OSS */
905 /*---------------------------------------------------------------------------*/
906 JOM(4, "freeing easycap structure.\n");
907 allocation_video_urb
= peasycap
->allocation_video_urb
;
908 allocation_video_page
= peasycap
->allocation_video_page
;
909 allocation_video_struct
= peasycap
->allocation_video_struct
;
910 registered_video
= peasycap
->registered_video
;
911 allocation_audio_urb
= peasycap
->allocation_audio_urb
;
912 allocation_audio_page
= peasycap
->allocation_audio_page
;
913 allocation_audio_struct
= peasycap
->allocation_audio_struct
;
914 registered_audio
= peasycap
->registered_audio
;
918 if (0 <= kd
&& DONGLE_MANY
> kd
) {
919 if (mutex_lock_interruptible(&mutex_dongle
)) {
920 SAY("ERROR: cannot down mutex_dongle\n");
922 JOM(4, "locked mutex_dongle\n");
923 easycapdc60_dongle
[kd
].peasycap
= NULL
;
924 mutex_unlock(&mutex_dongle
);
925 JOM(4, "unlocked mutex_dongle\n");
926 JOT(4, " null-->dongle[%i].peasycap\n", kd
);
927 allocation_video_struct
-= sizeof(struct easycap
);
930 SAY("ERROR: cannot purge dongle[].peasycap");
932 /*---------------------------------------------------------------------------*/
933 SAY("%8i=video urbs after all deletions\n", allocation_video_urb
);
934 SAY("%8i=video pages after all deletions\n", allocation_video_page
);
935 SAY("%8i=video structs after all deletions\n", allocation_video_struct
);
936 SAY("%8i=video devices after all deletions\n", registered_video
);
937 SAY("%8i=audio urbs after all deletions\n", allocation_audio_urb
);
938 SAY("%8i=audio pages after all deletions\n", allocation_audio_page
);
939 SAY("%8i=audio structs after all deletions\n", allocation_audio_struct
);
940 SAY("%8i=audio devices after all deletions\n", registered_audio
);
945 /*****************************************************************************/
946 static unsigned int easycap_poll(struct file
*file
, poll_table
*wait
)
948 struct easycap
*peasycap
;
953 if (NULL
== ((poll_table
*)wait
))
954 JOT(8, "WARNING: poll table pointer is NULL ... continuing\n");
956 SAY("ERROR: file pointer is NULL\n");
959 peasycap
= file
->private_data
;
961 SAY("ERROR: peasycap is NULL\n");
964 if (memcmp(&peasycap
->telltale
[0], TELLTALE
, strlen(TELLTALE
))) {
965 SAY("ERROR: bad peasycap: %p\n", peasycap
);
968 if (!peasycap
->pusb_device
) {
969 SAY("ERROR: peasycap->pusb_device is NULL\n");
972 /*---------------------------------------------------------------------------*/
973 kd
= isdongle(peasycap
);
974 if (0 <= kd
&& DONGLE_MANY
> kd
) {
975 if (mutex_lock_interruptible(&easycapdc60_dongle
[kd
].mutex_video
)) {
976 SAY("ERROR: cannot down dongle[%i].mutex_video\n", kd
);
979 JOM(4, "locked dongle[%i].mutex_video\n", kd
);
981 * MEANWHILE, easycap_usb_disconnect() MAY HAVE FREED POINTER
982 * peasycap, IN WHICH CASE A REPEAT CALL TO isdongle() WILL FAIL.
983 * IF NECESSARY, BAIL OUT.
985 if (kd
!= isdongle(peasycap
))
988 SAY("ERROR: file is NULL\n");
989 mutex_unlock(&easycapdc60_dongle
[kd
].mutex_video
);
992 peasycap
= file
->private_data
;
994 SAY("ERROR: peasycap is NULL\n");
995 mutex_unlock(&easycapdc60_dongle
[kd
].mutex_video
);
998 if (memcmp(&peasycap
->telltale
[0], TELLTALE
, strlen(TELLTALE
))) {
999 SAY("ERROR: bad peasycap: %p\n", peasycap
);
1000 mutex_unlock(&easycapdc60_dongle
[kd
].mutex_video
);
1001 return -ERESTARTSYS
;
1003 if (!peasycap
->pusb_device
) {
1004 SAM("ERROR: peasycap->pusb_device is NULL\n");
1005 mutex_unlock(&easycapdc60_dongle
[kd
].mutex_video
);
1006 return -ERESTARTSYS
;
1010 * IF easycap_usb_disconnect() HAS ALREADY FREED POINTER peasycap
1011 * BEFORE THE ATTEMPT TO ACQUIRE THE SEMAPHORE, isdongle() WILL
1012 * HAVE FAILED. BAIL OUT.
1014 return -ERESTARTSYS
;
1015 /*---------------------------------------------------------------------------*/
1016 rc
= easycap_dqbuf(peasycap
, 0);
1017 peasycap
->polled
= 1;
1018 mutex_unlock(&easycapdc60_dongle
[kd
].mutex_video
);
1020 return POLLIN
| POLLRDNORM
;
1024 /*****************************************************************************/
1025 /*---------------------------------------------------------------------------*/
1027 * IF mode IS NONZERO THIS ROUTINE RETURNS -EAGAIN RATHER THAN BLOCKING.
1029 /*---------------------------------------------------------------------------*/
1030 int easycap_dqbuf(struct easycap
*peasycap
, int mode
)
1032 int input
, ifield
, miss
, rc
;
1036 SAY("ERROR: peasycap is NULL\n");
1039 if (!peasycap
->pusb_device
) {
1040 SAY("ERROR: peasycap->pusb_device is NULL\n");
1044 JOM(8, "%i=ifield\n", ifield
);
1045 /*---------------------------------------------------------------------------*/
1047 * CHECK FOR LOST INPUT SIGNAL.
1049 * FOR THE FOUR-CVBS EasyCAP, THIS DOES NOT WORK AS EXPECTED.
1050 * IF INPUT 0 IS PRESENT AND SYNC ACQUIRED, UNPLUGGING INPUT 4 DOES NOT
1051 * RESULT IN SETTING BIT 0x40 ON REGISTER 0x1F, PRESUMABLY BECAUSE THERE
1052 * IS FLYWHEELING ON INPUT 0. THE UPSHOT IS:
1054 * INPUT 0 PLUGGED, INPUT 4 PLUGGED => SCREEN 0 OK, SCREEN 4 OK
1055 * INPUT 0 PLUGGED, INPUT 4 UNPLUGGED => SCREEN 0 OK, SCREEN 4 BLACK
1056 * INPUT 0 UNPLUGGED, INPUT 4 PLUGGED => SCREEN 0 BARS, SCREEN 4 OK
1057 * INPUT 0 UNPLUGGED, INPUT 4 UNPLUGGED => SCREEN 0 BARS, SCREEN 4 BARS
1059 /*---------------------------------------------------------------------------*/
1060 input
= peasycap
->input
;
1061 if (0 <= input
&& INPUT_MANY
> input
) {
1062 rc
= read_saa(peasycap
->pusb_device
, 0x1F);
1065 peasycap
->lost
[input
] += 1;
1067 peasycap
->lost
[input
] -= 2;
1069 if (0 > peasycap
->lost
[input
])
1070 peasycap
->lost
[input
] = 0;
1071 else if ((2 * VIDEO_LOST_TOLERATE
) < peasycap
->lost
[input
])
1072 peasycap
->lost
[input
] = (2 * VIDEO_LOST_TOLERATE
);
1075 /*---------------------------------------------------------------------------*/
1077 * WAIT FOR FIELD ifield (0 => TOP, 1 => BOTTOM)
1079 /*---------------------------------------------------------------------------*/
1081 while ((peasycap
->field_read
== peasycap
->field_fill
) ||
1082 (0 != (0xFF00 & peasycap
->field_buffer
1083 [peasycap
->field_read
][0].kount
)) ||
1084 (ifield
!= (0x00FF & peasycap
->field_buffer
1085 [peasycap
->field_read
][0].kount
))) {
1089 JOM(8, "first wait on wq_video, %i=field_read %i=field_fill\n",
1090 peasycap
->field_read
, peasycap
->field_fill
);
1092 if (0 != (wait_event_interruptible(peasycap
->wq_video
,
1093 (peasycap
->video_idle
|| peasycap
->video_eof
||
1094 ((peasycap
->field_read
!= peasycap
->field_fill
) &&
1095 (0 == (0xFF00 & peasycap
->field_buffer
[peasycap
->field_read
][0].kount
)) &&
1096 (ifield
== (0x00FF & peasycap
->field_buffer
[peasycap
->field_read
][0].kount
))))))) {
1097 SAM("aborted by signal\n");
1100 if (peasycap
->video_idle
) {
1101 JOM(8, "%i=peasycap->video_idle returning -EAGAIN\n",
1102 peasycap
->video_idle
);
1105 if (peasycap
->video_eof
) {
1106 JOM(8, "%i=peasycap->video_eof\n", peasycap
->video_eof
);
1107 #if defined(PERSEVERE)
1108 if (1 == peasycap
->status
) {
1109 JOM(8, "persevering ...\n");
1110 peasycap
->video_eof
= 0;
1111 peasycap
->audio_eof
= 0;
1112 if (0 != reset(peasycap
)) {
1113 JOM(8, " ... failed returning -EIO\n");
1114 peasycap
->video_eof
= 1;
1115 peasycap
->audio_eof
= 1;
1116 kill_video_urbs(peasycap
);
1119 peasycap
->status
= 0;
1120 JOM(8, " ... OK returning -EAGAIN\n");
1123 #endif /*PERSEVERE*/
1124 peasycap
->video_eof
= 1;
1125 peasycap
->audio_eof
= 1;
1126 kill_video_urbs(peasycap
);
1127 JOM(8, "returning -EIO\n");
1132 JOM(8, "first awakening on wq_video after %i waits\n", miss
);
1134 rc
= field2frame(peasycap
);
1136 SAM("ERROR: field2frame() rc = %i\n", rc
);
1137 /*---------------------------------------------------------------------------*/
1139 * WAIT FOR THE OTHER FIELD
1141 /*---------------------------------------------------------------------------*/
1147 while ((peasycap
->field_read
== peasycap
->field_fill
) ||
1148 (0 != (0xFF00 & peasycap
->field_buffer
[peasycap
->field_read
][0].kount
)) ||
1149 (ifield
!= (0x00FF & peasycap
->field_buffer
[peasycap
->field_read
][0].kount
))) {
1153 JOM(8, "second wait on wq_video %i=field_read %i=field_fill\n",
1154 peasycap
->field_read
, peasycap
->field_fill
);
1155 if (0 != (wait_event_interruptible(peasycap
->wq_video
,
1156 (peasycap
->video_idle
|| peasycap
->video_eof
||
1157 ((peasycap
->field_read
!= peasycap
->field_fill
) &&
1158 (0 == (0xFF00 & peasycap
->field_buffer
[peasycap
->field_read
][0].kount
)) &&
1159 (ifield
== (0x00FF & peasycap
->field_buffer
[peasycap
->field_read
][0].kount
))))))) {
1160 SAM("aborted by signal\n");
1163 if (peasycap
->video_idle
) {
1164 JOM(8, "%i=peasycap->video_idle returning -EAGAIN\n",
1165 peasycap
->video_idle
);
1168 if (peasycap
->video_eof
) {
1169 JOM(8, "%i=peasycap->video_eof\n", peasycap
->video_eof
);
1170 #if defined(PERSEVERE)
1171 if (1 == peasycap
->status
) {
1172 JOM(8, "persevering ...\n");
1173 peasycap
->video_eof
= 0;
1174 peasycap
->audio_eof
= 0;
1175 if (0 != reset(peasycap
)) {
1176 JOM(8, " ... failed returning -EIO\n");
1177 peasycap
->video_eof
= 1;
1178 peasycap
->audio_eof
= 1;
1179 kill_video_urbs(peasycap
);
1182 peasycap
->status
= 0;
1183 JOM(8, " ... OK ... returning -EAGAIN\n");
1186 #endif /*PERSEVERE*/
1187 peasycap
->video_eof
= 1;
1188 peasycap
->audio_eof
= 1;
1189 kill_video_urbs(peasycap
);
1190 JOM(8, "returning -EIO\n");
1195 JOM(8, "second awakening on wq_video after %i waits\n", miss
);
1197 rc
= field2frame(peasycap
);
1199 SAM("ERROR: field2frame() rc = %i\n", rc
);
1200 /*---------------------------------------------------------------------------*/
1204 /*---------------------------------------------------------------------------*/
1205 if (peasycap
->skip
) {
1206 peasycap
->skipped
++;
1207 if (peasycap
->skip
!= peasycap
->skipped
)
1208 return peasycap
->skip
- peasycap
->skipped
;
1210 peasycap
->skipped
= 0;
1212 /*---------------------------------------------------------------------------*/
1213 peasycap
->frame_read
= peasycap
->frame_fill
;
1214 peasycap
->queued
[peasycap
->frame_read
] = 0;
1215 peasycap
->done
[peasycap
->frame_read
] = V4L2_BUF_FLAG_DONE
;
1217 peasycap
->frame_fill
++;
1218 if (peasycap
->frame_buffer_many
<= peasycap
->frame_fill
)
1219 peasycap
->frame_fill
= 0;
1221 if (0x01 & easycap_standard
[peasycap
->standard_offset
].mask
)
1222 peasycap
->frame_buffer
[peasycap
->frame_read
][0].kount
=
1225 peasycap
->frame_buffer
[peasycap
->frame_read
][0].kount
=
1229 JOM(8, "setting: %i=peasycap->frame_read\n", peasycap
->frame_read
);
1230 JOM(8, "bumped to: %i=peasycap->frame_fill\n", peasycap
->frame_fill
);
1234 /*****************************************************************************/
1235 /*---------------------------------------------------------------------------*/
1237 * BY DEFINITION, odd IS true FOR THE FIELD OCCUPYING LINES 1,3,5,...,479
1238 * odd IS false FOR THE FIELD OCCUPYING LINES 0,2,4,...,478
1240 * WHEN BOOLEAN PARAMETER decimatepixel IS true, ONLY THE FIELD FOR WHICH
1241 * odd==false IS TRANSFERRED TO THE FRAME BUFFER.
1243 * THE BOOLEAN PARAMETER offerfields IS true ONLY WHEN THE USER PROGRAM
1244 * CHOOSES THE OPTION V4L2_FIELD_INTERLACED.
1246 /*---------------------------------------------------------------------------*/
1248 field2frame(struct easycap
*peasycap
)
1250 struct timeval timeval
;
1251 long long int above
, below
;
1253 struct signed_div_result sdr
;
1256 int kex
, kad
, mex
, mad
, rex
, rad
, rad2
;
1257 int c2
, c3
, w2
, w3
, cz
, wz
;
1258 int rc
, bytesperpixel
, multiplier
;
1259 int much
, more
, over
, rump
, caches
, input
;
1261 bool odd
, isuy
, decimatepixel
, offerfields
, badinput
;
1264 SAY("ERROR: peasycap is NULL\n");
1269 input
= 0x07 & peasycap
->field_buffer
[peasycap
->field_read
][0].input
;
1271 JOM(8, "===== parity %i, input 0x%02X, field buffer %i --> "
1272 "frame buffer %i\n",
1273 peasycap
->field_buffer
[peasycap
->field_read
][0].kount
,
1274 peasycap
->field_buffer
[peasycap
->field_read
][0].input
,
1275 peasycap
->field_read
, peasycap
->frame_fill
);
1276 JOM(8, "===== %i=bytesperpixel\n", peasycap
->bytesperpixel
);
1277 if (peasycap
->offerfields
)
1278 JOM(8, "===== offerfields\n");
1280 /*---------------------------------------------------------------------------*/
1282 * REJECT OR CLEAN BAD FIELDS
1284 /*---------------------------------------------------------------------------*/
1285 if (peasycap
->field_read
== peasycap
->field_fill
) {
1286 SAM("ERROR: on entry, still filling field buffer %i\n",
1287 peasycap
->field_read
);
1290 #ifdef EASYCAP_TESTCARD
1291 easycap_testcard(peasycap
, peasycap
->field_read
);
1293 if (0 <= input
&& INPUT_MANY
> input
) {
1294 if (easycap_bars
&& VIDEO_LOST_TOLERATE
<= peasycap
->lost
[input
])
1295 easycap_testcard(peasycap
, peasycap
->field_read
);
1297 #endif /*EASYCAP_TESTCARD*/
1298 /*---------------------------------------------------------------------------*/
1300 offerfields
= peasycap
->offerfields
;
1301 bytesperpixel
= peasycap
->bytesperpixel
;
1302 decimatepixel
= peasycap
->decimatepixel
;
1304 if ((2 != bytesperpixel
) &&
1305 (3 != bytesperpixel
) &&
1306 (4 != bytesperpixel
)) {
1307 SAM("MISTAKE: %i=bytesperpixel\n", bytesperpixel
);
1315 w2
= 2 * multiplier
* (peasycap
->width
);
1316 w3
= bytesperpixel
* multiplier
* (peasycap
->width
);
1317 wz
= multiplier
* (peasycap
->height
) *
1318 multiplier
* (peasycap
->width
);
1320 kex
= peasycap
->field_read
; mex
= 0;
1321 kad
= peasycap
->frame_fill
; mad
= 0;
1323 pex
= peasycap
->field_buffer
[kex
][0].pgo
; rex
= PAGE_SIZE
;
1324 pad
= peasycap
->frame_buffer
[kad
][0].pgo
; rad
= PAGE_SIZE
;
1325 odd
= !!(peasycap
->field_buffer
[kex
][0].kount
);
1327 if (odd
&& (!decimatepixel
)) {
1328 JOM(8, "initial skipping %4i bytes p.%4i\n",
1329 w3
/multiplier
, mad
);
1330 pad
+= (w3
/ multiplier
); rad
-= (w3
/ multiplier
);
1333 mask
= 0; rump
= 0; caches
= 0;
1338 * PROCESS ONE LINE OF FRAME AT FULL RESOLUTION:
1339 * READ w2 BYTES FROM FIELD BUFFER,
1340 * WRITE w3 BYTES TO FRAME BUFFER
1342 if (!decimatepixel
) {
1345 much
= over
; more
= 0;
1346 margin
= 0; mask
= 0x00;
1352 SAM("MISTAKE: much is odd\n");
1356 more
= (bytesperpixel
*
1358 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1359 if (1 < bytesperpixel
) {
1360 if (rad
* 2 < much
* bytesperpixel
) {
1362 * INJUDICIOUS ALTERATION OF
1363 * THIS STATEMENT BLOCK WILL
1364 * CAUSE BREAKAGE. BEWARE.
1366 rad2
= rad
+ bytesperpixel
- 1;
1367 much
= ((((2 * rad2
)/bytesperpixel
)/2) * 2);
1368 rump
= ((bytesperpixel
* much
) / 2) - rad
;
1375 if ((mex
+ 1) < FIELD_BUFFER_SIZE
/ PAGE_SIZE
)
1376 margin
= *((u8
*)(peasycap
->field_buffer
[kex
][mex
+ 1].pgo
));
1381 SAM("MISTAKE: %i=bytesperpixel\n",
1388 JOM(8, "ERROR: 0x%02X=->field_buffer"
1390 "0x%02X=(0x08|->input)\n",
1391 peasycap
->field_buffer
1392 [kex
][mex
].input
, kex
, mex
,
1393 (0x08|peasycap
->input
));
1395 rc
= redaub(peasycap
, pad
, pex
, much
, more
,
1396 mask
, margin
, isuy
);
1398 SAM("ERROR: redaub() failed\n");
1404 over
-= much
; cz
+= much
;
1405 pex
+= much
; rex
-= much
;
1408 pex
= peasycap
->field_buffer
[kex
][mex
].pgo
;
1410 if (peasycap
->field_buffer
[kex
][mex
].input
!= (0x08|peasycap
->input
))
1417 pad
= peasycap
->frame_buffer
[kad
][mad
].pgo
;
1425 /*---------------------------------------------------------------------------*/
1427 * SKIP w3 BYTES IN TARGET FRAME BUFFER,
1428 * UNLESS IT IS THE LAST LINE OF AN ODD FRAME
1430 /*---------------------------------------------------------------------------*/
1431 if (!odd
|| (cz
!= wz
)) {
1436 pad
= peasycap
->frame_buffer
1448 /*---------------------------------------------------------------------------*/
1450 * PROCESS ONE LINE OF FRAME AT REDUCED RESOLUTION:
1451 * ONLY IF false==odd,
1452 * READ w2 BYTES FROM FIELD BUFFER,
1453 * WRITE w3 / 2 BYTES TO FRAME BUFFER
1455 /*---------------------------------------------------------------------------*/
1459 much
= over
; more
= 0; margin
= 0; mask
= 0x00;
1465 SAM("MISTAKE: much is odd\n");
1469 more
= (bytesperpixel
* much
) / 4;
1470 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1471 if (1 < bytesperpixel
) {
1472 if (rad
* 4 < much
* bytesperpixel
) {
1474 * INJUDICIOUS ALTERATION OF
1475 * THIS STATEMENT BLOCK
1476 * WILL CAUSE BREAKAGE.
1479 rad2
= rad
+ bytesperpixel
- 1;
1480 much
= ((((2 * rad2
) / bytesperpixel
) / 2) * 4);
1481 rump
= ((bytesperpixel
* much
) / 4) - rad
;
1488 if ((mex
+ 1) < FIELD_BUFFER_SIZE
/ PAGE_SIZE
)
1489 margin
= *((u8
*)(peasycap
->field_buffer
[kex
][mex
+ 1].pgo
));
1493 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1495 SAM("MISTAKE: %i=bytesperpixel\n",
1499 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1504 JOM(8, "ERROR: 0x%02X=->field_buffer"
1506 "0x%02X=(0x08|->input)\n",
1507 peasycap
->field_buffer
1508 [kex
][mex
].input
, kex
, mex
,
1509 (0x08|peasycap
->input
));
1511 rc
= redaub(peasycap
, pad
, pex
, much
, more
,
1512 mask
, margin
, isuy
);
1514 SAM("ERROR: redaub() failed\n");
1517 over
-= much
; cz
+= much
;
1518 pex
+= much
; rex
-= much
;
1521 pex
= peasycap
->field_buffer
[kex
][mex
].pgo
;
1523 if (peasycap
->field_buffer
[kex
][mex
].input
!=
1524 (0x08|peasycap
->input
))
1531 pad
= peasycap
->frame_buffer
[kad
][mad
].pgo
;
1539 /*---------------------------------------------------------------------------*/
1542 * READ w2 BYTES FROM FIELD BUFFER AND DISCARD THEM
1544 /*---------------------------------------------------------------------------*/
1550 pex
= peasycap
->field_buffer
[kex
][mex
].pgo
;
1552 if (peasycap
->field_buffer
[kex
][mex
].input
!=
1553 (0x08|peasycap
->input
)) {
1554 JOM(8, "ERROR: 0x%02X=->field_buffer"
1556 "0x%02X=(0x08|->input)\n",
1557 peasycap
->field_buffer
1558 [kex
][mex
].input
, kex
, mex
,
1559 (0x08|peasycap
->input
));
1573 /*---------------------------------------------------------------------------*/
1577 /*---------------------------------------------------------------------------*/
1578 c2
= (mex
+ 1)*PAGE_SIZE
- rex
;
1580 SAM("ERROR: discrepancy %i in bytes read\n", c2
- cz
);
1581 c3
= (mad
+ 1)*PAGE_SIZE
- rad
;
1583 if (!decimatepixel
) {
1584 if (bytesperpixel
* cz
!= c3
)
1585 SAM("ERROR: discrepancy %i in bytes written\n",
1586 c3
- (bytesperpixel
* cz
));
1591 SAM("ERROR: discrepancy %i in bytes written\n",
1592 (2*c3
)-(bytesperpixel
* cz
));
1595 SAM("ERROR: discrepancy %i "
1596 "in bytes written\n", c3
);
1600 SAM("WORRY: undischarged cache at end of line in frame buffer\n");
1602 JOM(8, "===== field2frame(): %i bytes --> %i bytes (incl skip)\n", c2
, c3
);
1603 JOM(8, "===== field2frame(): %i=mad %i=rad\n", mad
, rad
);
1606 JOM(8, "+++++ field2frame(): frame buffer %i is full\n", kad
);
1608 if (peasycap
->field_read
== peasycap
->field_fill
)
1609 SAM("WARNING: on exit, filling field buffer %i\n",
1610 peasycap
->field_read
);
1611 /*---------------------------------------------------------------------------*/
1613 * CALCULATE VIDEO STREAMING RATE
1615 /*---------------------------------------------------------------------------*/
1616 do_gettimeofday(&timeval
);
1617 if (peasycap
->timeval6
.tv_sec
) {
1618 below
= ((long long int)(1000000)) *
1619 ((long long int)(timeval
.tv_sec
-
1620 peasycap
->timeval6
.tv_sec
)) +
1621 (long long int)(timeval
.tv_usec
- peasycap
->timeval6
.tv_usec
);
1622 above
= (long long int)1000000;
1624 sdr
= signed_div(above
, below
);
1625 above
= sdr
.quotient
;
1626 remainder
= (u32
)sdr
.remainder
;
1628 JOM(8, "video streaming at %3lli.%03i fields per second\n",
1629 above
, (remainder
/1000));
1631 peasycap
->timeval6
= timeval
;
1634 JOM(8, "%i=caches\n", caches
);
1637 /*****************************************************************************/
1638 struct signed_div_result
1639 signed_div(long long int above
, long long int below
)
1641 struct signed_div_result sdr
;
1643 if (((0 <= above
) && (0 <= below
)) || ((0 > above
) && (0 > below
))) {
1644 sdr
.remainder
= (unsigned long long int) do_div(above
, below
);
1645 sdr
.quotient
= (long long int) above
;
1651 sdr
.remainder
= (unsigned long long int) do_div(above
, below
);
1652 sdr
.quotient
= -((long long int) above
);
1656 /*****************************************************************************/
1657 /*---------------------------------------------------------------------------*/
1659 * DECIMATION AND COLOURSPACE CONVERSION.
1661 * THIS ROUTINE REQUIRES THAT ALL THE DATA TO BE READ RESIDES ON ONE PAGE
1662 * AND THAT ALL THE DATA TO BE WRITTEN RESIDES ON ONE (DIFFERENT) PAGE.
1663 * THE CALLING ROUTINE MUST ENSURE THAT THIS REQUIREMENT IS MET, AND MUST
1664 * ALSO ENSURE THAT much IS EVEN.
1666 * much BYTES ARE READ, AT LEAST (bytesperpixel * much)/2 BYTES ARE WRITTEN
1667 * IF THERE IS NO DECIMATION, HALF THIS AMOUNT IF THERE IS DECIMATION.
1669 * mask IS ZERO WHEN NO SPECIAL BEHAVIOUR REQUIRED. OTHERWISE IT IS SET THUS:
1670 * 0x03 & mask = number of bytes to be written to cache instead of to
1672 * 0x04 & mask => use argument margin to set the chrominance for last pixel
1673 * 0x08 & mask => do not set the chrominance for last pixel
1675 * YUV to RGB CONVERSION IS (OR SHOULD BE) ITU-R BT 601.
1677 * THERE IS A LOT OF CODE REPETITION IN THIS ROUTINE IN ORDER TO AVOID
1678 * INEFFICIENT SWITCHING INSIDE INNER LOOPS. REARRANGING THE LOGIC TO
1679 * REDUCE CODE LENGTH WILL GENERALLY IMPAIR RUNTIME PERFORMANCE. BEWARE.
1681 /*---------------------------------------------------------------------------*/
1683 redaub(struct easycap
*peasycap
, void *pad
, void *pex
, int much
, int more
,
1684 u8 mask
, u8 margin
, bool isuy
)
1686 static s32 ay
[256], bu
[256], rv
[256], gu
[256], gv
[256];
1688 u8 r
, g
, b
, y
, u
, v
, c
, *p2
, *p3
, *pz
, *pr
;
1690 bool byteswaporder
, decimatepixel
, last
;
1695 SAM("MISTAKE: much is odd\n");
1698 bytesperpixel
= peasycap
->bytesperpixel
;
1699 byteswaporder
= peasycap
->byteswaporder
;
1700 decimatepixel
= peasycap
->decimatepixel
;
1702 /*---------------------------------------------------------------------------*/
1704 for (j
= 0; j
< 112; j
++) {
1705 tmp
= (0xFF00 & (453 * j
)) >> 8;
1706 bu
[j
+ 128] = tmp
; bu
[127 - j
] = -tmp
;
1707 tmp
= (0xFF00 & (359 * j
)) >> 8;
1708 rv
[j
+ 128] = tmp
; rv
[127 - j
] = -tmp
;
1709 tmp
= (0xFF00 & (88 * j
)) >> 8;
1710 gu
[j
+ 128] = tmp
; gu
[127 - j
] = -tmp
;
1711 tmp
= (0xFF00 & (183 * j
)) >> 8;
1712 gv
[j
+ 128] = tmp
; gv
[127 - j
] = -tmp
;
1714 for (j
= 0; j
< 16; j
++) {
1715 bu
[j
] = bu
[16]; rv
[j
] = rv
[16];
1716 gu
[j
] = gu
[16]; gv
[j
] = gv
[16];
1718 for (j
= 240; j
< 256; j
++) {
1719 bu
[j
] = bu
[239]; rv
[j
] = rv
[239];
1720 gu
[j
] = gu
[239]; gv
[j
] = gv
[239];
1722 for (j
= 16; j
< 236; j
++)
1724 for (j
= 0; j
< 16; j
++)
1726 for (j
= 236; j
< 256; j
++)
1728 JOM(8, "lookup tables are prepared\n");
1730 pcache
= peasycap
->pcache
;
1732 pcache
= &peasycap
->cache
[0];
1733 /*---------------------------------------------------------------------------*/
1735 * TRANSFER CONTENTS OF CACHE TO THE FRAME BUFFER
1737 /*---------------------------------------------------------------------------*/
1739 SAM("MISTAKE: pcache is NULL\n");
1743 if (pcache
!= &peasycap
->cache
[0])
1744 JOM(16, "cache has %i bytes\n", (int)(pcache
- &peasycap
->cache
[0]));
1745 p2
= &peasycap
->cache
[0];
1746 p3
= (u8
*)pad
- (int)(pcache
- &peasycap
->cache
[0]);
1747 while (p2
< pcache
) {
1750 pcache
= &peasycap
->cache
[0];
1752 SAM("MISTAKE: pointer misalignment\n");
1755 /*---------------------------------------------------------------------------*/
1756 rump
= (int)(0x03 & mask
);
1758 p2
= (u8
*)pex
; pz
= p2
+ much
; pr
= p3
+ more
; last
= false;
1767 JOM(16, "%4i=much %4i=more %i=rump\n", much
, more
, rump
);
1769 /*---------------------------------------------------------------------------*/
1770 switch (bytesperpixel
) {
1772 if (!decimatepixel
) {
1773 memcpy(pad
, pex
, (size_t)much
);
1774 if (!byteswaporder
) {
1779 p3
= (u8
*)pad
; pz
= p3
+ much
;
1789 if (!byteswaporder
) {
1790 /* UYVY DECIMATED */
1791 p2
= (u8
*)pex
; p3
= (u8
*)pad
; pz
= p2
+ much
;
1794 *(p3
+ 1) = *(p2
+ 1);
1795 *(p3
+ 2) = *(p2
+ 2);
1796 *(p3
+ 3) = *(p2
+ 3);
1801 /* YUYV DECIMATED */
1802 p2
= (u8
*)pex
; p3
= (u8
*)pad
; pz
= p2
+ much
;
1806 *(p3
+ 2) = *(p2
+ 3);
1807 *(p3
+ 3) = *(p2
+ 2);
1817 if (!decimatepixel
) {
1818 if (!byteswaporder
) {
1821 if (pr
<= (p3
+ bytesperpixel
))
1826 if (last
&& (0x0C & mask
)) {
1842 tmp
= ay
[(int)y
] + rv
[(int)v
];
1843 r
= (255 < tmp
) ? 255 : ((0 > tmp
) ?
1845 tmp
= ay
[(int)y
] - gu
[(int)u
] - gv
[(int)v
];
1846 g
= (255 < tmp
) ? 255 : ((0 > tmp
) ?
1848 tmp
= ay
[(int)y
] + bu
[(int)u
];
1849 b
= (255 < tmp
) ? 255 : ((0 > tmp
) ?
1853 pcache
= &peasycap
->cache
[0];
1854 switch (bytesperpixel
- rump
) {
1868 SAM("MISTAKE: %i=rump\n",
1869 bytesperpixel
- rump
);
1883 p3
+= bytesperpixel
;
1889 if (pr
<= (p3
+ bytesperpixel
))
1894 if (last
&& (0x0C & mask
)) {
1911 tmp
= ay
[(int)y
] + rv
[(int)v
];
1912 r
= (255 < tmp
) ? 255 : ((0 > tmp
) ?
1914 tmp
= ay
[(int)y
] - gu
[(int)u
] - gv
[(int)v
];
1915 g
= (255 < tmp
) ? 255 : ((0 > tmp
) ?
1917 tmp
= ay
[(int)y
] + bu
[(int)u
];
1918 b
= (255 < tmp
) ? 255 : ((0 > tmp
) ?
1922 pcache
= &peasycap
->cache
[0];
1923 switch (bytesperpixel
- rump
) {
1937 SAM("MISTAKE: %i=rump\n",
1938 bytesperpixel
- rump
);
1952 p3
+= bytesperpixel
;
1957 if (!byteswaporder
) {
1960 if (pr
<= (p3
+ bytesperpixel
))
1965 if (last
&& (0x0C & mask
)) {
1982 tmp
= ay
[(int)y
] + rv
[(int)v
];
1983 r
= (255 < tmp
) ? 255 : ((0 > tmp
) ?
1985 tmp
= ay
[(int)y
] - gu
[(int)u
] -
1987 g
= (255 < tmp
) ? 255 : ((0 > tmp
) ?
1989 tmp
= ay
[(int)y
] + bu
[(int)u
];
1990 b
= (255 < tmp
) ? 255 : ((0 > tmp
) ?
1994 pcache
= &peasycap
->cache
[0];
1995 switch (bytesperpixel
- rump
) {
2011 bytesperpixel
- rump
);
2021 p3
+= bytesperpixel
;
2031 if (pr
<= (p3
+ bytesperpixel
))
2036 if (last
&& (0x0C & mask
)) {
2054 tmp
= ay
[(int)y
] + rv
[(int)v
];
2055 r
= (255 < tmp
) ? 255 : ((0 > tmp
) ?
2057 tmp
= ay
[(int)y
] - gu
[(int)u
] -
2059 g
= (255 < tmp
) ? 255 : ((0 > tmp
) ?
2061 tmp
= ay
[(int)y
] + bu
[(int)u
];
2062 b
= (255 < tmp
) ? 255 : ((0 > tmp
) ?
2066 pcache
= &peasycap
->cache
[0];
2067 switch (bytesperpixel
- rump
) {
2083 bytesperpixel
- rump
);
2093 p3
+= bytesperpixel
;
2106 if (!decimatepixel
) {
2107 if (!byteswaporder
) {
2110 if (pr
<= (p3
+ bytesperpixel
))
2115 if (last
&& (0x0C & mask
)) {
2131 tmp
= ay
[(int)y
] + rv
[(int)v
];
2132 r
= (255 < tmp
) ? 255 : ((0 > tmp
) ?
2134 tmp
= ay
[(int)y
] - gu
[(int)u
] - gv
[(int)v
];
2135 g
= (255 < tmp
) ? 255 : ((0 > tmp
) ?
2137 tmp
= ay
[(int)y
] + bu
[(int)u
];
2138 b
= (255 < tmp
) ? 255 : ((0 > tmp
) ?
2142 pcache
= &peasycap
->cache
[0];
2143 switch (bytesperpixel
- rump
) {
2166 SAM("MISTAKE: %i=rump\n",
2167 bytesperpixel
- rump
);
2182 p3
+= bytesperpixel
;
2190 if (pr
<= (p3
+ bytesperpixel
))
2195 if (last
&& (0x0C & mask
)) {
2211 tmp
= ay
[(int)y
] + rv
[(int)v
];
2212 r
= (255 < tmp
) ? 255 : ((0 > tmp
) ?
2214 tmp
= ay
[(int)y
] - gu
[(int)u
] - gv
[(int)v
];
2215 g
= (255 < tmp
) ? 255 : ((0 > tmp
) ?
2217 tmp
= ay
[(int)y
] + bu
[(int)u
];
2218 b
= (255 < tmp
) ? 255 : ((0 > tmp
) ?
2222 pcache
= &peasycap
->cache
[0];
2223 switch (bytesperpixel
- rump
) {
2246 SAM("MISTAKE: %i=rump\n",
2247 bytesperpixel
- rump
);
2261 p3
+= bytesperpixel
;
2266 if (!byteswaporder
) {
2271 if (pr
<= (p3
+ bytesperpixel
))
2276 if (last
&& (0x0C & mask
)) {
2294 tmp
= ay
[(int)y
] + rv
[(int)v
];
2295 r
= (255 < tmp
) ? 255 : ((0 > tmp
) ?
2297 tmp
= ay
[(int)y
] - gu
[(int)u
] -
2299 g
= (255 < tmp
) ? 255 : ((0 > tmp
) ?
2301 tmp
= ay
[(int)y
] + bu
[(int)u
];
2302 b
= (255 < tmp
) ? 255 : ((0 > tmp
) ?
2306 pcache
= &peasycap
->cache
[0];
2307 switch (bytesperpixel
- rump
) {
2344 p3
+= bytesperpixel
;
2355 if (pr
<= (p3
+ bytesperpixel
))
2360 if (last
&& (0x0C & mask
)) {
2377 tmp
= ay
[(int)y
] + rv
[(int)v
];
2378 r
= (255 < tmp
) ? 255 : ((0 > tmp
) ?
2380 tmp
= ay
[(int)y
] - gu
[(int)u
] -
2382 g
= (255 < tmp
) ? 255 : ((0 > tmp
) ?
2384 tmp
= ay
[(int)y
] + bu
[(int)u
];
2385 b
= (255 < tmp
) ? 255 : ((0 > tmp
) ?
2389 pcache
= &peasycap
->cache
[0];
2390 switch (bytesperpixel
- rump
) {
2415 bytesperpixel
- rump
);
2426 p3
+= bytesperpixel
;
2437 SAM("MISTAKE: %i=bytesperpixel\n", bytesperpixel
);
2443 /*****************************************************************************/
2445 * SEE CORBET ET AL. "LINUX DEVICE DRIVERS", 3rd EDITION, PAGES 430-434
2447 /*****************************************************************************/
2448 static void easycap_vma_open(struct vm_area_struct
*pvma
)
2450 struct easycap
*peasycap
;
2452 peasycap
= pvma
->vm_private_data
;
2454 SAY("ERROR: peasycap is NULL\n");
2457 if (memcmp(&peasycap
->telltale
[0], TELLTALE
, strlen(TELLTALE
))) {
2458 SAY("ERROR: bad peasycap: %p\n", peasycap
);
2461 peasycap
->vma_many
++;
2462 JOT(8, "%i=peasycap->vma_many\n", peasycap
->vma_many
);
2465 /*****************************************************************************/
2466 static void easycap_vma_close(struct vm_area_struct
*pvma
)
2468 struct easycap
*peasycap
;
2470 peasycap
= pvma
->vm_private_data
;
2472 SAY("ERROR: peasycap is NULL\n");
2475 if (memcmp(&peasycap
->telltale
[0], TELLTALE
, strlen(TELLTALE
))) {
2476 SAY("ERROR: bad peasycap: %p\n", peasycap
);
2479 peasycap
->vma_many
--;
2480 JOT(8, "%i=peasycap->vma_many\n", peasycap
->vma_many
);
2483 /*****************************************************************************/
2484 static int easycap_vma_fault(struct vm_area_struct
*pvma
, struct vm_fault
*pvmf
)
2489 struct easycap
*peasycap
;
2491 retcode
= VM_FAULT_NOPAGE
;
2494 SAY("pvma is NULL\n");
2498 SAY("pvmf is NULL\n");
2502 k
= (pvmf
->pgoff
) / (FRAME_BUFFER_SIZE
/PAGE_SIZE
);
2503 m
= (pvmf
->pgoff
) % (FRAME_BUFFER_SIZE
/PAGE_SIZE
);
2506 JOT(4, "%4i=k, %4i=m\n", k
, m
);
2508 JOT(16, "%4i=k, %4i=m\n", k
, m
);
2510 if ((0 > k
) || (FRAME_BUFFER_MANY
<= k
)) {
2511 SAY("ERROR: buffer index %i out of range\n", k
);
2514 if ((0 > m
) || (FRAME_BUFFER_SIZE
/PAGE_SIZE
<= m
)) {
2515 SAY("ERROR: page number %i out of range\n", m
);
2518 peasycap
= pvma
->vm_private_data
;
2520 SAY("ERROR: peasycap is NULL\n");
2523 /*---------------------------------------------------------------------------*/
2524 pbuf
= peasycap
->frame_buffer
[k
][m
].pgo
;
2526 SAM("ERROR: pbuf is NULL\n");
2529 page
= virt_to_page(pbuf
);
2531 SAM("ERROR: page is NULL\n");
2535 /*---------------------------------------------------------------------------*/
2537 SAM("ERROR: page is NULL after get_page(page)\n");
2540 retcode
= VM_FAULT_MINOR
;
2545 static const struct vm_operations_struct easycap_vm_ops
= {
2546 .open
= easycap_vma_open
,
2547 .close
= easycap_vma_close
,
2548 .fault
= easycap_vma_fault
,
2551 static int easycap_mmap(struct file
*file
, struct vm_area_struct
*pvma
)
2555 pvma
->vm_ops
= &easycap_vm_ops
;
2556 pvma
->vm_flags
|= VM_RESERVED
;
2558 pvma
->vm_private_data
= file
->private_data
;
2559 easycap_vma_open(pvma
);
2562 /*****************************************************************************/
2563 /*---------------------------------------------------------------------------*/
2565 * ON COMPLETION OF A VIDEO URB ITS DATA IS COPIED TO THE FIELD BUFFERS
2566 * PROVIDED peasycap->video_idle IS ZERO. REGARDLESS OF THIS BEING TRUE,
2567 * IT IS RESUBMITTED PROVIDED peasycap->video_isoc_streaming IS NOT ZERO.
2569 * THIS FUNCTION IS AN INTERRUPT SERVICE ROUTINE AND MUST NOT SLEEP.
2571 * INFORMATION ABOUT THE VALIDITY OF THE CONTENTS OF THE FIELD BUFFER ARE
2572 * STORED IN THE TWO-BYTE STATUS PARAMETER
2573 * peasycap->field_buffer[peasycap->field_fill][0].kount
2574 * NOTICE THAT THE INFORMATION IS STORED ONLY WITH PAGE 0 OF THE FIELD BUFFER.
2576 * THE LOWER BYTE CONTAINS THE FIELD PARITY BYTE FURNISHED BY THE SAA7113H
2579 * THE UPPER BYTE IS ZERO IF NO PROBLEMS, OTHERWISE:
2580 * 0 != (kount & 0x8000) => AT LEAST ONE URB COMPLETED WITH ERRORS
2581 * 0 != (kount & 0x4000) => BUFFER HAS TOO MUCH DATA
2582 * 0 != (kount & 0x2000) => BUFFER HAS NOT ENOUGH DATA
2583 * 0 != (kount & 0x1000) => BUFFER HAS DATA FROM DISPARATE INPUTS
2584 * 0 != (kount & 0x0400) => RESERVED
2585 * 0 != (kount & 0x0200) => FIELD BUFFER NOT YET CHECKED
2586 * 0 != (kount & 0x0100) => BUFFER HAS TWO EXTRA BYTES - WHY?
2588 /*---------------------------------------------------------------------------*/
2589 static void easycap_complete(struct urb
*purb
)
2591 struct easycap
*peasycap
;
2592 struct data_buffer
*pfield_buffer
;
2594 int i
, more
, much
, leap
, rc
, last
;
2595 int videofieldamount
;
2596 unsigned int override
, bad
;
2597 int framestatus
, framelength
, frameactual
, frameoffset
;
2601 SAY("ERROR: easycap_complete(): purb is NULL\n");
2604 peasycap
= purb
->context
;
2606 SAY("ERROR: easycap_complete(): peasycap is NULL\n");
2609 if (memcmp(&peasycap
->telltale
[0], TELLTALE
, strlen(TELLTALE
))) {
2610 SAY("ERROR: bad peasycap: %p\n", peasycap
);
2613 if (peasycap
->video_eof
)
2615 for (i
= 0; i
< VIDEO_ISOC_BUFFER_MANY
; i
++)
2616 if (purb
->transfer_buffer
== peasycap
->video_isoc_buffer
[i
].pgo
)
2618 JOM(16, "%2i=urb\n", i
);
2619 last
= peasycap
->video_isoc_sequence
;
2620 if ((((VIDEO_ISOC_BUFFER_MANY
- 1) == last
) && (0 != i
)) ||
2621 (((VIDEO_ISOC_BUFFER_MANY
- 1) != last
) && ((last
+ 1) != i
))) {
2622 JOM(16, "ERROR: out-of-order urbs %i,%i ... continuing\n",
2625 peasycap
->video_isoc_sequence
= i
;
2627 if (peasycap
->video_idle
) {
2628 JOM(16, "%i=video_idle %i=video_isoc_streaming\n",
2629 peasycap
->video_idle
, peasycap
->video_isoc_streaming
);
2630 if (peasycap
->video_isoc_streaming
) {
2631 rc
= usb_submit_urb(purb
, GFP_ATOMIC
);
2633 SAM("%s:%d ENOMEM\n", strerror(rc
), rc
);
2635 SAM("ERROR: while %i=video_idle, "
2637 "failed with rc:\n",
2638 peasycap
->video_idle
);
2644 /*---------------------------------------------------------------------------*/
2645 if (FIELD_BUFFER_MANY
<= peasycap
->field_fill
) {
2646 SAM("ERROR: bad peasycap->field_fill\n");
2650 if ((-ESHUTDOWN
== purb
->status
) || (-ENOENT
== purb
->status
)) {
2651 JOM(8, "urb status -ESHUTDOWN or -ENOENT\n");
2655 (peasycap
->field_buffer
[peasycap
->field_fill
][0].kount
) |= 0x8000 ;
2656 SAM("ERROR: bad urb status -%s: %d\n",
2657 strerror(purb
->status
), purb
->status
);
2658 /*---------------------------------------------------------------------------*/
2660 for (i
= 0; i
< purb
->number_of_packets
; i
++) {
2661 if (0 != purb
->iso_frame_desc
[i
].status
) {
2662 (peasycap
->field_buffer
2663 [peasycap
->field_fill
][0].kount
) |= 0x8000 ;
2664 /* FIXME: 1. missing '-' check boundaries */
2666 strerror(purb
->iso_frame_desc
[i
].status
));
2668 framestatus
= purb
->iso_frame_desc
[i
].status
;
2669 framelength
= purb
->iso_frame_desc
[i
].length
;
2670 frameactual
= purb
->iso_frame_desc
[i
].actual_length
;
2671 frameoffset
= purb
->iso_frame_desc
[i
].offset
;
2673 JOM(16, "frame[%2i]:"
2678 i
, framestatus
, frameactual
, framelength
, frameoffset
);
2679 if (!purb
->iso_frame_desc
[i
].status
) {
2680 more
= purb
->iso_frame_desc
[i
].actual_length
;
2681 pfield_buffer
= &peasycap
->field_buffer
2682 [peasycap
->field_fill
][peasycap
->field_page
];
2683 videofieldamount
= (peasycap
->field_page
*
2685 (int)(pfield_buffer
->pto
- pfield_buffer
->pgo
);
2687 peasycap
->video_mt
++;
2689 if (peasycap
->video_mt
) {
2690 JOM(8, "%4i empty video urb frames\n",
2691 peasycap
->video_mt
);
2692 peasycap
->video_mt
= 0;
2694 if (FIELD_BUFFER_MANY
<= peasycap
->field_fill
) {
2695 SAM("ERROR: bad peasycap->field_fill\n");
2698 if (FIELD_BUFFER_SIZE
/PAGE_SIZE
<=
2699 peasycap
->field_page
) {
2700 SAM("ERROR: bad peasycap->field_page\n");
2703 pfield_buffer
= &peasycap
->field_buffer
2704 [peasycap
->field_fill
][peasycap
->field_page
];
2705 pu
= (u8
*)(purb
->transfer_buffer
+
2706 purb
->iso_frame_desc
[i
].offset
);
2711 /*--------------------------------------------------------------------------*/
2713 * EIGHT-BYTE END-OF-VIDEOFIELD MARKER.
2714 * NOTE: A SUCCESSION OF URB FRAMES FOLLOWING THIS ARE EMPTY,
2715 * CORRESPONDING TO THE FIELD FLYBACK (VERTICAL BLANKING) PERIOD.
2717 * PROVIDED THE FIELD BUFFER CONTAINS GOOD DATA AS INDICATED BY A ZERO UPPER
2719 * peasycap->field_buffer[peasycap->field_fill][0].kount
2720 * THE CONTENTS OF THE FIELD BUFFER ARE OFFERED TO dqbuf(), field_read IS
2721 * UPDATED AND field_fill IS BUMPED. IF THE FIELD BUFFER CONTAINS BAD DATA
2722 * NOTHING IS OFFERED TO dqbuf().
2724 * THE DECISION ON WHETHER THE PARITY OF THE OFFERED FIELD BUFFER IS RIGHT
2725 * RESTS WITH dqbuf().
2727 /*---------------------------------------------------------------------------*/
2728 if ((8 == more
) || override
) {
2729 if (videofieldamount
>
2730 peasycap
->videofieldamount
) {
2731 if (2 == videofieldamount
-
2734 (peasycap
->field_buffer
2735 [peasycap
->field_fill
]
2736 [0].kount
) |= 0x0100;
2737 peasycap
->video_junk
+= (1 +
2738 VIDEO_JUNK_TOLERATE
);
2740 (peasycap
->field_buffer
2741 [peasycap
->field_fill
]
2742 [0].kount
) |= 0x4000;
2743 } else if (videofieldamount
<
2746 (peasycap
->field_buffer
2747 [peasycap
->field_fill
]
2748 [0].kount
) |= 0x2000;
2750 bad
= 0xFF00 & peasycap
->field_buffer
2751 [peasycap
->field_fill
]
2754 (peasycap
->video_junk
)--;
2755 if (-VIDEO_JUNK_TOLERATE
>
2756 peasycap
->video_junk
)
2757 peasycap
->video_junk
=
2758 -VIDEO_JUNK_TOLERATE
;
2759 peasycap
->field_read
=
2762 if (FIELD_BUFFER_MANY
<=
2767 peasycap
->field_page
= 0;
2768 pfield_buffer
= &peasycap
->
2774 pfield_buffer
->pto
=
2776 JOM(8, "bumped to: %i="
2780 peasycap
->field_fill
,
2782 pfield_buffer
->kount
);
2783 JOM(8, "field buffer %i has "
2784 "%i bytes fit to be "
2786 peasycap
->field_read
,
2788 JOM(8, "wakeup call to "
2793 peasycap
->field_read
,
2794 peasycap
->field_fill
,
2798 field_read
][0].kount
);
2799 wake_up_interruptible
2803 (&peasycap
->timeval7
);
2805 peasycap
->video_junk
++;
2807 peasycap
->video_junk
+=
2808 (1 + VIDEO_JUNK_TOLERATE
/2);
2809 JOM(8, "field buffer %i had %i "
2810 "bytes, now discarded: "
2812 peasycap
->field_fill
,
2815 peasycap
->field_buffer
2816 [peasycap
->field_fill
][0].
2818 (peasycap
->field_fill
)++;
2820 if (FIELD_BUFFER_MANY
<=
2821 peasycap
->field_fill
)
2822 peasycap
->field_fill
= 0;
2823 peasycap
->field_page
= 0;
2825 &peasycap
->field_buffer
2826 [peasycap
->field_fill
]
2827 [peasycap
->field_page
];
2828 pfield_buffer
->pto
=
2831 JOM(8, "bumped to: %i=peasycap->"
2832 "field_fill %i=parity\n",
2833 peasycap
->field_fill
,
2834 0x00FF & pfield_buffer
->kount
);
2837 JOM(8, "end-of-field: received "
2838 "parity byte 0x%02X\n",
2841 pfield_buffer
->kount
= 0x0000;
2843 pfield_buffer
->kount
= 0x0001;
2844 pfield_buffer
->input
= 0x08 |
2845 (0x07 & peasycap
->input
);
2846 JOM(8, "end-of-field: 0x%02X=kount\n",
2847 0xFF & pfield_buffer
->kount
);
2850 /*---------------------------------------------------------------------------*/
2852 * COPY more BYTES FROM ISOC BUFFER TO FIELD BUFFER
2854 /*---------------------------------------------------------------------------*/
2858 if (FIELD_BUFFER_MANY
<= peasycap
->field_fill
) {
2859 SAM("ERROR: bad peasycap->field_fill\n");
2862 if (FIELD_BUFFER_SIZE
/PAGE_SIZE
<= peasycap
->field_page
) {
2863 SAM("ERROR: bad peasycap->field_page\n");
2866 pfield_buffer
= &peasycap
->field_buffer
2867 [peasycap
->field_fill
][peasycap
->field_page
];
2869 pfield_buffer
= &peasycap
->field_buffer
2870 [peasycap
->field_fill
]
2871 [peasycap
->field_page
];
2872 if (PAGE_SIZE
< (pfield_buffer
->pto
-
2873 pfield_buffer
->pgo
)) {
2874 SAM("ERROR: bad pfield_buffer->pto\n");
2877 if (PAGE_SIZE
== (pfield_buffer
->pto
-
2878 pfield_buffer
->pgo
)) {
2879 (peasycap
->field_page
)++;
2880 if (FIELD_BUFFER_SIZE
/PAGE_SIZE
<=
2881 peasycap
->field_page
) {
2882 JOM(16, "wrapping peasycap->"
2884 peasycap
->field_page
= 0;
2886 pfield_buffer
= &peasycap
->
2888 [peasycap
->field_fill
]
2889 [peasycap
->field_page
];
2890 pfield_buffer
->pto
= pfield_buffer
->pgo
;
2891 pfield_buffer
->input
= 0x08 |
2892 (0x07 & peasycap
->input
);
2893 if ((peasycap
->field_buffer
[peasycap
->
2896 pfield_buffer
->input
)
2897 (peasycap
->field_buffer
2898 [peasycap
->field_fill
]
2899 [0]).kount
|= 0x1000;
2903 (int)(pfield_buffer
->pto
-
2904 pfield_buffer
->pgo
);
2908 memcpy(pfield_buffer
->pto
, pu
, much
);
2910 (pfield_buffer
->pto
) += much
;
2917 /*---------------------------------------------------------------------------*/
2919 * RESUBMIT THIS URB, UNLESS A SEVERE PERSISTENT ERROR CONDITION EXISTS.
2921 * IF THE WAIT QUEUES ARE NOT CLEARED IN RESPONSE TO AN ERROR CONDITION
2922 * THE USERSPACE PROGRAM, E.G. mplayer, MAY HANG ON EXIT. BEWARE.
2924 /*---------------------------------------------------------------------------*/
2925 if (VIDEO_ISOC_BUFFER_MANY
<= peasycap
->video_junk
) {
2926 SAM("easycap driver shutting down on condition green\n");
2927 peasycap
->status
= 1;
2928 peasycap
->video_eof
= 1;
2929 peasycap
->video_junk
= 0;
2930 wake_up_interruptible(&peasycap
->wq_video
);
2931 #if !defined(PERSEVERE)
2932 peasycap
->audio_eof
= 1;
2933 wake_up_interruptible(&peasycap
->wq_audio
);
2934 #endif /*PERSEVERE*/
2937 if (peasycap
->video_isoc_streaming
) {
2938 rc
= usb_submit_urb(purb
, GFP_ATOMIC
);
2940 SAM("%s: %d\n", strerror(rc
), rc
);
2942 SAM("ERROR: while %i=video_idle, "
2944 "failed with rc:\n",
2945 peasycap
->video_idle
);
2950 static const struct file_operations easycap_fops
= {
2951 .owner
= THIS_MODULE
,
2952 .open
= easycap_open
,
2953 .unlocked_ioctl
= easycap_unlocked_ioctl
,
2954 .poll
= easycap_poll
,
2955 .mmap
= easycap_mmap
,
2956 .llseek
= no_llseek
,
2958 static const struct usb_class_driver easycap_class
= {
2959 .name
= "usb/easycap%d",
2960 .fops
= &easycap_fops
,
2961 .minor_base
= USB_SKEL_MINOR_BASE
,
2963 /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
2964 static const struct v4l2_file_operations v4l2_fops
= {
2965 .owner
= THIS_MODULE
,
2966 .open
= easycap_open_noinode
,
2967 .unlocked_ioctl
= easycap_unlocked_ioctl
,
2968 .poll
= easycap_poll
,
2969 .mmap
= easycap_mmap
,
2971 /*****************************************************************************/
2972 /*---------------------------------------------------------------------------*/
2974 * WHEN THE EasyCAP IS PHYSICALLY PLUGGED IN, THIS FUNCTION IS CALLED THREE
2975 * TIMES, ONCE FOR EACH OF THE THREE INTERFACES. BEWARE.
2977 /*---------------------------------------------------------------------------*/
2978 static int easycap_usb_probe(struct usb_interface
*intf
,
2979 const struct usb_device_id
*id
)
2981 struct usb_device
*usbdev
;
2982 struct usb_host_interface
*alt
;
2983 struct usb_endpoint_descriptor
*ep
;
2984 struct usb_interface_descriptor
*interface
;
2986 struct easycap
*peasycap
;
2988 struct data_urb
*pdata_urb
;
2990 u8 bInterfaceNumber
;
2992 u8 bInterfaceSubClass
;
2994 int okalt
[8], isokalt
;
3000 struct easycap_format
*peasycap_format
;
3002 struct inputset
*inputset
;
3003 struct v4l2_device
*pv4l2_device
;
3005 usbdev
= interface_to_usbdev(intf
);
3007 /*---------------------------------------------------------------------------*/
3008 alt
= usb_altnum_to_altsetting(intf
, 0);
3010 SAY("ERROR: usb_host_interface not found\n");
3013 interface
= &alt
->desc
;
3015 SAY("ERROR: intf_descriptor is NULL\n");
3018 /*---------------------------------------------------------------------------*/
3020 * GET PROPERTIES OF PROBED INTERFACE
3022 /*---------------------------------------------------------------------------*/
3023 bInterfaceNumber
= interface
->bInterfaceNumber
;
3024 bInterfaceClass
= interface
->bInterfaceClass
;
3025 bInterfaceSubClass
= interface
->bInterfaceSubClass
;
3027 JOT(4, "intf[%i]: num_altsetting=%i\n",
3028 bInterfaceNumber
, intf
->num_altsetting
);
3029 JOT(4, "intf[%i]: cur_altsetting - altsetting=%li\n",
3031 (long int)(intf
->cur_altsetting
- intf
->altsetting
));
3032 JOT(4, "intf[%i]: bInterfaceClass=0x%02X bInterfaceSubClass=0x%02X\n",
3033 bInterfaceNumber
, bInterfaceClass
, bInterfaceSubClass
);
3034 /*---------------------------------------------------------------------------*/
3036 * A NEW struct easycap IS ALWAYS ALLOCATED WHEN INTERFACE 0 IS PROBED.
3037 * IT IS NOT POSSIBLE HERE TO FREE ANY EXISTING struct easycap. THIS
3038 * SHOULD HAVE BEEN DONE BY easycap_delete() WHEN THE EasyCAP WAS
3039 * PHYSICALLY UNPLUGGED.
3041 * THE POINTER peasycap TO THE struct easycap IS REMEMBERED WHEN
3042 * INTERFACES 1 AND 2 ARE PROBED.
3044 /*---------------------------------------------------------------------------*/
3045 if (0 == bInterfaceNumber
) {
3046 peasycap
= kzalloc(sizeof(struct easycap
), GFP_KERNEL
);
3048 SAY("ERROR: Could not allocate peasycap\n");
3051 /*---------------------------------------------------------------------------*/
3053 * PERFORM URGENT INTIALIZATIONS ...
3055 /*---------------------------------------------------------------------------*/
3056 peasycap
->minor
= -1;
3057 strcpy(&peasycap
->telltale
[0], TELLTALE
);
3058 kref_init(&peasycap
->kref
);
3059 JOM(8, "intf[%i]: after kref_init(..._video) "
3060 "%i=peasycap->kref.refcount.counter\n",
3061 bInterfaceNumber
, peasycap
->kref
.refcount
.counter
);
3064 peasycap
->gain
= (s8
)clamp(easycap_gain
, 0, 31);
3066 init_waitqueue_head(&peasycap
->wq_video
);
3067 init_waitqueue_head(&peasycap
->wq_audio
);
3068 init_waitqueue_head(&peasycap
->wq_trigger
);
3070 if (mutex_lock_interruptible(&mutex_dongle
)) {
3071 SAY("ERROR: cannot down mutex_dongle\n");
3072 return -ERESTARTSYS
;
3074 /*---------------------------------------------------------------------------*/
3076 * FOR INTERFACES 1 AND 2 THE POINTER peasycap WILL NEED TO
3077 * TO BE THE SAME AS THAT ALLOCATED NOW FOR INTERFACE 0.
3079 * NORMALLY ndong WILL NOT HAVE CHANGED SINCE INTERFACE 0 WAS
3080 * PROBED, BUT THIS MAY NOT BE THE CASE IF, FOR EXAMPLE, TWO
3081 * EASYCAPs ARE PLUGGED IN SIMULTANEOUSLY.
3083 /*---------------------------------------------------------------------------*/
3084 for (ndong
= 0; ndong
< DONGLE_MANY
; ndong
++) {
3085 if ((!easycapdc60_dongle
[ndong
].peasycap
) &&
3086 (!mutex_is_locked(&easycapdc60_dongle
3087 [ndong
].mutex_video
)) &&
3088 (!mutex_is_locked(&easycapdc60_dongle
3089 [ndong
].mutex_audio
))) {
3090 easycapdc60_dongle
[ndong
].peasycap
= peasycap
;
3091 peasycap
->isdongle
= ndong
;
3092 JOM(8, "intf[%i]: peasycap-->easycap"
3093 "_dongle[%i].peasycap\n",
3094 bInterfaceNumber
, ndong
);
3098 if (DONGLE_MANY
<= ndong
) {
3099 SAM("ERROR: too many dongles\n");
3100 mutex_unlock(&mutex_dongle
);
3103 mutex_unlock(&mutex_dongle
);
3105 peasycap
->allocation_video_struct
= sizeof(struct easycap
);
3106 peasycap
->allocation_video_page
= 0;
3107 peasycap
->allocation_video_urb
= 0;
3108 peasycap
->allocation_audio_struct
= 0;
3109 peasycap
->allocation_audio_page
= 0;
3110 peasycap
->allocation_audio_urb
= 0;
3112 /*---------------------------------------------------------------------------*/
3114 * ... AND FURTHER INITIALIZE THE STRUCTURE
3116 /*---------------------------------------------------------------------------*/
3117 peasycap
->pusb_device
= usbdev
;
3118 peasycap
->pusb_interface
= intf
;
3121 peasycap
->microphone
= false;
3123 peasycap
->video_interface
= -1;
3124 peasycap
->video_altsetting_on
= -1;
3125 peasycap
->video_altsetting_off
= -1;
3126 peasycap
->video_endpointnumber
= -1;
3127 peasycap
->video_isoc_maxframesize
= -1;
3128 peasycap
->video_isoc_buffer_size
= -1;
3130 peasycap
->audio_interface
= -1;
3131 peasycap
->audio_altsetting_on
= -1;
3132 peasycap
->audio_altsetting_off
= -1;
3133 peasycap
->audio_endpointnumber
= -1;
3134 peasycap
->audio_isoc_maxframesize
= -1;
3135 peasycap
->audio_isoc_buffer_size
= -1;
3137 peasycap
->frame_buffer_many
= FRAME_BUFFER_MANY
;
3139 for (k
= 0; k
< INPUT_MANY
; k
++)
3140 peasycap
->lost
[k
] = 0;
3142 peasycap
->skipped
= 0;
3143 peasycap
->offerfields
= 0;
3144 /*---------------------------------------------------------------------------*/
3146 * DYNAMICALLY FILL IN THE AVAILABLE FORMATS ...
3148 /*---------------------------------------------------------------------------*/
3149 rc
= fillin_formats();
3151 SAM("ERROR: fillin_formats() rc = %i\n", rc
);
3154 JOM(4, "%i formats available\n", rc
);
3155 /*---------------------------------------------------------------------------*/
3157 * ... AND POPULATE easycap.inputset[]
3159 /*---------------------------------------------------------------------------*/
3160 /* FIXME: maybe we just use memset 0 */
3161 inputset
= peasycap
->inputset
;
3162 for (k
= 0; k
< INPUT_MANY
; k
++) {
3163 inputset
[k
].input_ok
= 0;
3164 inputset
[k
].standard_offset_ok
= 0;
3165 inputset
[k
].format_offset_ok
= 0;
3166 inputset
[k
].brightness_ok
= 0;
3167 inputset
[k
].contrast_ok
= 0;
3168 inputset
[k
].saturation_ok
= 0;
3169 inputset
[k
].hue_ok
= 0;
3172 fmtidx
= peasycap
->ntsc
? NTSC_M
: PAL_BGHIN
;
3175 for (i
= 0; 0xFFFF != easycap_standard
[i
].mask
; i
++) {
3176 if (fmtidx
== easycap_standard
[i
].v4l2_standard
.index
) {
3178 for (k
= 0; k
< INPUT_MANY
; k
++)
3179 inputset
[k
].standard_offset
= i
;
3181 mask
= easycap_standard
[i
].mask
;
3187 "inputset->standard_offset unpopulated, %i=m\n", m
);
3191 peasycap_format
= &easycap_format
[0];
3193 for (i
= 0; peasycap_format
->v4l2_format
.fmt
.pix
.width
; i
++) {
3194 struct v4l2_pix_format
*pix
=
3195 &peasycap_format
->v4l2_format
.fmt
.pix
;
3196 if (((peasycap_format
->mask
& 0x0F) == (mask
& 0x0F)) &&
3197 pix
->field
== V4L2_FIELD_NONE
&&
3198 pix
->pixelformat
== V4L2_PIX_FMT_UYVY
&&
3199 pix
->width
== 640 && pix
->height
== 480) {
3201 for (k
= 0; k
< INPUT_MANY
; k
++)
3202 inputset
[k
].format_offset
= i
;
3208 SAM("ERROR: inputset[]->format_offset unpopulated\n");
3213 for (i
= 0; 0xFFFFFFFF != easycap_control
[i
].id
; i
++) {
3214 value
= easycap_control
[i
].default_value
;
3215 if (V4L2_CID_BRIGHTNESS
== easycap_control
[i
].id
) {
3217 for (k
= 0; k
< INPUT_MANY
; k
++)
3218 inputset
[k
].brightness
= value
;
3219 } else if (V4L2_CID_CONTRAST
== easycap_control
[i
].id
) {
3221 for (k
= 0; k
< INPUT_MANY
; k
++)
3222 inputset
[k
].contrast
= value
;
3223 } else if (V4L2_CID_SATURATION
== easycap_control
[i
].id
) {
3225 for (k
= 0; k
< INPUT_MANY
; k
++)
3226 inputset
[k
].saturation
= value
;
3227 } else if (V4L2_CID_HUE
== easycap_control
[i
].id
) {
3229 for (k
= 0; k
< INPUT_MANY
; k
++)
3230 inputset
[k
].hue
= value
;
3235 SAM("ERROR: inputset[]->brightness underpopulated\n");
3238 for (k
= 0; k
< INPUT_MANY
; k
++)
3239 inputset
[k
].input
= k
;
3240 JOM(4, "populated inputset[]\n");
3241 JOM(4, "finished initialization\n");
3243 /*---------------------------------------------------------------------------*/
3247 * IDENTIFY THE APPROPRIATE POINTER peasycap FOR INTERFACES 1 AND 2.
3248 * THE ADDRESS OF peasycap->pusb_device IS RELUCTANTLY USED FOR THIS PURPOSE.
3250 /*---------------------------------------------------------------------------*/
3251 for (ndong
= 0; ndong
< DONGLE_MANY
; ndong
++) {
3252 if (usbdev
== easycapdc60_dongle
[ndong
].peasycap
->
3254 peasycap
= easycapdc60_dongle
[ndong
].peasycap
;
3255 JOT(8, "intf[%i]: dongle[%i].peasycap\n",
3256 bInterfaceNumber
, ndong
);
3260 if (DONGLE_MANY
<= ndong
) {
3261 SAY("ERROR: peasycap is unknown when probing interface %i\n",
3266 SAY("ERROR: peasycap is NULL when probing interface %i\n",
3270 /*---------------------------------------------------------------------------*/
3272 * SOME VERSIONS OF THE videodev MODULE OVERWRITE THE DATA WHICH HAS
3273 * BEEN WRITTEN BY THE CALL TO usb_set_intfdata() IN easycap_usb_probe(),
3274 * REPLACING IT WITH A POINTER TO THE EMBEDDED v4l2_device STRUCTURE.
3275 * TO DETECT THIS, THE STRING IN THE easycap.telltale[] BUFFER IS CHECKED.
3277 /*---------------------------------------------------------------------------*/
3278 if (memcmp(&peasycap
->telltale
[0], TELLTALE
, strlen(TELLTALE
))) {
3279 pv4l2_device
= usb_get_intfdata(intf
);
3280 if (!pv4l2_device
) {
3281 SAY("ERROR: pv4l2_device is NULL\n");
3284 peasycap
= (struct easycap
*)
3285 container_of(pv4l2_device
, struct easycap
, v4l2_device
);
3288 /*---------------------------------------------------------------------------*/
3289 if ((USB_CLASS_VIDEO
== bInterfaceClass
) ||
3290 (USB_CLASS_VENDOR_SPEC
== bInterfaceClass
)) {
3291 if (-1 == peasycap
->video_interface
) {
3292 peasycap
->video_interface
= bInterfaceNumber
;
3293 JOM(4, "setting peasycap->video_interface=%i\n",
3294 peasycap
->video_interface
);
3296 if (peasycap
->video_interface
!= bInterfaceNumber
) {
3297 SAM("ERROR: attempting to reset "
3298 "peasycap->video_interface\n");
3299 SAM("...... continuing with "
3300 "%i=peasycap->video_interface\n",
3301 peasycap
->video_interface
);
3304 } else if ((USB_CLASS_AUDIO
== bInterfaceClass
) &&
3305 (USB_SUBCLASS_AUDIOSTREAMING
== bInterfaceSubClass
)) {
3306 if (-1 == peasycap
->audio_interface
) {
3307 peasycap
->audio_interface
= bInterfaceNumber
;
3308 JOM(4, "setting peasycap->audio_interface=%i\n",
3309 peasycap
->audio_interface
);
3311 if (peasycap
->audio_interface
!= bInterfaceNumber
) {
3312 SAM("ERROR: attempting to reset "
3313 "peasycap->audio_interface\n");
3314 SAM("...... continuing with "
3315 "%i=peasycap->audio_interface\n",
3316 peasycap
->audio_interface
);
3320 /*---------------------------------------------------------------------------*/
3322 * INVESTIGATE ALL ALTSETTINGS.
3323 * DONE IN DETAIL BECAUSE USB DEVICE 05e1:0408 HAS DISPARATE INCARNATIONS.
3325 /*---------------------------------------------------------------------------*/
3328 for (i
= 0; i
< intf
->num_altsetting
; i
++) {
3329 alt
= usb_altnum_to_altsetting(intf
, i
);
3331 SAM("ERROR: alt is NULL\n");
3334 interface
= &alt
->desc
;
3336 SAM("ERROR: intf_descriptor is NULL\n");
3340 if (0 == interface
->bNumEndpoints
)
3341 JOM(4, "intf[%i]alt[%i] has no endpoints\n",
3342 bInterfaceNumber
, i
);
3343 /*---------------------------------------------------------------------------*/
3344 for (j
= 0; j
< interface
->bNumEndpoints
; j
++) {
3345 ep
= &alt
->endpoint
[j
].desc
;
3347 SAM("ERROR: ep is NULL.\n");
3348 SAM("...... skipping\n");
3352 if (!usb_endpoint_is_isoc_in(ep
)) {
3353 JOM(4, "intf[%i]alt[%i]end[%i] is a %d endpoint\n",
3355 i
, j
, ep
->bmAttributes
);
3356 if (usb_endpoint_dir_out(ep
)) {
3357 SAM("ERROR: OUT endpoint unexpected\n");
3358 SAM("...... continuing\n");
3362 switch (bInterfaceClass
) {
3363 case USB_CLASS_VIDEO
:
3364 case USB_CLASS_VENDOR_SPEC
: {
3365 if (ep
->wMaxPacketSize
) {
3390 if (-1 == peasycap
->
3391 video_altsetting_off
) {
3393 video_altsetting_off
=
3399 video_altsetting_off
);
3401 SAM("ERROR: peasycap"
3402 "->video_altsetting_"
3403 "off already set\n");
3406 "%i=peasycap->video_"
3409 video_altsetting_off
);
3414 case USB_CLASS_AUDIO
: {
3415 if (bInterfaceSubClass
!=
3416 USB_SUBCLASS_AUDIOSTREAMING
)
3420 "peasycap is NULL\n");
3423 if (ep
->wMaxPacketSize
) {
3425 okalt
[isokalt
] = i
;
3448 if (-1 == peasycap
->
3449 audio_altsetting_off
) {
3451 audio_altsetting_off
=
3457 audio_altsetting_off
);
3459 SAM("ERROR: peasycap"
3460 "->audio_altsetting_"
3461 "off already set\n");
3468 audio_altsetting_off
);
3476 if (0 == ep
->wMaxPacketSize
) {
3477 JOM(4, "intf[%i]alt[%i]end[%i] "
3478 "has zero packet size\n",
3479 bInterfaceNumber
, i
, j
);
3483 /*---------------------------------------------------------------------------*/
3485 * PERFORM INITIALIZATION OF THE PROBED INTERFACE
3487 /*---------------------------------------------------------------------------*/
3488 JOM(4, "initialization begins for interface %i\n",
3489 interface
->bInterfaceNumber
);
3490 switch (bInterfaceNumber
) {
3491 /*---------------------------------------------------------------------------*/
3493 * INTERFACE 0 IS THE VIDEO INTERFACE
3495 /*---------------------------------------------------------------------------*/
3498 SAM("MISTAKE: peasycap is NULL\n");
3502 SAM("ERROR: no viable video_altsetting_on\n");
3505 peasycap
->video_altsetting_on
= okalt
[isokalt
- 1];
3506 JOM(4, "%i=video_altsetting_on <====\n",
3507 peasycap
->video_altsetting_on
);
3509 /*---------------------------------------------------------------------------*/
3511 * DECIDE THE VIDEO STREAMING PARAMETERS
3513 /*---------------------------------------------------------------------------*/
3514 peasycap
->video_endpointnumber
= okepn
[isokalt
- 1];
3515 JOM(4, "%i=video_endpointnumber\n", peasycap
->video_endpointnumber
);
3516 maxpacketsize
= okmps
[isokalt
- 1];
3518 peasycap
->video_isoc_maxframesize
=
3519 min(maxpacketsize
, USB_2_0_MAXPACKETSIZE
);
3520 if (0 >= peasycap
->video_isoc_maxframesize
) {
3521 SAM("ERROR: bad video_isoc_maxframesize\n");
3522 SAM(" possibly because port is USB 1.1\n");
3525 JOM(4, "%i=video_isoc_maxframesize\n",
3526 peasycap
->video_isoc_maxframesize
);
3528 peasycap
->video_isoc_framesperdesc
= VIDEO_ISOC_FRAMESPERDESC
;
3529 JOM(4, "%i=video_isoc_framesperdesc\n",
3530 peasycap
->video_isoc_framesperdesc
);
3531 if (0 >= peasycap
->video_isoc_framesperdesc
) {
3532 SAM("ERROR: bad video_isoc_framesperdesc\n");
3535 peasycap
->video_isoc_buffer_size
=
3536 peasycap
->video_isoc_maxframesize
*
3537 peasycap
->video_isoc_framesperdesc
;
3538 JOM(4, "%i=video_isoc_buffer_size\n",
3539 peasycap
->video_isoc_buffer_size
);
3540 if ((PAGE_SIZE
<< VIDEO_ISOC_ORDER
) <
3541 peasycap
->video_isoc_buffer_size
) {
3542 SAM("MISTAKE: peasycap->video_isoc_buffer_size too big\n");
3545 /*---------------------------------------------------------------------------*/
3546 if (-1 == peasycap
->video_interface
) {
3547 SAM("MISTAKE: video_interface is unset\n");
3550 if (-1 == peasycap
->video_altsetting_on
) {
3551 SAM("MISTAKE: video_altsetting_on is unset\n");
3554 if (-1 == peasycap
->video_altsetting_off
) {
3555 SAM("MISTAKE: video_interface_off is unset\n");
3558 if (-1 == peasycap
->video_endpointnumber
) {
3559 SAM("MISTAKE: video_endpointnumber is unset\n");
3562 if (-1 == peasycap
->video_isoc_maxframesize
) {
3563 SAM("MISTAKE: video_isoc_maxframesize is unset\n");
3566 if (-1 == peasycap
->video_isoc_buffer_size
) {
3567 SAM("MISTAKE: video_isoc_buffer_size is unset\n");
3570 /*---------------------------------------------------------------------------*/
3572 * ALLOCATE MEMORY FOR VIDEO BUFFERS. LISTS MUST BE INITIALIZED FIRST.
3574 /*---------------------------------------------------------------------------*/
3575 INIT_LIST_HEAD(&(peasycap
->urb_video_head
));
3576 peasycap
->purb_video_head
= &(peasycap
->urb_video_head
);
3577 /*---------------------------------------------------------------------------*/
3578 JOM(4, "allocating %i frame buffers of size %li\n",
3579 FRAME_BUFFER_MANY
, (long int)FRAME_BUFFER_SIZE
);
3580 JOM(4, ".... each scattered over %li pages\n",
3581 FRAME_BUFFER_SIZE
/PAGE_SIZE
);
3583 for (k
= 0; k
< FRAME_BUFFER_MANY
; k
++) {
3584 for (m
= 0; m
< FRAME_BUFFER_SIZE
/PAGE_SIZE
; m
++) {
3585 if (peasycap
->frame_buffer
[k
][m
].pgo
)
3586 SAM("attempting to reallocate frame "
3589 pbuf
= (void *)__get_free_page(GFP_KERNEL
);
3591 SAM("ERROR: Could not allocate frame "
3592 "buffer %i page %i\n", k
, m
);
3595 peasycap
->allocation_video_page
+= 1;
3596 peasycap
->frame_buffer
[k
][m
].pgo
= pbuf
;
3598 peasycap
->frame_buffer
[k
][m
].pto
=
3599 peasycap
->frame_buffer
[k
][m
].pgo
;
3603 peasycap
->frame_fill
= 0;
3604 peasycap
->frame_read
= 0;
3605 JOM(4, "allocation of frame buffers done: %i pages\n", k
*
3607 /*---------------------------------------------------------------------------*/
3608 JOM(4, "allocating %i field buffers of size %li\n",
3609 FIELD_BUFFER_MANY
, (long int)FIELD_BUFFER_SIZE
);
3610 JOM(4, ".... each scattered over %li pages\n",
3611 FIELD_BUFFER_SIZE
/PAGE_SIZE
);
3613 for (k
= 0; k
< FIELD_BUFFER_MANY
; k
++) {
3614 for (m
= 0; m
< FIELD_BUFFER_SIZE
/PAGE_SIZE
; m
++) {
3615 if (peasycap
->field_buffer
[k
][m
].pgo
) {
3616 SAM("ERROR: attempting to reallocate "
3619 pbuf
= (void *) __get_free_page(GFP_KERNEL
);
3621 SAM("ERROR: Could not allocate field"
3622 " buffer %i page %i\n", k
, m
);
3626 peasycap
->allocation_video_page
+= 1;
3627 peasycap
->field_buffer
[k
][m
].pgo
= pbuf
;
3629 peasycap
->field_buffer
[k
][m
].pto
=
3630 peasycap
->field_buffer
[k
][m
].pgo
;
3632 peasycap
->field_buffer
[k
][0].kount
= 0x0200;
3634 peasycap
->field_fill
= 0;
3635 peasycap
->field_page
= 0;
3636 peasycap
->field_read
= 0;
3637 JOM(4, "allocation of field buffers done: %i pages\n", k
*
3639 /*---------------------------------------------------------------------------*/
3640 JOM(4, "allocating %i isoc video buffers of size %i\n",
3641 VIDEO_ISOC_BUFFER_MANY
,
3642 peasycap
->video_isoc_buffer_size
);
3643 JOM(4, ".... each occupying contiguous memory pages\n");
3645 for (k
= 0; k
< VIDEO_ISOC_BUFFER_MANY
; k
++) {
3646 pbuf
= (void *)__get_free_pages(GFP_KERNEL
,
3649 SAM("ERROR: Could not allocate isoc video buffer "
3653 peasycap
->allocation_video_page
+=
3654 BIT(VIDEO_ISOC_ORDER
);
3656 peasycap
->video_isoc_buffer
[k
].pgo
= pbuf
;
3657 peasycap
->video_isoc_buffer
[k
].pto
=
3658 pbuf
+ peasycap
->video_isoc_buffer_size
;
3659 peasycap
->video_isoc_buffer
[k
].kount
= k
;
3661 JOM(4, "allocation of isoc video buffers done: %i pages\n",
3662 k
* (0x01 << VIDEO_ISOC_ORDER
));
3663 /*---------------------------------------------------------------------------*/
3665 * ALLOCATE AND INITIALIZE MULTIPLE struct urb ...
3667 /*---------------------------------------------------------------------------*/
3668 JOM(4, "allocating %i struct urb.\n", VIDEO_ISOC_BUFFER_MANY
);
3669 JOM(4, "using %i=peasycap->video_isoc_framesperdesc\n",
3670 peasycap
->video_isoc_framesperdesc
);
3671 JOM(4, "using %i=peasycap->video_isoc_maxframesize\n",
3672 peasycap
->video_isoc_maxframesize
);
3673 JOM(4, "using %i=peasycap->video_isoc_buffer_sizen",
3674 peasycap
->video_isoc_buffer_size
);
3676 for (k
= 0; k
< VIDEO_ISOC_BUFFER_MANY
; k
++) {
3677 purb
= usb_alloc_urb(peasycap
->video_isoc_framesperdesc
,
3680 SAM("ERROR: usb_alloc_urb returned NULL for buffer "
3684 peasycap
->allocation_video_urb
+= 1;
3685 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
3686 pdata_urb
= kzalloc(sizeof(struct data_urb
), GFP_KERNEL
);
3688 SAM("ERROR: Could not allocate struct data_urb.\n");
3691 peasycap
->allocation_video_struct
+=
3692 sizeof(struct data_urb
);
3694 pdata_urb
->purb
= purb
;
3695 pdata_urb
->isbuf
= k
;
3696 pdata_urb
->length
= 0;
3697 list_add_tail(&(pdata_urb
->list_head
),
3698 peasycap
->purb_video_head
);
3699 /*---------------------------------------------------------------------------*/
3701 * ... AND INITIALIZE THEM
3703 /*---------------------------------------------------------------------------*/
3705 JOM(4, "initializing video urbs thus:\n");
3706 JOM(4, " purb->interval = 1;\n");
3707 JOM(4, " purb->dev = peasycap->pusb_device;\n");
3708 JOM(4, " purb->pipe = usb_rcvisocpipe"
3709 "(peasycap->pusb_device,%i);\n",
3710 peasycap
->video_endpointnumber
);
3711 JOM(4, " purb->transfer_flags = URB_ISO_ASAP;\n");
3712 JOM(4, " purb->transfer_buffer = peasycap->"
3713 "video_isoc_buffer[.].pgo;\n");
3714 JOM(4, " purb->transfer_buffer_length = %i;\n",
3715 peasycap
->video_isoc_buffer_size
);
3716 JOM(4, " purb->complete = easycap_complete;\n");
3717 JOM(4, " purb->context = peasycap;\n");
3718 JOM(4, " purb->start_frame = 0;\n");
3719 JOM(4, " purb->number_of_packets = %i;\n",
3720 peasycap
->video_isoc_framesperdesc
);
3721 JOM(4, " for (j = 0; j < %i; j++)\n",
3722 peasycap
->video_isoc_framesperdesc
);
3724 JOM(4, " purb->iso_frame_desc[j].offset = j*%i;\n",
3725 peasycap
->video_isoc_maxframesize
);
3726 JOM(4, " purb->iso_frame_desc[j].length = %i;\n",
3727 peasycap
->video_isoc_maxframesize
);
3732 purb
->dev
= peasycap
->pusb_device
;
3733 purb
->pipe
= usb_rcvisocpipe(peasycap
->pusb_device
,
3734 peasycap
->video_endpointnumber
);
3735 purb
->transfer_flags
= URB_ISO_ASAP
;
3736 purb
->transfer_buffer
= peasycap
->video_isoc_buffer
[k
].pgo
;
3737 purb
->transfer_buffer_length
=
3738 peasycap
->video_isoc_buffer_size
;
3739 purb
->complete
= easycap_complete
;
3740 purb
->context
= peasycap
;
3741 purb
->start_frame
= 0;
3742 purb
->number_of_packets
= peasycap
->video_isoc_framesperdesc
;
3743 for (j
= 0; j
< peasycap
->video_isoc_framesperdesc
; j
++) {
3744 purb
->iso_frame_desc
[j
].offset
= j
*
3745 peasycap
->video_isoc_maxframesize
;
3746 purb
->iso_frame_desc
[j
].length
=
3747 peasycap
->video_isoc_maxframesize
;
3750 JOM(4, "allocation of %i struct urb done.\n", k
);
3751 /*--------------------------------------------------------------------------*/
3753 * SAVE POINTER peasycap IN THIS INTERFACE.
3755 /*--------------------------------------------------------------------------*/
3756 usb_set_intfdata(intf
, peasycap
);
3757 /*---------------------------------------------------------------------------*/
3759 * IT IS ESSENTIAL TO INITIALIZE THE HARDWARE BEFORE, RATHER THAN AFTER,
3760 * THE DEVICE IS REGISTERED, BECAUSE SOME VERSIONS OF THE videodev MODULE
3761 * CALL easycap_open() IMMEDIATELY AFTER REGISTRATION, CAUSING A CLASH.
3764 /*---------------------------------------------------------------------------*/
3765 peasycap
->ntsc
= easycap_ntsc
;
3766 JOM(8, "defaulting initially to %s\n",
3767 easycap_ntsc
? "NTSC" : "PAL");
3768 rc
= reset(peasycap
);
3770 SAM("ERROR: reset() rc = %i\n", rc
);
3773 /*--------------------------------------------------------------------------*/
3775 * THE VIDEO DEVICE CAN BE REGISTERED NOW, AS IT IS READY.
3777 /*--------------------------------------------------------------------------*/
3778 if (0 != (v4l2_device_register(&(intf
->dev
),
3779 &(peasycap
->v4l2_device
)))) {
3780 SAM("v4l2_device_register() failed\n");
3783 JOM(4, "registered device instance: %s\n",
3784 &(peasycap
->v4l2_device
.name
[0]));
3786 /*---------------------------------------------------------------------------*/
3791 * THIS IS BELIEVED TO BE HARMLESS, BUT MAY WELL BE UNNECESSARY OR WRONG:
3793 /*---------------------------------------------------------------------------*/
3794 peasycap
->video_device
.v4l2_dev
= NULL
;
3795 /*---------------------------------------------------------------------------*/
3798 strcpy(&peasycap
->video_device
.name
[0], "easycapdc60");
3799 peasycap
->video_device
.fops
= &v4l2_fops
;
3800 peasycap
->video_device
.minor
= -1;
3801 peasycap
->video_device
.release
= (void *)(&videodev_release
);
3803 video_set_drvdata(&(peasycap
->video_device
), (void *)peasycap
);
3805 if (0 != (video_register_device(&(peasycap
->video_device
),
3806 VFL_TYPE_GRABBER
, -1))) {
3807 err("Not able to register with videodev");
3808 videodev_release(&(peasycap
->video_device
));
3811 (peasycap
->registered_video
)++;
3812 SAM("registered with videodev: %i=minor\n",
3813 peasycap
->video_device
.minor
);
3814 peasycap
->minor
= peasycap
->video_device
.minor
;
3816 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
3820 /*--------------------------------------------------------------------------*/
3822 * INTERFACE 1 IS THE AUDIO CONTROL INTERFACE
3823 * INTERFACE 2 IS THE AUDIO STREAMING INTERFACE
3825 /*--------------------------------------------------------------------------*/
3828 SAM("MISTAKE: peasycap is NULL\n");
3831 /*--------------------------------------------------------------------------*/
3833 * SAVE POINTER peasycap IN INTERFACE 1
3835 /*--------------------------------------------------------------------------*/
3836 usb_set_intfdata(intf
, peasycap
);
3837 JOM(4, "no initialization required for interface %i\n",
3838 interface
->bInterfaceNumber
);
3841 /*--------------------------------------------------------------------------*/
3844 SAM("MISTAKE: peasycap is NULL\n");
3848 SAM("ERROR: no viable audio_altsetting_on\n");
3851 peasycap
->audio_altsetting_on
= okalt
[isokalt
- 1];
3852 JOM(4, "%i=audio_altsetting_on <====\n",
3853 peasycap
->audio_altsetting_on
);
3856 peasycap
->audio_endpointnumber
= okepn
[isokalt
- 1];
3857 JOM(4, "%i=audio_endpointnumber\n", peasycap
->audio_endpointnumber
);
3859 peasycap
->audio_isoc_maxframesize
= okmps
[isokalt
- 1];
3860 JOM(4, "%i=audio_isoc_maxframesize\n",
3861 peasycap
->audio_isoc_maxframesize
);
3862 if (0 >= peasycap
->audio_isoc_maxframesize
) {
3863 SAM("ERROR: bad audio_isoc_maxframesize\n");
3866 if (9 == peasycap
->audio_isoc_maxframesize
) {
3867 peasycap
->ilk
|= 0x02;
3868 SAM("audio hardware is microphone\n");
3869 peasycap
->microphone
= true;
3870 peasycap
->audio_pages_per_fragment
=
3871 PAGES_PER_AUDIO_FRAGMENT
;
3872 } else if (256 == peasycap
->audio_isoc_maxframesize
) {
3873 peasycap
->ilk
&= ~0x02;
3874 SAM("audio hardware is AC'97\n");
3875 peasycap
->microphone
= false;
3876 peasycap
->audio_pages_per_fragment
=
3877 PAGES_PER_AUDIO_FRAGMENT
;
3879 SAM("hardware is unidentified:\n");
3880 SAM("%i=audio_isoc_maxframesize\n",
3881 peasycap
->audio_isoc_maxframesize
);
3885 peasycap
->audio_bytes_per_fragment
=
3886 peasycap
->audio_pages_per_fragment
* PAGE_SIZE
;
3887 peasycap
->audio_buffer_page_many
= (AUDIO_FRAGMENT_MANY
*
3888 peasycap
->audio_pages_per_fragment
);
3890 JOM(4, "%6i=AUDIO_FRAGMENT_MANY\n", AUDIO_FRAGMENT_MANY
);
3891 JOM(4, "%6i=audio_pages_per_fragment\n",
3892 peasycap
->audio_pages_per_fragment
);
3893 JOM(4, "%6i=audio_bytes_per_fragment\n",
3894 peasycap
->audio_bytes_per_fragment
);
3895 JOM(4, "%6i=audio_buffer_page_many\n",
3896 peasycap
->audio_buffer_page_many
);
3898 peasycap
->audio_isoc_framesperdesc
= AUDIO_ISOC_FRAMESPERDESC
;
3900 JOM(4, "%i=audio_isoc_framesperdesc\n",
3901 peasycap
->audio_isoc_framesperdesc
);
3902 if (0 >= peasycap
->audio_isoc_framesperdesc
) {
3903 SAM("ERROR: bad audio_isoc_framesperdesc\n");
3907 peasycap
->audio_isoc_buffer_size
=
3908 peasycap
->audio_isoc_maxframesize
*
3909 peasycap
->audio_isoc_framesperdesc
;
3910 JOM(4, "%i=audio_isoc_buffer_size\n",
3911 peasycap
->audio_isoc_buffer_size
);
3912 if (AUDIO_ISOC_BUFFER_SIZE
< peasycap
->audio_isoc_buffer_size
) {
3913 SAM("MISTAKE: audio_isoc_buffer_size bigger "
3914 "than %li=AUDIO_ISOC_BUFFER_SIZE\n",
3915 AUDIO_ISOC_BUFFER_SIZE
);
3918 if (-1 == peasycap
->audio_interface
) {
3919 SAM("MISTAKE: audio_interface is unset\n");
3922 if (-1 == peasycap
->audio_altsetting_on
) {
3923 SAM("MISTAKE: audio_altsetting_on is unset\n");
3926 if (-1 == peasycap
->audio_altsetting_off
) {
3927 SAM("MISTAKE: audio_interface_off is unset\n");
3930 if (-1 == peasycap
->audio_endpointnumber
) {
3931 SAM("MISTAKE: audio_endpointnumber is unset\n");
3934 if (-1 == peasycap
->audio_isoc_maxframesize
) {
3935 SAM("MISTAKE: audio_isoc_maxframesize is unset\n");
3938 if (-1 == peasycap
->audio_isoc_buffer_size
) {
3939 SAM("MISTAKE: audio_isoc_buffer_size is unset\n");
3942 /*---------------------------------------------------------------------------*/
3944 * ALLOCATE MEMORY FOR AUDIO BUFFERS. LISTS MUST BE INITIALIZED FIRST.
3946 /*---------------------------------------------------------------------------*/
3947 INIT_LIST_HEAD(&(peasycap
->urb_audio_head
));
3948 peasycap
->purb_audio_head
= &(peasycap
->urb_audio_head
);
3950 #ifdef CONFIG_EASYCAP_OSS
3951 JOM(4, "allocating an audio buffer\n");
3952 JOM(4, ".... scattered over %i pages\n",
3953 peasycap
->audio_buffer_page_many
);
3955 for (k
= 0; k
< peasycap
->audio_buffer_page_many
; k
++) {
3956 if (peasycap
->audio_buffer
[k
].pgo
) {
3957 SAM("ERROR: attempting to reallocate audio buffers\n");
3959 pbuf
= (void *) __get_free_page(GFP_KERNEL
);
3961 SAM("ERROR: Could not allocate audio "
3962 "buffer page %i\n", k
);
3965 peasycap
->allocation_audio_page
+= 1;
3967 peasycap
->audio_buffer
[k
].pgo
= pbuf
;
3969 peasycap
->audio_buffer
[k
].pto
= peasycap
->audio_buffer
[k
].pgo
;
3972 peasycap
->audio_fill
= 0;
3973 peasycap
->audio_read
= 0;
3974 JOM(4, "allocation of audio buffer done: %i pages\n", k
);
3975 #endif /* CONFIG_EASYCAP_OSS */
3976 /*---------------------------------------------------------------------------*/
3977 JOM(4, "allocating %i isoc audio buffers of size %i\n",
3978 AUDIO_ISOC_BUFFER_MANY
,
3979 peasycap
->audio_isoc_buffer_size
);
3980 JOM(4, ".... each occupying contiguous memory pages\n");
3982 for (k
= 0; k
< AUDIO_ISOC_BUFFER_MANY
; k
++) {
3983 pbuf
= (void *)__get_free_pages(GFP_KERNEL
,
3986 SAM("ERROR: Could not allocate isoc audio buffer "
3990 peasycap
->allocation_audio_page
+=
3991 BIT(AUDIO_ISOC_ORDER
);
3993 peasycap
->audio_isoc_buffer
[k
].pgo
= pbuf
;
3994 peasycap
->audio_isoc_buffer
[k
].pto
= pbuf
+
3995 peasycap
->audio_isoc_buffer_size
;
3996 peasycap
->audio_isoc_buffer
[k
].kount
= k
;
3998 JOM(4, "allocation of isoc audio buffers done.\n");
3999 /*---------------------------------------------------------------------------*/
4001 * ALLOCATE AND INITIALIZE MULTIPLE struct urb ...
4003 /*---------------------------------------------------------------------------*/
4004 JOM(4, "allocating %i struct urb.\n", AUDIO_ISOC_BUFFER_MANY
);
4005 JOM(4, "using %i=peasycap->audio_isoc_framesperdesc\n",
4006 peasycap
->audio_isoc_framesperdesc
);
4007 JOM(4, "using %i=peasycap->audio_isoc_maxframesize\n",
4008 peasycap
->audio_isoc_maxframesize
);
4009 JOM(4, "using %i=peasycap->audio_isoc_buffer_size\n",
4010 peasycap
->audio_isoc_buffer_size
);
4012 for (k
= 0; k
< AUDIO_ISOC_BUFFER_MANY
; k
++) {
4013 purb
= usb_alloc_urb(peasycap
->audio_isoc_framesperdesc
,
4016 SAM("ERROR: usb_alloc_urb returned NULL for buffer "
4020 peasycap
->allocation_audio_urb
+= 1 ;
4021 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
4022 pdata_urb
= kzalloc(sizeof(struct data_urb
), GFP_KERNEL
);
4024 SAM("ERROR: Could not allocate struct data_urb.\n");
4027 peasycap
->allocation_audio_struct
+=
4028 sizeof(struct data_urb
);
4030 pdata_urb
->purb
= purb
;
4031 pdata_urb
->isbuf
= k
;
4032 pdata_urb
->length
= 0;
4033 list_add_tail(&(pdata_urb
->list_head
),
4034 peasycap
->purb_audio_head
);
4035 /*---------------------------------------------------------------------------*/
4037 * ... AND INITIALIZE THEM
4039 /*---------------------------------------------------------------------------*/
4041 JOM(4, "initializing audio urbs thus:\n");
4042 JOM(4, " purb->interval = 1;\n");
4043 JOM(4, " purb->dev = peasycap->pusb_device;\n");
4044 JOM(4, " purb->pipe = usb_rcvisocpipe(peasycap->"
4045 "pusb_device,%i);\n",
4046 peasycap
->audio_endpointnumber
);
4047 JOM(4, " purb->transfer_flags = URB_ISO_ASAP;\n");
4048 JOM(4, " purb->transfer_buffer = "
4049 "peasycap->audio_isoc_buffer[.].pgo;\n");
4050 JOM(4, " purb->transfer_buffer_length = %i;\n",
4051 peasycap
->audio_isoc_buffer_size
);
4052 #ifdef CONFIG_EASYCAP_OSS
4053 JOM(4, " purb->complete = easyoss_complete;\n");
4054 #else /* CONFIG_EASYCAP_OSS */
4055 JOM(4, " purb->complete = easycap_alsa_complete;\n");
4056 #endif /* CONFIG_EASYCAP_OSS */
4057 JOM(4, " purb->context = peasycap;\n");
4058 JOM(4, " purb->start_frame = 0;\n");
4059 JOM(4, " purb->number_of_packets = %i;\n",
4060 peasycap
->audio_isoc_framesperdesc
);
4061 JOM(4, " for (j = 0; j < %i; j++)\n",
4062 peasycap
->audio_isoc_framesperdesc
);
4064 JOM(4, " purb->iso_frame_desc[j].offset = j*%i;\n",
4065 peasycap
->audio_isoc_maxframesize
);
4066 JOM(4, " purb->iso_frame_desc[j].length = %i;\n",
4067 peasycap
->audio_isoc_maxframesize
);
4072 purb
->dev
= peasycap
->pusb_device
;
4073 purb
->pipe
= usb_rcvisocpipe(peasycap
->pusb_device
,
4074 peasycap
->audio_endpointnumber
);
4075 purb
->transfer_flags
= URB_ISO_ASAP
;
4076 purb
->transfer_buffer
= peasycap
->audio_isoc_buffer
[k
].pgo
;
4077 purb
->transfer_buffer_length
=
4078 peasycap
->audio_isoc_buffer_size
;
4079 #ifdef CONFIG_EASYCAP_OSS
4080 purb
->complete
= easyoss_complete
;
4081 #else /* CONFIG_EASYCAP_OSS */
4082 purb
->complete
= easycap_alsa_complete
;
4083 #endif /* CONFIG_EASYCAP_OSS */
4084 purb
->context
= peasycap
;
4085 purb
->start_frame
= 0;
4086 purb
->number_of_packets
= peasycap
->audio_isoc_framesperdesc
;
4087 for (j
= 0; j
< peasycap
->audio_isoc_framesperdesc
; j
++) {
4088 purb
->iso_frame_desc
[j
].offset
= j
*
4089 peasycap
->audio_isoc_maxframesize
;
4090 purb
->iso_frame_desc
[j
].length
=
4091 peasycap
->audio_isoc_maxframesize
;
4094 JOM(4, "allocation of %i struct urb done.\n", k
);
4095 /*---------------------------------------------------------------------------*/
4097 * SAVE POINTER peasycap IN THIS INTERFACE.
4099 /*---------------------------------------------------------------------------*/
4100 usb_set_intfdata(intf
, peasycap
);
4101 /*---------------------------------------------------------------------------*/
4103 * THE AUDIO DEVICE CAN BE REGISTERED NOW, AS IT IS READY.
4105 /*---------------------------------------------------------------------------*/
4106 #ifndef CONFIG_EASYCAP_OSS
4107 JOM(4, "initializing ALSA card\n");
4109 rc
= easycap_alsa_probe(peasycap
);
4111 err("easycap_alsa_probe() rc = %i\n", rc
);
4115 #else /* CONFIG_EASYCAP_OSS */
4116 rc
= usb_register_dev(intf
, &easyoss_class
);
4118 SAY("ERROR: usb_register_dev() failed\n");
4119 usb_set_intfdata(intf
, NULL
);
4122 SAM("easyoss attached to minor #%d\n", intf
->minor
);
4123 #endif /* CONFIG_EASYCAP_OSS */
4125 JOM(8, "kref_get() with %i=kref.refcount.counter\n",
4126 peasycap
->kref
.refcount
.counter
);
4127 kref_get(&peasycap
->kref
);
4128 peasycap
->registered_audio
++;
4131 /*---------------------------------------------------------------------------*/
4133 * INTERFACES OTHER THAN 0, 1 AND 2 ARE UNEXPECTED
4135 /*---------------------------------------------------------------------------*/
4137 JOM(4, "ERROR: unexpected interface %i\n", bInterfaceNumber
);
4140 SAM("ends successfully for interface %i\n", bInterfaceNumber
);
4143 /*****************************************************************************/
4144 /*---------------------------------------------------------------------------*/
4146 * WHEN THIS FUNCTION IS CALLED THE EasyCAP HAS ALREADY BEEN PHYSICALLY
4147 * UNPLUGGED. HENCE peasycap->pusb_device IS NO LONGER VALID.
4149 * THIS FUNCTION AFFECTS BOTH OSS AND ALSA. BEWARE.
4151 /*---------------------------------------------------------------------------*/
4152 static void easycap_usb_disconnect(struct usb_interface
*pusb_interface
)
4154 struct usb_host_interface
*pusb_host_interface
;
4155 struct usb_interface_descriptor
*pusb_interface_descriptor
;
4156 u8 bInterfaceNumber
;
4157 struct easycap
*peasycap
;
4159 struct list_head
*plist_head
;
4160 struct data_urb
*pdata_urb
;
4162 struct v4l2_device
*pv4l2_device
;
4166 pusb_host_interface
= pusb_interface
->cur_altsetting
;
4167 if (!pusb_host_interface
) {
4168 JOT(4, "ERROR: pusb_host_interface is NULL\n");
4171 pusb_interface_descriptor
= &(pusb_host_interface
->desc
);
4172 if (!pusb_interface_descriptor
) {
4173 JOT(4, "ERROR: pusb_interface_descriptor is NULL\n");
4176 bInterfaceNumber
= pusb_interface_descriptor
->bInterfaceNumber
;
4177 minor
= pusb_interface
->minor
;
4178 JOT(4, "intf[%i]: minor=%i\n", bInterfaceNumber
, minor
);
4180 if (1 == bInterfaceNumber
)
4183 peasycap
= usb_get_intfdata(pusb_interface
);
4185 SAY("ERROR: peasycap is NULL\n");
4188 /*---------------------------------------------------------------------------*/
4190 * SOME VERSIONS OF THE videodev MODULE OVERWRITE THE DATA WHICH HAS
4191 * BEEN WRITTEN BY THE CALL TO usb_set_intfdata() IN easycap_usb_probe(),
4192 * REPLACING IT WITH A POINTER TO THE EMBEDDED v4l2_device STRUCTURE.
4193 * TO DETECT THIS, THE STRING IN THE easycap.telltale[] BUFFER IS CHECKED.
4195 /*---------------------------------------------------------------------------*/
4196 if (memcmp(&peasycap
->telltale
[0], TELLTALE
, strlen(TELLTALE
))) {
4197 pv4l2_device
= usb_get_intfdata(pusb_interface
);
4198 if (!pv4l2_device
) {
4199 SAY("ERROR: pv4l2_device is NULL\n");
4202 peasycap
= (struct easycap
*)
4203 container_of(pv4l2_device
, struct easycap
, v4l2_device
);
4205 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
4206 /*---------------------------------------------------------------------------*/
4207 if (memcmp(&peasycap
->telltale
[0], TELLTALE
, strlen(TELLTALE
))) {
4208 SAY("ERROR: bad peasycap: %p\n", peasycap
);
4211 /*---------------------------------------------------------------------------*/
4213 * IF THE WAIT QUEUES ARE NOT CLEARED A DEADLOCK IS POSSIBLE. BEWARE.
4215 /*---------------------------------------------------------------------------*/
4216 peasycap
->video_eof
= 1;
4217 peasycap
->audio_eof
= 1;
4218 wake_up_interruptible(&(peasycap
->wq_video
));
4219 wake_up_interruptible(&(peasycap
->wq_audio
));
4220 /*---------------------------------------------------------------------------*/
4221 switch (bInterfaceNumber
) {
4223 if (peasycap
->purb_video_head
) {
4224 JOM(4, "killing video urbs\n");
4226 list_for_each(plist_head
, peasycap
->purb_video_head
) {
4227 pdata_urb
= list_entry(plist_head
,
4228 struct data_urb
, list_head
);
4230 if (pdata_urb
->purb
) {
4231 usb_kill_urb(pdata_urb
->purb
);
4236 JOM(4, "%i video urbs killed\n", m
);
4240 /*---------------------------------------------------------------------------*/
4242 if (peasycap
->purb_audio_head
) {
4243 JOM(4, "killing audio urbs\n");
4245 list_for_each(plist_head
, peasycap
->purb_audio_head
) {
4246 pdata_urb
= list_entry(plist_head
,
4247 struct data_urb
, list_head
);
4249 if (pdata_urb
->purb
) {
4250 usb_kill_urb(pdata_urb
->purb
);
4255 JOM(4, "%i audio urbs killed\n", m
);
4262 /*--------------------------------------------------------------------------*/
4266 * THIS PROCEDURE WILL BLOCK UNTIL easycap_poll(), VIDEO IOCTL AND AUDIO
4267 * IOCTL ARE ALL UNLOCKED. IF THIS IS NOT DONE AN Oops CAN OCCUR WHEN
4268 * AN EasyCAP IS UNPLUGGED WHILE THE URBS ARE RUNNING. BEWARE.
4270 /*--------------------------------------------------------------------------*/
4271 kd
= isdongle(peasycap
);
4272 switch (bInterfaceNumber
) {
4274 if (0 <= kd
&& DONGLE_MANY
> kd
) {
4275 wake_up_interruptible(&peasycap
->wq_video
);
4276 JOM(4, "about to lock dongle[%i].mutex_video\n", kd
);
4277 if (mutex_lock_interruptible(&easycapdc60_dongle
[kd
].
4280 "cannot lock dongle[%i].mutex_video\n", kd
);
4283 JOM(4, "locked dongle[%i].mutex_video\n", kd
);
4285 SAY("ERROR: %i=kd is bad: cannot lock dongle\n", kd
);
4287 /*---------------------------------------------------------------------------*/
4288 if (!peasycap
->v4l2_device
.name
[0]) {
4289 SAM("ERROR: peasycap->v4l2_device.name is empty\n");
4290 if (0 <= kd
&& DONGLE_MANY
> kd
)
4291 mutex_unlock(&easycapdc60_dongle
[kd
].mutex_video
);
4294 v4l2_device_disconnect(&peasycap
->v4l2_device
);
4295 JOM(4, "v4l2_device_disconnect() OK\n");
4296 v4l2_device_unregister(&peasycap
->v4l2_device
);
4297 JOM(4, "v4l2_device_unregister() OK\n");
4299 video_unregister_device(&peasycap
->video_device
);
4300 JOM(4, "intf[%i]: video_unregister_device() minor=%i\n",
4301 bInterfaceNumber
, minor
);
4302 peasycap
->registered_video
--;
4303 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
4305 if (0 <= kd
&& DONGLE_MANY
> kd
) {
4306 mutex_unlock(&easycapdc60_dongle
[kd
].mutex_video
);
4307 JOM(4, "unlocked dongle[%i].mutex_video\n", kd
);
4312 if (0 <= kd
&& DONGLE_MANY
> kd
) {
4313 wake_up_interruptible(&peasycap
->wq_audio
);
4314 JOM(4, "about to lock dongle[%i].mutex_audio\n", kd
);
4315 if (mutex_lock_interruptible(&easycapdc60_dongle
[kd
].
4318 "cannot lock dongle[%i].mutex_audio\n", kd
);
4321 JOM(4, "locked dongle[%i].mutex_audio\n", kd
);
4323 SAY("ERROR: %i=kd is bad: cannot lock dongle\n", kd
);
4324 #ifndef CONFIG_EASYCAP_OSS
4325 if (0 != snd_card_free(peasycap
->psnd_card
)) {
4326 SAY("ERROR: snd_card_free() failed\n");
4328 peasycap
->psnd_card
= NULL
;
4329 (peasycap
->registered_audio
)--;
4331 #else /* CONFIG_EASYCAP_OSS */
4332 usb_deregister_dev(pusb_interface
, &easyoss_class
);
4333 peasycap
->registered_audio
--;
4334 JOM(4, "intf[%i]: usb_deregister_dev()\n", bInterfaceNumber
);
4335 SAM("easyoss detached from minor #%d\n", minor
);
4336 #endif /* CONFIG_EASYCAP_OSS */
4337 if (0 <= kd
&& DONGLE_MANY
> kd
) {
4338 mutex_unlock(&easycapdc60_dongle
[kd
].mutex_audio
);
4339 JOM(4, "unlocked dongle[%i].mutex_audio\n", kd
);
4346 /*---------------------------------------------------------------------------*/
4348 * CALL easycap_delete() IF NO REMAINING REFERENCES TO peasycap
4349 * (ALSO WHEN ALSA HAS BEEN IN USE)
4351 /*---------------------------------------------------------------------------*/
4352 if (!peasycap
->kref
.refcount
.counter
) {
4353 SAM("ERROR: peasycap->kref.refcount.counter is zero "
4354 "so cannot call kref_put()\n");
4355 SAM("ending unsuccessfully: may cause memory leak\n");
4358 if (0 <= kd
&& DONGLE_MANY
> kd
) {
4359 JOM(4, "about to lock dongle[%i].mutex_video\n", kd
);
4360 if (mutex_lock_interruptible(&easycapdc60_dongle
[kd
].mutex_video
)) {
4361 SAY("ERROR: cannot lock dongle[%i].mutex_video\n", kd
);
4362 SAM("ending unsuccessfully: may cause memory leak\n");
4365 JOM(4, "locked dongle[%i].mutex_video\n", kd
);
4366 JOM(4, "about to lock dongle[%i].mutex_audio\n", kd
);
4367 if (mutex_lock_interruptible(&easycapdc60_dongle
[kd
].mutex_audio
)) {
4368 SAY("ERROR: cannot lock dongle[%i].mutex_audio\n", kd
);
4369 mutex_unlock(&(easycapdc60_dongle
[kd
].mutex_video
));
4370 JOM(4, "unlocked dongle[%i].mutex_video\n", kd
);
4371 SAM("ending unsuccessfully: may cause memory leak\n");
4374 JOM(4, "locked dongle[%i].mutex_audio\n", kd
);
4376 JOM(4, "intf[%i]: %i=peasycap->kref.refcount.counter\n",
4377 bInterfaceNumber
, (int)peasycap
->kref
.refcount
.counter
);
4378 kref_put(&peasycap
->kref
, easycap_delete
);
4379 JOT(4, "intf[%i]: kref_put() done.\n", bInterfaceNumber
);
4380 if (0 <= kd
&& DONGLE_MANY
> kd
) {
4381 mutex_unlock(&(easycapdc60_dongle
[kd
].mutex_audio
));
4382 JOT(4, "unlocked dongle[%i].mutex_audio\n", kd
);
4383 mutex_unlock(&easycapdc60_dongle
[kd
].mutex_video
);
4384 JOT(4, "unlocked dongle[%i].mutex_video\n", kd
);
4386 /*---------------------------------------------------------------------------*/
4390 /*****************************************************************************/
4392 /*---------------------------------------------------------------------------*/
4394 * PARAMETERS APPLICABLE TO ENTIRE DRIVER, I.E. BOTH VIDEO AND AUDIO
4396 /*---------------------------------------------------------------------------*/
4397 static struct usb_device_id easycap_usb_device_id_table
[] = {
4398 {USB_DEVICE(USB_EASYCAP_VENDOR_ID
, USB_EASYCAP_PRODUCT_ID
)},
4402 MODULE_DEVICE_TABLE(usb
, easycap_usb_device_id_table
);
4403 struct usb_driver easycap_usb_driver
= {
4405 .id_table
= easycap_usb_device_id_table
,
4406 .probe
= easycap_usb_probe
,
4407 .disconnect
= easycap_usb_disconnect
,
4410 static int __init
easycap_module_init(void)
4414 printk(KERN_INFO
"Easycap version: "EASYCAP_DRIVER_VERSION
"\n");
4416 JOT(4, "begins. %i=debug %i=bars %i=gain\n",
4417 easycap_debug
, easycap_bars
, easycap_gain
);
4419 mutex_init(&mutex_dongle
);
4420 for (k
= 0; k
< DONGLE_MANY
; k
++) {
4421 easycapdc60_dongle
[k
].peasycap
= NULL
;
4422 mutex_init(&easycapdc60_dongle
[k
].mutex_video
);
4423 mutex_init(&easycapdc60_dongle
[k
].mutex_audio
);
4425 rc
= usb_register(&easycap_usb_driver
);
4427 printk(KERN_ERR
"Easycap: usb_register failed rc=%d\n", rc
);
4431 /*****************************************************************************/
4432 static void __exit
easycap_module_exit(void)
4434 usb_deregister(&easycap_usb_driver
);
4436 /*****************************************************************************/
4438 module_init(easycap_module_init
);
4439 module_exit(easycap_module_exit
);
4441 /*****************************************************************************/